[
  {
    "path": ".bmp.yml",
    "content": "---\nversion: 0.7.20\ncommit: 'chore(version): bump to v%.%.%'\nfiles:\n  src/core.ts: 'version: ''%.%.%'''\n  package.json: '\"version\": \"%.%.%\"'\n  component.json: '\"version\": \"%.%.%\"'\n"
  },
  {
    "path": ".circleci/config.yml",
    "content": "version: 2\n\nnode12: &node12\n  working_directory: ~/c3\n  docker:\n    - image: circleci/node:12-browsers\n\nnode14: &node14\n  working_directory: ~/c3\n  docker:\n    - image: circleci/node:14-browsers\n\nrestore_modules_cache: &restore_modules_cache\n  restore_cache:\n    keys:\n    - npm-4-{{ checksum \"package.json\" }}\n    # fallback to using the latest cache if no exact match is found\n    - npm-4-\n\nsave_modules_cache: &save_modules_cache\n  save_cache:\n    key: npm-4-{{ checksum \"package.json\" }}\n    paths: ./node_modules\n\ninstall_and_test: &install_and_test\n  steps:\n    - checkout\n    - run:\n        name: Display versions\n        command: |\n          echo \"node $(node -v)\"\n          echo \"npm v$(npm --version)\"\n          echo \"$(google-chrome --version)\"\n    - *restore_modules_cache\n    - run:\n        name: Installing Dependencies\n        command: yarn\n    - *save_modules_cache\n    - run: yarn test\n    - run: yarn codecov\n    - store_artifacts:\n        path: htdocs\n        destination: htdocs\n    - run: npx status-back -s -c circleci/htdocs -r c3js/c3 \"preview build succes!\" \"https://${CIRCLE_BUILD_NUM}-11496279-gh.circle-artifacts.com/0/htdocs/index.html\"\n\njobs:\n  test_on_node12:\n    <<: *node12\n    <<: *install_and_test\n\n  test_on_node14:\n    <<: *node14\n    <<: *install_and_test\n\n  docs:\n    docker:\n      - image: circleci/ruby:2.4-node\n        env:\n          BUNDLE_PATH: vendor/bundle\n    steps:\n      - checkout\n      - restore_cache:\n          key: deps-bundle-{{ checksum \"Gemfile.lock\" }}\n      - run: bundle install\n      - save_cache:\n          key: deps-bundle-{{ checksum \"Gemfile.lock\" }}\n          paths:\n            - vendor/bundle\n      - *restore_modules_cache\n      - run: yarn\n      - *save_modules_cache\n      - run: yarn build\n      - run: yarn copy-to-docs\n      - run: yarn build:docs\n      - store_artifacts:\n          path: build\n          destination: docs\n\nworkflows:\n  version: 2\n  test:\n    jobs:\n      - test_on_node12\n      - test_on_node14\n      - docs\n"
  },
  {
    "path": ".editorconfig",
    "content": "# editorconfig.org\nroot = true\n\n[*]\nindent_style = space\nindent_size = 4\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.yml]\nindent_size = 2\n\n[*.json]\nindent_size = 2\n\n[*.haml]\nindent_size = 2\n\n[*.html]\nindent_size = 2\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "<!--\n\nThis is not a catch-all support forum, for general support enquiries, please use the Google Group at https://groups.google.com/forum/#!forum/c3js.\n \nThank you for reporting an issue.\n\nPlease fill in as much of the template below as you're able.\n\nC3 version: The c3 version number which is available from `c3.version`.\nD3 version: The d3 version number.\nBrowser: The browser version.\nOS: The operating system.\n\nIf possible, please provide codepen or jsfiddle example that demonstrates the problem, keeping it as\nsimple and free of external dependencies as you are able.\n-->\n\n* **C3 version**:\n* **D3 version**:\n* **Browser**:\n* **OS**:\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!--\n\nThank you for contributing!\n\nPlease make sure to:\n \n- provide tests with your code changes to ensure they are working as expected.\n- not commit any of the distribution file (`c3.js`, `c3.css`, `c3.min.js`, `c3.min.css`).\n\n-->\n"
  },
  {
    "path": ".gitignore",
    "content": "# npm modules\nnode_modules\nbower_components\nd3.js\nd3.min.js\ncomponents\npackage-lock.json\n\n# build\n/htdocs/js/c3.js\n/htdocs/js/c3.min.js\n/htdocs/js/c3.esm.js\n/htdocs/css/c3.css\n/htdocs/css/c3.min.css\n/build\n\n# sass\n.sass-cache\n\n# jetbrains\n.idea/\n\n# coverage report\n/coverage\n\n# OS related\n.DS_Store\n\n# IDE related\n.idea\n.iml\n\n# bundle\n.bundle/config\nvendor/bundle\n"
  },
  {
    "path": ".jshintrc",
    "content": "{\n    \"esversion\": 6,\n    \"eqeqeq\": true,\n    \"curly\": true,\n    \"strict\": false,\n    \"trailing\": true,\n    \"white\": true,\n    \"maxlen\": 210,\n    \"undef\": true,\n    \"unused\": true,\n    \"indent\": 2,\n    \"eqnull\": true,\n    \"expr\": true,\n    \"newcap\": false,\n    \"loopfunc\": true,\n    \"bitwise\": false,\n    \"asi\": true,\n    \"laxbreak\": true,\n\n    \"browser\": true,\n    \"jasmine\": true,\n\n    \"globals\": {\n        \"d3\": false,\n        \"require\": false\n    }\n}\n"
  },
  {
    "path": ".prettierrc.json",
    "content": "{\n  \"tabWidth\": 2,\n  \"semi\": false,\n  \"singleQuote\": true\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: ruby\nrvm:\n  - 2.4\n\nbranches:\n  only:\n    - master\n\nscript:\n  - bundle exec middleman build\n\ndeploy:\n  provider: pages\n  skip-cleanup: true\n  local-dir: build\n  github-token: $GITHUB_TOKEN\n  keep-history: true\n  on:\n    branch: master\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "## Filing an issue\n\nBefore filing an issue, please [search the queue](https://github.com/c3js/c3/issues) to make sure it hasn't already been reported.\n\nIf a bug, please include the following —\n\n1. What version of C3?\n1. What browsers have you confirmed it in?\n1. Can you isolate the issue by providing a jsFiddle demonstrating it in a minimalist capacity?\n\nPlease *do not* ask for support using the issue queue. For support, please ask [on chat](https://gitter.im/c3js/c3) or [the mailing list](groups.google.com/forum/#!forum/c3js).\n\n## Setup\n 1. **Clone the repo from GitHub**\n\n        git clone https://github.com/c3js/c3.git\n        cd c3\n\n 2. **Acquire build dependencies.** Make sure you have [Node.js](http://nodejs.org/) installed on your workstation. This is only needed to _build_ C3 from sources. C3 itself has no dependency on Node.js once it is built. Now run:\n\n        npm install -g grunt-cli\n        npm install\n\n    The first `npm` command sets up the popular [Grunt](http://gruntjs.com/) build tool. You might need to run this command with `sudo` if you're on Linux or Mac OS X, or in an Administrator command prompt on Windows. The second `npm` command fetches the remaining build dependencies.\n\n## Building C3 from sources\n    npm run build\n\n\n## Distribution\n    npm run dist\n\nNow you'll find the built files in `c3.js`, `c3.min.js`, `c3.css` & `c3.min.css`.\n\n## Running the tests\n    npm run test\n\nThis command will automatically run the specification suite and report its results.\n\nIf you want to see specs running live in browser (e.g., for debugging), simply open `http://localhost:9876/` in your browser when phantomjs starts.\n\n## Building the document site (c3js.org)\n\nFirst you need ruby and [bundler][] to build the documentation site.\n\n**Note:** Currently the site doesn't build with ruby 2.5.x, so you need ruby 2.4.4 or below. ([rbenv][] is useful for switching between ruby versions.)\n\n```console\n$ gem install bundler\n```\n\nThen you need to install bundler dependencies.\n\n```console\n$ bundle install\n```\n\nThen hit the following command to build the site.\n\n```console\n$ npm run watch:docs\n```\n\nThen access `http://0.0.0.0:4567`.\n\n## Contributing your changes\n\nAdd something about PRs here, indicate that PRs should not bump the version number & the build output files (`c3.js`, `c3.min.js`, `c3.css` & `c3.min.css`) should be excluded\n\n[bundler]: https://bundler.io\n[rbenv]: https://github.com/rbenv/rbenv\n"
  },
  {
    "path": "Gemfile",
    "content": "# If you have OpenSSL installed, we recommend updating\n# the following line to use \"https\"\nsource 'http://rubygems.org'\n\ngem \"middleman\", \"~>3.2.2\"\n\n# Live-reloading plugin\ngem \"middleman-livereload\", \"~> 3.1.0\"\n\n# Sync plugin\ngem 'middleman-sync', '3.0.12'\ngem 'unf'\n\n# For faster file watcher updates on Windows:\ngem \"wdm\", \"~> 0.1.0\", :platforms => [:mswin, :mingw]\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013 Masayuki Tanaka\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject 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, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "MAINTAINANCE.md",
    "content": "# Release process\n\nIf you don't have `bmp` command installed, first install `bmp` ruby gem:\n\n    gem install bmp\n\nWhen master is ready for the next release, hit the command:\n\n    bmp -p\n\nThis automatically updates all the version numbers with a new one in the repository.\n\nThen hit the command:\n\n    npm run dist\n\nThis builds the scripts and stylesheets. Then hit:\n\n    bmp -c\n\nThis commits all the changes (including the built assets) and git-tags a new version (like v0.4.16):\n\nThen publish it to the npm registry (you need admin access to c3 module):\n\n    npm publish\n\nAt this point, the new version is available through npm.\n\nThen push master and the tag to github:\n\n    git push origin master vX.Y.Z\n\nThat's all.\n"
  },
  {
    "path": "README.md",
    "content": "# c3\n\n[![CircleCI](https://circleci.com/gh/c3js/c3.svg?style=shield)](https://circleci.com/gh/c3js/c3)\n[![license](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/c3js/c3/blob/master/LICENSE)\n[![codecov.io](https://codecov.io/github/c3js/c3/coverage.svg?branch=master)](https://codecov.io/github/c3js/c3?branch=master)\n\n[![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/c3/badge?style=rounded)](https://www.jsdelivr.com/package/npm/c3)\n\n> c3 is a D3-based reusable chart library that enables deeper integration of charts into web applications.\n\nFollow the link for more information: [http://c3js.org](http://c3js.org/)\n\n## Documentation\n\n+ [Getting Started](http://c3js.org/gettingstarted.html)\n+ [Examples](http://c3js.org/examples.html)\n+ [Full API Reference](https://c3js.org/reference.html)\n\nAdditional samples can be found in this repository:\n+ [https://github.com/c3js/c3/tree/master/htdocs/samples](https://github.com/c3js/c3/tree/master/htdocs/samples)\n\nYou can run these samples as:\n```\n$ npm run serve-static\n```\n\n## Google Group\nFor general C3.js-related discussion, please visit our [Google Group at https://groups.google.com/forum/#!forum/c3js](https://groups.google.com/forum/#!forum/c3js).\n\n## Gitter\n[![Join the chat at https://gitter.im/c3js/c3](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/c3js/c3?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n## Using the issue queue\nThe [issue queue](https://github.com/c3js/c3/issues) is to be used for reporting defects and problems with C3.js, in addition to feature requests and ideas. It is **not** a catch-all support forum. **For general support enquiries, please use the [Google Group](https://groups.google.com/forum/#!forum/c3js) at https://groups.google.com/forum/#!forum/c3js.** All questions involving the interplay between C3.js and any other library (such as AngularJS) should be posted there first!\n\nBefore reporting an issue, please do the following:\n\n1. [Search for existing issues](https://github.com/c3js/c3/issues) to ensure you're not posting a duplicate.\n\n1.  [Search the Google Group](https://groups.google.com/forum/#!forum/c3js) to ensure it hasn't been addressed there already.\n\n1. Create a JSFiddle or Plunkr highlighting the issue. Please don't include any unnecessary dependencies so we can isolate that the issue is in fact with C3. *Please be advised that custom CSS can modify C3.js output!*\n\n1. When posting the issue, please use a descriptive title and include the version of C3 (or, if cloning from Git, the commit hash — C3 is under active development and the master branch contains the latest dev commits!), along with any platform/browser/OS information that may be relevant.\n\n## Pull requests\nPull requests are welcome, though please post an issue first to see whether such a change is desirable.\nIf you choose to submit a pull request, please do not bump the version number unless asked to, and please include test cases for any new features. Squash all your commits as well, please.\n\n## Playground\nPlease fork this fiddle:\n\n+ http://jsfiddle.net/7kYJu/4742/\n\n## Dependency\n\n+ [D3.js](https://github.com/mbostock/d3) `^5.0.0`\n\n## License\n\nMIT\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"c3\",\n  \"main\": [\"c3.css\", \"c3.js\"],\n  \"homepage\": \"https://github.com/c3js/c3\",\n  \"authors\": [\"Masayuki Tanaka <masayuki0812@mac.com>\"],\n  \"description\": \"D3-based reusable chart library\",\n  \"keywords\": [\"chart\", \"d3\"],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"htdocs\",\n    \"spec\",\n    \"src/**/*.js\",\n    \"package.json\",\n    \"component.json\",\n    \"Gruntfile.*\"\n  ],\n  \"dependencies\": {\n    \"d3\": \"^5.0.0\"\n  }\n}\n"
  },
  {
    "path": "c3.css",
    "content": "/*-- Chart --*/\n.c3 svg {\n  font: 10px sans-serif;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\n.c3 path, .c3 line {\n  fill: none;\n  stroke: #000;\n}\n\n.c3 text {\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  user-select: none;\n}\n\n.c3-legend-item-tile,\n.c3-xgrid-focus,\n.c3-ygrid,\n.c3-event-rect,\n.c3-bars path {\n  shape-rendering: crispEdges;\n}\n\n.c3-chart-arc path {\n  stroke: #fff;\n}\n\n.c3-chart-arc rect {\n  stroke: white;\n  stroke-width: 1;\n}\n\n.c3-chart-arc text {\n  fill: #fff;\n  font-size: 13px;\n}\n\n/*-- Axis --*/\n/*-- Grid --*/\n.c3-grid line {\n  stroke: #aaa;\n}\n\n.c3-grid text {\n  fill: #aaa;\n}\n\n.c3-xgrid, .c3-ygrid {\n  stroke-dasharray: 3 3;\n}\n\n/*-- Text on Chart --*/\n.c3-text.c3-empty {\n  fill: #808080;\n  font-size: 2em;\n}\n\n/*-- Line --*/\n.c3-line {\n  stroke-width: 1px;\n}\n\n/*-- Point --*/\n.c3-circle {\n  fill: currentColor;\n}\n\n.c3-circle._expanded_ {\n  stroke-width: 1px;\n  stroke: white;\n}\n\n.c3-selected-circle {\n  fill: white;\n  stroke-width: 2px;\n}\n\n/*-- Bar --*/\n.c3-bar {\n  stroke-width: 0;\n}\n\n.c3-bar._expanded_ {\n  fill-opacity: 1;\n  fill-opacity: 0.75;\n}\n\n/*-- Focus --*/\n.c3-target.c3-focused {\n  opacity: 1;\n}\n\n.c3-target.c3-focused path.c3-line, .c3-target.c3-focused path.c3-step {\n  stroke-width: 2px;\n}\n\n.c3-target.c3-defocused {\n  opacity: 0.3 !important;\n}\n\n/*-- Region --*/\n.c3-region {\n  fill: steelblue;\n  fill-opacity: 0.1;\n}\n.c3-region text {\n  fill-opacity: 1;\n}\n\n/*-- Brush --*/\n.c3-brush .extent {\n  fill-opacity: 0.1;\n}\n\n/*-- Select - Drag --*/\n/*-- Legend --*/\n.c3-legend-item {\n  font-size: 12px;\n}\n\n.c3-legend-item-hidden {\n  opacity: 0.15;\n}\n\n.c3-legend-background {\n  opacity: 0.75;\n  fill: white;\n  stroke: lightgray;\n  stroke-width: 1;\n}\n\n/*-- Title --*/\n.c3-title {\n  font: 14px sans-serif;\n}\n\n/*-- Tooltip --*/\n.c3-tooltip-container {\n  z-index: 10;\n}\n\n.c3-tooltip {\n  border-collapse: collapse;\n  border-spacing: 0;\n  background-color: #fff;\n  empty-cells: show;\n  -webkit-box-shadow: 7px 7px 12px -9px #777777;\n  -moz-box-shadow: 7px 7px 12px -9px #777777;\n  box-shadow: 7px 7px 12px -9px #777777;\n  opacity: 0.9;\n}\n\n.c3-tooltip tr {\n  border: 1px solid #CCC;\n}\n\n.c3-tooltip th {\n  background-color: #aaa;\n  font-size: 14px;\n  padding: 2px 5px;\n  text-align: left;\n  color: #FFF;\n}\n\n.c3-tooltip td {\n  font-size: 13px;\n  padding: 3px 6px;\n  background-color: #fff;\n  border-left: 1px dotted #999;\n}\n\n.c3-tooltip td > span {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin-right: 6px;\n}\n\n.c3-tooltip .value {\n  text-align: right;\n}\n\n/*-- Area --*/\n.c3-area {\n  stroke-width: 0;\n  opacity: 0.2;\n}\n\n/*-- Arc --*/\n.c3-chart-arcs-title {\n  dominant-baseline: middle;\n  font-size: 1.3em;\n}\n\n.c3-chart-arcs .c3-chart-arcs-background {\n  fill: #e0e0e0;\n  stroke: #FFF;\n}\n\n.c3-chart-arcs .c3-chart-arcs-gauge-unit {\n  fill: #000;\n  font-size: 16px;\n}\n\n.c3-chart-arcs .c3-chart-arcs-gauge-max {\n  fill: #777;\n}\n\n.c3-chart-arcs .c3-chart-arcs-gauge-min {\n  fill: #777;\n}\n\n.c3-chart-arc .c3-gauge-value {\n  fill: #000;\n  /*  font-size: 28px !important;*/\n}\n\n.c3-chart-arc.c3-target g path {\n  opacity: 1;\n}\n\n.c3-chart-arc.c3-target.c3-focused g path {\n  opacity: 1;\n}\n\n/*-- Zoom --*/\n.c3-drag-zoom.enabled {\n  pointer-events: all !important;\n  visibility: visible;\n}\n\n.c3-drag-zoom.disabled {\n  pointer-events: none !important;\n  visibility: hidden;\n}\n\n.c3-drag-zoom .extent {\n  fill-opacity: 0.1;\n}\n"
  },
  {
    "path": "c3.esm.js",
    "content": "/* @license C3.js v0.7.18 | (c) C3 Team and other contributors | http://c3js.org/ */\nimport * as d3 from 'd3';\n\nfunction ChartInternal(api) {\n  var $$ = this;\n  // Note: This part will be replaced by rollup-plugin-modify\n  // When bundling esm output. Beware of changing this line.\n  // TODO: Maybe we should check that the modification by rollup-plugin-modify\n  // is valid during unit tests.\n  $$.d3 = window.d3\n    ? window.d3\n    : typeof require !== 'undefined'\n    ? require('d3')\n    : undefined;\n  $$.api = api;\n  $$.config = $$.getDefaultConfig();\n  $$.data = {};\n  $$.cache = {};\n  $$.axes = {};\n}\n\n/**\n * The Chart class\n *\n * The methods of this class is the public APIs of the chart object.\n */\nfunction Chart(config) {\n  this.internal = new ChartInternal(this);\n  this.internal.loadConfig(config);\n\n  this.internal.beforeInit(config);\n  this.internal.init();\n  this.internal.afterInit(config)\n\n  // bind \"this\" to nested API\n  ;(function bindThis(fn, target, argThis) {\n    Object.keys(fn).forEach(function(key) {\n      target[key] = fn[key].bind(argThis);\n      if (Object.keys(fn[key]).length > 0) {\n        bindThis(fn[key], target[key], argThis);\n      }\n    });\n  })(Chart.prototype, this, this);\n}\n\nvar asHalfPixel = function(n) {\n  return Math.ceil(n) + 0.5\n};\nvar ceil10 = function(v) {\n  return Math.ceil(v / 10) * 10\n};\nvar diffDomain = function(d) {\n  return d[1] - d[0]\n};\nvar getOption = function(options, key, defaultValue) {\n  return isDefined(options[key]) ? options[key] : defaultValue\n};\nvar getPathBox = function(path) {\n  var box = getBBox(path),\n    items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)],\n    minX = items[0].x,\n    minY = Math.min(items[0].y, items[1].y);\n  return { x: minX, y: minY, width: box.width, height: box.height }\n};\nvar getBBox = function(element) {\n  try {\n    return element.getBBox()\n  } catch (ignore) {\n    // Firefox will throw an exception if getBBox() is called whereas the\n    // element is rendered with display:none\n    // See https://github.com/c3js/c3/issues/2692\n\n    // The previous code was using `getBoundingClientRect` which was returning\n    // everything at 0 in this case so let's reproduce this behavior here.\n\n    return { x: 0, y: 0, width: 0, height: 0 }\n  }\n};\nvar hasValue = function(dict, value) {\n  var found = false;\n  Object.keys(dict).forEach(function(key) {\n    if (dict[key] === value) {\n      found = true;\n    }\n  });\n  return found\n};\nvar isArray = function(o) {\n  return Array.isArray(o)\n};\nvar isDefined = function(v) {\n  return typeof v !== 'undefined'\n};\nvar isEmpty = function(o) {\n  return (\n    typeof o === 'undefined' ||\n    o === null ||\n    (isString(o) && o.length === 0) ||\n    (typeof o === 'object' && Object.keys(o).length === 0)\n  )\n};\nvar isFunction = function(o) {\n  return typeof o === 'function'\n};\nvar isNumber = function(o) {\n  return typeof o === 'number'\n};\nvar isString = function(o) {\n  return typeof o === 'string'\n};\nvar isUndefined = function(v) {\n  return typeof v === 'undefined'\n};\nvar isValue = function(v) {\n  return v || v === 0\n};\nvar notEmpty = function(o) {\n  return !isEmpty(o)\n};\nvar sanitise = function(str) {\n  return typeof str === 'string'\n    ? str.replace(/</g, '&lt;').replace(/>/g, '&gt;')\n    : str\n};\nvar flattenArray = function(arr) {\n  return Array.isArray(arr) ? [].concat(...arr) : []\n};\n/**\n * Returns whether the point is within the given box.\n *\n * @param {Array} point An [x,y] coordinate\n * @param {Object} box An object with {x, y, width, height} keys\n * @param {Number} sensitivity An offset to ease check on very small boxes\n */\nvar isWithinBox = function(point, box, sensitivity = 0) {\n  const xStart = box.x - sensitivity;\n  const xEnd = box.x + box.width + sensitivity;\n  const yStart = box.y + box.height + sensitivity;\n  const yEnd = box.y - sensitivity;\n\n  return (\n    xStart < point[0] && point[0] < xEnd && yEnd < point[1] && point[1] < yStart\n  )\n};\n\n/**\n * Returns Internet Explorer version number (or false if no Internet Explorer used).\n *\n * @param string agent Optional parameter to specify user agent\n */\nvar getIEVersion = function(agent) {\n  // https://stackoverflow.com/questions/19999388/check-if-user-is-using-ie\n  if (typeof agent === 'undefined') {\n    agent = window.navigator.userAgent;\n  }\n\n  let pos = agent.indexOf('MSIE '); // up to IE10\n  if (pos > 0) {\n    return parseInt(agent.substring(pos + 5, agent.indexOf('.', pos)), 10)\n  }\n\n  pos = agent.indexOf('Trident/'); // IE11\n  if (pos > 0) {\n    pos = agent.indexOf('rv:');\n    return parseInt(agent.substring(pos + 3, agent.indexOf('.', pos)), 10)\n  }\n\n  return false\n};\n\n/**\n * Returns whether the used browser is Internet Explorer.\n *\n * @param {Number} version Optional parameter to specify IE version\n */\nvar isIE = function(version) {\n  const ver = getIEVersion();\n\n  if (typeof version === 'undefined') {\n    return !!ver\n  }\n\n  return version === ver\n};\n\nfunction AxisInternal(component, params) {\n  var internal = this;\n  internal.component = component;\n  internal.params = params || {};\n\n  internal.d3 = component.d3;\n  internal.scale = internal.d3.scaleLinear();\n  internal.range;\n  internal.orient = 'bottom';\n  internal.innerTickSize = 6;\n  internal.outerTickSize = this.params.withOuterTick ? 6 : 0;\n  internal.tickPadding = 3;\n  internal.tickValues = null;\n  internal.tickFormat;\n  internal.tickArguments;\n\n  internal.tickOffset = 0;\n  internal.tickCulling = true;\n  internal.tickCentered;\n  internal.tickTextCharSize;\n  internal.tickTextRotate = internal.params.tickTextRotate;\n  internal.tickLength;\n\n  internal.axis = internal.generateAxis();\n}\n\nAxisInternal.prototype.axisX = function(selection, x, tickOffset) {\n  selection.attr('transform', function(d) {\n    return 'translate(' + Math.ceil(x(d) + tickOffset) + ', 0)'\n  });\n};\nAxisInternal.prototype.axisY = function(selection, y) {\n  selection.attr('transform', function(d) {\n    return 'translate(0,' + Math.ceil(y(d)) + ')'\n  });\n};\nAxisInternal.prototype.scaleExtent = function(domain) {\n  var start = domain[0],\n    stop = domain[domain.length - 1];\n  return start < stop ? [start, stop] : [stop, start]\n};\nAxisInternal.prototype.generateTicks = function(scale) {\n  var internal = this;\n  var i,\n    domain,\n    ticks = [];\n  if (scale.ticks) {\n    return scale.ticks.apply(scale, internal.tickArguments)\n  }\n  domain = scale.domain();\n  for (i = Math.ceil(domain[0]); i < domain[1]; i++) {\n    ticks.push(i);\n  }\n  if (ticks.length > 0 && ticks[0] > 0) {\n    ticks.unshift(ticks[0] - (ticks[1] - ticks[0]));\n  }\n  return ticks\n};\nAxisInternal.prototype.copyScale = function() {\n  var internal = this;\n  var newScale = internal.scale.copy(),\n    domain;\n  if (internal.params.isCategory) {\n    domain = internal.scale.domain();\n    newScale.domain([domain[0], domain[1] - 1]);\n  }\n  return newScale\n};\nAxisInternal.prototype.textFormatted = function(v) {\n  var internal = this,\n    formatted = internal.tickFormat ? internal.tickFormat(v) : v;\n  return typeof formatted !== 'undefined' ? formatted : ''\n};\nAxisInternal.prototype.updateRange = function() {\n  var internal = this;\n  internal.range = internal.scale.rangeExtent\n    ? internal.scale.rangeExtent()\n    : internal.scaleExtent(internal.scale.range());\n  return internal.range\n};\nAxisInternal.prototype.updateTickTextCharSize = function(tick) {\n  var internal = this;\n  if (internal.tickTextCharSize) {\n    return internal.tickTextCharSize\n  }\n  var size = {\n    h: 11.5,\n    w: 5.5\n  };\n  tick\n    .select('text')\n    .text(function(d) {\n      return internal.textFormatted(d)\n    })\n    .each(function(d) {\n      var box = getBBox(this),\n        text = internal.textFormatted(d),\n        h = box.height,\n        w = text ? box.width / text.length : undefined;\n      if (h && w) {\n        size.h = h;\n        size.w = w;\n      }\n    })\n    .text('');\n  internal.tickTextCharSize = size;\n  return size\n};\nAxisInternal.prototype.isVertical = function() {\n  return this.orient === 'left' || this.orient === 'right'\n};\nAxisInternal.prototype.tspanData = function(d, i, scale) {\n  var internal = this;\n  var splitted = internal.params.tickMultiline\n    ? internal.splitTickText(d, scale)\n    : [].concat(internal.textFormatted(d));\n\n  if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) {\n    splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax);\n  }\n\n  return splitted.map(function(s) {\n    return { index: i, splitted: s, length: splitted.length }\n  })\n};\nAxisInternal.prototype.splitTickText = function(d, scale) {\n  var internal = this,\n    tickText = internal.textFormatted(d),\n    maxWidth = internal.params.tickWidth,\n    subtext,\n    spaceIndex,\n    textWidth,\n    splitted = [];\n\n  if (Object.prototype.toString.call(tickText) === '[object Array]') {\n    return tickText\n  }\n\n  if (!maxWidth || maxWidth <= 0) {\n    maxWidth = internal.isVertical()\n      ? 95\n      : internal.params.isCategory\n      ? Math.ceil(scale(1) - scale(0)) - 12\n      : 110;\n  }\n\n  function split(splitted, text) {\n    spaceIndex = undefined;\n    for (var i = 1; i < text.length; i++) {\n      if (text.charAt(i) === ' ') {\n        spaceIndex = i;\n      }\n      subtext = text.substr(0, i + 1);\n      textWidth = internal.tickTextCharSize.w * subtext.length;\n      // if text width gets over tick width, split by space index or crrent index\n      if (maxWidth < textWidth) {\n        return split(\n          splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)),\n          text.slice(spaceIndex ? spaceIndex + 1 : i)\n        )\n      }\n    }\n    return splitted.concat(text)\n  }\n\n  return split(splitted, tickText + '')\n};\nAxisInternal.prototype.ellipsify = function(splitted, max) {\n  if (splitted.length <= max) {\n    return splitted\n  }\n\n  var ellipsified = splitted.slice(0, max);\n  var remaining = 3;\n  for (var i = max - 1; i >= 0; i--) {\n    var available = ellipsified[i].length;\n\n    ellipsified[i] = ellipsified[i]\n      .substr(0, available - remaining)\n      .padEnd(available, '.');\n\n    remaining -= available;\n\n    if (remaining <= 0) {\n      break\n    }\n  }\n\n  return ellipsified\n};\nAxisInternal.prototype.updateTickLength = function() {\n  var internal = this;\n  internal.tickLength =\n    Math.max(internal.innerTickSize, 0) + internal.tickPadding;\n};\nAxisInternal.prototype.lineY2 = function(d) {\n  var internal = this,\n    tickPosition =\n      internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset);\n  return internal.range[0] < tickPosition && tickPosition < internal.range[1]\n    ? internal.innerTickSize\n    : 0\n};\nAxisInternal.prototype.textY = function() {\n  var internal = this,\n    rotate = internal.tickTextRotate;\n  return rotate\n    ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1)\n    : internal.tickLength\n};\nAxisInternal.prototype.textTransform = function() {\n  var internal = this,\n    rotate = internal.tickTextRotate;\n  return rotate ? 'rotate(' + rotate + ')' : ''\n};\nAxisInternal.prototype.textTextAnchor = function() {\n  var internal = this,\n    rotate = internal.tickTextRotate;\n  return rotate ? (rotate > 0 ? 'start' : 'end') : 'middle'\n};\nAxisInternal.prototype.tspanDx = function() {\n  var internal = this,\n    rotate = internal.tickTextRotate;\n  return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0\n};\nAxisInternal.prototype.tspanDy = function(d, i) {\n  var internal = this,\n    dy = internal.tickTextCharSize.h;\n  if (i === 0) {\n    if (internal.isVertical()) {\n      dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3);\n    } else {\n      dy = '.71em';\n    }\n  }\n  return dy\n};\n\nAxisInternal.prototype.generateAxis = function() {\n  var internal = this,\n    d3 = internal.d3,\n    params = internal.params;\n  function axis(g, transition) {\n    var self;\n    g.each(function() {\n      var g = (axis.g = d3.select(this));\n\n      var scale0 = this.__chart__ || internal.scale,\n        scale1 = (this.__chart__ = internal.copyScale());\n\n      var ticksValues = internal.tickValues\n          ? internal.tickValues\n          : internal.generateTicks(scale1),\n        ticks = g.selectAll('.tick').data(ticksValues, scale1),\n        tickEnter = ticks\n          .enter()\n          .insert('g', '.domain')\n          .attr('class', 'tick')\n          .style('opacity', 1e-6),\n        // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks.\n        tickExit = ticks.exit().remove(),\n        tickUpdate = ticks.merge(tickEnter),\n        tickTransform,\n        tickX,\n        tickY;\n\n      if (params.isCategory) {\n        internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);\n        tickX = internal.tickCentered ? 0 : internal.tickOffset;\n        tickY = internal.tickCentered ? internal.tickOffset : 0;\n      } else {\n        internal.tickOffset = tickX = 0;\n      }\n\n      internal.updateRange();\n      internal.updateTickLength();\n      internal.updateTickTextCharSize(g.select('.tick'));\n\n      var lineUpdate = tickUpdate\n          .select('line')\n          .merge(tickEnter.append('line')),\n        textUpdate = tickUpdate.select('text').merge(tickEnter.append('text'));\n\n      var tspans = tickUpdate\n          .selectAll('text')\n          .selectAll('tspan')\n          .data(function(d, i) {\n            return internal.tspanData(d, i, scale1)\n          }),\n        tspanEnter = tspans.enter().append('tspan'),\n        tspanUpdate = tspanEnter.merge(tspans).text(function(d) {\n          return d.splitted\n        });\n      tspans.exit().remove();\n\n      var path = g.selectAll('.domain').data([0]),\n        pathUpdate = path\n          .enter()\n          .append('path')\n          .merge(path)\n          .attr('class', 'domain');\n\n      // TODO: each attr should be one function and change its behavior by internal.orient, probably\n      switch (internal.orient) {\n        case 'bottom': {\n          tickTransform = internal.axisX;\n          lineUpdate\n            .attr('x1', tickX)\n            .attr('x2', tickX)\n            .attr('y2', function(d, i) {\n              return internal.lineY2(d, i)\n            });\n          textUpdate\n            .attr('x', 0)\n            .attr('y', function(d, i) {\n              return internal.textY(d, i)\n            })\n            .attr('transform', function(d, i) {\n              return internal.textTransform(d, i)\n            })\n            .style('text-anchor', function(d, i) {\n              return internal.textTextAnchor(d, i)\n            });\n          tspanUpdate\n            .attr('x', 0)\n            .attr('dy', function(d, i) {\n              return internal.tspanDy(d, i)\n            })\n            .attr('dx', function(d, i) {\n              return internal.tspanDx(d, i)\n            });\n          pathUpdate.attr(\n            'd',\n            'M' +\n              internal.range[0] +\n              ',' +\n              internal.outerTickSize +\n              'V0H' +\n              internal.range[1] +\n              'V' +\n              internal.outerTickSize\n          );\n          break\n        }\n        case 'top': {\n          // TODO: rotated tick text\n          tickTransform = internal.axisX;\n          lineUpdate\n            .attr('x1', tickX)\n            .attr('x2', tickX)\n            .attr('y2', function(d, i) {\n              return -1 * internal.lineY2(d, i)\n            });\n          textUpdate\n            .attr('x', 0)\n            .attr('y', function(d, i) {\n              return (\n                -1 * internal.textY(d, i) -\n                (params.isCategory ? 2 : internal.tickLength - 2)\n              )\n            })\n            .attr('transform', function(d, i) {\n              return internal.textTransform(d, i)\n            })\n            .style('text-anchor', function(d, i) {\n              return internal.textTextAnchor(d, i)\n            });\n          tspanUpdate\n            .attr('x', 0)\n            .attr('dy', function(d, i) {\n              return internal.tspanDy(d, i)\n            })\n            .attr('dx', function(d, i) {\n              return internal.tspanDx(d, i)\n            });\n          pathUpdate.attr(\n            'd',\n            'M' +\n              internal.range[0] +\n              ',' +\n              -internal.outerTickSize +\n              'V0H' +\n              internal.range[1] +\n              'V' +\n              -internal.outerTickSize\n          );\n          break\n        }\n        case 'left': {\n          tickTransform = internal.axisY;\n          lineUpdate\n            .attr('x2', -internal.innerTickSize)\n            .attr('y1', tickY)\n            .attr('y2', tickY);\n          textUpdate\n            .attr('x', -internal.tickLength)\n            .attr('y', internal.tickOffset)\n            .style('text-anchor', 'end');\n          tspanUpdate\n            .attr('x', -internal.tickLength)\n            .attr('dy', function(d, i) {\n              return internal.tspanDy(d, i)\n            });\n          pathUpdate.attr(\n            'd',\n            'M' +\n              -internal.outerTickSize +\n              ',' +\n              internal.range[0] +\n              'H0V' +\n              internal.range[1] +\n              'H' +\n              -internal.outerTickSize\n          );\n          break\n        }\n        case 'right': {\n          tickTransform = internal.axisY;\n          lineUpdate\n            .attr('x2', internal.innerTickSize)\n            .attr('y1', tickY)\n            .attr('y2', tickY);\n          textUpdate\n            .attr('x', internal.tickLength)\n            .attr('y', internal.tickOffset)\n            .style('text-anchor', 'start');\n          tspanUpdate.attr('x', internal.tickLength).attr('dy', function(d, i) {\n            return internal.tspanDy(d, i)\n          });\n          pathUpdate.attr(\n            'd',\n            'M' +\n              internal.outerTickSize +\n              ',' +\n              internal.range[0] +\n              'H0V' +\n              internal.range[1] +\n              'H' +\n              internal.outerTickSize\n          );\n          break\n        }\n      }\n      if (scale1.rangeBand) {\n        var x = scale1,\n          dx = x.rangeBand() / 2;\n        scale0 = scale1 = function(d) {\n          return x(d) + dx\n        };\n      } else if (scale0.rangeBand) {\n        scale0 = scale1;\n      } else {\n        tickExit.call(tickTransform, scale1, internal.tickOffset);\n      }\n      tickEnter.call(tickTransform, scale0, internal.tickOffset);\n      self = (transition ? tickUpdate.transition(transition) : tickUpdate)\n        .style('opacity', 1)\n        .call(tickTransform, scale1, internal.tickOffset);\n    });\n    return self\n  }\n  axis.scale = function(x) {\n    if (!arguments.length) {\n      return internal.scale\n    }\n    internal.scale = x;\n    return axis\n  };\n  axis.orient = function(x) {\n    if (!arguments.length) {\n      return internal.orient\n    }\n    internal.orient =\n      x in { top: 1, right: 1, bottom: 1, left: 1 } ? x + '' : 'bottom';\n    return axis\n  };\n  axis.tickFormat = function(format) {\n    if (!arguments.length) {\n      return internal.tickFormat\n    }\n    internal.tickFormat = format;\n    return axis\n  };\n  axis.tickCentered = function(isCentered) {\n    if (!arguments.length) {\n      return internal.tickCentered\n    }\n    internal.tickCentered = isCentered;\n    return axis\n  };\n  axis.tickOffset = function() {\n    return internal.tickOffset\n  };\n  axis.tickInterval = function() {\n    var interval, length;\n    if (params.isCategory) {\n      interval = internal.tickOffset * 2;\n    } else {\n      length =\n        axis.g\n          .select('path.domain')\n          .node()\n          .getTotalLength() -\n        internal.outerTickSize * 2;\n      interval = length / axis.g.selectAll('line').size();\n    }\n    return interval === Infinity ? 0 : interval\n  };\n  axis.ticks = function() {\n    if (!arguments.length) {\n      return internal.tickArguments\n    }\n    internal.tickArguments = arguments;\n    return axis\n  };\n  axis.tickCulling = function(culling) {\n    if (!arguments.length) {\n      return internal.tickCulling\n    }\n    internal.tickCulling = culling;\n    return axis\n  };\n  axis.tickValues = function(x) {\n    if (typeof x === 'function') {\n      internal.tickValues = function() {\n        return x(internal.scale.domain())\n      };\n    } else {\n      if (!arguments.length) {\n        return internal.tickValues\n      }\n      internal.tickValues = x;\n    }\n    return axis\n  };\n  return axis\n};\n\nvar CLASS = {\n  target: 'c3-target',\n  chart: 'c3-chart',\n  chartLine: 'c3-chart-line',\n  chartLines: 'c3-chart-lines',\n  chartBar: 'c3-chart-bar',\n  chartBars: 'c3-chart-bars',\n  chartText: 'c3-chart-text',\n  chartTexts: 'c3-chart-texts',\n  chartArc: 'c3-chart-arc',\n  chartArcs: 'c3-chart-arcs',\n  chartArcsTitle: 'c3-chart-arcs-title',\n  chartArcsBackground: 'c3-chart-arcs-background',\n  chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit',\n  chartArcsGaugeMax: 'c3-chart-arcs-gauge-max',\n  chartArcsGaugeMin: 'c3-chart-arcs-gauge-min',\n  selectedCircle: 'c3-selected-circle',\n  selectedCircles: 'c3-selected-circles',\n  eventRect: 'c3-event-rect',\n  eventRects: 'c3-event-rects',\n  eventRectsSingle: 'c3-event-rects-single',\n  eventRectsMultiple: 'c3-event-rects-multiple',\n  zoomRect: 'c3-zoom-rect',\n  brush: 'c3-brush',\n  dragZoom: 'c3-drag-zoom',\n  focused: 'c3-focused',\n  defocused: 'c3-defocused',\n  region: 'c3-region',\n  regions: 'c3-regions',\n  title: 'c3-title',\n  tooltipContainer: 'c3-tooltip-container',\n  tooltip: 'c3-tooltip',\n  tooltipName: 'c3-tooltip-name',\n  shape: 'c3-shape',\n  shapes: 'c3-shapes',\n  line: 'c3-line',\n  lines: 'c3-lines',\n  bar: 'c3-bar',\n  bars: 'c3-bars',\n  circle: 'c3-circle',\n  circles: 'c3-circles',\n  arc: 'c3-arc',\n  arcLabelLine: 'c3-arc-label-line',\n  arcs: 'c3-arcs',\n  area: 'c3-area',\n  areas: 'c3-areas',\n  empty: 'c3-empty',\n  text: 'c3-text',\n  texts: 'c3-texts',\n  gaugeValue: 'c3-gauge-value',\n  grid: 'c3-grid',\n  gridLines: 'c3-grid-lines',\n  xgrid: 'c3-xgrid',\n  xgrids: 'c3-xgrids',\n  xgridLine: 'c3-xgrid-line',\n  xgridLines: 'c3-xgrid-lines',\n  xgridFocus: 'c3-xgrid-focus',\n  ygrid: 'c3-ygrid',\n  ygrids: 'c3-ygrids',\n  ygridLine: 'c3-ygrid-line',\n  ygridLines: 'c3-ygrid-lines',\n  colorScale: 'c3-colorscale',\n  stanfordElements: 'c3-stanford-elements',\n  stanfordLine: 'c3-stanford-line',\n  stanfordLines: 'c3-stanford-lines',\n  stanfordRegion: 'c3-stanford-region',\n  stanfordRegions: 'c3-stanford-regions',\n  stanfordText: 'c3-stanford-text',\n  stanfordTexts: 'c3-stanford-texts',\n  axis: 'c3-axis',\n  axisX: 'c3-axis-x',\n  axisXLabel: 'c3-axis-x-label',\n  axisY: 'c3-axis-y',\n  axisYLabel: 'c3-axis-y-label',\n  axisY2: 'c3-axis-y2',\n  axisY2Label: 'c3-axis-y2-label',\n  legendBackground: 'c3-legend-background',\n  legendItem: 'c3-legend-item',\n  legendItemEvent: 'c3-legend-item-event',\n  legendItemTile: 'c3-legend-item-tile',\n  legendItemHidden: 'c3-legend-item-hidden',\n  legendItemFocused: 'c3-legend-item-focused',\n  dragarea: 'c3-dragarea',\n  EXPANDED: '_expanded_',\n  SELECTED: '_selected_',\n  INCLUDED: '_included_'\n};\n\nclass Axis {\n  constructor(owner) {\n    this.owner = owner;\n    this.d3 = owner.d3;\n    this.internal = AxisInternal;\n  }\n}\nAxis.prototype.init = function init() {\n  var $$ = this.owner,\n    config = $$.config,\n    main = $$.main;\n  $$.axes.x = main\n    .append('g')\n    .attr('class', CLASS.axis + ' ' + CLASS.axisX)\n    .attr('clip-path', config.axis_x_inner ? '' : $$.clipPathForXAxis)\n    .attr('transform', $$.getTranslate('x'))\n    .style('visibility', config.axis_x_show ? 'visible' : 'hidden');\n  $$.axes.x\n    .append('text')\n    .attr('class', CLASS.axisXLabel)\n    .attr('transform', config.axis_rotated ? 'rotate(-90)' : '')\n    .style('text-anchor', this.textAnchorForXAxisLabel.bind(this));\n  $$.axes.y = main\n    .append('g')\n    .attr('class', CLASS.axis + ' ' + CLASS.axisY)\n    .attr('clip-path', config.axis_y_inner ? '' : $$.clipPathForYAxis)\n    .attr('transform', $$.getTranslate('y'))\n    .style('visibility', config.axis_y_show ? 'visible' : 'hidden');\n  $$.axes.y\n    .append('text')\n    .attr('class', CLASS.axisYLabel)\n    .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\n    .style('text-anchor', this.textAnchorForYAxisLabel.bind(this));\n\n  $$.axes.y2 = main\n    .append('g')\n    .attr('class', CLASS.axis + ' ' + CLASS.axisY2)\n    // clip-path?\n    .attr('transform', $$.getTranslate('y2'))\n    .style('visibility', config.axis_y2_show ? 'visible' : 'hidden');\n  $$.axes.y2\n    .append('text')\n    .attr('class', CLASS.axisY2Label)\n    .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\n    .style('text-anchor', this.textAnchorForY2AxisLabel.bind(this));\n};\nAxis.prototype.getXAxis = function getXAxis(\n  scale,\n  orient,\n  tickFormat,\n  tickValues,\n  withOuterTick,\n  withoutTransition,\n  withoutRotateTickText\n) {\n  var $$ = this.owner,\n    config = $$.config,\n    axisParams = {\n      isCategory: $$.isCategorized(),\n      withOuterTick: withOuterTick,\n      tickMultiline: config.axis_x_tick_multiline,\n      tickMultilineMax: config.axis_x_tick_multiline\n        ? Number(config.axis_x_tick_multilineMax)\n        : 0,\n      tickWidth: config.axis_x_tick_width,\n      tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate,\n      withoutTransition: withoutTransition\n    },\n    axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient);\n\n  if ($$.isTimeSeries() && tickValues && typeof tickValues !== 'function') {\n    tickValues = tickValues.map(function(v) {\n      return $$.parseDate(v)\n    });\n  }\n\n  // Set tick\n  axis.tickFormat(tickFormat).tickValues(tickValues);\n  if ($$.isCategorized()) {\n    axis.tickCentered(config.axis_x_tick_centered);\n    if (isEmpty(config.axis_x_tick_culling)) {\n      config.axis_x_tick_culling = false;\n    }\n  }\n\n  return axis\n};\nAxis.prototype.updateXAxisTickValues = function updateXAxisTickValues(\n  targets,\n  axis\n) {\n  var $$ = this.owner,\n    config = $$.config,\n    tickValues;\n  if (config.axis_x_tick_fit || config.axis_x_tick_count) {\n    tickValues = this.generateTickValues(\n      $$.mapTargetsToUniqueXs(targets),\n      config.axis_x_tick_count,\n      $$.isTimeSeries()\n    );\n  }\n  if (axis) {\n    axis.tickValues(tickValues);\n  } else {\n    $$.xAxis.tickValues(tickValues);\n    $$.subXAxis.tickValues(tickValues);\n  }\n  return tickValues\n};\nAxis.prototype.getYAxis = function getYAxis(\n  axisId,\n  scale,\n  orient,\n  tickValues,\n  withOuterTick,\n  withoutTransition,\n  withoutRotateTickText\n) {\n  const $$ = this.owner;\n  const config = $$.config;\n\n  let tickFormat = config[`axis_${axisId}_tick_format`];\n  if (!tickFormat && $$.isAxisNormalized(axisId)) {\n    tickFormat = x => `${x}%`;\n  }\n\n  const axis = new this.internal(this, {\n    withOuterTick: withOuterTick,\n    withoutTransition: withoutTransition,\n    tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate\n  }).axis\n    .scale(scale)\n    .orient(orient);\n\n  if (tickFormat) {\n    axis.tickFormat(tickFormat);\n  }\n\n  if ($$.isTimeSeriesY()) {\n    axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval);\n  } else {\n    axis.tickValues(tickValues);\n  }\n  return axis\n};\nAxis.prototype.getId = function getId(id) {\n  var config = this.owner.config;\n  return id in config.data_axes ? config.data_axes[id] : 'y'\n};\nAxis.prototype.getXAxisTickFormat = function getXAxisTickFormat() {\n  // #2251 previously set any negative values to a whole number,\n  // however both should be truncated according to the users format specification\n  var $$ = this.owner,\n    config = $$.config;\n  let format = $$.isTimeSeries()\n    ? $$.defaultAxisTimeFormat\n    : $$.isCategorized()\n    ? $$.categoryName\n    : function(v) {\n        return v\n      };\n\n  if (config.axis_x_tick_format) {\n    if (isFunction(config.axis_x_tick_format)) {\n      format = config.axis_x_tick_format;\n    } else if ($$.isTimeSeries()) {\n      format = function(date) {\n        return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : ''\n      };\n    }\n  }\n  return isFunction(format)\n    ? function(v) {\n        return format.call($$, v)\n      }\n    : format\n};\nAxis.prototype.getTickValues = function getTickValues(tickValues, axis) {\n  return tickValues ? tickValues : axis ? axis.tickValues() : undefined\n};\nAxis.prototype.getXAxisTickValues = function getXAxisTickValues() {\n  return this.getTickValues(\n    this.owner.config.axis_x_tick_values,\n    this.owner.xAxis\n  )\n};\nAxis.prototype.getYAxisTickValues = function getYAxisTickValues() {\n  return this.getTickValues(\n    this.owner.config.axis_y_tick_values,\n    this.owner.yAxis\n  )\n};\nAxis.prototype.getY2AxisTickValues = function getY2AxisTickValues() {\n  return this.getTickValues(\n    this.owner.config.axis_y2_tick_values,\n    this.owner.y2Axis\n  )\n};\nAxis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(\n  axisId\n) {\n  var $$ = this.owner,\n    config = $$.config,\n    option;\n  if (axisId === 'y') {\n    option = config.axis_y_label;\n  } else if (axisId === 'y2') {\n    option = config.axis_y2_label;\n  } else if (axisId === 'x') {\n    option = config.axis_x_label;\n  }\n  return option\n};\nAxis.prototype.getLabelText = function getLabelText(axisId) {\n  var option = this.getLabelOptionByAxisId(axisId);\n  return isString(option) ? option : option ? option.text : null\n};\nAxis.prototype.setLabelText = function setLabelText(axisId, text) {\n  var $$ = this.owner,\n    config = $$.config,\n    option = this.getLabelOptionByAxisId(axisId);\n  if (isString(option)) {\n    if (axisId === 'y') {\n      config.axis_y_label = text;\n    } else if (axisId === 'y2') {\n      config.axis_y2_label = text;\n    } else if (axisId === 'x') {\n      config.axis_x_label = text;\n    }\n  } else if (option) {\n    option.text = text;\n  }\n};\nAxis.prototype.getLabelPosition = function getLabelPosition(\n  axisId,\n  defaultPosition\n) {\n  var option = this.getLabelOptionByAxisId(axisId),\n    position =\n      option && typeof option === 'object' && option.position\n        ? option.position\n        : defaultPosition;\n  return {\n    isInner: position.indexOf('inner') >= 0,\n    isOuter: position.indexOf('outer') >= 0,\n    isLeft: position.indexOf('left') >= 0,\n    isCenter: position.indexOf('center') >= 0,\n    isRight: position.indexOf('right') >= 0,\n    isTop: position.indexOf('top') >= 0,\n    isMiddle: position.indexOf('middle') >= 0,\n    isBottom: position.indexOf('bottom') >= 0\n  }\n};\nAxis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() {\n  return this.getLabelPosition(\n    'x',\n    this.owner.config.axis_rotated ? 'inner-top' : 'inner-right'\n  )\n};\nAxis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() {\n  return this.getLabelPosition(\n    'y',\n    this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'\n  )\n};\nAxis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() {\n  return this.getLabelPosition(\n    'y2',\n    this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'\n  )\n};\nAxis.prototype.getLabelPositionById = function getLabelPositionById(id) {\n  return id === 'y2'\n    ? this.getY2AxisLabelPosition()\n    : id === 'y'\n    ? this.getYAxisLabelPosition()\n    : this.getXAxisLabelPosition()\n};\nAxis.prototype.textForXAxisLabel = function textForXAxisLabel() {\n  return this.getLabelText('x')\n};\nAxis.prototype.textForYAxisLabel = function textForYAxisLabel() {\n  return this.getLabelText('y')\n};\nAxis.prototype.textForY2AxisLabel = function textForY2AxisLabel() {\n  return this.getLabelText('y2')\n};\nAxis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) {\n  var $$ = this.owner;\n  if (forHorizontal) {\n    return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width\n  } else {\n    return position.isBottom\n      ? -$$.height\n      : position.isMiddle\n      ? -$$.height / 2\n      : 0\n  }\n};\nAxis.prototype.dxForAxisLabel = function dxForAxisLabel(\n  forHorizontal,\n  position\n) {\n  if (forHorizontal) {\n    return position.isLeft ? '0.5em' : position.isRight ? '-0.5em' : '0'\n  } else {\n    return position.isTop ? '-0.5em' : position.isBottom ? '0.5em' : '0'\n  }\n};\nAxis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(\n  forHorizontal,\n  position\n) {\n  if (forHorizontal) {\n    return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end'\n  } else {\n    return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end'\n  }\n};\nAxis.prototype.xForXAxisLabel = function xForXAxisLabel() {\n  return this.xForAxisLabel(\n    !this.owner.config.axis_rotated,\n    this.getXAxisLabelPosition()\n  )\n};\nAxis.prototype.xForYAxisLabel = function xForYAxisLabel() {\n  return this.xForAxisLabel(\n    this.owner.config.axis_rotated,\n    this.getYAxisLabelPosition()\n  )\n};\nAxis.prototype.xForY2AxisLabel = function xForY2AxisLabel() {\n  return this.xForAxisLabel(\n    this.owner.config.axis_rotated,\n    this.getY2AxisLabelPosition()\n  )\n};\nAxis.prototype.dxForXAxisLabel = function dxForXAxisLabel() {\n  return this.dxForAxisLabel(\n    !this.owner.config.axis_rotated,\n    this.getXAxisLabelPosition()\n  )\n};\nAxis.prototype.dxForYAxisLabel = function dxForYAxisLabel() {\n  return this.dxForAxisLabel(\n    this.owner.config.axis_rotated,\n    this.getYAxisLabelPosition()\n  )\n};\nAxis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() {\n  return this.dxForAxisLabel(\n    this.owner.config.axis_rotated,\n    this.getY2AxisLabelPosition()\n  )\n};\nAxis.prototype.dyForXAxisLabel = function dyForXAxisLabel() {\n  var $$ = this.owner,\n    config = $$.config,\n    position = this.getXAxisLabelPosition();\n  if (config.axis_rotated) {\n    return position.isInner\n      ? '1.2em'\n      : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x'))\n  } else {\n    return position.isInner ? '-0.5em' : $$.getHorizontalAxisHeight('x') - 10\n  }\n};\nAxis.prototype.dyForYAxisLabel = function dyForYAxisLabel() {\n  var $$ = this.owner,\n    position = this.getYAxisLabelPosition();\n  if ($$.config.axis_rotated) {\n    return position.isInner ? '-0.5em' : '3em'\n  } else {\n    return position.isInner\n      ? '1.2em'\n      : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10)\n  }\n};\nAxis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() {\n  var $$ = this.owner,\n    position = this.getY2AxisLabelPosition();\n  if ($$.config.axis_rotated) {\n    return position.isInner ? '1.2em' : '-2.2em'\n  } else {\n    return position.isInner\n      ? '-0.5em'\n      : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15)\n  }\n};\nAxis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() {\n  var $$ = this.owner;\n  return this.textAnchorForAxisLabel(\n    !$$.config.axis_rotated,\n    this.getXAxisLabelPosition()\n  )\n};\nAxis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() {\n  var $$ = this.owner;\n  return this.textAnchorForAxisLabel(\n    $$.config.axis_rotated,\n    this.getYAxisLabelPosition()\n  )\n};\nAxis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() {\n  var $$ = this.owner;\n  return this.textAnchorForAxisLabel(\n    $$.config.axis_rotated,\n    this.getY2AxisLabelPosition()\n  )\n};\nAxis.prototype.getMaxTickWidth = function getMaxTickWidth(\n  id,\n  withoutRecompute\n) {\n  var $$ = this.owner,\n    maxWidth = 0,\n    targetsToShow,\n    scale,\n    axis,\n    dummy,\n    svg;\n  if (withoutRecompute && $$.currentMaxTickWidths[id]) {\n    return $$.currentMaxTickWidths[id]\n  }\n  if ($$.svg) {\n    targetsToShow = $$.filterTargetsToShow($$.data.targets);\n    if (id === 'y') {\n      scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));\n      axis = this.getYAxis(\n        id,\n        scale,\n        $$.yOrient,\n        $$.yAxisTickValues,\n        false,\n        true,\n        true\n      );\n    } else if (id === 'y2') {\n      scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));\n      axis = this.getYAxis(\n        id,\n        scale,\n        $$.y2Orient,\n        $$.y2AxisTickValues,\n        false,\n        true,\n        true\n      );\n    } else {\n      scale = $$.x.copy().domain($$.getXDomain(targetsToShow));\n      axis = this.getXAxis(\n        scale,\n        $$.xOrient,\n        $$.xAxisTickFormat,\n        $$.xAxisTickValues,\n        false,\n        true,\n        true\n      );\n      this.updateXAxisTickValues(targetsToShow, axis);\n    }\n    dummy = $$.d3\n      .select('body')\n      .append('div')\n      .classed('c3', true)\n    ;(svg = dummy\n      .append('svg')\n      .style('visibility', 'hidden')\n      .style('position', 'fixed')\n      .style('top', 0)\n      .style('left', 0)),\n      svg\n        .append('g')\n        .call(axis)\n        .each(function() {\n          $$.d3\n            .select(this)\n            .selectAll('text')\n            .each(function() {\n              var box = getBBox(this);\n              if (maxWidth < box.width) {\n                maxWidth = box.width;\n              }\n            });\n          dummy.remove();\n        });\n  }\n  $$.currentMaxTickWidths[id] =\n    maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth;\n  return $$.currentMaxTickWidths[id]\n};\n\nAxis.prototype.updateLabels = function updateLabels(withTransition) {\n  var $$ = this.owner;\n  var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel),\n    axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel),\n    axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label)\n  ;(withTransition ? axisXLabel.transition() : axisXLabel)\n    .attr('x', this.xForXAxisLabel.bind(this))\n    .attr('dx', this.dxForXAxisLabel.bind(this))\n    .attr('dy', this.dyForXAxisLabel.bind(this))\n    .text(this.textForXAxisLabel.bind(this))\n  ;(withTransition ? axisYLabel.transition() : axisYLabel)\n    .attr('x', this.xForYAxisLabel.bind(this))\n    .attr('dx', this.dxForYAxisLabel.bind(this))\n    .attr('dy', this.dyForYAxisLabel.bind(this))\n    .text(this.textForYAxisLabel.bind(this))\n  ;(withTransition ? axisY2Label.transition() : axisY2Label)\n    .attr('x', this.xForY2AxisLabel.bind(this))\n    .attr('dx', this.dxForY2AxisLabel.bind(this))\n    .attr('dy', this.dyForY2AxisLabel.bind(this))\n    .text(this.textForY2AxisLabel.bind(this));\n};\nAxis.prototype.getPadding = function getPadding(\n  padding,\n  key,\n  defaultValue,\n  domainLength\n) {\n  var p = typeof padding === 'number' ? padding : padding[key];\n  if (!isValue(p)) {\n    return defaultValue\n  }\n  if (padding.unit === 'ratio') {\n    return padding[key] * domainLength\n  }\n  // assume padding is pixels if unit is not specified\n  return this.convertPixelsToAxisPadding(p, domainLength)\n};\nAxis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(\n  pixels,\n  domainLength\n) {\n  var $$ = this.owner,\n    length = $$.config.axis_rotated ? $$.width : $$.height;\n  return domainLength * (pixels / length)\n};\nAxis.prototype.generateTickValues = function generateTickValues(\n  values,\n  tickCount,\n  forTimeSeries\n) {\n  var tickValues = values,\n    targetCount,\n    start,\n    end,\n    count,\n    interval,\n    i,\n    tickValue;\n  if (tickCount) {\n    targetCount = isFunction(tickCount) ? tickCount() : tickCount;\n    // compute ticks according to tickCount\n    if (targetCount === 1) {\n      tickValues = [values[0]];\n    } else if (targetCount === 2) {\n      tickValues = [values[0], values[values.length - 1]];\n    } else if (targetCount > 2) {\n      count = targetCount - 2;\n      start = values[0];\n      end = values[values.length - 1];\n      interval = (end - start) / (count + 1);\n      // re-construct unique values\n      tickValues = [start];\n      for (i = 0; i < count; i++) {\n        tickValue = +start + interval * (i + 1);\n        tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue);\n      }\n      tickValues.push(end);\n    }\n  }\n  if (!forTimeSeries) {\n    tickValues = tickValues.sort(function(a, b) {\n      return a - b\n    });\n  }\n  return tickValues\n};\nAxis.prototype.generateTransitions = function generateTransitions(duration) {\n  var $$ = this.owner,\n    axes = $$.axes;\n  return {\n    axisX: duration ? axes.x.transition().duration(duration) : axes.x,\n    axisY: duration ? axes.y.transition().duration(duration) : axes.y,\n    axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2,\n    axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx\n  }\n};\nAxis.prototype.redraw = function redraw(duration, isHidden) {\n  var $$ = this.owner,\n    transition = duration ? $$.d3.transition().duration(duration) : null;\n  $$.axes.x.style('opacity', isHidden ? 0 : 1).call($$.xAxis, transition);\n  $$.axes.y.style('opacity', isHidden ? 0 : 1).call($$.yAxis, transition);\n  $$.axes.y2.style('opacity', isHidden ? 0 : 1).call($$.y2Axis, transition);\n  $$.axes.subx.style('opacity', isHidden ? 0 : 1).call($$.subXAxis, transition);\n};\n\nvar c3 = {\n  version: '0.7.18',\n  chart: {\n    fn: Chart.prototype,\n    internal: {\n      fn: ChartInternal.prototype,\n      axis: {\n        fn: Axis.prototype,\n        internal: {\n          fn: AxisInternal.prototype\n        }\n      }\n    }\n  },\n  generate: function(config) {\n    return new Chart(config)\n  }\n};\n\nChartInternal.prototype.beforeInit = function() {\n  // can do something\n};\nChartInternal.prototype.afterInit = function() {\n  // can do something\n};\nChartInternal.prototype.init = function() {\n  var $$ = this,\n    config = $$.config;\n\n  $$.initParams();\n\n  if (config.data_url) {\n    $$.convertUrlToData(\n      config.data_url,\n      config.data_mimeType,\n      config.data_headers,\n      config.data_keys,\n      $$.initWithData\n    );\n  } else if (config.data_json) {\n    $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));\n  } else if (config.data_rows) {\n    $$.initWithData($$.convertRowsToData(config.data_rows));\n  } else if (config.data_columns) {\n    $$.initWithData($$.convertColumnsToData(config.data_columns));\n  } else {\n    throw Error('url or json or rows or columns is required.')\n  }\n};\n\nChartInternal.prototype.initParams = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config;\n\n  // MEMO: clipId needs to be unique because it conflicts when multiple charts exist\n  $$.clipId = 'c3-' + new Date().valueOf() + '-clip';\n  $$.clipIdForXAxis = $$.clipId + '-xaxis';\n  $$.clipIdForYAxis = $$.clipId + '-yaxis';\n  $$.clipIdForGrid = $$.clipId + '-grid';\n  $$.clipIdForSubchart = $$.clipId + '-subchart';\n  $$.clipPath = $$.getClipPath($$.clipId);\n  $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis);\n  $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis);\n  $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid);\n  $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart);\n\n  $$.dragStart = null;\n  $$.dragging = false;\n  $$.flowing = false;\n  $$.cancelClick = false;\n  $$.mouseover = undefined;\n  $$.transiting = false;\n\n  $$.color = $$.generateColor();\n  $$.levelColor = $$.generateLevelColor();\n\n  $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)(\n    $$.config.data_xFormat\n  );\n  $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat;\n  $$.defaultAxisTimeFormat = function(date) {\n    if (date.getMilliseconds()) {\n      return d3.timeFormat('.%L')(date)\n    }\n    if (date.getSeconds()) {\n      return d3.timeFormat(':%S')(date)\n    }\n    if (date.getMinutes()) {\n      return d3.timeFormat('%I:%M')(date)\n    }\n    if (date.getHours()) {\n      return d3.timeFormat('%I %p')(date)\n    }\n    if (date.getDay() && date.getDate() !== 1) {\n      return d3.timeFormat('%-m/%-d')(date)\n    }\n    if (date.getDate() !== 1) {\n      return d3.timeFormat('%-m/%-d')(date)\n    }\n    if (date.getMonth()) {\n      return d3.timeFormat('%-m/%-d')(date)\n    }\n    return d3.timeFormat('%Y/%-m/%-d')(date)\n  };\n  $$.hiddenTargetIds = [];\n  $$.hiddenLegendIds = [];\n  $$.focusedTargetIds = [];\n  $$.defocusedTargetIds = [];\n\n  $$.xOrient = config.axis_rotated\n    ? config.axis_x_inner\n      ? 'right'\n      : 'left'\n    : config.axis_x_inner\n    ? 'top'\n    : 'bottom';\n  $$.yOrient = config.axis_rotated\n    ? config.axis_y_inner\n      ? 'top'\n      : 'bottom'\n    : config.axis_y_inner\n    ? 'right'\n    : 'left';\n  $$.y2Orient = config.axis_rotated\n    ? config.axis_y2_inner\n      ? 'bottom'\n      : 'top'\n    : config.axis_y2_inner\n    ? 'left'\n    : 'right';\n  $$.subXOrient = config.axis_rotated ? 'left' : 'bottom';\n\n  $$.isLegendRight = config.legend_position === 'right';\n  $$.isLegendInset = config.legend_position === 'inset';\n  $$.isLegendTop =\n    config.legend_inset_anchor === 'top-left' ||\n    config.legend_inset_anchor === 'top-right';\n  $$.isLegendLeft =\n    config.legend_inset_anchor === 'top-left' ||\n    config.legend_inset_anchor === 'bottom-left';\n  $$.legendStep = 0;\n  $$.legendItemWidth = 0;\n  $$.legendItemHeight = 0;\n\n  $$.currentMaxTickWidths = {\n    x: 0,\n    y: 0,\n    y2: 0\n  };\n\n  $$.rotated_padding_left = 30;\n  $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30;\n  $$.rotated_padding_top = 5;\n\n  $$.withoutFadeIn = {};\n\n  $$.intervalForObserveInserted = undefined;\n\n  $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js\n};\n\nChartInternal.prototype.initChartElements = function() {\n  if (this.initBar) {\n    this.initBar();\n  }\n  if (this.initLine) {\n    this.initLine();\n  }\n  if (this.initArc) {\n    this.initArc();\n  }\n  if (this.initGauge) {\n    this.initGauge();\n  }\n  if (this.initText) {\n    this.initText();\n  }\n};\n\nChartInternal.prototype.initWithData = function(data) {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config;\n  var defs,\n    main,\n    binding = true;\n\n  $$.axis = new Axis($$);\n\n  if (!config.bindto) {\n    $$.selectChart = d3.selectAll([]);\n  } else if (typeof config.bindto.node === 'function') {\n    $$.selectChart = config.bindto;\n  } else {\n    $$.selectChart = d3.select(config.bindto);\n  }\n  if ($$.selectChart.empty()) {\n    $$.selectChart = d3\n      .select(document.createElement('div'))\n      .style('opacity', 0);\n    $$.observeInserted($$.selectChart);\n    binding = false;\n  }\n  $$.selectChart.html('').classed('c3', true);\n\n  // Init data as targets\n  $$.data.xs = {};\n  $$.data.targets = $$.convertDataToTargets(data);\n\n  if (config.data_filter) {\n    $$.data.targets = $$.data.targets.filter(config.data_filter);\n  }\n\n  // Set targets to hide if needed\n  if (config.data_hide) {\n    $$.addHiddenTargetIds(\n      config.data_hide === true\n        ? $$.mapToIds($$.data.targets)\n        : config.data_hide\n    );\n  }\n  if (config.legend_hide) {\n    $$.addHiddenLegendIds(\n      config.legend_hide === true\n        ? $$.mapToIds($$.data.targets)\n        : config.legend_hide\n    );\n  }\n\n  if ($$.isStanfordGraphType()) {\n    $$.initStanfordData();\n  }\n\n  // Init sizes and scales\n  $$.updateSizes();\n  $$.updateScales();\n\n  // Set domains for each scale\n  $$.x.domain(d3.extent($$.getXDomain($$.data.targets)));\n  $$.y.domain($$.getYDomain($$.data.targets, 'y'));\n  $$.y2.domain($$.getYDomain($$.data.targets, 'y2'));\n  $$.subX.domain($$.x.domain());\n  $$.subY.domain($$.y.domain());\n  $$.subY2.domain($$.y2.domain());\n\n  // Save original x domain for zoom update\n  $$.orgXDomain = $$.x.domain();\n\n  /*-- Basic Elements --*/\n\n  // Define svgs\n  $$.svg = $$.selectChart\n    .append('svg')\n    .style('overflow', 'hidden')\n    .on('mouseenter', function() {\n      return config.onmouseover.call($$)\n    })\n    .on('mouseleave', function() {\n      return config.onmouseout.call($$)\n    });\n\n  if ($$.config.svg_classname) {\n    $$.svg.attr('class', $$.config.svg_classname);\n  }\n\n  // Define defs\n  defs = $$.svg.append('defs');\n  $$.clipChart = $$.appendClip(defs, $$.clipId);\n  $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis);\n  $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis);\n  $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid);\n  $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart);\n  $$.updateSvgSize();\n\n  // Define regions\n  main = $$.main = $$.svg.append('g').attr('transform', $$.getTranslate('main'));\n\n  if ($$.initPie) {\n    $$.initPie();\n  }\n  if ($$.initDragZoom) {\n    $$.initDragZoom();\n  }\n  if (config.subchart_show && $$.initSubchart) {\n    $$.initSubchart();\n  }\n  if ($$.initTooltip) {\n    $$.initTooltip();\n  }\n  if ($$.initLegend) {\n    $$.initLegend();\n  }\n  if ($$.initTitle) {\n    $$.initTitle();\n  }\n  if ($$.initZoom) {\n    $$.initZoom();\n  }\n  if ($$.isStanfordGraphType()) {\n    $$.drawColorScale();\n  }\n\n  // Update selection based on size and scale\n  // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart.\n  if (config.subchart_show && $$.initSubchartBrush) {\n    $$.initSubchartBrush();\n  }\n\n  /*-- Main Region --*/\n\n  // text when empty\n  main\n    .append('text')\n    .attr('class', CLASS.text + ' ' + CLASS.empty)\n    .attr('text-anchor', 'middle') // horizontal centering of text at x position in all browsers.\n    .attr('dominant-baseline', 'middle'); // vertical centering of text at y position in all browsers, except IE.\n\n  // Regions\n  $$.initRegion();\n\n  // Grids\n  $$.initGrid();\n\n  // Define g for chart area\n  main\n    .append('g')\n    .attr('clip-path', $$.clipPath)\n    .attr('class', CLASS.chart);\n\n  // Grid lines\n  if (config.grid_lines_front) {\n    $$.initGridLines();\n  }\n\n  $$.initStanfordElements();\n\n  // Cover whole with rects for events\n  $$.initEventRect();\n\n  // Define g for chart\n  $$.initChartElements();\n\n  // Add Axis\n  $$.axis.init();\n\n  // Set targets\n  $$.updateTargets($$.data.targets);\n\n  // Set default extent if defined\n  if (config.axis_x_selection) {\n    $$.brush.selectionAsValue($$.getDefaultSelection());\n  }\n\n  // Draw with targets\n  if (binding) {\n    $$.updateDimension();\n    $$.config.oninit.call($$);\n    $$.redraw({\n      withTransition: false,\n      withTransform: true,\n      withUpdateXDomain: true,\n      withUpdateOrgXDomain: true,\n      withTransitionForAxis: false\n    });\n  }\n\n  // Bind to resize event\n  $$.bindResize();\n\n  // Bind to window focus event\n  $$.bindWindowFocus();\n\n  // export element of the chart\n  $$.api.element = $$.selectChart.node();\n};\n\nChartInternal.prototype.smoothLines = function(el, type) {\n  var $$ = this;\n  if (type === 'grid') {\n    el.each(function() {\n      var g = $$.d3.select(this),\n        x1 = g.attr('x1'),\n        x2 = g.attr('x2'),\n        y1 = g.attr('y1'),\n        y2 = g.attr('y2');\n      g.attr({\n        x1: Math.ceil(x1),\n        x2: Math.ceil(x2),\n        y1: Math.ceil(y1),\n        y2: Math.ceil(y2)\n      });\n    });\n  }\n};\n\nChartInternal.prototype.updateSizes = function() {\n  var $$ = this,\n    config = $$.config;\n  var legendHeight = $$.legend ? $$.getLegendHeight() : 0,\n    legendWidth = $$.legend ? $$.getLegendWidth() : 0,\n    legendHeightForBottom =\n      $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight,\n    hasArc = $$.hasArcType(),\n    xAxisHeight =\n      config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'),\n    subchartHeight =\n      config.subchart_show && !hasArc\n        ? config.subchart_size_height + xAxisHeight\n        : 0;\n\n  $$.currentWidth = $$.getCurrentWidth();\n  $$.currentHeight = $$.getCurrentHeight();\n\n  // for main\n  $$.margin = config.axis_rotated\n    ? {\n        top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(),\n        right: hasArc ? 0 : $$.getCurrentPaddingRight(),\n        bottom:\n          $$.getHorizontalAxisHeight('y') +\n          legendHeightForBottom +\n          $$.getCurrentPaddingBottom(),\n        left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft())\n      }\n    : {\n        top: 4 + $$.getCurrentPaddingTop(), // for top tick text\n        right: hasArc ? 0 : $$.getCurrentPaddingRight(),\n        bottom:\n          xAxisHeight +\n          subchartHeight +\n          legendHeightForBottom +\n          $$.getCurrentPaddingBottom(),\n        left: hasArc ? 0 : $$.getCurrentPaddingLeft()\n      };\n\n  // for subchart\n  $$.margin2 = config.axis_rotated\n    ? {\n        top: $$.margin.top,\n        right: NaN,\n        bottom: 20 + legendHeightForBottom,\n        left: $$.rotated_padding_left\n      }\n    : {\n        top: $$.currentHeight - subchartHeight - legendHeightForBottom,\n        right: NaN,\n        bottom: xAxisHeight + legendHeightForBottom,\n        left: $$.margin.left\n      };\n\n  // for legend\n  $$.margin3 = {\n    top: 0,\n    right: NaN,\n    bottom: 0,\n    left: 0\n  };\n  if ($$.updateSizeForLegend) {\n    $$.updateSizeForLegend(legendHeight, legendWidth);\n  }\n\n  $$.width = $$.currentWidth - $$.margin.left - $$.margin.right;\n  $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom;\n  if ($$.width < 0) {\n    $$.width = 0;\n  }\n  if ($$.height < 0) {\n    $$.height = 0;\n  }\n\n  $$.width2 = config.axis_rotated\n    ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right\n    : $$.width;\n  $$.height2 = config.axis_rotated\n    ? $$.height\n    : $$.currentHeight - $$.margin2.top - $$.margin2.bottom;\n  if ($$.width2 < 0) {\n    $$.width2 = 0;\n  }\n  if ($$.height2 < 0) {\n    $$.height2 = 0;\n  }\n\n  // for arc\n  $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0);\n  $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10);\n  if ($$.hasType('gauge') && !config.gauge_fullCircle) {\n    $$.arcHeight += $$.height - $$.getGaugeLabelHeight();\n  }\n  if ($$.updateRadius) {\n    $$.updateRadius();\n  }\n\n  if ($$.isLegendRight && hasArc) {\n    $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1;\n  }\n};\n\nChartInternal.prototype.updateTargets = function(targets) {\n  var $$ = this,\n    config = $$.config;\n\n  /*-- Main --*/\n\n  //-- Text --//\n  $$.updateTargetsForText(targets);\n\n  //-- Bar --//\n  $$.updateTargetsForBar(targets);\n\n  //-- Line --//\n  $$.updateTargetsForLine(targets);\n\n  //-- Arc --//\n  if ($$.hasArcType() && $$.updateTargetsForArc) {\n    $$.updateTargetsForArc(targets);\n  }\n\n  /*-- Sub --*/\n\n  if (config.subchart_show && $$.updateTargetsForSubchart) {\n    $$.updateTargetsForSubchart(targets);\n  }\n\n  // Fade-in each chart\n  $$.showTargets();\n};\nChartInternal.prototype.showTargets = function() {\n  var $$ = this;\n  $$.svg\n    .selectAll('.' + CLASS.target)\n    .filter(function(d) {\n      return $$.isTargetToShow(d.id)\n    })\n    .transition()\n    .duration($$.config.transition_duration)\n    .style('opacity', 1);\n};\n\nChartInternal.prototype.redraw = function(options, transitions) {\n  var $$ = this,\n    main = $$.main,\n    d3 = $$.d3,\n    config = $$.config;\n  var areaIndices = $$.getShapeIndices($$.isAreaType),\n    barIndices = $$.getShapeIndices($$.isBarType),\n    lineIndices = $$.getShapeIndices($$.isLineType);\n  var withY,\n    withSubchart,\n    withTransition,\n    withTransitionForExit,\n    withTransitionForAxis,\n    withTransform,\n    withUpdateXDomain,\n    withUpdateOrgXDomain,\n    withTrimXDomain,\n    withLegend,\n    withEventRect,\n    withDimension,\n    withUpdateXAxis;\n  var hideAxis = $$.hasArcType();\n  var drawArea, drawBar, drawLine, xForText, yForText;\n  var duration, durationForExit, durationForAxis;\n  var transitionsToWait, waitForDraw, flow, transition;\n  var targetsToShow = $$.filterTargetsToShow($$.data.targets),\n    tickValues,\n    i,\n    intervalForCulling,\n    xDomainForZoom;\n  var xv = $$.xv.bind($$),\n    cx,\n    cy;\n\n  options = options || {};\n  withY = getOption(options, 'withY', true);\n  withSubchart = getOption(options, 'withSubchart', true);\n  withTransition = getOption(options, 'withTransition', true);\n  withTransform = getOption(options, 'withTransform', false);\n  withUpdateXDomain = getOption(options, 'withUpdateXDomain', false);\n  withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', false);\n  withTrimXDomain = getOption(options, 'withTrimXDomain', true);\n  withUpdateXAxis = getOption(options, 'withUpdateXAxis', withUpdateXDomain);\n  withLegend = getOption(options, 'withLegend', false);\n  withEventRect = getOption(options, 'withEventRect', true);\n  withDimension = getOption(options, 'withDimension', true);\n  withTransitionForExit = getOption(\n    options,\n    'withTransitionForExit',\n    withTransition\n  );\n  withTransitionForAxis = getOption(\n    options,\n    'withTransitionForAxis',\n    withTransition\n  );\n\n  duration = withTransition ? config.transition_duration : 0;\n  durationForExit = withTransitionForExit ? duration : 0;\n  durationForAxis = withTransitionForAxis ? duration : 0;\n\n  transitions = transitions || $$.axis.generateTransitions(durationForAxis);\n\n  // update legend and transform each g\n  if (withLegend && config.legend_show) {\n    $$.updateLegend($$.mapToIds($$.data.targets), options, transitions);\n  } else if (withDimension) {\n    // need to update dimension (e.g. axis.y.tick.values) because y tick values should change\n    // no need to update axis in it because they will be updated in redraw()\n    $$.updateDimension(true);\n  }\n\n  // MEMO: needed for grids calculation\n  if ($$.isCategorized() && targetsToShow.length === 0) {\n    $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]);\n  }\n\n  if (targetsToShow.length) {\n    $$.updateXDomain(\n      targetsToShow,\n      withUpdateXDomain,\n      withUpdateOrgXDomain,\n      withTrimXDomain\n    );\n    if (!config.axis_x_tick_values) {\n      tickValues = $$.axis.updateXAxisTickValues(targetsToShow);\n    }\n  } else {\n    $$.xAxis.tickValues([]);\n    $$.subXAxis.tickValues([]);\n  }\n\n  if (config.zoom_rescale && !options.flow) {\n    xDomainForZoom = $$.x.orgDomain();\n  }\n\n  $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom));\n  $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom));\n\n  if (!config.axis_y_tick_values && config.axis_y_tick_count) {\n    $$.yAxis.tickValues(\n      $$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count)\n    );\n  }\n  if (!config.axis_y2_tick_values && config.axis_y2_tick_count) {\n    $$.y2Axis.tickValues(\n      $$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count)\n    );\n  }\n\n  // axes\n  $$.axis.redraw(durationForAxis, hideAxis);\n\n  // Update axis label\n  $$.axis.updateLabels(withTransition);\n\n  // show/hide if manual culling needed\n  if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) {\n    if (config.axis_x_tick_culling && tickValues) {\n      for (i = 1; i < tickValues.length; i++) {\n        if (tickValues.length / i < config.axis_x_tick_culling_max) {\n          intervalForCulling = i;\n          break\n        }\n      }\n      $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function(e) {\n        var index = tickValues.indexOf(e);\n        if (index >= 0) {\n          d3.select(this).style(\n            'display',\n            index % intervalForCulling ? 'none' : 'block'\n          );\n        }\n      });\n    } else {\n      $$.svg\n        .selectAll('.' + CLASS.axisX + ' .tick text')\n        .style('display', 'block');\n    }\n  }\n\n  // setup drawer - MEMO: these must be called after axis updated\n  drawArea = $$.generateDrawArea\n    ? $$.generateDrawArea(areaIndices, false)\n    : undefined;\n  drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined;\n  drawLine = $$.generateDrawLine\n    ? $$.generateDrawLine(lineIndices, false)\n    : undefined;\n  xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true);\n  yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false);\n\n  // update circleY based on updated parameters\n  $$.updateCircleY();\n  // generate circle x/y functions depending on updated params\n  cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$);\n  cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$);\n\n  // Update sub domain\n  if (withY) {\n    $$.subY.domain($$.getYDomain(targetsToShow, 'y'));\n    $$.subY2.domain($$.getYDomain(targetsToShow, 'y2'));\n  }\n\n  // xgrid focus\n  $$.updateXgridFocus();\n\n  // Data empty label positioning and text.\n  main\n    .select('text.' + CLASS.text + '.' + CLASS.empty)\n    .attr('x', $$.width / 2)\n    .attr('y', $$.height / 2)\n    .text(config.data_empty_label_text)\n    .transition()\n    .style('opacity', targetsToShow.length ? 0 : 1);\n\n  // event rect\n  if (withEventRect) {\n    $$.redrawEventRect();\n  }\n\n  // grid\n  $$.updateGrid(duration);\n\n  $$.updateStanfordElements(duration);\n\n  // rect for regions\n  $$.updateRegion(duration);\n\n  // bars\n  $$.updateBar(durationForExit);\n\n  // lines, areas and circles\n  $$.updateLine(durationForExit);\n  $$.updateArea(durationForExit);\n  $$.updateCircle(cx, cy);\n\n  // text\n  if ($$.hasDataLabel()) {\n    $$.updateText(xForText, yForText, durationForExit);\n  }\n\n  // title\n  if ($$.redrawTitle) {\n    $$.redrawTitle();\n  }\n\n  // arc\n  if ($$.redrawArc) {\n    $$.redrawArc(duration, durationForExit, withTransform);\n  }\n\n  // subchart\n  if (config.subchart_show && $$.redrawSubchart) {\n    $$.redrawSubchart(\n      withSubchart,\n      transitions,\n      duration,\n      durationForExit,\n      areaIndices,\n      barIndices,\n      lineIndices\n    );\n  }\n\n  if ($$.isStanfordGraphType()) {\n    $$.drawColorScale();\n  }\n\n  // circles for select\n  main\n    .selectAll('.' + CLASS.selectedCircles)\n    .filter($$.isBarType.bind($$))\n    .selectAll('circle')\n    .remove();\n\n  if (options.flow) {\n    flow = $$.generateFlow({\n      targets: targetsToShow,\n      flow: options.flow,\n      duration: options.flow.duration,\n      drawBar: drawBar,\n      drawLine: drawLine,\n      drawArea: drawArea,\n      cx: cx,\n      cy: cy,\n      xv: xv,\n      xForText: xForText,\n      yForText: yForText\n    });\n  }\n\n  if (duration && $$.isTabVisible()) {\n    // Only use transition if tab visible. See #938.\n    // transition should be derived from one transition\n    transition = d3.transition().duration(duration);\n    transitionsToWait = []\n    ;[\n      $$.redrawBar(drawBar, true, transition),\n      $$.redrawLine(drawLine, true, transition),\n      $$.redrawArea(drawArea, true, transition),\n      $$.redrawCircle(cx, cy, true, transition),\n      $$.redrawText(xForText, yForText, options.flow, true, transition),\n      $$.redrawRegion(true, transition),\n      $$.redrawGrid(true, transition)\n    ].forEach(function(transitions) {\n      transitions.forEach(function(transition) {\n        transitionsToWait.push(transition);\n      });\n    });\n    // Wait for end of transitions to call flow and onrendered callback\n    waitForDraw = $$.generateWait();\n    transitionsToWait.forEach(function(t) {\n      waitForDraw.add(t);\n    });\n    waitForDraw(function() {\n      if (flow) {\n        flow();\n      }\n      if (config.onrendered) {\n        config.onrendered.call($$);\n      }\n    });\n  } else {\n    $$.redrawBar(drawBar);\n    $$.redrawLine(drawLine);\n    $$.redrawArea(drawArea);\n    $$.redrawCircle(cx, cy);\n    $$.redrawText(xForText, yForText, options.flow);\n    $$.redrawRegion();\n    $$.redrawGrid();\n    if (flow) {\n      flow();\n    }\n    if (config.onrendered) {\n      config.onrendered.call($$);\n    }\n  }\n\n  // update fadein condition\n  $$.mapToIds($$.data.targets).forEach(function(id) {\n    $$.withoutFadeIn[id] = true;\n  });\n};\n\nChartInternal.prototype.updateAndRedraw = function(options) {\n  var $$ = this,\n    config = $$.config,\n    transitions;\n  options = options || {};\n  // same with redraw\n  options.withTransition = getOption(options, 'withTransition', true);\n  options.withTransform = getOption(options, 'withTransform', false);\n  options.withLegend = getOption(options, 'withLegend', false);\n  // NOT same with redraw\n  options.withUpdateXDomain = getOption(options, 'withUpdateXDomain', true);\n  options.withUpdateOrgXDomain = getOption(\n    options,\n    'withUpdateOrgXDomain',\n    true\n  );\n  options.withTransitionForExit = false;\n  options.withTransitionForTransform = getOption(\n    options,\n    'withTransitionForTransform',\n    options.withTransition\n  );\n  // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called)\n  $$.updateSizes();\n  // MEMO: called in updateLegend in redraw if withLegend\n  if (!(options.withLegend && config.legend_show)) {\n    transitions = $$.axis.generateTransitions(\n      options.withTransitionForAxis ? config.transition_duration : 0\n    );\n    // Update scales\n    $$.updateScales();\n    $$.updateSvgSize();\n    // Update g positions\n    $$.transformAll(options.withTransitionForTransform, transitions);\n  }\n  // Draw with new sizes & scales\n  $$.redraw(options, transitions);\n};\nChartInternal.prototype.redrawWithoutRescale = function() {\n  this.redraw({\n    withY: false,\n    withSubchart: false,\n    withEventRect: false,\n    withTransitionForAxis: false\n  });\n};\n\nChartInternal.prototype.isTimeSeries = function() {\n  return this.config.axis_x_type === 'timeseries'\n};\nChartInternal.prototype.isCategorized = function() {\n  return this.config.axis_x_type.indexOf('categor') >= 0\n};\nChartInternal.prototype.isCustomX = function() {\n  var $$ = this,\n    config = $$.config;\n  return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs))\n};\n\nChartInternal.prototype.isTimeSeriesY = function() {\n  return this.config.axis_y_type === 'timeseries'\n};\n\nChartInternal.prototype.getTranslate = function(target) {\n  var $$ = this,\n    config = $$.config,\n    x,\n    y;\n  if (target === 'main') {\n    x = asHalfPixel($$.margin.left);\n    y = asHalfPixel($$.margin.top);\n  } else if (target === 'context') {\n    x = asHalfPixel($$.margin2.left);\n    y = asHalfPixel($$.margin2.top);\n  } else if (target === 'legend') {\n    x = $$.margin3.left;\n    y = $$.margin3.top;\n  } else if (target === 'x') {\n    x = 0;\n    y = config.axis_rotated ? 0 : $$.height;\n  } else if (target === 'y') {\n    x = 0;\n    y = config.axis_rotated ? $$.height : 0;\n  } else if (target === 'y2') {\n    x = config.axis_rotated ? 0 : $$.width;\n    y = config.axis_rotated ? 1 : 0;\n  } else if (target === 'subx') {\n    x = 0;\n    y = config.axis_rotated ? 0 : $$.height2;\n  } else if (target === 'arc') {\n    x = $$.arcWidth / 2;\n    y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label\n  }\n  return 'translate(' + x + ',' + y + ')'\n};\nChartInternal.prototype.initialOpacity = function(d) {\n  return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0\n};\nChartInternal.prototype.initialOpacityForCircle = function(d) {\n  return d.value !== null && this.withoutFadeIn[d.id]\n    ? this.opacityForCircle(d)\n    : 0\n};\nChartInternal.prototype.opacityForCircle = function(d) {\n  var isPointShouldBeShown = isFunction(this.config.point_show)\n    ? this.config.point_show(d)\n    : this.config.point_show;\n  var opacity = isPointShouldBeShown || this.isStanfordType(d) ? 1 : 0;\n  return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0\n};\nChartInternal.prototype.opacityForText = function() {\n  return this.hasDataLabel() ? 1 : 0\n};\nChartInternal.prototype.xx = function(d) {\n  return d ? this.x(d.x) : null\n};\nChartInternal.prototype.xvCustom = function(d, xyValue) {\n  var $$ = this,\n    value = xyValue ? d[xyValue] : d.value;\n  if ($$.isTimeSeries()) {\n    value = $$.parseDate(d.value);\n  } else if ($$.isCategorized() && typeof d.value === 'string') {\n    value = $$.config.axis_x_categories.indexOf(d.value);\n  }\n  return Math.ceil($$.x(value))\n};\nChartInternal.prototype.yvCustom = function(d, xyValue) {\n  var $$ = this,\n    yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y,\n    value = xyValue ? d[xyValue] : d.value;\n  return Math.ceil(yScale(value))\n};\nChartInternal.prototype.xv = function(d) {\n  var $$ = this,\n    value = d.value;\n  if ($$.isTimeSeries()) {\n    value = $$.parseDate(d.value);\n  } else if ($$.isCategorized() && typeof d.value === 'string') {\n    value = $$.config.axis_x_categories.indexOf(d.value);\n  }\n  return Math.ceil($$.x(value))\n};\nChartInternal.prototype.yv = function(d) {\n  var $$ = this,\n    yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y;\n  return Math.ceil(yScale(d.value))\n};\nChartInternal.prototype.subxx = function(d) {\n  return d ? this.subX(d.x) : null\n};\n\nChartInternal.prototype.transformMain = function(withTransition, transitions) {\n  var $$ = this,\n    xAxis,\n    yAxis,\n    y2Axis;\n  if (transitions && transitions.axisX) {\n    xAxis = transitions.axisX;\n  } else {\n    xAxis = $$.main.select('.' + CLASS.axisX);\n    if (withTransition) {\n      xAxis = xAxis.transition();\n    }\n  }\n  if (transitions && transitions.axisY) {\n    yAxis = transitions.axisY;\n  } else {\n    yAxis = $$.main.select('.' + CLASS.axisY);\n    if (withTransition) {\n      yAxis = yAxis.transition();\n    }\n  }\n  if (transitions && transitions.axisY2) {\n    y2Axis = transitions.axisY2;\n  } else {\n    y2Axis = $$.main.select('.' + CLASS.axisY2);\n    if (withTransition) {\n      y2Axis = y2Axis.transition();\n    }\n  }\n(withTransition ? $$.main.transition() : $$.main).attr(\n    'transform',\n    $$.getTranslate('main')\n  );\n  xAxis.attr('transform', $$.getTranslate('x'));\n  yAxis.attr('transform', $$.getTranslate('y'));\n  y2Axis.attr('transform', $$.getTranslate('y2'));\n  $$.main\n    .select('.' + CLASS.chartArcs)\n    .attr('transform', $$.getTranslate('arc'));\n};\nChartInternal.prototype.transformAll = function(withTransition, transitions) {\n  var $$ = this;\n  $$.transformMain(withTransition, transitions);\n  if ($$.config.subchart_show) {\n    $$.transformContext(withTransition, transitions);\n  }\n  if ($$.legend) {\n    $$.transformLegend(withTransition);\n  }\n};\n\nChartInternal.prototype.updateSvgSize = function() {\n  var $$ = this,\n    brush = $$.svg.select(`.${CLASS.brush} .overlay`);\n  $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight);\n  $$.svg\n    .selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid])\n    .select('rect')\n    .attr('width', $$.width)\n    .attr('height', $$.height);\n  $$.svg\n    .select('#' + $$.clipIdForXAxis)\n    .select('rect')\n    .attr('x', $$.getXAxisClipX.bind($$))\n    .attr('y', $$.getXAxisClipY.bind($$))\n    .attr('width', $$.getXAxisClipWidth.bind($$))\n    .attr('height', $$.getXAxisClipHeight.bind($$));\n  $$.svg\n    .select('#' + $$.clipIdForYAxis)\n    .select('rect')\n    .attr('x', $$.getYAxisClipX.bind($$))\n    .attr('y', $$.getYAxisClipY.bind($$))\n    .attr('width', $$.getYAxisClipWidth.bind($$))\n    .attr('height', $$.getYAxisClipHeight.bind($$));\n  $$.svg\n    .select('#' + $$.clipIdForSubchart)\n    .select('rect')\n    .attr('width', $$.width)\n    .attr('height', (brush.size() && brush.attr('height')) || 0);\n  // MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>\n  $$.selectChart.style('max-height', $$.currentHeight + 'px');\n};\n\nChartInternal.prototype.updateDimension = function(withoutAxis) {\n  var $$ = this;\n  if (!withoutAxis) {\n    if ($$.config.axis_rotated) {\n      $$.axes.x.call($$.xAxis);\n      $$.axes.subx.call($$.subXAxis);\n    } else {\n      $$.axes.y.call($$.yAxis);\n      $$.axes.y2.call($$.y2Axis);\n    }\n  }\n  $$.updateSizes();\n  $$.updateScales();\n  $$.updateSvgSize();\n  $$.transformAll(false);\n};\n\nChartInternal.prototype.observeInserted = function(selection) {\n  var $$ = this,\n    observer;\n  if (typeof MutationObserver === 'undefined') {\n    window.console.error('MutationObserver not defined.');\n    return\n  }\n  observer = new MutationObserver(function(mutations) {\n    mutations.forEach(function(mutation) {\n      if (mutation.type === 'childList' && mutation.previousSibling) {\n        observer.disconnect();\n        // need to wait for completion of load because size calculation requires the actual sizes determined after that completion\n        $$.intervalForObserveInserted = window.setInterval(function() {\n          // parentNode will NOT be null when completed\n          if (selection.node().parentNode) {\n            window.clearInterval($$.intervalForObserveInserted);\n            $$.updateDimension();\n            if ($$.brush) {\n              $$.brush.update();\n            }\n            $$.config.oninit.call($$);\n            $$.redraw({\n              withTransform: true,\n              withUpdateXDomain: true,\n              withUpdateOrgXDomain: true,\n              withTransition: false,\n              withTransitionForTransform: false,\n              withLegend: true\n            });\n            selection.transition().style('opacity', 1);\n          }\n        }, 10);\n      }\n    });\n  });\n  observer.observe(selection.node(), {\n    attributes: true,\n    childList: true,\n    characterData: true\n  });\n};\n\n/**\n * Binds handlers to the window resize event.\n */\nChartInternal.prototype.bindResize = function() {\n  var $$ = this,\n    config = $$.config;\n\n  $$.resizeFunction = $$.generateResize(); // need to call .remove\n\n  $$.resizeFunction.add(function() {\n    config.onresize.call($$);\n  });\n  if (config.resize_auto) {\n    $$.resizeFunction.add(function() {\n      if ($$.resizeTimeout !== undefined) {\n        window.clearTimeout($$.resizeTimeout);\n      }\n      $$.resizeTimeout = window.setTimeout(function() {\n        delete $$.resizeTimeout;\n        $$.updateAndRedraw({\n          withUpdateXDomain: false,\n          withUpdateOrgXDomain: false,\n          withTransition: false,\n          withTransitionForTransform: false,\n          withLegend: true\n        });\n        if ($$.brush) {\n          $$.brush.update();\n        }\n      }, 100);\n    });\n  }\n  $$.resizeFunction.add(function() {\n    config.onresized.call($$);\n  });\n\n  $$.resizeIfElementDisplayed = function() {\n    // if element not displayed skip it\n    if ($$.api == null || !$$.api.element.offsetParent) {\n      return\n    }\n\n    $$.resizeFunction();\n  };\n\n  if (window.attachEvent) {\n    window.attachEvent('onresize', $$.resizeIfElementDisplayed);\n  } else if (window.addEventListener) {\n    window.addEventListener('resize', $$.resizeIfElementDisplayed, false);\n  } else {\n    // fallback to this, if this is a very old browser\n    var wrapper = window.onresize;\n    if (!wrapper) {\n      // create a wrapper that will call all charts\n      wrapper = $$.generateResize();\n    } else if (!wrapper.add || !wrapper.remove) {\n      // there is already a handler registered, make sure we call it too\n      wrapper = $$.generateResize();\n      wrapper.add(window.onresize);\n    }\n    // add this graph to the wrapper, we will be removed if the user calls destroy\n    wrapper.add($$.resizeFunction);\n    window.onresize = function() {\n      // if element not displayed skip it\n      if (!$$.api.element.offsetParent) {\n        return\n      }\n\n      wrapper();\n    };\n  }\n};\n\n/**\n * Binds handlers to the window focus event.\n */\nChartInternal.prototype.bindWindowFocus = function() {\n  if (this.windowFocusHandler) {\n    // The handler is already set\n    return\n  }\n\n  this.windowFocusHandler = () => {\n    this.redraw();\n  };\n\n  window.addEventListener('focus', this.windowFocusHandler);\n};\n\n/**\n * Unbinds from the window focus event.\n */\nChartInternal.prototype.unbindWindowFocus = function() {\n  window.removeEventListener('focus', this.windowFocusHandler);\n  delete this.windowFocusHandler;\n};\n\nChartInternal.prototype.generateResize = function() {\n  var resizeFunctions = [];\n\n  function callResizeFunctions() {\n    resizeFunctions.forEach(function(f) {\n      f();\n    });\n  }\n  callResizeFunctions.add = function(f) {\n    resizeFunctions.push(f);\n  };\n  callResizeFunctions.remove = function(f) {\n    for (var i = 0; i < resizeFunctions.length; i++) {\n      if (resizeFunctions[i] === f) {\n        resizeFunctions.splice(i, 1);\n        break\n      }\n    }\n  };\n  return callResizeFunctions\n};\n\nChartInternal.prototype.endall = function(transition, callback) {\n  var n = 0;\n  transition\n    .each(function() {\n      ++n;\n    })\n    .on('end', function() {\n      if (!--n) {\n        callback.apply(this, arguments);\n      }\n    });\n};\nChartInternal.prototype.generateWait = function() {\n  var $$ = this;\n  var transitionsToWait = [],\n    f = function(callback) {\n      var timer = setInterval(function() {\n        if (!$$.isTabVisible()) {\n          return\n        }\n\n        var done = 0;\n        transitionsToWait.forEach(function(t) {\n          if (t.empty()) {\n            done += 1;\n            return\n          }\n          try {\n            t.transition();\n          } catch (e) {\n            done += 1;\n          }\n        });\n        if (done === transitionsToWait.length) {\n          clearInterval(timer);\n          if (callback) {\n            callback();\n          }\n        }\n      }, 50);\n    };\n  f.add = function(transition) {\n    transitionsToWait.push(transition);\n  };\n  return f\n};\n\nChartInternal.prototype.parseDate = function(date) {\n  var $$ = this,\n    parsedDate;\n  if (date instanceof Date) {\n    parsedDate = date;\n  } else if (typeof date === 'string') {\n    parsedDate = $$.dataTimeParse(date);\n  } else if (typeof date === 'object') {\n    parsedDate = new Date(+date);\n  } else if (typeof date === 'number' && !isNaN(date)) {\n    parsedDate = new Date(+date);\n  }\n  if (!parsedDate || isNaN(+parsedDate)) {\n    window.console.error(\"Failed to parse x '\" + date + \"' to Date object\");\n  }\n  return parsedDate\n};\n\nChartInternal.prototype.isTabVisible = function() {\n  return !document.hidden\n};\n\nChartInternal.prototype.getPathBox = getPathBox;\nChartInternal.prototype.CLASS = CLASS;\n\n/* jshint ignore:start */\n(function() {\n  if (!('SVGPathSeg' in window)) {\n    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg\n    window.SVGPathSeg = function(type, typeAsLetter, owningPathSegList) {\n      this.pathSegType = type;\n      this.pathSegTypeAsLetter = typeAsLetter;\n      this._owningPathSegList = owningPathSegList;\n    };\n\n    window.SVGPathSeg.prototype.classname = 'SVGPathSeg';\n\n    window.SVGPathSeg.PATHSEG_UNKNOWN = 0;\n    window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;\n    window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;\n    window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;\n    window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;\n    window.SVGPathSeg.PATHSEG_LINETO_REL = 5;\n    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;\n    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;\n    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;\n    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;\n    window.SVGPathSeg.PATHSEG_ARC_ABS = 10;\n    window.SVGPathSeg.PATHSEG_ARC_REL = 11;\n    window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;\n    window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;\n    window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;\n    window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;\n    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;\n    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;\n    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;\n    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;\n\n    // Notify owning PathSegList on any changes so they can be synchronized back to the path element.\n    window.SVGPathSeg.prototype._segmentChanged = function() {\n      if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this);\n    };\n\n    window.SVGPathSegClosePath = function(owningPathSegList) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CLOSEPATH,\n        'z',\n        owningPathSegList\n      );\n    };\n    window.SVGPathSegClosePath.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegClosePath.prototype.toString = function() {\n      return '[object SVGPathSegClosePath]'\n    };\n    window.SVGPathSegClosePath.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter\n    };\n    window.SVGPathSegClosePath.prototype.clone = function() {\n      return new window.SVGPathSegClosePath(undefined)\n    };\n\n    window.SVGPathSegMovetoAbs = function(owningPathSegList, x, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_MOVETO_ABS,\n        'M',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n    };\n    window.SVGPathSegMovetoAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegMovetoAbs.prototype.toString = function() {\n      return '[object SVGPathSegMovetoAbs]'\n    };\n    window.SVGPathSegMovetoAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    };\n    window.SVGPathSegMovetoAbs.prototype.clone = function() {\n      return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y)\n    };\n    Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegMovetoRel = function(owningPathSegList, x, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_MOVETO_REL,\n        'm',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n    };\n    window.SVGPathSegMovetoRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegMovetoRel.prototype.toString = function() {\n      return '[object SVGPathSegMovetoRel]'\n    };\n    window.SVGPathSegMovetoRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    };\n    window.SVGPathSegMovetoRel.prototype.clone = function() {\n      return new window.SVGPathSegMovetoRel(undefined, this._x, this._y)\n    };\n    Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegLinetoAbs = function(owningPathSegList, x, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_ABS,\n        'L',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n    };\n    window.SVGPathSegLinetoAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegLinetoAbs.prototype.toString = function() {\n      return '[object SVGPathSegLinetoAbs]'\n    };\n    window.SVGPathSegLinetoAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    };\n    window.SVGPathSegLinetoAbs.prototype.clone = function() {\n      return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y)\n    };\n    Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegLinetoRel = function(owningPathSegList, x, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_REL,\n        'l',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n    };\n    window.SVGPathSegLinetoRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegLinetoRel.prototype.toString = function() {\n      return '[object SVGPathSegLinetoRel]'\n    };\n    window.SVGPathSegLinetoRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    };\n    window.SVGPathSegLinetoRel.prototype.clone = function() {\n      return new window.SVGPathSegLinetoRel(undefined, this._x, this._y)\n    };\n    Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegCurvetoCubicAbs = function(\n      owningPathSegList,\n      x,\n      y,\n      x1,\n      y1,\n      x2,\n      y2\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS,\n        'C',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._x1 = x1;\n      this._y1 = y1;\n      this._x2 = x2;\n      this._y2 = y2;\n    };\n    window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoCubicAbs.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoCubicAbs]'\n    };\n    window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x1 +\n        ' ' +\n        this._y1 +\n        ' ' +\n        this._x2 +\n        ' ' +\n        this._y2 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegCurvetoCubicAbs.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoCubicAbs(\n        undefined,\n        this._x,\n        this._y,\n        this._x1,\n        this._y1,\n        this._x2,\n        this._y2\n      )\n    };\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x1', {\n      get: function() {\n        return this._x1\n      },\n      set: function(x1) {\n        this._x1 = x1;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y1', {\n      get: function() {\n        return this._y1\n      },\n      set: function(y1) {\n        this._y1 = y1;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x2', {\n      get: function() {\n        return this._x2\n      },\n      set: function(x2) {\n        this._x2 = x2;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y2', {\n      get: function() {\n        return this._y2\n      },\n      set: function(y2) {\n        this._y2 = y2;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegCurvetoCubicRel = function(\n      owningPathSegList,\n      x,\n      y,\n      x1,\n      y1,\n      x2,\n      y2\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL,\n        'c',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._x1 = x1;\n      this._y1 = y1;\n      this._x2 = x2;\n      this._y2 = y2;\n    };\n    window.SVGPathSegCurvetoCubicRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoCubicRel.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoCubicRel]'\n    };\n    window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x1 +\n        ' ' +\n        this._y1 +\n        ' ' +\n        this._x2 +\n        ' ' +\n        this._y2 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegCurvetoCubicRel.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoCubicRel(\n        undefined,\n        this._x,\n        this._y,\n        this._x1,\n        this._y1,\n        this._x2,\n        this._y2\n      )\n    };\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x1', {\n      get: function() {\n        return this._x1\n      },\n      set: function(x1) {\n        this._x1 = x1;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y1', {\n      get: function() {\n        return this._y1\n      },\n      set: function(y1) {\n        this._y1 = y1;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x2', {\n      get: function() {\n        return this._x2\n      },\n      set: function(x2) {\n        this._x2 = x2;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y2', {\n      get: function() {\n        return this._y2\n      },\n      set: function(y2) {\n        this._y2 = y2;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegCurvetoQuadraticAbs = function(\n      owningPathSegList,\n      x,\n      y,\n      x1,\n      y1\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS,\n        'Q',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._x1 = x1;\n      this._y1 = y1;\n    };\n    window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoQuadraticAbs]'\n    };\n    window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x1 +\n        ' ' +\n        this._y1 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoQuadraticAbs(\n        undefined,\n        this._x,\n        this._y,\n        this._x1,\n        this._y1\n      )\n    };\n    Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticAbs.prototype,\n      'x1',\n      {\n        get: function() {\n          return this._x1\n        },\n        set: function(x1) {\n          this._x1 = x1;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticAbs.prototype,\n      'y1',\n      {\n        get: function() {\n          return this._y1\n        },\n        set: function(y1) {\n          this._y1 = y1;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n\n    window.SVGPathSegCurvetoQuadraticRel = function(\n      owningPathSegList,\n      x,\n      y,\n      x1,\n      y1\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL,\n        'q',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._x1 = x1;\n      this._y1 = y1;\n    };\n    window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoQuadraticRel]'\n    };\n    window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x1 +\n        ' ' +\n        this._y1 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoQuadraticRel(\n        undefined,\n        this._x,\n        this._y,\n        this._x1,\n        this._y1\n      )\n    };\n    Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticRel.prototype,\n      'x1',\n      {\n        get: function() {\n          return this._x1\n        },\n        set: function(x1) {\n          this._x1 = x1;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticRel.prototype,\n      'y1',\n      {\n        get: function() {\n          return this._y1\n        },\n        set: function(y1) {\n          this._y1 = y1;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n\n    window.SVGPathSegArcAbs = function(\n      owningPathSegList,\n      x,\n      y,\n      r1,\n      r2,\n      angle,\n      largeArcFlag,\n      sweepFlag\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_ARC_ABS,\n        'A',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._r1 = r1;\n      this._r2 = r2;\n      this._angle = angle;\n      this._largeArcFlag = largeArcFlag;\n      this._sweepFlag = sweepFlag;\n    };\n    window.SVGPathSegArcAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegArcAbs.prototype.toString = function() {\n      return '[object SVGPathSegArcAbs]'\n    };\n    window.SVGPathSegArcAbs.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._r1 +\n        ' ' +\n        this._r2 +\n        ' ' +\n        this._angle +\n        ' ' +\n        (this._largeArcFlag ? '1' : '0') +\n        ' ' +\n        (this._sweepFlag ? '1' : '0') +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegArcAbs.prototype.clone = function() {\n      return new window.SVGPathSegArcAbs(\n        undefined,\n        this._x,\n        this._y,\n        this._r1,\n        this._r2,\n        this._angle,\n        this._largeArcFlag,\n        this._sweepFlag\n      )\n    };\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r1', {\n      get: function() {\n        return this._r1\n      },\n      set: function(r1) {\n        this._r1 = r1;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r2', {\n      get: function() {\n        return this._r2\n      },\n      set: function(r2) {\n        this._r2 = r2;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'angle', {\n      get: function() {\n        return this._angle\n      },\n      set: function(angle) {\n        this._angle = angle;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'largeArcFlag', {\n      get: function() {\n        return this._largeArcFlag\n      },\n      set: function(largeArcFlag) {\n        this._largeArcFlag = largeArcFlag;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'sweepFlag', {\n      get: function() {\n        return this._sweepFlag\n      },\n      set: function(sweepFlag) {\n        this._sweepFlag = sweepFlag;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegArcRel = function(\n      owningPathSegList,\n      x,\n      y,\n      r1,\n      r2,\n      angle,\n      largeArcFlag,\n      sweepFlag\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_ARC_REL,\n        'a',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._r1 = r1;\n      this._r2 = r2;\n      this._angle = angle;\n      this._largeArcFlag = largeArcFlag;\n      this._sweepFlag = sweepFlag;\n    };\n    window.SVGPathSegArcRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegArcRel.prototype.toString = function() {\n      return '[object SVGPathSegArcRel]'\n    };\n    window.SVGPathSegArcRel.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._r1 +\n        ' ' +\n        this._r2 +\n        ' ' +\n        this._angle +\n        ' ' +\n        (this._largeArcFlag ? '1' : '0') +\n        ' ' +\n        (this._sweepFlag ? '1' : '0') +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegArcRel.prototype.clone = function() {\n      return new window.SVGPathSegArcRel(\n        undefined,\n        this._x,\n        this._y,\n        this._r1,\n        this._r2,\n        this._angle,\n        this._largeArcFlag,\n        this._sweepFlag\n      )\n    };\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r1', {\n      get: function() {\n        return this._r1\n      },\n      set: function(r1) {\n        this._r1 = r1;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r2', {\n      get: function() {\n        return this._r2\n      },\n      set: function(r2) {\n        this._r2 = r2;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'angle', {\n      get: function() {\n        return this._angle\n      },\n      set: function(angle) {\n        this._angle = angle;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'largeArcFlag', {\n      get: function() {\n        return this._largeArcFlag\n      },\n      set: function(largeArcFlag) {\n        this._largeArcFlag = largeArcFlag;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'sweepFlag', {\n      get: function() {\n        return this._sweepFlag\n      },\n      set: function(sweepFlag) {\n        this._sweepFlag = sweepFlag;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegLinetoHorizontalAbs = function(owningPathSegList, x) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS,\n        'H',\n        owningPathSegList\n      );\n      this._x = x;\n    };\n    window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function() {\n      return '[object SVGPathSegLinetoHorizontalAbs]'\n    };\n    window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x\n    };\n    window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function() {\n      return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x)\n    };\n    Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegLinetoHorizontalRel = function(owningPathSegList, x) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL,\n        'h',\n        owningPathSegList\n      );\n      this._x = x;\n    };\n    window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegLinetoHorizontalRel.prototype.toString = function() {\n      return '[object SVGPathSegLinetoHorizontalRel]'\n    };\n    window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x\n    };\n    window.SVGPathSegLinetoHorizontalRel.prototype.clone = function() {\n      return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x)\n    };\n    Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegLinetoVerticalAbs = function(owningPathSegList, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS,\n        'V',\n        owningPathSegList\n      );\n      this._y = y;\n    };\n    window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegLinetoVerticalAbs.prototype.toString = function() {\n      return '[object SVGPathSegLinetoVerticalAbs]'\n    };\n    window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._y\n    };\n    window.SVGPathSegLinetoVerticalAbs.prototype.clone = function() {\n      return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y)\n    };\n    Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegLinetoVerticalRel = function(owningPathSegList, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL,\n        'v',\n        owningPathSegList\n      );\n      this._y = y;\n    };\n    window.SVGPathSegLinetoVerticalRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegLinetoVerticalRel.prototype.toString = function() {\n      return '[object SVGPathSegLinetoVerticalRel]'\n    };\n    window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._y\n    };\n    window.SVGPathSegLinetoVerticalRel.prototype.clone = function() {\n      return new window.SVGPathSegLinetoVerticalRel(undefined, this._y)\n    };\n    Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegCurvetoCubicSmoothAbs = function(\n      owningPathSegList,\n      x,\n      y,\n      x2,\n      y2\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS,\n        'S',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._x2 = x2;\n      this._y2 = y2;\n    };\n    window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoCubicSmoothAbs]'\n    };\n    window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x2 +\n        ' ' +\n        this._y2 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoCubicSmoothAbs(\n        undefined,\n        this._x,\n        this._y,\n        this._x2,\n        this._y2\n      )\n    };\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,\n      'x',\n      {\n        get: function() {\n          return this._x\n        },\n        set: function(x) {\n          this._x = x;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,\n      'y',\n      {\n        get: function() {\n          return this._y\n        },\n        set: function(y) {\n          this._y = y;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,\n      'x2',\n      {\n        get: function() {\n          return this._x2\n        },\n        set: function(x2) {\n          this._x2 = x2;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,\n      'y2',\n      {\n        get: function() {\n          return this._y2\n        },\n        set: function(y2) {\n          this._y2 = y2;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n\n    window.SVGPathSegCurvetoCubicSmoothRel = function(\n      owningPathSegList,\n      x,\n      y,\n      x2,\n      y2\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL,\n        's',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._x2 = x2;\n      this._y2 = y2;\n    };\n    window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoCubicSmoothRel]'\n    };\n    window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x2 +\n        ' ' +\n        this._y2 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoCubicSmoothRel(\n        undefined,\n        this._x,\n        this._y,\n        this._x2,\n        this._y2\n      )\n    };\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothRel.prototype,\n      'x',\n      {\n        get: function() {\n          return this._x\n        },\n        set: function(x) {\n          this._x = x;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothRel.prototype,\n      'y',\n      {\n        get: function() {\n          return this._y\n        },\n        set: function(y) {\n          this._y = y;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothRel.prototype,\n      'x2',\n      {\n        get: function() {\n          return this._x2\n        },\n        set: function(x2) {\n          this._x2 = x2;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothRel.prototype,\n      'y2',\n      {\n        get: function() {\n          return this._y2\n        },\n        set: function(y2) {\n          this._y2 = y2;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n\n    window.SVGPathSegCurvetoQuadraticSmoothAbs = function(\n      owningPathSegList,\n      x,\n      y\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS,\n        'T',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n    };\n    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoQuadraticSmoothAbs]'\n    };\n    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    };\n    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoQuadraticSmoothAbs(\n        undefined,\n        this._x,\n        this._y\n      )\n    };\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype,\n      'x',\n      {\n        get: function() {\n          return this._x\n        },\n        set: function(x) {\n          this._x = x;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype,\n      'y',\n      {\n        get: function() {\n          return this._y\n        },\n        set: function(y) {\n          this._y = y;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n\n    window.SVGPathSegCurvetoQuadraticSmoothRel = function(\n      owningPathSegList,\n      x,\n      y\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL,\n        't',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n    };\n    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoQuadraticSmoothRel]'\n    };\n    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    };\n    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoQuadraticSmoothRel(\n        undefined,\n        this._x,\n        this._y\n      )\n    };\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticSmoothRel.prototype,\n      'x',\n      {\n        get: function() {\n          return this._x\n        },\n        set: function(x) {\n          this._x = x;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticSmoothRel.prototype,\n      'y',\n      {\n        get: function() {\n          return this._y\n        },\n        set: function(y) {\n          this._y = y;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n\n    // Add createSVGPathSeg* functions to window.SVGPathElement.\n    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.\n    window.SVGPathElement.prototype.createSVGPathSegClosePath = function() {\n      return new window.SVGPathSegClosePath(undefined)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function(x, y) {\n      return new window.SVGPathSegMovetoAbs(undefined, x, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function(x, y) {\n      return new window.SVGPathSegMovetoRel(undefined, x, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function(x, y) {\n      return new window.SVGPathSegLinetoAbs(undefined, x, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function(x, y) {\n      return new window.SVGPathSegLinetoRel(undefined, x, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function(\n      x,\n      y,\n      x1,\n      y1,\n      x2,\n      y2\n    ) {\n      return new window.SVGPathSegCurvetoCubicAbs(\n        undefined,\n        x,\n        y,\n        x1,\n        y1,\n        x2,\n        y2\n      )\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function(\n      x,\n      y,\n      x1,\n      y1,\n      x2,\n      y2\n    ) {\n      return new window.SVGPathSegCurvetoCubicRel(\n        undefined,\n        x,\n        y,\n        x1,\n        y1,\n        x2,\n        y2\n      )\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function(\n      x,\n      y,\n      x1,\n      y1\n    ) {\n      return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function(\n      x,\n      y,\n      x1,\n      y1\n    ) {\n      return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegArcAbs = function(\n      x,\n      y,\n      r1,\n      r2,\n      angle,\n      largeArcFlag,\n      sweepFlag\n    ) {\n      return new window.SVGPathSegArcAbs(\n        undefined,\n        x,\n        y,\n        r1,\n        r2,\n        angle,\n        largeArcFlag,\n        sweepFlag\n      )\n    };\n    window.SVGPathElement.prototype.createSVGPathSegArcRel = function(\n      x,\n      y,\n      r1,\n      r2,\n      angle,\n      largeArcFlag,\n      sweepFlag\n    ) {\n      return new window.SVGPathSegArcRel(\n        undefined,\n        x,\n        y,\n        r1,\n        r2,\n        angle,\n        largeArcFlag,\n        sweepFlag\n      )\n    };\n    window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function(\n      x\n    ) {\n      return new window.SVGPathSegLinetoHorizontalAbs(undefined, x)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function(\n      x\n    ) {\n      return new window.SVGPathSegLinetoHorizontalRel(undefined, x)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function(\n      y\n    ) {\n      return new window.SVGPathSegLinetoVerticalAbs(undefined, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function(\n      y\n    ) {\n      return new window.SVGPathSegLinetoVerticalRel(undefined, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function(\n      x,\n      y,\n      x2,\n      y2\n    ) {\n      return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function(\n      x,\n      y,\n      x2,\n      y2\n    ) {\n      return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function(\n      x,\n      y\n    ) {\n      return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function(\n      x,\n      y\n    ) {\n      return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y)\n    };\n\n    if (!('getPathSegAtLength' in window.SVGPathElement.prototype)) {\n      // Add getPathSegAtLength to SVGPathElement.\n      // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength\n      // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.\n      window.SVGPathElement.prototype.getPathSegAtLength = function(distance) {\n        if (distance === undefined || !isFinite(distance))\n          throw 'Invalid arguments.'\n\n        var measurementElement = document.createElementNS(\n          'http://www.w3.org/2000/svg',\n          'path'\n        );\n        measurementElement.setAttribute('d', this.getAttribute('d'));\n        var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1;\n\n        // If the path is empty, return 0.\n        if (lastPathSegment <= 0) return 0\n\n        do {\n          measurementElement.pathSegList.removeItem(lastPathSegment);\n          if (distance > measurementElement.getTotalLength()) break\n          lastPathSegment--;\n        } while (lastPathSegment > 0)\n        return lastPathSegment\n      };\n    }\n  }\n\n  if (!('SVGPathSegList' in window)) {\n    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList\n    window.SVGPathSegList = function(pathElement) {\n      this._pathElement = pathElement;\n      this._list = this._parsePath(this._pathElement.getAttribute('d'));\n\n      // Use a MutationObserver to catch changes to the path's \"d\" attribute.\n      this._mutationObserverConfig = {\n        attributes: true,\n        attributeFilter: ['d']\n      };\n      this._pathElementMutationObserver = new MutationObserver(\n        this._updateListFromPathMutations.bind(this)\n      );\n      this._pathElementMutationObserver.observe(\n        this._pathElement,\n        this._mutationObserverConfig\n      );\n    };\n\n    window.SVGPathSegList.prototype.classname = 'SVGPathSegList';\n\n    Object.defineProperty(window.SVGPathSegList.prototype, 'numberOfItems', {\n      get: function() {\n        this._checkPathSynchronizedToList();\n        return this._list.length\n      },\n      enumerable: true\n    });\n\n    // Add the pathSegList accessors to window.SVGPathElement.\n    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData\n    Object.defineProperty(window.SVGPathElement.prototype, 'pathSegList', {\n      get: function() {\n        if (!this._pathSegList)\n          this._pathSegList = new window.SVGPathSegList(this);\n        return this._pathSegList\n      },\n      enumerable: true\n    });\n    // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.\n    Object.defineProperty(\n      window.SVGPathElement.prototype,\n      'normalizedPathSegList',\n      {\n        get: function() {\n          return this.pathSegList\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathElement.prototype,\n      'animatedPathSegList',\n      {\n        get: function() {\n          return this.pathSegList\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathElement.prototype,\n      'animatedNormalizedPathSegList',\n      {\n        get: function() {\n          return this.pathSegList\n        },\n        enumerable: true\n      }\n    );\n\n    // Process any pending mutations to the path element and update the list as needed.\n    // This should be the first call of all public functions and is needed because\n    // MutationObservers are not synchronous so we can have pending asynchronous mutations.\n    window.SVGPathSegList.prototype._checkPathSynchronizedToList = function() {\n      this._updateListFromPathMutations(\n        this._pathElementMutationObserver.takeRecords()\n      );\n    };\n\n    window.SVGPathSegList.prototype._updateListFromPathMutations = function(\n      mutationRecords\n    ) {\n      if (!this._pathElement) return\n      var hasPathMutations = false;\n      mutationRecords.forEach(function(record) {\n        if (record.attributeName == 'd') hasPathMutations = true;\n      });\n      if (hasPathMutations)\n        this._list = this._parsePath(this._pathElement.getAttribute('d'));\n    };\n\n    // Serialize the list and update the path's 'd' attribute.\n    window.SVGPathSegList.prototype._writeListToPath = function() {\n      this._pathElementMutationObserver.disconnect();\n      this._pathElement.setAttribute(\n        'd',\n        window.SVGPathSegList._pathSegArrayAsString(this._list)\n      );\n      this._pathElementMutationObserver.observe(\n        this._pathElement,\n        this._mutationObserverConfig\n      );\n    };\n\n    // When a path segment changes the list needs to be synchronized back to the path element.\n    window.SVGPathSegList.prototype.segmentChanged = function(pathSeg) {\n      this._writeListToPath();\n    };\n\n    window.SVGPathSegList.prototype.clear = function() {\n      this._checkPathSynchronizedToList();\n\n      this._list.forEach(function(pathSeg) {\n        pathSeg._owningPathSegList = null;\n      });\n      this._list = [];\n      this._writeListToPath();\n    };\n\n    window.SVGPathSegList.prototype.initialize = function(newItem) {\n      this._checkPathSynchronizedToList();\n\n      this._list = [newItem];\n      newItem._owningPathSegList = this;\n      this._writeListToPath();\n      return newItem\n    };\n\n    window.SVGPathSegList.prototype._checkValidIndex = function(index) {\n      if (isNaN(index) || index < 0 || index >= this.numberOfItems)\n        throw 'INDEX_SIZE_ERR'\n    };\n\n    window.SVGPathSegList.prototype.getItem = function(index) {\n      this._checkPathSynchronizedToList();\n\n      this._checkValidIndex(index);\n      return this._list[index]\n    };\n\n    window.SVGPathSegList.prototype.insertItemBefore = function(\n      newItem,\n      index\n    ) {\n      this._checkPathSynchronizedToList();\n\n      // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.\n      if (index > this.numberOfItems) index = this.numberOfItems;\n      if (newItem._owningPathSegList) {\n        // SVG2 spec says to make a copy.\n        newItem = newItem.clone();\n      }\n      this._list.splice(index, 0, newItem);\n      newItem._owningPathSegList = this;\n      this._writeListToPath();\n      return newItem\n    };\n\n    window.SVGPathSegList.prototype.replaceItem = function(newItem, index) {\n      this._checkPathSynchronizedToList();\n\n      if (newItem._owningPathSegList) {\n        // SVG2 spec says to make a copy.\n        newItem = newItem.clone();\n      }\n      this._checkValidIndex(index);\n      this._list[index] = newItem;\n      newItem._owningPathSegList = this;\n      this._writeListToPath();\n      return newItem\n    };\n\n    window.SVGPathSegList.prototype.removeItem = function(index) {\n      this._checkPathSynchronizedToList();\n\n      this._checkValidIndex(index);\n      var item = this._list[index];\n      this._list.splice(index, 1);\n      this._writeListToPath();\n      return item\n    };\n\n    window.SVGPathSegList.prototype.appendItem = function(newItem) {\n      this._checkPathSynchronizedToList();\n\n      if (newItem._owningPathSegList) {\n        // SVG2 spec says to make a copy.\n        newItem = newItem.clone();\n      }\n      this._list.push(newItem);\n      newItem._owningPathSegList = this;\n      // TODO: Optimize this to just append to the existing attribute.\n      this._writeListToPath();\n      return newItem\n    };\n\n    window.SVGPathSegList._pathSegArrayAsString = function(pathSegArray) {\n      var string = '';\n      var first = true;\n      pathSegArray.forEach(function(pathSeg) {\n        if (first) {\n          first = false;\n          string += pathSeg._asPathString();\n        } else {\n          string += ' ' + pathSeg._asPathString();\n        }\n      });\n      return string\n    };\n\n    // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.\n    window.SVGPathSegList.prototype._parsePath = function(string) {\n      if (!string || string.length == 0) return []\n\n      var owningPathSegList = this;\n\n      var Builder = function() {\n        this.pathSegList = [];\n      };\n\n      Builder.prototype.appendSegment = function(pathSeg) {\n        this.pathSegList.push(pathSeg);\n      };\n\n      var Source = function(string) {\n        this._string = string;\n        this._currentIndex = 0;\n        this._endIndex = this._string.length;\n        this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;\n\n        this._skipOptionalSpaces();\n      };\n\n      Source.prototype._isCurrentSpace = function() {\n        var character = this._string[this._currentIndex];\n        return (\n          character <= ' ' &&\n          (character == ' ' ||\n            character == '\\n' ||\n            character == '\\t' ||\n            character == '\\r' ||\n            character == '\\f')\n        )\n      };\n\n      Source.prototype._skipOptionalSpaces = function() {\n        while (this._currentIndex < this._endIndex && this._isCurrentSpace())\n          this._currentIndex++;\n        return this._currentIndex < this._endIndex\n      };\n\n      Source.prototype._skipOptionalSpacesOrDelimiter = function() {\n        if (\n          this._currentIndex < this._endIndex &&\n          !this._isCurrentSpace() &&\n          this._string.charAt(this._currentIndex) != ','\n        )\n          return false\n        if (this._skipOptionalSpaces()) {\n          if (\n            this._currentIndex < this._endIndex &&\n            this._string.charAt(this._currentIndex) == ','\n          ) {\n            this._currentIndex++;\n            this._skipOptionalSpaces();\n          }\n        }\n        return this._currentIndex < this._endIndex\n      };\n\n      Source.prototype.hasMoreData = function() {\n        return this._currentIndex < this._endIndex\n      };\n\n      Source.prototype.peekSegmentType = function() {\n        var lookahead = this._string[this._currentIndex];\n        return this._pathSegTypeFromChar(lookahead)\n      };\n\n      Source.prototype._pathSegTypeFromChar = function(lookahead) {\n        switch (lookahead) {\n          case 'Z':\n          case 'z':\n            return window.SVGPathSeg.PATHSEG_CLOSEPATH\n          case 'M':\n            return window.SVGPathSeg.PATHSEG_MOVETO_ABS\n          case 'm':\n            return window.SVGPathSeg.PATHSEG_MOVETO_REL\n          case 'L':\n            return window.SVGPathSeg.PATHSEG_LINETO_ABS\n          case 'l':\n            return window.SVGPathSeg.PATHSEG_LINETO_REL\n          case 'C':\n            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS\n          case 'c':\n            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL\n          case 'Q':\n            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS\n          case 'q':\n            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL\n          case 'A':\n            return window.SVGPathSeg.PATHSEG_ARC_ABS\n          case 'a':\n            return window.SVGPathSeg.PATHSEG_ARC_REL\n          case 'H':\n            return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS\n          case 'h':\n            return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL\n          case 'V':\n            return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS\n          case 'v':\n            return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL\n          case 'S':\n            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS\n          case 's':\n            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL\n          case 'T':\n            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS\n          case 't':\n            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL\n          default:\n            return window.SVGPathSeg.PATHSEG_UNKNOWN\n        }\n      };\n\n      Source.prototype._nextCommandHelper = function(\n        lookahead,\n        previousCommand\n      ) {\n        // Check for remaining coordinates in the current command.\n        if (\n          (lookahead == '+' ||\n            lookahead == '-' ||\n            lookahead == '.' ||\n            (lookahead >= '0' && lookahead <= '9')) &&\n          previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH\n        ) {\n          if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS)\n            return window.SVGPathSeg.PATHSEG_LINETO_ABS\n          if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL)\n            return window.SVGPathSeg.PATHSEG_LINETO_REL\n          return previousCommand\n        }\n        return window.SVGPathSeg.PATHSEG_UNKNOWN\n      };\n\n      Source.prototype.initialCommandIsMoveTo = function() {\n        // If the path is empty it is still valid, so return true.\n        if (!this.hasMoreData()) return true\n        var command = this.peekSegmentType();\n        // Path must start with moveTo.\n        return (\n          command == window.SVGPathSeg.PATHSEG_MOVETO_ABS ||\n          command == window.SVGPathSeg.PATHSEG_MOVETO_REL\n        )\n      };\n\n      // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.\n      // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF\n      Source.prototype._parseNumber = function() {\n        var exponent = 0;\n        var integer = 0;\n        var frac = 1;\n        var decimal = 0;\n        var sign = 1;\n        var expsign = 1;\n\n        var startIndex = this._currentIndex;\n\n        this._skipOptionalSpaces();\n\n        // Read the sign.\n        if (\n          this._currentIndex < this._endIndex &&\n          this._string.charAt(this._currentIndex) == '+'\n        )\n          this._currentIndex++;\n        else if (\n          this._currentIndex < this._endIndex &&\n          this._string.charAt(this._currentIndex) == '-'\n        ) {\n          this._currentIndex++;\n          sign = -1;\n        }\n\n        if (\n          this._currentIndex == this._endIndex ||\n          ((this._string.charAt(this._currentIndex) < '0' ||\n            this._string.charAt(this._currentIndex) > '9') &&\n            this._string.charAt(this._currentIndex) != '.')\n        )\n          // The first character of a number must be one of [0-9+-.].\n          return undefined\n\n        // Read the integer part, build right-to-left.\n        var startIntPartIndex = this._currentIndex;\n        while (\n          this._currentIndex < this._endIndex &&\n          this._string.charAt(this._currentIndex) >= '0' &&\n          this._string.charAt(this._currentIndex) <= '9'\n        )\n          this._currentIndex++; // Advance to first non-digit.\n\n        if (this._currentIndex != startIntPartIndex) {\n          var scanIntPartIndex = this._currentIndex - 1;\n          var multiplier = 1;\n          while (scanIntPartIndex >= startIntPartIndex) {\n            integer +=\n              multiplier * (this._string.charAt(scanIntPartIndex--) - '0');\n            multiplier *= 10;\n          }\n        }\n\n        // Read the decimals.\n        if (\n          this._currentIndex < this._endIndex &&\n          this._string.charAt(this._currentIndex) == '.'\n        ) {\n          this._currentIndex++;\n\n          // There must be a least one digit following the .\n          if (\n            this._currentIndex >= this._endIndex ||\n            this._string.charAt(this._currentIndex) < '0' ||\n            this._string.charAt(this._currentIndex) > '9'\n          )\n            return undefined\n          while (\n            this._currentIndex < this._endIndex &&\n            this._string.charAt(this._currentIndex) >= '0' &&\n            this._string.charAt(this._currentIndex) <= '9'\n          ) {\n            frac *= 10;\n            decimal += (this._string.charAt(this._currentIndex) - '0') / frac;\n            this._currentIndex += 1;\n          }\n        }\n\n        // Read the exponent part.\n        if (\n          this._currentIndex != startIndex &&\n          this._currentIndex + 1 < this._endIndex &&\n          (this._string.charAt(this._currentIndex) == 'e' ||\n            this._string.charAt(this._currentIndex) == 'E') &&\n          this._string.charAt(this._currentIndex + 1) != 'x' &&\n          this._string.charAt(this._currentIndex + 1) != 'm'\n        ) {\n          this._currentIndex++;\n\n          // Read the sign of the exponent.\n          if (this._string.charAt(this._currentIndex) == '+') {\n            this._currentIndex++;\n          } else if (this._string.charAt(this._currentIndex) == '-') {\n            this._currentIndex++;\n            expsign = -1;\n          }\n\n          // There must be an exponent.\n          if (\n            this._currentIndex >= this._endIndex ||\n            this._string.charAt(this._currentIndex) < '0' ||\n            this._string.charAt(this._currentIndex) > '9'\n          )\n            return undefined\n\n          while (\n            this._currentIndex < this._endIndex &&\n            this._string.charAt(this._currentIndex) >= '0' &&\n            this._string.charAt(this._currentIndex) <= '9'\n          ) {\n            exponent *= 10;\n            exponent += this._string.charAt(this._currentIndex) - '0';\n            this._currentIndex++;\n          }\n        }\n\n        var number = integer + decimal;\n        number *= sign;\n\n        if (exponent) number *= Math.pow(10, expsign * exponent);\n\n        if (startIndex == this._currentIndex) return undefined\n\n        this._skipOptionalSpacesOrDelimiter();\n\n        return number\n      };\n\n      Source.prototype._parseArcFlag = function() {\n        if (this._currentIndex >= this._endIndex) return undefined\n        var flag = false;\n        var flagChar = this._string.charAt(this._currentIndex++);\n        if (flagChar == '0') flag = false;\n        else if (flagChar == '1') flag = true;\n        else return undefined\n\n        this._skipOptionalSpacesOrDelimiter();\n        return flag\n      };\n\n      Source.prototype.parseSegment = function() {\n        var lookahead = this._string[this._currentIndex];\n        var command = this._pathSegTypeFromChar(lookahead);\n        if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {\n          // Possibly an implicit command. Not allowed if this is the first command.\n          if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN)\n            return null\n          command = this._nextCommandHelper(lookahead, this._previousCommand);\n          if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null\n        } else {\n          this._currentIndex++;\n        }\n\n        this._previousCommand = command;\n\n        switch (command) {\n          case window.SVGPathSeg.PATHSEG_MOVETO_REL:\n            return new window.SVGPathSegMovetoRel(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_MOVETO_ABS:\n            return new window.SVGPathSegMovetoAbs(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_REL:\n            return new window.SVGPathSegLinetoRel(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_ABS:\n            return new window.SVGPathSegLinetoAbs(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:\n            return new window.SVGPathSegLinetoHorizontalRel(\n              owningPathSegList,\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:\n            return new window.SVGPathSegLinetoHorizontalAbs(\n              owningPathSegList,\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:\n            return new window.SVGPathSegLinetoVerticalRel(\n              owningPathSegList,\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:\n            return new window.SVGPathSegLinetoVerticalAbs(\n              owningPathSegList,\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_CLOSEPATH:\n            this._skipOptionalSpaces();\n            return new window.SVGPathSegClosePath(owningPathSegList)\n          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              x2: this._parseNumber(),\n              y2: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegCurvetoCubicRel(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1,\n              points.x2,\n              points.y2\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              x2: this._parseNumber(),\n              y2: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegCurvetoCubicAbs(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1,\n              points.x2,\n              points.y2\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:\n            var points = {\n              x2: this._parseNumber(),\n              y2: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegCurvetoCubicSmoothRel(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x2,\n              points.y2\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:\n            var points = {\n              x2: this._parseNumber(),\n              y2: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegCurvetoCubicSmoothAbs(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x2,\n              points.y2\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegCurvetoQuadraticRel(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegCurvetoQuadraticAbs(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:\n            return new window.SVGPathSegCurvetoQuadraticSmoothRel(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:\n            return new window.SVGPathSegCurvetoQuadraticSmoothAbs(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_ARC_REL:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              arcAngle: this._parseNumber(),\n              arcLarge: this._parseArcFlag(),\n              arcSweep: this._parseArcFlag(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegArcRel(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1,\n              points.arcAngle,\n              points.arcLarge,\n              points.arcSweep\n            )\n          case window.SVGPathSeg.PATHSEG_ARC_ABS:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              arcAngle: this._parseNumber(),\n              arcLarge: this._parseArcFlag(),\n              arcSweep: this._parseArcFlag(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegArcAbs(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1,\n              points.arcAngle,\n              points.arcLarge,\n              points.arcSweep\n            )\n          default:\n            throw 'Unknown path seg type.'\n        }\n      };\n\n      var builder = new Builder();\n      var source = new Source(string);\n\n      if (!source.initialCommandIsMoveTo()) return []\n      while (source.hasMoreData()) {\n        var pathSeg = source.parseSegment();\n        if (!pathSeg) return []\n        builder.appendSegment(pathSeg);\n      }\n\n      return builder.pathSegList\n    };\n  }\n})();\n\n// String.padEnd polyfill for IE11\n//\n// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd\nif (!String.prototype.padEnd) {\n  String.prototype.padEnd = function padEnd(targetLength, padString) {\n    targetLength = targetLength >> 0; //floor if number or convert non-number to 0;\n    padString = String(typeof padString !== 'undefined' ? padString : ' ');\n    if (this.length > targetLength) {\n      return String(this)\n    } else {\n      targetLength = targetLength - this.length;\n      if (targetLength > padString.length) {\n        padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed\n      }\n      return String(this) + padString.slice(0, targetLength)\n    }\n  };\n}\n\n// Object.assign polyfill for IE11\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill\nif (typeof Object.assign !== 'function') {\n  // Must be writable: true, enumerable: false, configurable: true\n  Object.defineProperty(Object, 'assign', {\n    value: function assign(target, varArgs) {\n      if (target === null || target === undefined) {\n        throw new TypeError('Cannot convert undefined or null to object')\n      }\n\n      var to = Object(target);\n\n      for (var index = 1; index < arguments.length; index++) {\n        var nextSource = arguments[index];\n\n        if (nextSource !== null && nextSource !== undefined) {\n          for (var nextKey in nextSource) {\n            // Avoid bugs when hasOwnProperty is shadowed\n            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n              to[nextKey] = nextSource[nextKey];\n            }\n          }\n        }\n      }\n      return to\n    },\n    writable: true,\n    configurable: true\n  });\n}\n\n/* jshint ignore:end */\n\nChart.prototype.axis = function() {};\nChart.prototype.axis.labels = function(labels) {\n  var $$ = this.internal;\n  if (arguments.length) {\n    Object.keys(labels).forEach(function(axisId) {\n      $$.axis.setLabelText(axisId, labels[axisId]);\n    });\n    $$.axis.updateLabels();\n  }\n  // TODO: return some values?\n};\nChart.prototype.axis.max = function(max) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (arguments.length) {\n    if (typeof max === 'object') {\n      if (isValue(max.x)) {\n        config.axis_x_max = max.x;\n      }\n      if (isValue(max.y)) {\n        config.axis_y_max = max.y;\n      }\n      if (isValue(max.y2)) {\n        config.axis_y2_max = max.y2;\n      }\n    } else {\n      config.axis_y_max = config.axis_y2_max = max;\n    }\n    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\n  } else {\n    return {\n      x: config.axis_x_max,\n      y: config.axis_y_max,\n      y2: config.axis_y2_max\n    }\n  }\n};\nChart.prototype.axis.min = function(min) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (arguments.length) {\n    if (typeof min === 'object') {\n      if (isValue(min.x)) {\n        config.axis_x_min = min.x;\n      }\n      if (isValue(min.y)) {\n        config.axis_y_min = min.y;\n      }\n      if (isValue(min.y2)) {\n        config.axis_y2_min = min.y2;\n      }\n    } else {\n      config.axis_y_min = config.axis_y2_min = min;\n    }\n    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\n  } else {\n    return {\n      x: config.axis_x_min,\n      y: config.axis_y_min,\n      y2: config.axis_y2_min\n    }\n  }\n};\nChart.prototype.axis.range = function(range) {\n  if (arguments.length) {\n    if (isDefined(range.max)) {\n      this.axis.max(range.max);\n    }\n    if (isDefined(range.min)) {\n      this.axis.min(range.min);\n    }\n  } else {\n    return {\n      max: this.axis.max(),\n      min: this.axis.min()\n    }\n  }\n};\n\nChart.prototype.axis.types = function(types) {\n  const $$ = this.internal;\n  if (types === undefined) {\n    return {\n      y: $$.config.axis_y_type,\n      y2: $$.config.axis_y2_type\n    }\n  } else {\n    if (isDefined(types.y)) {\n      $$.config.axis_y_type = types.y;\n    }\n\n    if (isDefined(types.y2)) {\n      $$.config.axis_y2_type = types.y2;\n    }\n\n    $$.updateScales();\n    $$.redraw();\n  }\n};\n\nChart.prototype.category = function(i, category) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (arguments.length > 1) {\n    config.axis_x_categories[i] = category;\n    $$.redraw();\n  }\n  return config.axis_x_categories[i]\n};\nChart.prototype.categories = function(categories) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (!arguments.length) {\n    return config.axis_x_categories\n  }\n  config.axis_x_categories = categories;\n  $$.redraw();\n  return config.axis_x_categories\n};\n\nChart.prototype.resize = function(size) {\n  var $$ = this.internal,\n    config = $$.config;\n  config.size_width = size ? size.width : null;\n  config.size_height = size ? size.height : null;\n  this.flush();\n};\n\nChart.prototype.flush = function() {\n  var $$ = this.internal;\n  $$.updateAndRedraw({\n    withLegend: true,\n    withTransition: false,\n    withTransitionForTransform: false\n  });\n};\n\nChart.prototype.destroy = function() {\n  var $$ = this.internal;\n\n  window.clearInterval($$.intervalForObserveInserted);\n\n  if ($$.resizeTimeout !== undefined) {\n    window.clearTimeout($$.resizeTimeout);\n  }\n\n  if (window.detachEvent) {\n    window.detachEvent('onresize', $$.resizeIfElementDisplayed);\n  } else if (window.removeEventListener) {\n    window.removeEventListener('resize', $$.resizeIfElementDisplayed);\n  } else {\n    var wrapper = window.onresize;\n    // check if no one else removed our wrapper and remove our resizeFunction from it\n    if (wrapper && wrapper.add && wrapper.remove) {\n      wrapper.remove($$.resizeFunction);\n    }\n  }\n\n  // Removes the inner resize functions\n  $$.resizeFunction.remove();\n\n  // Unbinds from the window focus event\n  $$.unbindWindowFocus();\n\n  $$.selectChart.classed('c3', false).html('');\n\n  // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen.\n  Object.keys($$).forEach(function(key) {\n    $$[key] = null;\n  });\n\n  return null\n};\n\n// TODO: fix\nChart.prototype.color = function(id) {\n  var $$ = this.internal;\n  return $$.color(id) // more patterns\n};\n\nChart.prototype.data = function(targetIds) {\n  var targets = this.internal.data.targets;\n  return typeof targetIds === 'undefined'\n    ? targets\n    : targets.filter(function(t) {\n        return [].concat(targetIds).indexOf(t.id) >= 0\n      })\n};\nChart.prototype.data.shown = function(targetIds) {\n  return this.internal.filterTargetsToShow(this.data(targetIds))\n};\n\n/**\n * Get values of the data loaded in the chart.\n *\n * @param {String|Array} targetId This API returns the value of specified target.\n * @param flat\n * @return {Array} Data values\n */\nChart.prototype.data.values = function(targetId, flat = true) {\n  let values = null;\n\n  if (targetId) {\n    const targets = this.data(targetId);\n    if (targets && isArray(targets)) {\n      values = targets.reduce((ret, v) => {\n        const dataValue = v.values.map(d => d.value);\n        if (flat) {\n          ret = ret.concat(dataValue);\n        } else {\n          ret.push(dataValue);\n        }\n        return ret\n      }, []);\n    }\n  }\n\n  return values\n};\nChart.prototype.data.names = function(names) {\n  this.internal.clearLegendItemTextBoxCache();\n  return this.internal.updateDataAttributes('names', names)\n};\nChart.prototype.data.colors = function(colors) {\n  return this.internal.updateDataAttributes('colors', colors)\n};\nChart.prototype.data.axes = function(axes) {\n  return this.internal.updateDataAttributes('axes', axes)\n};\n\nChart.prototype.data.stackNormalized = function(normalized) {\n  if (normalized === undefined) {\n    return this.internal.isStackNormalized()\n  }\n\n  this.internal.config.data_stack_normalize = !!normalized;\n  this.internal.redraw();\n};\n\nChart.prototype.donut = function() {};\n\nChart.prototype.donut.padAngle = function(padAngle) {\n  if (padAngle === undefined) {\n    return this.internal.config.donut_padAngle\n  }\n  this.internal.config.donut_padAngle = padAngle;\n  this.flush();\n};\n\nChart.prototype.flow = function(args) {\n  var $$ = this.internal,\n    targets,\n    data,\n    notfoundIds = [],\n    orgDataCount = $$.getMaxDataCount(),\n    dataCount,\n    domain,\n    baseTarget,\n    baseValue,\n    length = 0,\n    tail = 0,\n    diff,\n    to;\n\n  if (args.json) {\n    data = $$.convertJsonToData(args.json, args.keys);\n  } else if (args.rows) {\n    data = $$.convertRowsToData(args.rows);\n  } else if (args.columns) {\n    data = $$.convertColumnsToData(args.columns);\n  } else {\n    return\n  }\n  targets = $$.convertDataToTargets(data, true);\n\n  // Update/Add data\n  $$.data.targets.forEach(function(t) {\n    var found = false,\n      i,\n      j;\n    for (i = 0; i < targets.length; i++) {\n      if (t.id === targets[i].id) {\n        found = true;\n\n        if (t.values[t.values.length - 1]) {\n          tail = t.values[t.values.length - 1].index + 1;\n        }\n        length = targets[i].values.length;\n\n        for (j = 0; j < length; j++) {\n          targets[i].values[j].index = tail + j;\n          if (!$$.isTimeSeries()) {\n            targets[i].values[j].x = tail + j;\n          }\n        }\n        t.values = t.values.concat(targets[i].values);\n\n        targets.splice(i, 1);\n        break\n      }\n    }\n    if (!found) {\n      notfoundIds.push(t.id);\n    }\n  });\n\n  // Append null for not found targets\n  $$.data.targets.forEach(function(t) {\n    var i, j;\n    for (i = 0; i < notfoundIds.length; i++) {\n      if (t.id === notfoundIds[i]) {\n        tail = t.values[t.values.length - 1].index + 1;\n        for (j = 0; j < length; j++) {\n          t.values.push({\n            id: t.id,\n            index: tail + j,\n            x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,\n            value: null\n          });\n        }\n      }\n    }\n  });\n\n  // Generate null values for new target\n  if ($$.data.targets.length) {\n    targets.forEach(function(t) {\n      var i,\n        missing = [];\n      for (i = $$.data.targets[0].values[0].index; i < tail; i++) {\n        missing.push({\n          id: t.id,\n          index: i,\n          x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,\n          value: null\n        });\n      }\n      t.values.forEach(function(v) {\n        v.index += tail;\n        if (!$$.isTimeSeries()) {\n          v.x += tail;\n        }\n      });\n      t.values = missing.concat(t.values);\n    });\n  }\n  $$.data.targets = $$.data.targets.concat(targets); // add remained\n\n  // check data count because behavior needs to change when it's only one\n  dataCount = $$.getMaxDataCount();\n  baseTarget = $$.data.targets[0];\n  baseValue = baseTarget.values[0];\n\n  // Update length to flow if needed\n  if (isDefined(args.to)) {\n    length = 0;\n    to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to;\n    baseTarget.values.forEach(function(v) {\n      if (v.x < to) {\n        length++;\n      }\n    });\n  } else if (isDefined(args.length)) {\n    length = args.length;\n  }\n\n  // If only one data, update the domain to flow from left edge of the chart\n  if (!orgDataCount) {\n    if ($$.isTimeSeries()) {\n      if (baseTarget.values.length > 1) {\n        diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x;\n      } else {\n        diff = baseValue.x - $$.getXDomain($$.data.targets)[0];\n      }\n    } else {\n      diff = 1;\n    }\n    domain = [baseValue.x - diff, baseValue.x];\n    $$.updateXDomain(null, true, true, false, domain);\n  } else if (orgDataCount === 1) {\n    if ($$.isTimeSeries()) {\n      diff =\n        (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;\n      domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];\n      $$.updateXDomain(null, true, true, false, domain);\n    }\n  }\n\n  // Set targets\n  $$.updateTargets($$.data.targets);\n\n  // Redraw with new targets\n  $$.redraw({\n    flow: {\n      index: baseValue.index,\n      length: length,\n      duration: isValue(args.duration)\n        ? args.duration\n        : $$.config.transition_duration,\n      done: args.done,\n      orgDataCount: orgDataCount\n    },\n    withLegend: true,\n    withTransition: orgDataCount > 1,\n    withTrimXDomain: false,\n    withUpdateXAxis: true\n  });\n};\n\nChartInternal.prototype.generateFlow = function(args) {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3;\n\n  return function() {\n    var targets = args.targets,\n      flow = args.flow,\n      drawBar = args.drawBar,\n      drawLine = args.drawLine,\n      drawArea = args.drawArea,\n      cx = args.cx,\n      cy = args.cy,\n      xv = args.xv,\n      xForText = args.xForText,\n      yForText = args.yForText,\n      duration = args.duration;\n\n    var translateX,\n      scaleX = 1,\n      transform,\n      flowIndex = flow.index,\n      flowLength = flow.length,\n      flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex),\n      flowEnd = $$.getValueOnIndex(\n        $$.data.targets[0].values,\n        flowIndex + flowLength\n      ),\n      orgDomain = $$.x.domain(),\n      domain,\n      durationForFlow = flow.duration || duration,\n      done = flow.done || function() {},\n      wait = $$.generateWait();\n\n    var xgrid,\n      xgridLines,\n      mainRegion,\n      mainText,\n      mainBar,\n      mainLine,\n      mainArea,\n      mainCircle;\n\n    // set flag\n    $$.flowing = true;\n\n    // remove head data after rendered\n    $$.data.targets.forEach(function(d) {\n      d.values.splice(0, flowLength);\n    });\n\n    // update x domain to generate axis elements for flow\n    domain = $$.updateXDomain(targets, true, true);\n    // update elements related to x scale\n    if ($$.updateXGrid) {\n      $$.updateXGrid(true);\n    }\n\n    xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid\n    xgridLines = $$.xgridLines || d3.selectAll([]);\n    mainRegion = $$.mainRegion || d3.selectAll([]);\n    mainText = $$.mainText || d3.selectAll([]);\n    mainBar = $$.mainBar || d3.selectAll([]);\n    mainLine = $$.mainLine || d3.selectAll([]);\n    mainArea = $$.mainArea || d3.selectAll([]);\n    mainCircle = $$.mainCircle || d3.selectAll([]);\n\n    // generate transform to flow\n    if (!flow.orgDataCount) {\n      // if empty\n      if ($$.data.targets[0].values.length !== 1) {\n        translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);\n      } else {\n        if ($$.isTimeSeries()) {\n          flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0);\n          flowEnd = $$.getValueOnIndex(\n            $$.data.targets[0].values,\n            $$.data.targets[0].values.length - 1\n          );\n          translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);\n        } else {\n          translateX = diffDomain(domain) / 2;\n        }\n      }\n    } else if (\n      flow.orgDataCount === 1 ||\n      (flowStart && flowStart.x) === (flowEnd && flowEnd.x)\n    ) {\n      translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);\n    } else {\n      if ($$.isTimeSeries()) {\n        translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);\n      } else {\n        translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);\n      }\n    }\n    scaleX = diffDomain(orgDomain) / diffDomain(domain);\n    transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)';\n\n    $$.hideXGridFocus();\n\n    var flowTransition = d3\n      .transition()\n      .ease(d3.easeLinear)\n      .duration(durationForFlow);\n    wait.add($$.xAxis($$.axes.x, flowTransition));\n    wait.add(mainBar.transition(flowTransition).attr('transform', transform));\n    wait.add(mainLine.transition(flowTransition).attr('transform', transform));\n    wait.add(mainArea.transition(flowTransition).attr('transform', transform));\n    wait.add(mainCircle.transition(flowTransition).attr('transform', transform));\n    wait.add(mainText.transition(flowTransition).attr('transform', transform));\n    wait.add(\n      mainRegion\n        .filter($$.isRegionOnX)\n        .transition(flowTransition)\n        .attr('transform', transform)\n    );\n    wait.add(xgrid.transition(flowTransition).attr('transform', transform));\n    wait.add(xgridLines.transition(flowTransition).attr('transform', transform));\n    wait(function() {\n      var i,\n        shapes = [],\n        texts = [];\n\n      // remove flowed elements\n      if (flowLength) {\n        for (i = 0; i < flowLength; i++) {\n          shapes.push('.' + CLASS.shape + '-' + (flowIndex + i));\n          texts.push('.' + CLASS.text + '-' + (flowIndex + i));\n        }\n        $$.svg\n          .selectAll('.' + CLASS.shapes)\n          .selectAll(shapes)\n          .remove();\n        $$.svg\n          .selectAll('.' + CLASS.texts)\n          .selectAll(texts)\n          .remove();\n        $$.svg.select('.' + CLASS.xgrid).remove();\n      }\n\n      // draw again for removing flowed elements and reverting attr\n      xgrid\n        .attr('transform', null)\n        .attr('x1', $$.xgridAttr.x1)\n        .attr('x2', $$.xgridAttr.x2)\n        .attr('y1', $$.xgridAttr.y1)\n        .attr('y2', $$.xgridAttr.y2)\n        .style('opacity', $$.xgridAttr.opacity);\n      xgridLines.attr('transform', null);\n      xgridLines\n        .select('line')\n        .attr('x1', config.axis_rotated ? 0 : xv)\n        .attr('x2', config.axis_rotated ? $$.width : xv);\n      xgridLines\n        .select('text')\n        .attr('x', config.axis_rotated ? $$.width : 0)\n        .attr('y', xv);\n      mainBar.attr('transform', null).attr('d', drawBar);\n      mainLine.attr('transform', null).attr('d', drawLine);\n      mainArea.attr('transform', null).attr('d', drawArea);\n      mainCircle\n        .attr('transform', null)\n        .attr('cx', cx)\n        .attr('cy', cy);\n      mainText\n        .attr('transform', null)\n        .attr('x', xForText)\n        .attr('y', yForText)\n        .style('fill-opacity', $$.opacityForText.bind($$));\n      mainRegion.attr('transform', null);\n      mainRegion\n        .filter($$.isRegionOnX)\n        .attr('x', $$.regionX.bind($$))\n        .attr('width', $$.regionWidth.bind($$));\n\n      // callback for end of flow\n      done();\n\n      $$.flowing = false;\n    });\n  }\n};\n\nChart.prototype.focus = function(targetIds) {\n  var $$ = this.internal,\n    candidates;\n\n  targetIds = $$.mapToTargetIds(targetIds)\n  ;(candidates = $$.svg.selectAll(\n    $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))\n  )),\n    this.revert();\n  this.defocus();\n  candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false);\n  if ($$.hasArcType()) {\n    $$.expandArc(targetIds);\n  }\n  $$.toggleFocusLegend(targetIds, true);\n\n  $$.focusedTargetIds = targetIds;\n  $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function(id) {\n    return targetIds.indexOf(id) < 0\n  });\n};\n\nChart.prototype.defocus = function(targetIds) {\n  var $$ = this.internal,\n    candidates;\n\n  targetIds = $$.mapToTargetIds(targetIds)\n  ;(candidates = $$.svg.selectAll(\n    $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))\n  )),\n    candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true);\n  if ($$.hasArcType()) {\n    $$.unexpandArc(targetIds);\n  }\n  $$.toggleFocusLegend(targetIds, false);\n\n  $$.focusedTargetIds = $$.focusedTargetIds.filter(function(id) {\n    return targetIds.indexOf(id) < 0\n  });\n  $$.defocusedTargetIds = targetIds;\n};\n\nChart.prototype.revert = function(targetIds) {\n  var $$ = this.internal,\n    candidates;\n\n  targetIds = $$.mapToTargetIds(targetIds);\n  candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets\n\n  candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false);\n  if ($$.hasArcType()) {\n    $$.unexpandArc(targetIds);\n  }\n  if ($$.config.legend_show) {\n    $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$)));\n    $$.legend\n      .selectAll($$.selectorLegends(targetIds))\n      .filter(function() {\n        return $$.d3.select(this).classed(CLASS.legendItemFocused)\n      })\n      .classed(CLASS.legendItemFocused, false);\n  }\n\n  $$.focusedTargetIds = [];\n  $$.defocusedTargetIds = [];\n};\n\nChart.prototype.xgrids = function(grids) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (!grids) {\n    return config.grid_x_lines\n  }\n  config.grid_x_lines = grids;\n  $$.redrawWithoutRescale();\n  return config.grid_x_lines\n};\nChart.prototype.xgrids.add = function(grids) {\n  var $$ = this.internal;\n  return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : []))\n};\nChart.prototype.xgrids.remove = function(params) {\n  // TODO: multiple\n  var $$ = this.internal;\n  $$.removeGridLines(params, true);\n};\n\nChart.prototype.ygrids = function(grids) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (!grids) {\n    return config.grid_y_lines\n  }\n  config.grid_y_lines = grids;\n  $$.redrawWithoutRescale();\n  return config.grid_y_lines\n};\nChart.prototype.ygrids.add = function(grids) {\n  var $$ = this.internal;\n  return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : []))\n};\nChart.prototype.ygrids.remove = function(params) {\n  // TODO: multiple\n  var $$ = this.internal;\n  $$.removeGridLines(params, false);\n};\n\nChart.prototype.groups = function(groups) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (isUndefined(groups)) {\n    return config.data_groups\n  }\n  config.data_groups = groups;\n  $$.redraw();\n  return config.data_groups\n};\n\nChart.prototype.legend = function() {};\nChart.prototype.legend.show = function(targetIds) {\n  var $$ = this.internal;\n  $$.showLegend($$.mapToTargetIds(targetIds));\n  $$.updateAndRedraw({ withLegend: true });\n};\nChart.prototype.legend.hide = function(targetIds) {\n  var $$ = this.internal;\n  $$.hideLegend($$.mapToTargetIds(targetIds));\n  $$.updateAndRedraw({ withLegend: false });\n};\n\nChart.prototype.load = function(args) {\n  var $$ = this.internal,\n    config = $$.config;\n  // update xs if specified\n  if (args.xs) {\n    $$.addXs(args.xs);\n  }\n  // update names if exists\n  if ('names' in args) {\n    Chart.prototype.data.names.bind(this)(args.names);\n  }\n  // update classes if exists\n  if ('classes' in args) {\n    Object.keys(args.classes).forEach(function(id) {\n      config.data_classes[id] = args.classes[id];\n    });\n  }\n  // update categories if exists\n  if ('categories' in args && $$.isCategorized()) {\n    config.axis_x_categories = args.categories;\n  }\n  // update axes if exists\n  if ('axes' in args) {\n    Object.keys(args.axes).forEach(function(id) {\n      config.data_axes[id] = args.axes[id];\n    });\n  }\n  // update colors if exists\n  if ('colors' in args) {\n    Object.keys(args.colors).forEach(function(id) {\n      config.data_colors[id] = args.colors[id];\n    });\n  }\n  // use cache if exists\n  if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) {\n    $$.load($$.getCaches(args.cacheIds), args.done);\n    return\n  }\n  // unload if needed\n  if (args.unload) {\n    // TODO: do not unload if target will load (included in url/rows/columns)\n    $$.unload(\n      $$.mapToTargetIds(args.unload === true ? null : args.unload),\n      function() {\n        $$.loadFromArgs(args);\n      }\n    );\n  } else {\n    $$.loadFromArgs(args);\n  }\n};\n\nChart.prototype.unload = function(args) {\n  var $$ = this.internal;\n  args = args || {};\n  if (args instanceof Array) {\n    args = { ids: args };\n  } else if (typeof args === 'string') {\n    args = { ids: [args] };\n  }\n  $$.unload($$.mapToTargetIds(args.ids), function() {\n    $$.redraw({\n      withUpdateOrgXDomain: true,\n      withUpdateXDomain: true,\n      withLegend: true\n    });\n    if (args.done) {\n      args.done();\n    }\n  });\n};\n\nChart.prototype.pie = function() {};\n\nChart.prototype.pie.padAngle = function(padAngle) {\n  if (padAngle === undefined) {\n    return this.internal.config.pie_padAngle\n  }\n  this.internal.config.pie_padAngle = padAngle;\n  this.flush();\n};\n\nChart.prototype.regions = function(regions) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (!regions) {\n    return config.regions\n  }\n  config.regions = regions;\n  $$.redrawWithoutRescale();\n  return config.regions\n};\nChart.prototype.regions.add = function(regions) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (!regions) {\n    return config.regions\n  }\n  config.regions = config.regions.concat(regions);\n  $$.redrawWithoutRescale();\n  return config.regions\n};\nChart.prototype.regions.remove = function(options) {\n  var $$ = this.internal,\n    config = $$.config,\n    duration,\n    classes,\n    regions;\n\n  options = options || {};\n  duration = getOption(options, 'duration', config.transition_duration);\n  classes = getOption(options, 'classes', [CLASS.region]);\n\n  regions = $$.main.select('.' + CLASS.regions).selectAll(\n    classes.map(function(c) {\n      return '.' + c\n    })\n  )\n  ;(duration ? regions.transition().duration(duration) : regions)\n    .style('opacity', 0)\n    .remove();\n\n  config.regions = config.regions.filter(function(region) {\n    var found = false;\n    if (!region['class']) {\n      return true\n    }\n    region['class'].split(' ').forEach(function(c) {\n      if (classes.indexOf(c) >= 0) {\n        found = true;\n      }\n    });\n    return !found\n  });\n\n  return config.regions\n};\n\nChart.prototype.selected = function(targetId) {\n  var $$ = this.internal,\n    d3 = $$.d3;\n  return $$.main\n    .selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId))\n    .selectAll('.' + CLASS.shape)\n    .filter(function() {\n      return d3.select(this).classed(CLASS.SELECTED)\n    })\n    .nodes()\n    .map(function(d) {\n      var data = d.__data__;\n      return data.data ? data.data : data\n    })\n};\nChart.prototype.select = function(ids, indices, resetOther) {\n  var $$ = this.internal,\n    d3 = $$.d3,\n    config = $$.config;\n  if (!config.data_selection_enabled) {\n    return\n  }\n  $$.main\n    .selectAll('.' + CLASS.shapes)\n    .selectAll('.' + CLASS.shape)\n    .each(function(d, i) {\n      var shape = d3.select(this),\n        id = d.data ? d.data.id : d.id,\n        toggle = $$.getToggle(this, d).bind($$),\n        isTargetId =\n          config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,\n        isTargetIndex = !indices || indices.indexOf(i) >= 0,\n        isSelected = shape.classed(CLASS.SELECTED);\n      // line/area selection not supported yet\n      if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {\n        return\n      }\n      if (isTargetId && isTargetIndex) {\n        if (config.data_selection_isselectable(d) && !isSelected) {\n          toggle(true, shape.classed(CLASS.SELECTED, true), d, i);\n        }\n      } else if (isDefined(resetOther) && resetOther) {\n        if (isSelected) {\n          toggle(false, shape.classed(CLASS.SELECTED, false), d, i);\n        }\n      }\n    });\n};\nChart.prototype.unselect = function(ids, indices) {\n  var $$ = this.internal,\n    d3 = $$.d3,\n    config = $$.config;\n  if (!config.data_selection_enabled) {\n    return\n  }\n  $$.main\n    .selectAll('.' + CLASS.shapes)\n    .selectAll('.' + CLASS.shape)\n    .each(function(d, i) {\n      var shape = d3.select(this),\n        id = d.data ? d.data.id : d.id,\n        toggle = $$.getToggle(this, d).bind($$),\n        isTargetId =\n          config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,\n        isTargetIndex = !indices || indices.indexOf(i) >= 0,\n        isSelected = shape.classed(CLASS.SELECTED);\n      // line/area selection not supported yet\n      if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {\n        return\n      }\n      if (isTargetId && isTargetIndex) {\n        if (config.data_selection_isselectable(d)) {\n          if (isSelected) {\n            toggle(false, shape.classed(CLASS.SELECTED, false), d, i);\n          }\n        }\n      }\n    });\n};\n\nChart.prototype.show = function(targetIds, options) {\n  var $$ = this.internal,\n    targets;\n\n  targetIds = $$.mapToTargetIds(targetIds);\n  options = options || {};\n\n  $$.removeHiddenTargetIds(targetIds);\n  targets = $$.svg.selectAll($$.selectorTargets(targetIds));\n\n  targets\n    .transition()\n    .style('display', isIE() ? 'block' : 'initial', 'important')\n    .style('opacity', 1, 'important')\n    .call($$.endall, function() {\n      targets.style('opacity', null).style('opacity', 1);\n    });\n\n  if (options.withLegend) {\n    $$.showLegend(targetIds);\n  }\n\n  $$.redraw({\n    withUpdateOrgXDomain: true,\n    withUpdateXDomain: true,\n    withLegend: true\n  });\n};\n\nChart.prototype.hide = function(targetIds, options) {\n  var $$ = this.internal,\n    targets;\n\n  targetIds = $$.mapToTargetIds(targetIds);\n  options = options || {};\n\n  $$.addHiddenTargetIds(targetIds);\n  targets = $$.svg.selectAll($$.selectorTargets(targetIds));\n\n  targets\n    .transition()\n    .style('opacity', 0, 'important')\n    .call($$.endall, function() {\n      targets.style('opacity', null).style('opacity', 0);\n      targets.style('display', 'none');\n    });\n\n  if (options.withLegend) {\n    $$.hideLegend(targetIds);\n  }\n\n  $$.redraw({\n    withUpdateOrgXDomain: true,\n    withUpdateXDomain: true,\n    withLegend: true\n  });\n};\n\nChart.prototype.toggle = function(targetIds, options) {\n  var that = this,\n    $$ = this.internal;\n  $$.mapToTargetIds(targetIds).forEach(function(targetId) {\n    $$.isTargetToShow(targetId)\n      ? that.hide(targetId, options)\n      : that.show(targetId, options);\n  });\n};\n\nChart.prototype.subchart = function() {};\n\nChart.prototype.subchart.isShown = function() {\n  const $$ = this.internal;\n\n  return $$.config.subchart_show\n};\n\nChart.prototype.subchart.show = function() {\n  const $$ = this.internal;\n\n  if ($$.config.subchart_show) {\n    return\n  }\n\n  $$.config.subchart_show = true;\n\n  // insert DOM\n  $$.initSubchart();\n\n  // update dimensions with sub chart now visible\n  $$.updateDimension();\n\n  // insert brush (depends on sizes previously updated)\n  $$.initSubchartBrush();\n\n  // attach data\n  $$.updateTargetsForSubchart($$.getTargets());\n\n  // reset fade-in state\n  $$.mapToIds($$.data.targets).forEach(function(id) {\n    $$.withoutFadeIn[id] = false;\n  });\n\n  // redraw chart !\n  $$.updateAndRedraw();\n\n  // update visible targets !\n  $$.showTargets();\n};\n\nChart.prototype.subchart.hide = function() {\n  const $$ = this.internal;\n\n  if (!$$.config.subchart_show) {\n    return\n  }\n\n  $$.config.subchart_show = false;\n\n  // remove DOM\n  $$.removeSubchart();\n\n  // re-render chart\n  $$.redraw();\n};\n\nChart.prototype.tooltip = function() {};\nChart.prototype.tooltip.show = function(args) {\n  var $$ = this.internal,\n    targets,\n    data,\n    mouse = {};\n\n  // determine mouse position on the chart\n  if (args.mouse) {\n    mouse = args.mouse;\n  } else {\n    // determine focus data\n    if (args.data) {\n      data = args.data;\n    } else if (typeof args.x !== 'undefined') {\n      if (args.id) {\n        targets = $$.data.targets.filter(function(t) {\n          return t.id === args.id\n        });\n      } else {\n        targets = $$.data.targets;\n      }\n      data = $$.filterByX(targets, args.x).slice(0, 1)[0];\n    }\n    mouse = data ? $$.getMousePosition(data) : null;\n  }\n\n  // emulate mouse events to show\n  $$.dispatchEvent('mousemove', mouse);\n\n  $$.config.tooltip_onshow.call($$, data);\n};\nChart.prototype.tooltip.hide = function() {\n  // TODO: get target data by checking the state of focus\n  this.internal.dispatchEvent('mouseout', 0);\n\n  this.internal.config.tooltip_onhide.call(this);\n};\n\nChart.prototype.transform = function(type, targetIds) {\n  var $$ = this.internal,\n    options =\n      ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null;\n  $$.transformTo(targetIds, type, options);\n};\n\nChartInternal.prototype.transformTo = function(\n  targetIds,\n  type,\n  optionsForRedraw\n) {\n  var $$ = this,\n    withTransitionForAxis = !$$.hasArcType(),\n    options = optionsForRedraw || {\n      withTransitionForAxis: withTransitionForAxis\n    };\n  options.withTransitionForTransform = false;\n  $$.transiting = false;\n  $$.setTargetType(targetIds, type);\n  $$.updateTargets($$.data.targets); // this is needed when transforming to arc\n  $$.updateAndRedraw(options);\n};\n\nChart.prototype.x = function(x) {\n  var $$ = this.internal;\n  if (arguments.length) {\n    $$.updateTargetX($$.data.targets, x);\n    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\n  }\n  return $$.data.xs\n};\nChart.prototype.xs = function(xs) {\n  var $$ = this.internal;\n  if (arguments.length) {\n    $$.updateTargetXs($$.data.targets, xs);\n    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\n  }\n  return $$.data.xs\n};\n\nChart.prototype.zoom = function(domain) {\n  var $$ = this.internal;\n  if (domain) {\n    if ($$.isTimeSeries()) {\n      domain = domain.map(function(x) {\n        return $$.parseDate(x)\n      });\n    }\n    if ($$.config.subchart_show) {\n      $$.brush.selectionAsValue(domain, true);\n    } else {\n      $$.updateXDomain(null, true, false, false, domain);\n      $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false });\n    }\n    $$.config.zoom_onzoom.call(this, $$.x.orgDomain());\n    return domain\n  } else {\n    return $$.x.domain()\n  }\n};\nChart.prototype.zoom.enable = function(enabled) {\n  var $$ = this.internal;\n  $$.config.zoom_enabled = enabled;\n  $$.updateAndRedraw();\n};\nChart.prototype.unzoom = function() {\n  var $$ = this.internal;\n  if ($$.config.subchart_show) {\n    $$.brush.clear();\n  } else {\n    $$.updateXDomain(null, true, false, false, $$.subX.domain());\n    $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false });\n  }\n};\n\nChart.prototype.zoom.max = function(max) {\n  var $$ = this.internal,\n    config = $$.config,\n    d3 = $$.d3;\n  if (max === 0 || max) {\n    config.zoom_x_max = d3.max([$$.orgXDomain[1], max]);\n  } else {\n    return config.zoom_x_max\n  }\n};\n\nChart.prototype.zoom.min = function(min) {\n  var $$ = this.internal,\n    config = $$.config,\n    d3 = $$.d3;\n  if (min === 0 || min) {\n    config.zoom_x_min = d3.min([$$.orgXDomain[0], min]);\n  } else {\n    return config.zoom_x_min\n  }\n};\n\nChart.prototype.zoom.range = function(range) {\n  if (arguments.length) {\n    if (isDefined(range.max)) {\n      this.domain.max(range.max);\n    }\n    if (isDefined(range.min)) {\n      this.domain.min(range.min);\n    }\n  } else {\n    return {\n      max: this.domain.max(),\n      min: this.domain.min()\n    }\n  }\n};\n\nChartInternal.prototype.initPie = function() {\n  var $$ = this,\n    d3 = $$.d3;\n  $$.pie = d3\n    .pie()\n    .padAngle(this.getPadAngle.bind(this))\n    .value(function(d) {\n      return d.values.reduce(function(a, b) {\n        return a + b.value\n      }, 0)\n    });\n\n  let orderFct = $$.getOrderFunction();\n\n  // we need to reverse the returned order if asc or desc to have the slice in expected order.\n  if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) {\n    let defaultSort = orderFct;\n    orderFct = (t1, t2) => defaultSort(t1, t2) * -1;\n  }\n\n  $$.pie.sort(orderFct || null);\n};\n\nChartInternal.prototype.updateRadius = function() {\n  var $$ = this,\n    config = $$.config,\n    w = config.gauge_width || config.donut_width,\n    gaugeArcWidth =\n      $$.filterTargetsToShow($$.data.targets).length *\n      $$.config.gauge_arcs_minWidth;\n  $$.radiusExpanded =\n    (Math.min($$.arcWidth, $$.arcHeight) / 2) * ($$.hasType('gauge') ? 0.85 : 1);\n  $$.radius = $$.radiusExpanded * 0.95;\n  $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6;\n  $$.innerRadius =\n    $$.hasType('donut') || $$.hasType('gauge')\n      ? $$.radius * $$.innerRadiusRatio\n      : 0;\n  $$.gaugeArcWidth = w\n    ? w\n    : gaugeArcWidth <= $$.radius - $$.innerRadius\n    ? $$.radius - $$.innerRadius\n    : gaugeArcWidth <= $$.radius\n    ? gaugeArcWidth\n    : $$.radius;\n};\n\nChartInternal.prototype.getPadAngle = function() {\n  if (this.hasType('pie')) {\n    return this.config.pie_padAngle || 0\n  } else if (this.hasType('donut')) {\n    return this.config.donut_padAngle || 0\n  } else {\n    return 0\n  }\n};\n\nChartInternal.prototype.updateArc = function() {\n  var $$ = this;\n  $$.svgArc = $$.getSvgArc();\n  $$.svgArcExpanded = $$.getSvgArcExpanded();\n  $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98);\n};\n\nChartInternal.prototype.updateAngle = function(d) {\n  var $$ = this,\n    config = $$.config,\n    found = false,\n    index = 0,\n    gMin,\n    gMax,\n    gTic,\n    gValue;\n\n  if (!config) {\n    return null\n  }\n\n  $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function(t) {\n    if (!found && t.data.id === d.data.id) {\n      found = true;\n      d = t;\n      d.index = index;\n    }\n    index++;\n  });\n  if (isNaN(d.startAngle)) {\n    d.startAngle = 0;\n  }\n  if (isNaN(d.endAngle)) {\n    d.endAngle = d.startAngle;\n  }\n  if ($$.isGaugeType(d.data)) {\n    gMin = config.gauge_min;\n    gMax = config.gauge_max;\n    gTic = (Math.PI * (config.gauge_fullCircle ? 2 : 1)) / (gMax - gMin);\n    gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin;\n    d.startAngle = config.gauge_startingAngle;\n    d.endAngle = d.startAngle + gTic * gValue;\n  }\n  return found ? d : null\n};\n\nChartInternal.prototype.getSvgArc = function() {\n  var $$ = this,\n    hasGaugeType = $$.hasType('gauge'),\n    singleArcWidth =\n      $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,\n    arc = $$.d3\n      .arc()\n      .outerRadius(function(d) {\n        return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius\n      })\n      .innerRadius(function(d) {\n        return hasGaugeType\n          ? $$.radius - singleArcWidth * (d.index + 1)\n          : $$.innerRadius\n      }),\n    newArc = function(d, withoutUpdate) {\n      var updated;\n      if (withoutUpdate) {\n        return arc(d)\n      } // for interpolate\n      updated = $$.updateAngle(d);\n      return updated ? arc(updated) : 'M 0 0'\n    };\n  // TODO: extends all function\n  newArc.centroid = arc.centroid;\n  return newArc\n};\n\nChartInternal.prototype.getSvgArcExpanded = function(rate) {\n  rate = rate || 1;\n  var $$ = this,\n    hasGaugeType = $$.hasType('gauge'),\n    singleArcWidth =\n      $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,\n    expandWidth = Math.min(\n      $$.radiusExpanded * rate - $$.radius,\n      singleArcWidth * 0.8 - (1 - rate) * 100\n    ),\n    arc = $$.d3\n      .arc()\n      .outerRadius(function(d) {\n        return hasGaugeType\n          ? $$.radius - singleArcWidth * d.index + expandWidth\n          : $$.radiusExpanded * rate\n      })\n      .innerRadius(function(d) {\n        return hasGaugeType\n          ? $$.radius - singleArcWidth * (d.index + 1)\n          : $$.innerRadius\n      });\n  return function(d) {\n    var updated = $$.updateAngle(d);\n    return updated ? arc(updated) : 'M 0 0'\n  }\n};\n\nChartInternal.prototype.getArc = function(d, withoutUpdate, force) {\n  return force || this.isArcType(d.data)\n    ? this.svgArc(d, withoutUpdate)\n    : 'M 0 0'\n};\n\nChartInternal.prototype.transformForArcLabel = function(d) {\n  var $$ = this,\n    config = $$.config,\n    updated = $$.updateAngle(d),\n    c,\n    x,\n    y,\n    h,\n    ratio,\n    translate = '',\n    hasGauge = $$.hasType('gauge');\n  if (updated && !hasGauge) {\n    c = this.svgArc.centroid(updated);\n    x = isNaN(c[0]) ? 0 : c[0];\n    y = isNaN(c[1]) ? 0 : c[1];\n    h = Math.sqrt(x * x + y * y);\n    if ($$.hasType('donut') && config.donut_label_ratio) {\n      ratio = isFunction(config.donut_label_ratio)\n        ? config.donut_label_ratio(d, $$.radius, h)\n        : config.donut_label_ratio;\n    } else if ($$.hasType('pie') && config.pie_label_ratio) {\n      ratio = isFunction(config.pie_label_ratio)\n        ? config.pie_label_ratio(d, $$.radius, h)\n        : config.pie_label_ratio;\n    } else {\n      ratio =\n        $$.radius && h\n          ? ((36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) *\n              $$.radius) /\n            h\n          : 0;\n    }\n    translate = 'translate(' + x * ratio + ',' + y * ratio + ')';\n  } else if (\n    updated &&\n    hasGauge &&\n    $$.filterTargetsToShow($$.data.targets).length > 1\n  ) {\n    var y1 = Math.sin(updated.endAngle - Math.PI / 2);\n    x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25);\n    y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3;\n    translate = 'translate(' + x + ',' + y + ')';\n  }\n  return translate\n};\n\n/**\n * @deprecated Use `getRatio('arc', d)` instead.\n */\nChartInternal.prototype.getArcRatio = function(d) {\n  return this.getRatio('arc', d)\n};\n\nChartInternal.prototype.convertToArcData = function(d) {\n  return this.addName({\n    id: d.data.id,\n    value: d.value,\n    ratio: this.getRatio('arc', d),\n    index: d.index\n  })\n};\n\nChartInternal.prototype.textForArcLabel = function(d) {\n  var $$ = this,\n    updated,\n    value,\n    ratio,\n    id,\n    format;\n  if (!$$.shouldShowArcLabel()) {\n    return ''\n  }\n  updated = $$.updateAngle(d);\n  value = updated ? updated.value : null;\n  ratio = $$.getRatio('arc', updated);\n  id = d.data.id;\n  if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) {\n    return ''\n  }\n  format = $$.getArcLabelFormat();\n  return format\n    ? format(value, ratio, id)\n    : $$.defaultArcValueFormat(value, ratio)\n};\n\nChartInternal.prototype.textForGaugeMinMax = function(value, isMax) {\n  var $$ = this,\n    format = $$.getGaugeLabelExtents();\n\n  return format ? format(value, isMax) : value\n};\n\nChartInternal.prototype.expandArc = function(targetIds) {\n  var $$ = this,\n    interval;\n\n  // MEMO: avoid to cancel transition\n  if ($$.transiting) {\n    interval = window.setInterval(function() {\n      if (!$$.transiting) {\n        window.clearInterval(interval);\n        if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) {\n          $$.expandArc(targetIds);\n        }\n      }\n    }, 10);\n    return\n  }\n\n  targetIds = $$.mapToTargetIds(targetIds);\n\n  $$.svg\n    .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc))\n    .each(function(d) {\n      if (!$$.shouldExpand(d.data.id)) {\n        return\n      }\n      $$.d3\n        .select(this)\n        .selectAll('path')\n        .transition()\n        .duration($$.expandDuration(d.data.id))\n        .attr('d', $$.svgArcExpanded)\n        .transition()\n        .duration($$.expandDuration(d.data.id) * 2)\n        .attr('d', $$.svgArcExpandedSub)\n        .each(function(d) {\n          if ($$.isDonutType(d.data)) ;\n        });\n    });\n};\n\nChartInternal.prototype.unexpandArc = function(targetIds) {\n  var $$ = this;\n\n  if ($$.transiting) {\n    return\n  }\n\n  targetIds = $$.mapToTargetIds(targetIds);\n\n  $$.svg\n    .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc))\n    .selectAll('path')\n    .transition()\n    .duration(function(d) {\n      return $$.expandDuration(d.data.id)\n    })\n    .attr('d', $$.svgArc);\n  $$.svg.selectAll('.' + CLASS.arc);\n};\n\nChartInternal.prototype.expandDuration = function(id) {\n  var $$ = this,\n    config = $$.config;\n\n  if ($$.isDonutType(id)) {\n    return config.donut_expand_duration\n  } else if ($$.isGaugeType(id)) {\n    return config.gauge_expand_duration\n  } else if ($$.isPieType(id)) {\n    return config.pie_expand_duration\n  } else {\n    return 50\n  }\n};\n\nChartInternal.prototype.shouldExpand = function(id) {\n  var $$ = this,\n    config = $$.config;\n  return (\n    ($$.isDonutType(id) && config.donut_expand) ||\n    ($$.isGaugeType(id) && config.gauge_expand) ||\n    ($$.isPieType(id) && config.pie_expand)\n  )\n};\n\nChartInternal.prototype.shouldShowArcLabel = function() {\n  var $$ = this,\n    config = $$.config,\n    shouldShow = true;\n  if ($$.hasType('donut')) {\n    shouldShow = config.donut_label_show;\n  } else if ($$.hasType('pie')) {\n    shouldShow = config.pie_label_show;\n  }\n  // when gauge, always true\n  return shouldShow\n};\n\nChartInternal.prototype.meetsArcLabelThreshold = function(ratio) {\n  var $$ = this,\n    config = $$.config,\n    threshold = $$.hasType('donut')\n      ? config.donut_label_threshold\n      : config.pie_label_threshold;\n  return ratio >= threshold\n};\n\nChartInternal.prototype.getArcLabelFormat = function() {\n  var $$ = this,\n    config = $$.config,\n    format = config.pie_label_format;\n  if ($$.hasType('gauge')) {\n    format = config.gauge_label_format;\n  } else if ($$.hasType('donut')) {\n    format = config.donut_label_format;\n  }\n  return format\n};\n\nChartInternal.prototype.getGaugeLabelExtents = function() {\n  var $$ = this,\n    config = $$.config;\n  return config.gauge_label_extents\n};\n\nChartInternal.prototype.getArcTitle = function() {\n  var $$ = this;\n  return $$.hasType('donut') ? $$.config.donut_title : ''\n};\n\nChartInternal.prototype.updateTargetsForArc = function(targets) {\n  var $$ = this,\n    main = $$.main,\n    mainPies,\n    mainPieEnter,\n    classChartArc = $$.classChartArc.bind($$),\n    classArcs = $$.classArcs.bind($$),\n    classFocus = $$.classFocus.bind($$);\n  mainPies = main\n    .select('.' + CLASS.chartArcs)\n    .selectAll('.' + CLASS.chartArc)\n    .data($$.pie(targets))\n    .attr('class', function(d) {\n      return classChartArc(d) + classFocus(d.data)\n    });\n  mainPieEnter = mainPies\n    .enter()\n    .append('g')\n    .attr('class', classChartArc);\n  mainPieEnter.append('g').attr('class', classArcs);\n  mainPieEnter\n    .append('text')\n    .attr('dy', $$.hasType('gauge') ? '-.1em' : '.35em')\n    .style('opacity', 0)\n    .style('text-anchor', 'middle')\n    .style('pointer-events', 'none');\n  // MEMO: can not keep same color..., but not bad to update color in redraw\n  //mainPieUpdate.exit().remove();\n};\n\nChartInternal.prototype.initArc = function() {\n  var $$ = this;\n  $$.arcs = $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartArcs)\n    .attr('transform', $$.getTranslate('arc'));\n  $$.arcs\n    .append('text')\n    .attr('class', CLASS.chartArcsTitle)\n    .style('text-anchor', 'middle')\n    .text($$.getArcTitle());\n};\n\nChartInternal.prototype.redrawArc = function(\n  duration,\n  durationForExit,\n  withTransform\n) {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    main = $$.main,\n    arcs,\n    mainArc,\n    arcLabelLines,\n    mainArcLabelLine,\n    hasGaugeType = $$.hasType('gauge');\n  arcs = main\n    .selectAll('.' + CLASS.arcs)\n    .selectAll('.' + CLASS.arc)\n    .data($$.arcData.bind($$));\n  mainArc = arcs\n    .enter()\n    .append('path')\n    .attr('class', $$.classArc.bind($$))\n    .style('fill', function(d) {\n      return $$.color(d.data)\n    })\n    .style('cursor', function(d) {\n      return config.interaction_enabled && config.data_selection_isselectable(d)\n        ? 'pointer'\n        : null\n    })\n    .each(function(d) {\n      if ($$.isGaugeType(d.data)) {\n        d.startAngle = d.endAngle = config.gauge_startingAngle;\n      }\n      this._current = d;\n    })\n    .merge(arcs);\n  if (hasGaugeType) {\n    arcLabelLines = main\n      .selectAll('.' + CLASS.arcs)\n      .selectAll('.' + CLASS.arcLabelLine)\n      .data($$.arcData.bind($$));\n    mainArcLabelLine = arcLabelLines\n      .enter()\n      .append('rect')\n      .attr('class', function(d) {\n        return (\n          CLASS.arcLabelLine +\n          ' ' +\n          CLASS.target +\n          ' ' +\n          CLASS.target +\n          '-' +\n          d.data.id\n        )\n      })\n      .merge(arcLabelLines);\n\n    if ($$.filterTargetsToShow($$.data.targets).length === 1) {\n      mainArcLabelLine.style('display', 'none');\n    } else {\n      mainArcLabelLine\n        .style('fill', function(d) {\n          return $$.levelColor\n            ? $$.levelColor(\n                d.data.values.reduce(function(total, item) {\n                  return total + item.value\n                }, 0)\n              )\n            : $$.color(d.data)\n        })\n        .style('display', config.gauge_labelLine_show ? '' : 'none')\n        .each(function(d) {\n          var lineLength = 0,\n            lineThickness = 2,\n            x = 0,\n            y = 0,\n            transform = '';\n          if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) {\n            var updated = $$.updateAngle(d),\n              innerLineLength =\n                ($$.gaugeArcWidth /\n                  $$.filterTargetsToShow($$.data.targets).length) *\n                (updated.index + 1),\n              lineAngle = updated.endAngle - Math.PI / 2,\n              arcInnerRadius = $$.radius - innerLineLength,\n              linePositioningAngle =\n                lineAngle - (arcInnerRadius === 0 ? 0 : 1 / arcInnerRadius);\n            lineLength = $$.radiusExpanded - $$.radius + innerLineLength;\n            x = Math.cos(linePositioningAngle) * arcInnerRadius;\n            y = Math.sin(linePositioningAngle) * arcInnerRadius;\n            transform =\n              'rotate(' +\n              (lineAngle * 180) / Math.PI +\n              ', ' +\n              x +\n              ', ' +\n              y +\n              ')';\n          }\n          d3.select(this)\n            .attr('x', x)\n            .attr('y', y)\n            .attr('width', lineLength)\n            .attr('height', lineThickness)\n            .attr('transform', transform)\n            .style(\n              'stroke-dasharray',\n              '0, ' + (lineLength + lineThickness) + ', 0'\n            );\n        });\n    }\n  }\n  mainArc\n    .attr('transform', function(d) {\n      return !$$.isGaugeType(d.data) && withTransform ? 'scale(0)' : ''\n    })\n    .on(\n      'mouseover',\n      config.interaction_enabled\n        ? function(d) {\n            var updated, arcData;\n            if ($$.transiting) {\n              // skip while transiting\n              return\n            }\n            updated = $$.updateAngle(d);\n            if (updated) {\n              arcData = $$.convertToArcData(updated);\n              // transitions\n              $$.expandArc(updated.data.id);\n              $$.api.focus(updated.data.id);\n              $$.toggleFocusLegend(updated.data.id, true);\n              $$.config.data_onmouseover(arcData, this);\n            }\n          }\n        : null\n    )\n    .on(\n      'mousemove',\n      config.interaction_enabled\n        ? function(d) {\n            var updated = $$.updateAngle(d),\n              arcData,\n              selectedData;\n            if (updated) {\n(arcData = $$.convertToArcData(updated)),\n                (selectedData = [arcData]);\n              $$.showTooltip(selectedData, this);\n            }\n          }\n        : null\n    )\n    .on(\n      'mouseout',\n      config.interaction_enabled\n        ? function(d) {\n            var updated, arcData;\n            if ($$.transiting) {\n              // skip while transiting\n              return\n            }\n            updated = $$.updateAngle(d);\n            if (updated) {\n              arcData = $$.convertToArcData(updated);\n              // transitions\n              $$.unexpandArc(updated.data.id);\n              $$.api.revert();\n              $$.revertLegend();\n              $$.hideTooltip();\n              $$.config.data_onmouseout(arcData, this);\n            }\n          }\n        : null\n    )\n    .on(\n      'click',\n      config.interaction_enabled\n        ? function(d, i) {\n            var updated = $$.updateAngle(d),\n              arcData;\n            if (updated) {\n              arcData = $$.convertToArcData(updated);\n              if ($$.toggleShape) {\n                $$.toggleShape(this, arcData, i);\n              }\n              $$.config.data_onclick.call($$.api, arcData, this);\n            }\n          }\n        : null\n    )\n    .each(function() {\n      $$.transiting = true;\n    })\n    .transition()\n    .duration(duration)\n    .attrTween('d', function(d) {\n      var updated = $$.updateAngle(d),\n        interpolate;\n      if (!updated) {\n        return function() {\n          return 'M 0 0'\n        }\n      }\n      //                if (this._current === d) {\n      //                    this._current = {\n      //                        startAngle: Math.PI*2,\n      //                        endAngle: Math.PI*2,\n      //                    };\n      //                }\n      if (isNaN(this._current.startAngle)) {\n        this._current.startAngle = 0;\n      }\n      if (isNaN(this._current.endAngle)) {\n        this._current.endAngle = this._current.startAngle;\n      }\n      interpolate = d3.interpolate(this._current, updated);\n      this._current = interpolate(0);\n      return function(t) {\n        // prevents crashing the charts once in transition and chart.destroy() has been called\n        if ($$.config === null) {\n          return 'M 0 0'\n        }\n        var interpolated = interpolate(t);\n        interpolated.data = d.data; // data.id will be updated by interporator\n        return $$.getArc(interpolated, true)\n      }\n    })\n    .attr('transform', withTransform ? 'scale(1)' : '')\n    .style('fill', function(d) {\n      return $$.levelColor\n        ? $$.levelColor(\n            d.data.values.reduce(function(total, item) {\n              return total + item.value\n            }, 0)\n          )\n        : $$.color(d.data.id)\n    }) // Where gauge reading color would receive customization.\n    .call($$.endall, function() {\n      $$.transiting = false;\n    });\n  arcs\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n    .remove();\n  main\n    .selectAll('.' + CLASS.chartArc)\n    .select('text')\n    .style('opacity', 0)\n    .attr('class', function(d) {\n      return $$.isGaugeType(d.data) ? CLASS.gaugeValue : ''\n    })\n    .text($$.textForArcLabel.bind($$))\n    .attr('transform', $$.transformForArcLabel.bind($$))\n    .style('font-size', function(d) {\n      return $$.isGaugeType(d.data) &&\n        $$.filterTargetsToShow($$.data.targets).length === 1\n        ? Math.round($$.radius / 5) + 'px'\n        : ''\n    })\n    .transition()\n    .duration(duration)\n    .style('opacity', function(d) {\n      return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0\n    });\n  main\n    .select('.' + CLASS.chartArcsTitle)\n    .style('opacity', $$.hasType('donut') || hasGaugeType ? 1 : 0);\n\n  if (hasGaugeType) {\n    let index = 0;\n    const backgroundArc = $$.arcs\n      .select('g.' + CLASS.chartArcsBackground)\n      .selectAll('path.' + CLASS.chartArcsBackground)\n      .data($$.data.targets);\n\n    backgroundArc\n      .enter()\n      .append('path')\n      .attr(\n        'class',\n        (d, i) =>\n          CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i\n      )\n      .merge(backgroundArc)\n      .attr('d', d1 => {\n        if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) {\n          return 'M 0 0'\n        }\n\n        var d = {\n          data: [{ value: config.gauge_max }],\n          startAngle: config.gauge_startingAngle,\n          endAngle:\n            -1 *\n            config.gauge_startingAngle *\n            (config.gauge_fullCircle ? Math.PI : 1),\n          index: index++\n        };\n        return $$.getArc(d, true, true)\n      });\n\n    backgroundArc.exit().remove();\n\n    $$.arcs\n      .select('.' + CLASS.chartArcsGaugeUnit)\n      .attr('dy', '.75em')\n      .text(config.gauge_label_show ? config.gauge_units : '');\n    $$.arcs\n      .select('.' + CLASS.chartArcsGaugeMin)\n      .attr(\n        'dx',\n        -1 *\n          ($$.innerRadius +\n            ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) +\n          'px'\n      )\n      .attr('dy', '1.2em')\n      .text(\n        config.gauge_label_show\n          ? $$.textForGaugeMinMax(config.gauge_min, false)\n          : ''\n      );\n    $$.arcs\n      .select('.' + CLASS.chartArcsGaugeMax)\n      .attr(\n        'dx',\n        $$.innerRadius +\n          ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) +\n          'px'\n      )\n      .attr('dy', '1.2em')\n      .text(\n        config.gauge_label_show\n          ? $$.textForGaugeMinMax(config.gauge_max, true)\n          : ''\n      );\n  }\n};\nChartInternal.prototype.initGauge = function() {\n  var arcs = this.arcs;\n  if (this.hasType('gauge')) {\n    arcs.append('g').attr('class', CLASS.chartArcsBackground);\n    arcs\n      .append('text')\n      .attr('class', CLASS.chartArcsGaugeUnit)\n      .style('text-anchor', 'middle')\n      .style('pointer-events', 'none');\n    arcs\n      .append('text')\n      .attr('class', CLASS.chartArcsGaugeMin)\n      .style('text-anchor', 'middle')\n      .style('pointer-events', 'none');\n    arcs\n      .append('text')\n      .attr('class', CLASS.chartArcsGaugeMax)\n      .style('text-anchor', 'middle')\n      .style('pointer-events', 'none');\n  }\n};\nChartInternal.prototype.getGaugeLabelHeight = function() {\n  return this.config.gauge_label_show ? 20 : 0\n};\n\n/**\n * Store value into cache\n *\n * @param key\n * @param value\n */\nChartInternal.prototype.addToCache = function(key, value) {\n  this.cache[`$${key}`] = value;\n};\n\n/**\n * Returns a cached value or undefined\n *\n * @param key\n * @return {*}\n */\nChartInternal.prototype.getFromCache = function(key) {\n  return this.cache[`$${key}`]\n};\n\n/**\n * Reset cached data\n */\nChartInternal.prototype.resetCache = function() {\n  Object.keys(this.cache)\n    .filter(key => /^\\$/.test(key))\n    .forEach(key => {\n      delete this.cache[key];\n    });\n};\n\n// Old API that stores Targets\n\nChartInternal.prototype.hasCaches = function(ids) {\n  for (var i = 0; i < ids.length; i++) {\n    if (!(ids[i] in this.cache)) {\n      return false\n    }\n  }\n  return true\n};\nChartInternal.prototype.addCache = function(id, target) {\n  this.cache[id] = this.cloneTarget(target);\n};\nChartInternal.prototype.getCaches = function(ids) {\n  var targets = [],\n    i;\n  for (i = 0; i < ids.length; i++) {\n    if (ids[i] in this.cache) {\n      targets.push(this.cloneTarget(this.cache[ids[i]]));\n    }\n  }\n  return targets\n};\n\nChartInternal.prototype.categoryName = function(i) {\n  var config = this.config;\n  return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i\n};\n\nChartInternal.prototype.generateTargetClass = function(targetId) {\n  return targetId || targetId === 0 ? ('-' + targetId).replace(/\\s/g, '-') : ''\n};\nChartInternal.prototype.generateClass = function(prefix, targetId) {\n  return ' ' + prefix + ' ' + prefix + this.generateTargetClass(targetId)\n};\nChartInternal.prototype.classText = function(d) {\n  return this.generateClass(CLASS.text, d.index)\n};\nChartInternal.prototype.classTexts = function(d) {\n  return this.generateClass(CLASS.texts, d.id)\n};\nChartInternal.prototype.classShape = function(d) {\n  return this.generateClass(CLASS.shape, d.index)\n};\nChartInternal.prototype.classShapes = function(d) {\n  return this.generateClass(CLASS.shapes, d.id)\n};\nChartInternal.prototype.classLine = function(d) {\n  return this.classShape(d) + this.generateClass(CLASS.line, d.id)\n};\nChartInternal.prototype.classLines = function(d) {\n  return this.classShapes(d) + this.generateClass(CLASS.lines, d.id)\n};\nChartInternal.prototype.classCircle = function(d) {\n  return this.classShape(d) + this.generateClass(CLASS.circle, d.index)\n};\nChartInternal.prototype.classCircles = function(d) {\n  return this.classShapes(d) + this.generateClass(CLASS.circles, d.id)\n};\nChartInternal.prototype.classBar = function(d) {\n  return this.classShape(d) + this.generateClass(CLASS.bar, d.index)\n};\nChartInternal.prototype.classBars = function(d) {\n  return this.classShapes(d) + this.generateClass(CLASS.bars, d.id)\n};\nChartInternal.prototype.classArc = function(d) {\n  return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id)\n};\nChartInternal.prototype.classArcs = function(d) {\n  return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id)\n};\nChartInternal.prototype.classArea = function(d) {\n  return this.classShape(d) + this.generateClass(CLASS.area, d.id)\n};\nChartInternal.prototype.classAreas = function(d) {\n  return this.classShapes(d) + this.generateClass(CLASS.areas, d.id)\n};\nChartInternal.prototype.classRegion = function(d, i) {\n  return (\n    this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : '')\n  )\n};\nChartInternal.prototype.classEvent = function(d) {\n  return this.generateClass(CLASS.eventRect, d.index)\n};\nChartInternal.prototype.classTarget = function(id) {\n  var $$ = this;\n  var additionalClassSuffix = $$.config.data_classes[id],\n    additionalClass = '';\n  if (additionalClassSuffix) {\n    additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix;\n  }\n  return $$.generateClass(CLASS.target, id) + additionalClass\n};\nChartInternal.prototype.classFocus = function(d) {\n  return this.classFocused(d) + this.classDefocused(d)\n};\nChartInternal.prototype.classFocused = function(d) {\n  return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '')\n};\nChartInternal.prototype.classDefocused = function(d) {\n  return (\n    ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : '')\n  )\n};\nChartInternal.prototype.classChartText = function(d) {\n  return CLASS.chartText + this.classTarget(d.id)\n};\nChartInternal.prototype.classChartLine = function(d) {\n  return CLASS.chartLine + this.classTarget(d.id)\n};\nChartInternal.prototype.classChartBar = function(d) {\n  return CLASS.chartBar + this.classTarget(d.id)\n};\nChartInternal.prototype.classChartArc = function(d) {\n  return CLASS.chartArc + this.classTarget(d.data.id)\n};\nChartInternal.prototype.getTargetSelectorSuffix = function(targetId) {\n  const targetClass = this.generateTargetClass(targetId);\n  if (window.CSS && window.CSS.escape) {\n    return window.CSS.escape(targetClass)\n  }\n\n  // fallback on imperfect method for old browsers (does not handles unicode)\n  return targetClass.replace(/([?!@#$%^&*()=+,.<>'\":;\\[\\]\\/|~`{}\\\\])/g, '\\\\$1')\n};\nChartInternal.prototype.selectorTarget = function(id, prefix) {\n  return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id)\n};\nChartInternal.prototype.selectorTargets = function(ids, prefix) {\n  var $$ = this;\n  ids = ids || [];\n  return ids.length\n    ? ids.map(function(id) {\n        return $$.selectorTarget(id, prefix)\n      })\n    : null\n};\nChartInternal.prototype.selectorLegend = function(id) {\n  return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id)\n};\nChartInternal.prototype.selectorLegends = function(ids) {\n  var $$ = this;\n  return ids && ids.length\n    ? ids.map(function(id) {\n        return $$.selectorLegend(id)\n      })\n    : null\n};\n\nChartInternal.prototype.getClipPath = function(id) {\n  return 'url(' + (isIE(9) ? '' : document.URL.split('#')[0]) + '#' + id + ')'\n};\nChartInternal.prototype.appendClip = function(parent, id) {\n  return parent\n    .append('clipPath')\n    .attr('id', id)\n    .append('rect')\n};\nChartInternal.prototype.getAxisClipX = function(forHorizontal) {\n  // axis line width + padding for left\n  var left = Math.max(30, this.margin.left);\n  return forHorizontal ? -(1 + left) : -(left - 1)\n};\nChartInternal.prototype.getAxisClipY = function(forHorizontal) {\n  return forHorizontal ? -20 : -this.margin.top\n};\nChartInternal.prototype.getXAxisClipX = function() {\n  var $$ = this;\n  return $$.getAxisClipX(!$$.config.axis_rotated)\n};\nChartInternal.prototype.getXAxisClipY = function() {\n  var $$ = this;\n  return $$.getAxisClipY(!$$.config.axis_rotated)\n};\nChartInternal.prototype.getYAxisClipX = function() {\n  var $$ = this;\n  return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated)\n};\nChartInternal.prototype.getYAxisClipY = function() {\n  var $$ = this;\n  return $$.getAxisClipY($$.config.axis_rotated)\n};\nChartInternal.prototype.getAxisClipWidth = function(forHorizontal) {\n  var $$ = this,\n    left = Math.max(30, $$.margin.left),\n    right = Math.max(30, $$.margin.right);\n  // width + axis line width + padding for left/right\n  return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20\n};\nChartInternal.prototype.getAxisClipHeight = function(forHorizontal) {\n  // less than 20 is not enough to show the axis label 'outer' without legend\n  return (\n    (forHorizontal ? this.margin.bottom : this.margin.top + this.height) + 20\n  )\n};\nChartInternal.prototype.getXAxisClipWidth = function() {\n  var $$ = this;\n  return $$.getAxisClipWidth(!$$.config.axis_rotated)\n};\nChartInternal.prototype.getXAxisClipHeight = function() {\n  var $$ = this;\n  return $$.getAxisClipHeight(!$$.config.axis_rotated)\n};\nChartInternal.prototype.getYAxisClipWidth = function() {\n  var $$ = this;\n  return (\n    $$.getAxisClipWidth($$.config.axis_rotated) +\n    ($$.config.axis_y_inner ? 20 : 0)\n  )\n};\nChartInternal.prototype.getYAxisClipHeight = function() {\n  var $$ = this;\n  return $$.getAxisClipHeight($$.config.axis_rotated)\n};\n\nChartInternal.prototype.generateColor = function() {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3,\n    colors = config.data_colors,\n    pattern = notEmpty(config.color_pattern)\n      ? config.color_pattern\n      : d3.schemeCategory10,\n    callback = config.data_color,\n    ids = [];\n\n  return function(d) {\n    var id = d.id || (d.data && d.data.id) || d,\n      color;\n\n    // if callback function is provided\n    if (colors[id] instanceof Function) {\n      color = colors[id](d);\n    }\n    // if specified, choose that color\n    else if (colors[id]) {\n      color = colors[id];\n    }\n    // if not specified, choose from pattern\n    else {\n      if (ids.indexOf(id) < 0) {\n        ids.push(id);\n      }\n      color = pattern[ids.indexOf(id) % pattern.length];\n      colors[id] = color;\n    }\n    return callback instanceof Function ? callback(color, d) : color\n  }\n};\nChartInternal.prototype.generateLevelColor = function() {\n  var $$ = this,\n    config = $$.config,\n    colors = config.color_pattern,\n    threshold = config.color_threshold,\n    asValue = threshold.unit === 'value',\n    values =\n      threshold.values && threshold.values.length ? threshold.values : [],\n    max = threshold.max || 100;\n  return notEmpty(threshold) && notEmpty(colors)\n    ? function(value) {\n        var i,\n          v,\n          color = colors[colors.length - 1];\n        for (i = 0; i < values.length; i++) {\n          v = asValue ? value : (value * 100) / max;\n          if (v < values[i]) {\n            color = colors[i];\n            break\n          }\n        }\n        return color\n      }\n    : null\n};\n\nChartInternal.prototype.getDefaultConfig = function() {\n  var config = {\n    bindto: '#chart',\n    svg_classname: undefined,\n    size_width: undefined,\n    size_height: undefined,\n    padding_left: undefined,\n    padding_right: undefined,\n    padding_top: undefined,\n    padding_bottom: undefined,\n    resize_auto: true,\n    zoom_enabled: false,\n    zoom_initialRange: undefined,\n    zoom_type: 'scroll',\n    zoom_disableDefaultBehavior: false,\n    zoom_privileged: false,\n    zoom_rescale: false,\n    zoom_onzoom: function() {},\n    zoom_onzoomstart: function() {},\n    zoom_onzoomend: function() {},\n    zoom_x_min: undefined,\n    zoom_x_max: undefined,\n    interaction_brighten: true,\n    interaction_enabled: true,\n    onmouseover: function() {},\n    onmouseout: function() {},\n    onresize: function() {},\n    onresized: function() {},\n    oninit: function() {},\n    onrendered: function() {},\n    transition_duration: 350,\n    data_epochs: 'epochs',\n    data_x: undefined,\n    data_xs: {},\n    data_xFormat: '%Y-%m-%d',\n    data_xLocaltime: true,\n    data_xSort: true,\n    data_idConverter: function(id) {\n      return id\n    },\n    data_names: {},\n    data_classes: {},\n    data_groups: [],\n    data_axes: {},\n    data_type: undefined,\n    data_types: {},\n    data_labels: {},\n    data_order: 'desc',\n    data_regions: {},\n    data_color: undefined,\n    data_colors: {},\n    data_hide: false,\n    data_filter: undefined,\n    data_selection_enabled: false,\n    data_selection_grouped: false,\n    data_selection_isselectable: function() {\n      return true\n    },\n    data_selection_multiple: true,\n    data_selection_draggable: false,\n    data_stack_normalize: false,\n    data_onclick: function() {},\n    data_onmouseover: function() {},\n    data_onmouseout: function() {},\n    data_onselected: function() {},\n    data_onunselected: function() {},\n    data_url: undefined,\n    data_headers: undefined,\n    data_json: undefined,\n    data_rows: undefined,\n    data_columns: undefined,\n    data_mimeType: undefined,\n    data_keys: undefined,\n    // configuration for no plot-able data supplied.\n    data_empty_label_text: '',\n    // subchart\n    subchart_show: false,\n    subchart_size_height: 60,\n    subchart_axis_x_show: true,\n    subchart_onbrush: function() {},\n    // color\n    color_pattern: [],\n    color_threshold: {},\n    // legend\n    legend_show: true,\n    legend_hide: false,\n    legend_position: 'bottom',\n    legend_inset_anchor: 'top-left',\n    legend_inset_x: 10,\n    legend_inset_y: 0,\n    legend_inset_step: undefined,\n    legend_item_onclick: undefined,\n    legend_item_onmouseover: undefined,\n    legend_item_onmouseout: undefined,\n    legend_equally: false,\n    legend_padding: 0,\n    legend_item_tile_width: 10,\n    legend_item_tile_height: 10,\n    // axis\n    axis_rotated: false,\n    axis_x_show: true,\n    axis_x_type: 'indexed',\n    axis_x_localtime: true,\n    axis_x_categories: [],\n    axis_x_tick_centered: false,\n    axis_x_tick_format: undefined,\n    axis_x_tick_culling: {},\n    axis_x_tick_culling_max: 10,\n    axis_x_tick_count: undefined,\n    axis_x_tick_fit: true,\n    axis_x_tick_values: null,\n    axis_x_tick_rotate: 0,\n    axis_x_tick_outer: true,\n    axis_x_tick_multiline: true,\n    axis_x_tick_multilineMax: 0,\n    axis_x_tick_width: null,\n    axis_x_max: undefined,\n    axis_x_min: undefined,\n    axis_x_padding: {},\n    axis_x_height: undefined,\n    axis_x_selection: undefined,\n    axis_x_label: {},\n    axis_x_inner: undefined,\n    axis_y_show: true,\n    axis_y_type: 'linear',\n    axis_y_max: undefined,\n    axis_y_min: undefined,\n    axis_y_inverted: false,\n    axis_y_center: undefined,\n    axis_y_inner: undefined,\n    axis_y_label: {},\n    axis_y_tick_format: undefined,\n    axis_y_tick_outer: true,\n    axis_y_tick_values: null,\n    axis_y_tick_rotate: 0,\n    axis_y_tick_count: undefined,\n    axis_y_tick_time_type: undefined,\n    axis_y_tick_time_interval: undefined,\n    axis_y_padding: {},\n    axis_y_default: undefined,\n    axis_y2_show: false,\n    axis_y2_type: 'linear',\n    axis_y2_max: undefined,\n    axis_y2_min: undefined,\n    axis_y2_inverted: false,\n    axis_y2_center: undefined,\n    axis_y2_inner: undefined,\n    axis_y2_label: {},\n    axis_y2_tick_format: undefined,\n    axis_y2_tick_outer: true,\n    axis_y2_tick_values: null,\n    axis_y2_tick_count: undefined,\n    axis_y2_padding: {},\n    axis_y2_default: undefined,\n    // grid\n    grid_x_show: false,\n    grid_x_type: 'tick',\n    grid_x_lines: [],\n    grid_y_show: false,\n    // not used\n    // grid_y_type: 'tick',\n    grid_y_lines: [],\n    grid_y_ticks: 10,\n    grid_focus_show: true,\n    grid_lines_front: true,\n    // point - point of each data\n    point_show: true,\n    point_r: 2.5,\n    point_sensitivity: 10,\n    point_focus_expand_enabled: true,\n    point_focus_expand_r: undefined,\n    point_select_r: undefined,\n    // line\n    line_connectNull: false,\n    line_step_type: 'step',\n    // bar\n    bar_width: undefined,\n    bar_width_ratio: 0.6,\n    bar_width_max: undefined,\n    bar_zerobased: true,\n    bar_space: 0,\n    // area\n    area_zerobased: true,\n    area_above: false,\n    // pie\n    pie_label_show: true,\n    pie_label_format: undefined,\n    pie_label_threshold: 0.05,\n    pie_label_ratio: undefined,\n    pie_expand: {},\n    pie_expand_duration: 50,\n    pie_padAngle: 0,\n    // gauge\n    gauge_fullCircle: false,\n    gauge_label_show: true,\n    gauge_labelLine_show: true,\n    gauge_label_format: undefined,\n    gauge_min: 0,\n    gauge_max: 100,\n    gauge_startingAngle: (-1 * Math.PI) / 2,\n    gauge_label_extents: undefined,\n    gauge_units: undefined,\n    gauge_width: undefined,\n    gauge_arcs_minWidth: 5,\n    gauge_expand: {},\n    gauge_expand_duration: 50,\n    // donut\n    donut_label_show: true,\n    donut_label_format: undefined,\n    donut_label_threshold: 0.05,\n    donut_label_ratio: undefined,\n    donut_width: undefined,\n    donut_title: '',\n    donut_expand: {},\n    donut_expand_duration: 50,\n    donut_padAngle: 0,\n    // spline\n    spline_interpolation_type: 'cardinal',\n    // stanford\n    stanford_lines: [],\n    stanford_regions: [],\n    stanford_texts: [],\n    stanford_scaleMin: undefined,\n    stanford_scaleMax: undefined,\n    stanford_scaleWidth: undefined,\n    stanford_scaleFormat: undefined,\n    stanford_scaleValues: undefined,\n    stanford_colors: undefined,\n    stanford_padding: {\n      top: 0,\n      right: 0,\n      bottom: 0,\n      left: 0\n    },\n    // region - region to change style\n    regions: [],\n    // tooltip - show when mouseover on each data\n    tooltip_show: true,\n    tooltip_grouped: true,\n    tooltip_order: undefined,\n    tooltip_format_title: undefined,\n    tooltip_format_name: undefined,\n    tooltip_format_value: undefined,\n    tooltip_horizontal: undefined,\n    tooltip_position: undefined,\n    tooltip_contents: function(\n      d,\n      defaultTitleFormat,\n      defaultValueFormat,\n      color\n    ) {\n      return this.getTooltipContent\n        ? this.getTooltipContent(\n            d,\n            defaultTitleFormat,\n            defaultValueFormat,\n            color\n          )\n        : ''\n    },\n    tooltip_init_show: false,\n    tooltip_init_x: 0,\n    tooltip_init_position: { top: '0px', left: '50px' },\n    tooltip_onshow: function() {},\n    tooltip_onhide: function() {},\n    // title\n    title_text: undefined,\n    title_padding: {\n      top: 0,\n      right: 0,\n      bottom: 0,\n      left: 0\n    },\n    title_position: 'top-center'\n  };\n\n  Object.keys(this.additionalConfig).forEach(function(key) {\n    config[key] = this.additionalConfig[key];\n  }, this);\n\n  return config\n};\nChartInternal.prototype.additionalConfig = {};\n\nChartInternal.prototype.loadConfig = function(config) {\n  var this_config = this.config,\n    target,\n    keys,\n    read;\n  function find() {\n    var key = keys.shift();\n    //        console.log(\"key =>\", key, \", target =>\", target);\n    if (key && target && typeof target === 'object' && key in target) {\n      target = target[key];\n      return find()\n    } else if (!key) {\n      return target\n    } else {\n      return undefined\n    }\n  }\n  Object.keys(this_config).forEach(function(key) {\n    target = config;\n    keys = key.split('_');\n    read = find();\n    //        console.log(\"CONFIG : \", key, read);\n    if (isDefined(read)) {\n      this_config[key] = read;\n    }\n  });\n};\n\nChartInternal.prototype.convertUrlToData = function(\n  url,\n  mimeType,\n  headers,\n  keys,\n  done\n) {\n  var $$ = this,\n    type = mimeType ? mimeType : 'csv',\n    f,\n    converter;\n\n  if (type === 'json') {\n    f = $$.d3.json;\n    converter = $$.convertJsonToData;\n  } else if (type === 'tsv') {\n    f = $$.d3.tsv;\n    converter = $$.convertXsvToData;\n  } else {\n    f = $$.d3.csv;\n    converter = $$.convertXsvToData;\n  }\n\n  f(url, headers)\n    .then(function(data) {\n      done.call($$, converter.call($$, data, keys));\n    })\n    .catch(function(error) {\n      throw error\n    });\n};\nChartInternal.prototype.convertXsvToData = function(xsv) {\n  var keys = xsv.columns,\n    rows = xsv;\n  if (rows.length === 0) {\n    return {\n      keys,\n      rows: [keys.reduce((row, key) => Object.assign(row, { [key]: null }), {})]\n    }\n  } else {\n    // [].concat() is to convert result into a plain array otherwise\n    // test is not happy because rows have properties.\n    return { keys, rows: [].concat(xsv) }\n  }\n};\nChartInternal.prototype.convertJsonToData = function(json, keys) {\n  var $$ = this,\n    new_rows = [],\n    targetKeys,\n    data;\n  if (keys) {\n    // when keys specified, json would be an array that includes objects\n    if (keys.x) {\n      targetKeys = keys.value.concat(keys.x);\n      $$.config.data_x = keys.x;\n    } else {\n      targetKeys = keys.value;\n    }\n    new_rows.push(targetKeys);\n    json.forEach(function(o) {\n      var new_row = [];\n      targetKeys.forEach(function(key) {\n        // convert undefined to null because undefined data will be removed in convertDataToTargets()\n        var v = $$.findValueInJson(o, key);\n        if (isUndefined(v)) {\n          v = null;\n        }\n        new_row.push(v);\n      });\n      new_rows.push(new_row);\n    });\n    data = $$.convertRowsToData(new_rows);\n  } else {\n    Object.keys(json).forEach(function(key) {\n      new_rows.push([key].concat(json[key]));\n    });\n    data = $$.convertColumnsToData(new_rows);\n  }\n  return data\n};\n/**\n * Finds value from the given nested object by the given path.\n * If it's not found, then this returns undefined.\n * @param {Object} object the object\n * @param {string} path the path\n */\nChartInternal.prototype.findValueInJson = function(object, path) {\n  if (path in object) {\n    // If object has a key that contains . or [], return the key's value\n    // instead of searching for an inner object.\n    // See https://github.com/c3js/c3/issues/1691 for details.\n    return object[path]\n  }\n\n  path = path.replace(/\\[(\\w+)\\]/g, '.$1'); // convert indexes to properties (replace [] with .)\n  path = path.replace(/^\\./, ''); // strip a leading dot\n  var pathArray = path.split('.');\n  for (var i = 0; i < pathArray.length; ++i) {\n    var k = pathArray[i];\n    if (k in object) {\n      object = object[k];\n    } else {\n      return\n    }\n  }\n  return object\n};\n\n/**\n * Converts the rows to normalized data.\n * @param {any[][]} rows The row data\n * @return {Object}\n */\nChartInternal.prototype.convertRowsToData = rows => {\n  const newRows = [];\n  const keys = rows[0];\n\n  for (let i = 1; i < rows.length; i++) {\n    const newRow = {};\n    for (let j = 0; j < rows[i].length; j++) {\n      if (isUndefined(rows[i][j])) {\n        throw new Error(\n          'Source data is missing a component at (' + i + ',' + j + ')!'\n        )\n      }\n      newRow[keys[j]] = rows[i][j];\n    }\n    newRows.push(newRow);\n  }\n  return { keys, rows: newRows }\n};\n\n/**\n * Converts the columns to normalized data.\n * @param {any[][]} columns The column data\n * @return {Object}\n */\nChartInternal.prototype.convertColumnsToData = columns => {\n  const newRows = [];\n  const keys = [];\n\n  for (let i = 0; i < columns.length; i++) {\n    const key = columns[i][0];\n    for (let j = 1; j < columns[i].length; j++) {\n      if (isUndefined(newRows[j - 1])) {\n        newRows[j - 1] = {};\n      }\n      if (isUndefined(columns[i][j])) {\n        throw new Error(\n          'Source data is missing a component at (' + i + ',' + j + ')!'\n        )\n      }\n      newRows[j - 1][key] = columns[i][j];\n    }\n    keys.push(key);\n  }\n\n  return { keys, rows: newRows }\n};\n\n/**\n * Converts the data format into the target format.\n * @param {!Object} data\n * @param {!Array} data.keys Ordered list of target IDs.\n * @param {!Array} data.rows Rows of data to convert.\n * @param {boolean} appendXs True to append to $$.data.xs, False to replace.\n * @return {!Array}\n */\nChartInternal.prototype.convertDataToTargets = function(data, appendXs) {\n  var $$ = this,\n    config = $$.config,\n    targets,\n    ids,\n    xs,\n    keys,\n    epochs;\n\n  // handles format where keys are not orderly provided\n  if (isArray(data)) {\n    keys = Object.keys(data[0]);\n  } else {\n    keys = data.keys;\n    data = data.rows;\n  }\n\n  xs = keys.filter($$.isX, $$);\n\n  if (!$$.isStanfordGraphType()) {\n    ids = keys.filter($$.isNotX, $$);\n  } else {\n    epochs = keys.filter($$.isEpochs, $$);\n    ids = keys.filter($$.isNotXAndNotEpochs, $$);\n\n    if (xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) {\n      throw new Error(\n        \"You must define the 'x' key name and the 'epochs' for Stanford Diagrams\"\n      )\n    }\n  }\n\n  // save x for update data by load when custom x and c3.x API\n  ids.forEach(function(id) {\n    var xKey = $$.getXKey(id);\n\n    if ($$.isCustomX() || $$.isTimeSeries()) {\n      // if included in input data\n      if (xs.indexOf(xKey) >= 0) {\n        $$.data.xs[id] = (appendXs && $$.data.xs[id]\n          ? $$.data.xs[id]\n          : []\n        ).concat(\n          data\n            .map(function(d) {\n              return d[xKey]\n            })\n            .filter(isValue)\n            .map(function(rawX, i) {\n              return $$.generateTargetX(rawX, id, i)\n            })\n        );\n      }\n      // if not included in input data, find from preloaded data of other id's x\n      else if (config.data_x) {\n        $$.data.xs[id] = $$.getOtherTargetXs();\n      }\n      // if not included in input data, find from preloaded data\n      else if (notEmpty(config.data_xs)) {\n        $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets);\n      }\n      // MEMO: if no x included, use same x of current will be used\n    } else {\n      $$.data.xs[id] = data.map(function(d, i) {\n        return i\n      });\n    }\n  });\n\n  // check x is defined\n  ids.forEach(function(id) {\n    if (!$$.data.xs[id]) {\n      throw new Error('x is not defined for id = \"' + id + '\".')\n    }\n  });\n\n  // convert to target\n  targets = ids.map(function(id, index) {\n    var convertedId = config.data_idConverter(id);\n    return {\n      id: convertedId,\n      id_org: id,\n      values: data\n        .map(function(d, i) {\n          var xKey = $$.getXKey(id),\n            rawX = d[xKey],\n            value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null,\n            x,\n            returnData;\n          // use x as categories if custom x and categorized\n          if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) {\n            if (index === 0 && i === 0) {\n              config.axis_x_categories = [];\n            }\n            x = config.axis_x_categories.indexOf(rawX);\n            if (x === -1) {\n              x = config.axis_x_categories.length;\n              config.axis_x_categories.push(rawX);\n            }\n          } else {\n            x = $$.generateTargetX(rawX, id, i);\n          }\n          // mark as x = undefined if value is undefined and filter to remove after mapped\n          if (isUndefined(d[id]) || $$.data.xs[id].length <= i) {\n            x = undefined;\n          }\n\n          returnData = { x: x, value: value, id: convertedId };\n\n          if ($$.isStanfordGraphType()) {\n            returnData.epochs = d[epochs];\n          }\n\n          return returnData\n        })\n        .filter(function(v) {\n          return isDefined(v.x)\n        })\n    }\n  });\n\n  // finish targets\n  targets.forEach(function(t) {\n    var i;\n    // sort values by its x\n    if (config.data_xSort) {\n      t.values = t.values.sort(function(v1, v2) {\n        var x1 = v1.x || v1.x === 0 ? v1.x : Infinity,\n          x2 = v2.x || v2.x === 0 ? v2.x : Infinity;\n        return x1 - x2\n      });\n    }\n    // indexing each value\n    i = 0;\n    t.values.forEach(function(v) {\n      v.index = i++;\n    });\n    // this needs to be sorted because its index and value.index is identical\n    $$.data.xs[t.id].sort(function(v1, v2) {\n      return v1 - v2\n    });\n  });\n\n  // cache information about values\n  $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets);\n  $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets);\n\n  // set target types\n  if (config.data_type) {\n    $$.setTargetType(\n      $$.mapToIds(targets).filter(function(id) {\n        return !(id in config.data_types)\n      }),\n      config.data_type\n    );\n  }\n\n  // cache as original id keyed\n  targets.forEach(function(d) {\n    $$.addCache(d.id_org, d);\n  });\n\n  return targets\n};\n\nChartInternal.prototype.isEpochs = function(key) {\n  var $$ = this,\n    config = $$.config;\n  return config.data_epochs && key === config.data_epochs\n};\nChartInternal.prototype.isX = function(key) {\n  var $$ = this,\n    config = $$.config;\n  return (\n    (config.data_x && key === config.data_x) ||\n    (notEmpty(config.data_xs) && hasValue(config.data_xs, key))\n  )\n};\nChartInternal.prototype.isNotX = function(key) {\n  return !this.isX(key)\n};\nChartInternal.prototype.isNotXAndNotEpochs = function(key) {\n  return !this.isX(key) && !this.isEpochs(key)\n};\n\n/**\n * Returns whether the normalized stack option is enabled or not.\n *\n * To be enabled it must also have data.groups defined.\n *\n * @return {boolean}\n */\nChartInternal.prototype.isStackNormalized = function() {\n  return this.config.data_stack_normalize && this.config.data_groups.length > 0\n};\n\n/**\n * Returns whether the axis is normalized or not.\n *\n * An axis is normalized as long as one of its associated target\n * is normalized.\n *\n * @param axisId Axis ID (y or y2)\n * @return {Boolean}\n */\nChartInternal.prototype.isAxisNormalized = function(axisId) {\n  const $$ = this;\n\n  if (!$$.isStackNormalized()) {\n    // shortcut\n    return false\n  }\n\n  return $$.data.targets\n    .filter(target => $$.axis.getId(target.id) === axisId)\n    .some(target => $$.isTargetNormalized(target.id))\n};\n\n/**\n * Returns whether the values for this target ID is normalized or not.\n *\n * To be normalized the option needs to be enabled and target needs\n * to be defined in `data.groups`.\n *\n * @param targetId ID of the target\n * @return {Boolean} True if the target is normalized, false otherwise.\n */\nChartInternal.prototype.isTargetNormalized = function(targetId) {\n  const $$ = this;\n\n  return (\n    $$.isStackNormalized() &&\n    $$.config.data_groups.some(group => group.includes(targetId))\n  )\n};\n\nChartInternal.prototype.getXKey = function(id) {\n  var $$ = this,\n    config = $$.config;\n  return config.data_x\n    ? config.data_x\n    : notEmpty(config.data_xs)\n    ? config.data_xs[id]\n    : null\n};\n\n/**\n * Get sum of visible data per index for given axis.\n *\n * Expect axisId to be either 'y' or 'y2'.\n *\n * @private\n * @param axisId Compute sum for data associated to given axis.\n * @return {Array}\n */\nChartInternal.prototype.getTotalPerIndex = function(axisId) {\n  const $$ = this;\n\n  if (!$$.isStackNormalized()) {\n    return null\n  }\n\n  const cached = $$.getFromCache('getTotalPerIndex');\n  if (cached !== undefined) {\n    return cached[axisId]\n  }\n\n  const sum = { y: [], y2: [] };\n\n  $$.data.targets\n    // keep only target that are normalized\n    .filter(target => $$.isTargetNormalized(target.id))\n\n    // keep only target that are visible\n    .filter(target => $$.isTargetToShow(target.id))\n\n    // compute sum per axis\n    .forEach(target => {\n      const sumByAxis = sum[$$.axis.getId(target.id)];\n\n      target.values.forEach((v, i) => {\n        if (!sumByAxis[i]) {\n          sumByAxis[i] = 0;\n        }\n        sumByAxis[i] += isNumber(v.value) ? v.value : 0;\n      });\n    });\n\n  $$.addToCache('getTotalPerIndex', sum);\n\n  return sum[axisId]\n};\n\n/**\n * Get sum of visible data.\n *\n * Should be used for normalised data only since all values\n * are expected to be positive.\n *\n * @private\n * @return {Number}\n */\nChartInternal.prototype.getTotalDataSum = function() {\n  const $$ = this;\n\n  const cached = $$.getFromCache('getTotalDataSum');\n  if (cached !== undefined) {\n    return cached\n  }\n\n  const totalDataSum = flattenArray(\n    $$.data.targets\n      .filter(target => $$.isTargetToShow(target.id))\n      .map(target => target.values)\n  )\n    .map(d => d.value)\n    .reduce((p, c) => p + c, 0);\n\n  $$.addToCache('getTotalDataSum', totalDataSum);\n\n  return totalDataSum\n};\n\nChartInternal.prototype.getXValuesOfXKey = function(key, targets) {\n  var $$ = this,\n    xValues,\n    ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : [];\n  ids.forEach(function(id) {\n    if ($$.getXKey(id) === key) {\n      xValues = $$.data.xs[id];\n    }\n  });\n  return xValues\n};\nChartInternal.prototype.getXValue = function(id, i) {\n  var $$ = this;\n  return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i])\n    ? $$.data.xs[id][i]\n    : i\n};\nChartInternal.prototype.getOtherTargetXs = function() {\n  var $$ = this,\n    idsForX = Object.keys($$.data.xs);\n  return idsForX.length ? $$.data.xs[idsForX[0]] : null\n};\nChartInternal.prototype.getOtherTargetX = function(index) {\n  var xs = this.getOtherTargetXs();\n  return xs && index < xs.length ? xs[index] : null\n};\nChartInternal.prototype.addXs = function(xs) {\n  var $$ = this;\n  Object.keys(xs).forEach(function(id) {\n    $$.config.data_xs[id] = xs[id];\n  });\n};\nChartInternal.prototype.addName = function(data) {\n  var $$ = this,\n    name;\n  if (data) {\n    name = $$.config.data_names[data.id];\n    data.name = name !== undefined ? name : data.id;\n  }\n  return data\n};\nChartInternal.prototype.getValueOnIndex = function(values, index) {\n  var valueOnIndex = values.filter(function(v) {\n    return v.index === index\n  });\n  return valueOnIndex.length ? valueOnIndex[0] : null\n};\nChartInternal.prototype.updateTargetX = function(targets, x) {\n  var $$ = this;\n  targets.forEach(function(t) {\n    t.values.forEach(function(v, i) {\n      v.x = $$.generateTargetX(x[i], t.id, i);\n    });\n    $$.data.xs[t.id] = x;\n  });\n};\nChartInternal.prototype.updateTargetXs = function(targets, xs) {\n  var $$ = this;\n  targets.forEach(function(t) {\n    if (xs[t.id]) {\n      $$.updateTargetX([t], xs[t.id]);\n    }\n  });\n};\nChartInternal.prototype.generateTargetX = function(rawX, id, index) {\n  var $$ = this,\n    x;\n  if ($$.isTimeSeries()) {\n    x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index));\n  } else if ($$.isCustomX() && !$$.isCategorized()) {\n    x = isValue(rawX) ? +rawX : $$.getXValue(id, index);\n  } else {\n    x = index;\n  }\n  return x\n};\nChartInternal.prototype.cloneTarget = function(target) {\n  return {\n    id: target.id,\n    id_org: target.id_org,\n    values: target.values.map(function(d) {\n      return {\n        x: d.x,\n        value: d.value,\n        id: d.id\n      }\n    })\n  }\n};\nChartInternal.prototype.getMaxDataCount = function() {\n  var $$ = this;\n  return $$.d3.max($$.data.targets, function(t) {\n    return t.values.length\n  })\n};\nChartInternal.prototype.mapToIds = function(targets) {\n  return targets.map(function(d) {\n    return d.id\n  })\n};\nChartInternal.prototype.mapToTargetIds = function(ids) {\n  var $$ = this;\n  return ids ? [].concat(ids) : $$.mapToIds($$.data.targets)\n};\nChartInternal.prototype.hasTarget = function(targets, id) {\n  var ids = this.mapToIds(targets),\n    i;\n  for (i = 0; i < ids.length; i++) {\n    if (ids[i] === id) {\n      return true\n    }\n  }\n  return false\n};\nChartInternal.prototype.isTargetToShow = function(targetId) {\n  return this.hiddenTargetIds.indexOf(targetId) < 0\n};\nChartInternal.prototype.isLegendToShow = function(targetId) {\n  return this.hiddenLegendIds.indexOf(targetId) < 0\n};\n\n/**\n * Returns only visible targets.\n *\n * This is the same as calling {@link filterTargetsToShow} on $$.data.targets.\n *\n * @return {Array}\n */\nChartInternal.prototype.getTargetsToShow = function() {\n  const $$ = this;\n  return $$.filterTargetsToShow($$.data.targets)\n};\n\nChartInternal.prototype.filterTargetsToShow = function(targets) {\n  var $$ = this;\n  return targets.filter(function(t) {\n    return $$.isTargetToShow(t.id)\n  })\n};\n\n/**\n * @return {Array} Returns all the targets attached to the chart, visible or not\n */\nChartInternal.prototype.getTargets = function() {\n  const $$ = this;\n  return $$.data.targets\n};\n\nChartInternal.prototype.mapTargetsToUniqueXs = function(targets) {\n  var $$ = this;\n  var xs = $$.d3\n    .set(\n      $$.d3.merge(\n        targets.map(function(t) {\n          return t.values.map(function(v) {\n            return +v.x\n          })\n        })\n      )\n    )\n    .values();\n  xs = $$.isTimeSeries()\n    ? xs.map(function(x) {\n        return new Date(+x)\n      })\n    : xs.map(function(x) {\n        return +x\n      });\n  return xs.sort(function(a, b) {\n    return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN\n  })\n};\nChartInternal.prototype.addHiddenTargetIds = function(targetIds) {\n  targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);\n  for (var i = 0; i < targetIds.length; i++) {\n    if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) {\n      this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]);\n    }\n  }\n  this.resetCache();\n};\nChartInternal.prototype.removeHiddenTargetIds = function(targetIds) {\n  this.hiddenTargetIds = this.hiddenTargetIds.filter(function(id) {\n    return targetIds.indexOf(id) < 0\n  });\n  this.resetCache();\n};\nChartInternal.prototype.addHiddenLegendIds = function(targetIds) {\n  targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);\n  for (var i = 0; i < targetIds.length; i++) {\n    if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) {\n      this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]);\n    }\n  }\n};\nChartInternal.prototype.removeHiddenLegendIds = function(targetIds) {\n  this.hiddenLegendIds = this.hiddenLegendIds.filter(function(id) {\n    return targetIds.indexOf(id) < 0\n  });\n};\nChartInternal.prototype.getValuesAsIdKeyed = function(targets) {\n  var ys = {};\n  targets.forEach(function(t) {\n    ys[t.id] = [];\n    t.values.forEach(function(v) {\n      ys[t.id].push(v.value);\n    });\n  });\n  return ys\n};\nChartInternal.prototype.checkValueInTargets = function(targets, checker) {\n  var ids = Object.keys(targets),\n    i,\n    j,\n    values;\n  for (i = 0; i < ids.length; i++) {\n    values = targets[ids[i]].values;\n    for (j = 0; j < values.length; j++) {\n      if (checker(values[j].value)) {\n        return true\n      }\n    }\n  }\n  return false\n};\nChartInternal.prototype.hasNegativeValueInTargets = function(targets) {\n  return this.checkValueInTargets(targets, function(v) {\n    return v < 0\n  })\n};\nChartInternal.prototype.hasPositiveValueInTargets = function(targets) {\n  return this.checkValueInTargets(targets, function(v) {\n    return v > 0\n  })\n};\nChartInternal.prototype.isOrderDesc = function() {\n  var config = this.config;\n  return (\n    typeof config.data_order === 'string' &&\n    config.data_order.toLowerCase() === 'desc'\n  )\n};\nChartInternal.prototype.isOrderAsc = function() {\n  var config = this.config;\n  return (\n    typeof config.data_order === 'string' &&\n    config.data_order.toLowerCase() === 'asc'\n  )\n};\nChartInternal.prototype.getOrderFunction = function() {\n  var $$ = this,\n    config = $$.config,\n    orderAsc = $$.isOrderAsc(),\n    orderDesc = $$.isOrderDesc();\n  if (orderAsc || orderDesc) {\n    var reducer = function(p, c) {\n      return p + Math.abs(c.value)\n    };\n    return function(t1, t2) {\n      var t1Sum = t1.values.reduce(reducer, 0),\n        t2Sum = t2.values.reduce(reducer, 0);\n      return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum\n    }\n  } else if (isFunction(config.data_order)) {\n    return config.data_order\n  } else if (isArray(config.data_order)) {\n    var order = config.data_order;\n    return function(t1, t2) {\n      return order.indexOf(t1.id) - order.indexOf(t2.id)\n    }\n  }\n};\nChartInternal.prototype.orderTargets = function(targets) {\n  var fct = this.getOrderFunction();\n  if (fct) {\n    targets.sort(fct);\n  }\n  return targets\n};\n\n/**\n * Returns all the values from the given targets at the given index.\n *\n * @param {Array} targets\n * @param {Number} index\n * @return {Array}\n */\nChartInternal.prototype.filterByIndex = function(targets, index) {\n  return this.d3.merge(\n    targets.map(t => t.values.filter(v => v.index === index))\n  )\n};\n\nChartInternal.prototype.filterByX = function(targets, x) {\n  return this.d3\n    .merge(\n      targets.map(function(t) {\n        return t.values\n      })\n    )\n    .filter(function(v) {\n      return v.x - x === 0\n    })\n};\nChartInternal.prototype.filterRemoveNull = function(data) {\n  return data.filter(function(d) {\n    return isValue(d.value)\n  })\n};\nChartInternal.prototype.filterByXDomain = function(targets, xDomain) {\n  return targets.map(function(t) {\n    return {\n      id: t.id,\n      id_org: t.id_org,\n      values: t.values.filter(function(v) {\n        return xDomain[0] <= v.x && v.x <= xDomain[1]\n      })\n    }\n  })\n};\nChartInternal.prototype.hasDataLabel = function() {\n  var config = this.config;\n  if (typeof config.data_labels === 'boolean' && config.data_labels) {\n    return true\n  } else if (\n    typeof config.data_labels === 'object' &&\n    notEmpty(config.data_labels)\n  ) {\n    return true\n  }\n  return false\n};\nChartInternal.prototype.getDataLabelLength = function(min, max, key) {\n  var $$ = this,\n    lengths = [0, 0],\n    paddingCoef = 1.3;\n  $$.selectChart\n    .select('svg')\n    .selectAll('.dummy')\n    .data([min, max])\n    .enter()\n    .append('text')\n    .text(function(d) {\n      return $$.dataLabelFormat(d.id)(d)\n    })\n    .each(function(d, i) {\n      lengths[i] = getBBox(this)[key] * paddingCoef;\n    })\n    .remove();\n  return lengths\n};\n/**\n * Returns true if the given data point is not arc type, otherwise false.\n * @param {Object} d The data point\n * @return {boolean}\n */\nChartInternal.prototype.isNoneArc = function(d) {\n  return this.hasTarget(this.data.targets, d.id)\n};\n\n/**\n * Returns true if the given data point is arc type, otherwise false.\n * @param {Object} d The data point\n * @return {boolean}\n */\nChartInternal.prototype.isArc = function(d) {\n  return 'data' in d && this.hasTarget(this.data.targets, d.data.id)\n};\n\n/**\n * Find the closest point from the given pos among the given targets or\n * undefined if none satisfies conditions.\n *\n * @param {Array} targets\n * @param {Array} pos An [x,y] coordinate\n * @return {Object|undefined}\n */\nChartInternal.prototype.findClosestFromTargets = function(targets, pos) {\n  const $$ = this;\n\n  // for each target, find the closest point\n  const candidates = targets\n    .map(t =>\n      $$.findClosest(\n        t.values,\n        pos,\n        $$.config.tooltip_horizontal\n          ? $$.horizontalDistance.bind($$)\n          : $$.dist.bind($$),\n        $$.config.point_sensitivity\n      )\n    )\n    .filter(v => v);\n\n  // returns the closest of candidates\n  if (candidates.length === 0) {\n    return undefined\n  } else if (candidates.length === 1) {\n    return candidates[0]\n  } else {\n    return $$.findClosest(candidates, pos, $$.dist.bind($$))\n  }\n};\n\n/**\n * Find the closest point from the x value or undefined if none satisfies conditions.\n *\n * @param {Array} targets\n * @param {Array} x A value on X axis\n * @return {Object|undefined}\n */\nChartInternal.prototype.findClosestFromTargetsByX = function(targets, x) {\n  let closest;\n  let diff;\n\n  targets.forEach(t => {\n    t.values.forEach(d => {\n      let newDiff = Math.abs(x - d.x);\n\n      if (diff === undefined || newDiff < diff) {\n        closest = d;\n        diff = newDiff;\n      }\n    });\n  });\n\n  return closest\n};\n\n/**\n * Using given compute distance method, returns the closest data point from the\n * given position.\n *\n * Giving optionally a minimum distance to satisfy.\n *\n * @param {Array} dataPoints List of DataPoints\n * @param {Array} pos An [x,y] coordinate\n * @param {Function} computeDist Function to compute distance between 2 points\n * @param {Number} minDist Minimal distance to satisfy\n * @return {Object|undefined} Closest data point\n */\nChartInternal.prototype.findClosest = function(\n  dataPoints,\n  pos,\n  computeDist,\n  minDist = Infinity\n) {\n  const $$ = this;\n\n  let closest;\n\n  // find closest bar\n  dataPoints\n    .filter(v => v && $$.isBarType(v.id))\n    .forEach(function(v) {\n      if (!closest) {\n        const shape = $$.main\n          .select(\n            '.' +\n              CLASS.bars +\n              $$.getTargetSelectorSuffix(v.id) +\n              ' .' +\n              CLASS.bar +\n              '-' +\n              v.index\n          )\n          .node();\n        if ($$.isWithinBar(pos, shape)) {\n          closest = v;\n        }\n      }\n    });\n\n  // find closest point from non-bar\n  dataPoints\n    .filter(v => v && !$$.isBarType(v.id))\n    .forEach(v => {\n      let d = computeDist(v, pos);\n      if (d < minDist) {\n        minDist = d;\n        closest = v;\n      }\n    });\n\n  return closest\n};\nChartInternal.prototype.dist = function(data, pos) {\n  var $$ = this,\n    config = $$.config,\n    xIndex = config.axis_rotated ? 1 : 0,\n    yIndex = config.axis_rotated ? 0 : 1,\n    y = $$.circleY(data, data.index),\n    x = $$.x(data.x);\n  return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2))\n};\nChartInternal.prototype.horizontalDistance = function(data, pos) {\n  var $$ = this,\n    config = $$.config,\n    xIndex = config.axis_rotated ? 1 : 0,\n    x = $$.x(data.x);\n\n  return Math.abs(x - pos[xIndex])\n};\nChartInternal.prototype.convertValuesToStep = function(values) {\n  var converted = [].concat(values),\n    i;\n\n  if (!this.isCategorized()) {\n    return values\n  }\n\n  for (i = values.length + 1; 0 < i; i--) {\n    converted[i] = converted[i - 1];\n  }\n\n  converted[0] = {\n    x: converted[0].x - 1,\n    value: converted[0].value,\n    id: converted[0].id\n  };\n  converted[values.length + 1] = {\n    x: converted[values.length].x + 1,\n    value: converted[values.length].value,\n    id: converted[values.length].id\n  };\n\n  return converted\n};\n\n/**\n * Get ratio value\n *\n * @param {String} type Ratio for given type\n * @param {Object} d Data value object\n * @param {Boolean} asPercent Convert the return as percent or not\n * @return {Number} Ratio value\n * @private\n */\nChartInternal.prototype.getRatio = function(type, d, asPercent = false) {\n  const $$ = this;\n  const api = $$.api;\n  let ratio = 0;\n\n  if (d && api.data.shown.call(api).length) {\n    ratio = d.ratio || d.value;\n\n    if (type === 'arc') {\n      if ($$.hasType('gauge')) {\n        ratio =\n          (d.endAngle - d.startAngle) /\n          (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1));\n      } else {\n        const total = $$.getTotalDataSum();\n\n        ratio = d.value / total;\n      }\n    } else if (type === 'index') {\n      const total = $$.getTotalPerIndex($$.axis.getId(d.id));\n\n      d.ratio =\n        isNumber(d.value) && total && total[d.index] > 0\n          ? d.value / total[d.index]\n          : 0;\n\n      ratio = d.ratio;\n    }\n  }\n\n  return asPercent && ratio ? ratio * 100 : ratio\n};\n\nChartInternal.prototype.updateDataAttributes = function(name, attrs) {\n  var $$ = this,\n    config = $$.config,\n    current = config['data_' + name];\n  if (typeof attrs === 'undefined') {\n    return current\n  }\n  Object.keys(attrs).forEach(function(id) {\n    current[id] = attrs[id];\n  });\n  $$.redraw({\n    withLegend: true\n  });\n  return current\n};\n\nChartInternal.prototype.load = function(targets, args) {\n  var $$ = this;\n  if (targets) {\n    // filter loading targets if needed\n    if (args.filter) {\n      targets = targets.filter(args.filter);\n    }\n    // set type if args.types || args.type specified\n    if (args.type || args.types) {\n      targets.forEach(function(t) {\n        var type = args.types && args.types[t.id] ? args.types[t.id] : args.type;\n        $$.setTargetType(t.id, type);\n      });\n    }\n    // Update/Add data\n    $$.data.targets.forEach(function(d) {\n      for (var i = 0; i < targets.length; i++) {\n        if (d.id === targets[i].id) {\n          d.values = targets[i].values;\n          targets.splice(i, 1);\n          break\n        }\n      }\n    });\n    $$.data.targets = $$.data.targets.concat(targets); // add remained\n  }\n\n  // Set targets\n  $$.updateTargets($$.data.targets);\n\n  // Redraw with new targets\n  $$.redraw({\n    withUpdateOrgXDomain: true,\n    withUpdateXDomain: true,\n    withLegend: true\n  });\n\n  if (args.done) {\n    args.done();\n  }\n};\nChartInternal.prototype.loadFromArgs = function(args) {\n  var $$ = this;\n\n  $$.resetCache();\n\n  if (args.data) {\n    $$.load($$.convertDataToTargets(args.data), args);\n  } else if (args.url) {\n    $$.convertUrlToData(\n      args.url,\n      args.mimeType,\n      args.headers,\n      args.keys,\n      function(data) {\n        $$.load($$.convertDataToTargets(data), args);\n      }\n    );\n  } else if (args.json) {\n    $$.load(\n      $$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)),\n      args\n    );\n  } else if (args.rows) {\n    $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args);\n  } else if (args.columns) {\n    $$.load(\n      $$.convertDataToTargets($$.convertColumnsToData(args.columns)),\n      args\n    );\n  } else {\n    $$.load(null, args);\n  }\n};\nChartInternal.prototype.unload = function(targetIds, done) {\n  var $$ = this;\n\n  $$.resetCache();\n\n  if (!done) {\n    done = function() {};\n  }\n  // filter existing target\n  targetIds = targetIds.filter(function(id) {\n    return $$.hasTarget($$.data.targets, id)\n  });\n  // If no target, call done and return\n  if (!targetIds || targetIds.length === 0) {\n    done();\n    return\n  }\n  $$.svg\n    .selectAll(\n      targetIds.map(function(id) {\n        return $$.selectorTarget(id)\n      })\n    )\n    .transition()\n    .style('opacity', 0)\n    .remove()\n    .call($$.endall, done);\n  targetIds.forEach(function(id) {\n    // Reset fadein for future load\n    $$.withoutFadeIn[id] = false;\n    // Remove target's elements\n    if ($$.legend) {\n      $$.legend\n        .selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id))\n        .remove();\n    }\n    // Remove target\n    $$.data.targets = $$.data.targets.filter(function(t) {\n      return t.id !== id\n    });\n  });\n};\n\nChartInternal.prototype.getYDomainMin = function(targets) {\n  var $$ = this,\n    config = $$.config,\n    ids = $$.mapToIds(targets),\n    ys = $$.getValuesAsIdKeyed(targets),\n    j,\n    k,\n    baseId,\n    idsInGroup,\n    id,\n    hasNegativeValue;\n  if (config.data_groups.length > 0) {\n    hasNegativeValue = $$.hasNegativeValueInTargets(targets);\n    for (j = 0; j < config.data_groups.length; j++) {\n      // Determine baseId\n      idsInGroup = config.data_groups[j].filter(function(id) {\n        return ids.indexOf(id) >= 0\n      });\n      if (idsInGroup.length === 0) {\n        continue\n      }\n      baseId = idsInGroup[0];\n      // Consider negative values\n      if (hasNegativeValue && ys[baseId]) {\n        ys[baseId].forEach(function(v, i) {\n          ys[baseId][i] = v < 0 ? v : 0;\n        });\n      }\n      // Compute min\n      for (k = 1; k < idsInGroup.length; k++) {\n        id = idsInGroup[k];\n        if (!ys[id]) {\n          continue\n        }\n        ys[id].forEach(function(v, i) {\n          if (\n            $$.axis.getId(id) === $$.axis.getId(baseId) &&\n            ys[baseId] &&\n            !(hasNegativeValue && +v > 0)\n          ) {\n            ys[baseId][i] += +v;\n          }\n        });\n      }\n    }\n  }\n  return $$.d3.min(\n    Object.keys(ys).map(function(key) {\n      return $$.d3.min(ys[key])\n    })\n  )\n};\nChartInternal.prototype.getYDomainMax = function(targets) {\n  var $$ = this,\n    config = $$.config,\n    ids = $$.mapToIds(targets),\n    ys = $$.getValuesAsIdKeyed(targets),\n    j,\n    k,\n    baseId,\n    idsInGroup,\n    id,\n    hasPositiveValue;\n  if (config.data_groups.length > 0) {\n    hasPositiveValue = $$.hasPositiveValueInTargets(targets);\n    for (j = 0; j < config.data_groups.length; j++) {\n      // Determine baseId\n      idsInGroup = config.data_groups[j].filter(function(id) {\n        return ids.indexOf(id) >= 0\n      });\n      if (idsInGroup.length === 0) {\n        continue\n      }\n      baseId = idsInGroup[0];\n      // Consider positive values\n      if (hasPositiveValue && ys[baseId]) {\n        ys[baseId].forEach(function(v, i) {\n          ys[baseId][i] = v > 0 ? v : 0;\n        });\n      }\n      // Compute max\n      for (k = 1; k < idsInGroup.length; k++) {\n        id = idsInGroup[k];\n        if (!ys[id]) {\n          continue\n        }\n        ys[id].forEach(function(v, i) {\n          if (\n            $$.axis.getId(id) === $$.axis.getId(baseId) &&\n            ys[baseId] &&\n            !(hasPositiveValue && +v < 0)\n          ) {\n            ys[baseId][i] += +v;\n          }\n        });\n      }\n    }\n  }\n  return $$.d3.max(\n    Object.keys(ys).map(function(key) {\n      return $$.d3.max(ys[key])\n    })\n  )\n};\nChartInternal.prototype.getYDomain = function(targets, axisId, xDomain) {\n  var $$ = this,\n    config = $$.config;\n\n  if ($$.isAxisNormalized(axisId)) {\n    return [0, 100]\n  }\n\n  var targetsByAxisId = targets.filter(function(t) {\n      return $$.axis.getId(t.id) === axisId\n    }),\n    yTargets = xDomain\n      ? $$.filterByXDomain(targetsByAxisId, xDomain)\n      : targetsByAxisId,\n    yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min,\n    yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max,\n    yDomainMin = $$.getYDomainMin(yTargets),\n    yDomainMax = $$.getYDomainMax(yTargets),\n    domain,\n    domainLength,\n    padding_top,\n    padding_bottom,\n    center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center,\n    yDomainAbs,\n    lengths,\n    diff,\n    ratio,\n    isAllPositive,\n    isAllNegative,\n    isZeroBased =\n      ($$.hasType('bar', yTargets) && config.bar_zerobased) ||\n      ($$.hasType('area', yTargets) && config.area_zerobased),\n    isInverted =\n      axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted,\n    showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated,\n    showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated;\n\n  // MEMO: avoid inverting domain unexpectedly\n  yDomainMin = isValue(yMin)\n    ? yMin\n    : isValue(yMax)\n    ? yDomainMin < yMax\n      ? yDomainMin\n      : yMax - 10\n    : yDomainMin;\n  yDomainMax = isValue(yMax)\n    ? yMax\n    : isValue(yMin)\n    ? yMin < yDomainMax\n      ? yDomainMax\n      : yMin + 10\n    : yDomainMax;\n\n  if (yTargets.length === 0) {\n    // use current domain if target of axisId is none\n    return axisId === 'y2' ? $$.y2.domain() : $$.y.domain()\n  }\n  if (isNaN(yDomainMin)) {\n    // set minimum to zero when not number\n    yDomainMin = 0;\n  }\n  if (isNaN(yDomainMax)) {\n    // set maximum to have same value as yDomainMin\n    yDomainMax = yDomainMin;\n  }\n  if (yDomainMin === yDomainMax) {\n    yDomainMin < 0 ? (yDomainMax = 0) : (yDomainMin = 0);\n  }\n  isAllPositive = yDomainMin >= 0 && yDomainMax >= 0;\n  isAllNegative = yDomainMin <= 0 && yDomainMax <= 0;\n\n  // Cancel zerobased if axis_*_min / axis_*_max specified\n  if ((isValue(yMin) && isAllPositive) || (isValue(yMax) && isAllNegative)) {\n    isZeroBased = false;\n  }\n\n  // Bar/Area chart should be 0-based if all positive|negative\n  if (isZeroBased) {\n    if (isAllPositive) {\n      yDomainMin = 0;\n    }\n    if (isAllNegative) {\n      yDomainMax = 0;\n    }\n  }\n\n  domainLength = Math.abs(yDomainMax - yDomainMin);\n  padding_top = padding_bottom = domainLength * 0.1;\n\n  if (typeof center !== 'undefined') {\n    yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax));\n    yDomainMax = center + yDomainAbs;\n    yDomainMin = center - yDomainAbs;\n  }\n  // add padding for data label\n  if (showHorizontalDataLabel) {\n    lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width');\n    diff = diffDomain($$.y.range());\n    ratio = [lengths[0] / diff, lengths[1] / diff];\n    padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1]));\n    padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1]));\n  } else if (showVerticalDataLabel) {\n    lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height');\n\n    const pixelsToAxisPadding = $$.getY(\n      config[`axis_${axisId}_type`],\n      // input domain as pixels\n      [0, config.axis_rotated ? $$.width : $$.height],\n      // output range as axis padding\n      [0, domainLength]\n    );\n\n    padding_top += pixelsToAxisPadding(lengths[1]);\n    padding_bottom += pixelsToAxisPadding(lengths[0]);\n  }\n  if (axisId === 'y' && notEmpty(config.axis_y_padding)) {\n    padding_top = $$.axis.getPadding(\n      config.axis_y_padding,\n      'top',\n      padding_top,\n      domainLength\n    );\n    padding_bottom = $$.axis.getPadding(\n      config.axis_y_padding,\n      'bottom',\n      padding_bottom,\n      domainLength\n    );\n  }\n  if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) {\n    padding_top = $$.axis.getPadding(\n      config.axis_y2_padding,\n      'top',\n      padding_top,\n      domainLength\n    );\n    padding_bottom = $$.axis.getPadding(\n      config.axis_y2_padding,\n      'bottom',\n      padding_bottom,\n      domainLength\n    );\n  }\n  // Bar/Area chart should be 0-based if all positive|negative\n  if (isZeroBased) {\n    if (isAllPositive) {\n      padding_bottom = yDomainMin;\n    }\n    if (isAllNegative) {\n      padding_top = -yDomainMax;\n    }\n  }\n  domain = [yDomainMin - padding_bottom, yDomainMax + padding_top];\n  return isInverted ? domain.reverse() : domain\n};\nChartInternal.prototype.getXDomainMin = function(targets) {\n  var $$ = this,\n    config = $$.config;\n  return isDefined(config.axis_x_min)\n    ? $$.isTimeSeries()\n      ? this.parseDate(config.axis_x_min)\n      : config.axis_x_min\n    : $$.d3.min(targets, function(t) {\n        return $$.d3.min(t.values, function(v) {\n          return v.x\n        })\n      })\n};\nChartInternal.prototype.getXDomainMax = function(targets) {\n  var $$ = this,\n    config = $$.config;\n  return isDefined(config.axis_x_max)\n    ? $$.isTimeSeries()\n      ? this.parseDate(config.axis_x_max)\n      : config.axis_x_max\n    : $$.d3.max(targets, function(t) {\n        return $$.d3.max(t.values, function(v) {\n          return v.x\n        })\n      })\n};\nChartInternal.prototype.getXDomainPadding = function(domain) {\n  var $$ = this,\n    config = $$.config,\n    diff = domain[1] - domain[0],\n    maxDataCount,\n    padding,\n    paddingLeft,\n    paddingRight;\n  if ($$.isCategorized()) {\n    padding = 0;\n  } else if ($$.hasType('bar')) {\n    maxDataCount = $$.getMaxDataCount();\n    padding = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : 0.5;\n  } else {\n    padding = diff * 0.01;\n  }\n  if (\n    typeof config.axis_x_padding === 'object' &&\n    notEmpty(config.axis_x_padding)\n  ) {\n    paddingLeft = isValue(config.axis_x_padding.left)\n      ? config.axis_x_padding.left\n      : padding;\n    paddingRight = isValue(config.axis_x_padding.right)\n      ? config.axis_x_padding.right\n      : padding;\n  } else if (typeof config.axis_x_padding === 'number') {\n    paddingLeft = paddingRight = config.axis_x_padding;\n  } else {\n    paddingLeft = paddingRight = padding;\n  }\n  return { left: paddingLeft, right: paddingRight }\n};\nChartInternal.prototype.getXDomain = function(targets) {\n  var $$ = this,\n    xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)],\n    firstX = xDomain[0],\n    lastX = xDomain[1],\n    padding = $$.getXDomainPadding(xDomain),\n    min = 0,\n    max = 0;\n  // show center of x domain if min and max are the same\n  if (firstX - lastX === 0 && !$$.isCategorized()) {\n    if ($$.isTimeSeries()) {\n      firstX = new Date(firstX.getTime() * 0.5);\n      lastX = new Date(lastX.getTime() * 1.5);\n    } else {\n      firstX = firstX === 0 ? 1 : firstX * 0.5;\n      lastX = lastX === 0 ? -1 : lastX * 1.5;\n    }\n  }\n  if (firstX || firstX === 0) {\n    min = $$.isTimeSeries()\n      ? new Date(firstX.getTime() - padding.left)\n      : firstX - padding.left;\n  }\n  if (lastX || lastX === 0) {\n    max = $$.isTimeSeries()\n      ? new Date(lastX.getTime() + padding.right)\n      : lastX + padding.right;\n  }\n  return [min, max]\n};\nChartInternal.prototype.updateXDomain = function(\n  targets,\n  withUpdateXDomain,\n  withUpdateOrgXDomain,\n  withTrim,\n  domain\n) {\n  var $$ = this,\n    config = $$.config;\n\n  if (withUpdateOrgXDomain) {\n    $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets)));\n    $$.orgXDomain = $$.x.domain();\n    if (config.zoom_enabled) {\n      $$.zoom.update();\n    }\n    $$.subX.domain($$.x.domain());\n    if ($$.brush) {\n      $$.brush.updateScale($$.subX);\n    }\n  }\n  if (withUpdateXDomain) {\n    $$.x.domain(\n      domain\n        ? domain\n        : !$$.brush || $$.brush.empty()\n        ? $$.orgXDomain\n        : $$.brush.selectionAsValue()\n    );\n  }\n\n  // Trim domain when too big by zoom mousemove event\n  if (withTrim) {\n    $$.x.domain($$.trimXDomain($$.x.orgDomain()));\n  }\n\n  return $$.x.domain()\n};\nChartInternal.prototype.trimXDomain = function(domain) {\n  var zoomDomain = this.getZoomDomain(),\n    min = zoomDomain[0],\n    max = zoomDomain[1];\n  if (domain[0] <= min) {\n    domain[1] = +domain[1] + (min - domain[0]);\n    domain[0] = min;\n  }\n  if (max <= domain[1]) {\n    domain[0] = +domain[0] - (domain[1] - max);\n    domain[1] = max;\n  }\n  return domain\n};\n\nChartInternal.prototype.drag = function(mouse) {\n  var $$ = this,\n    config = $$.config,\n    main = $$.main,\n    d3 = $$.d3;\n  var sx, sy, mx, my, minX, maxX, minY, maxY;\n\n  if ($$.hasArcType()) {\n    return\n  }\n  if (!config.data_selection_enabled) {\n    return\n  } // do nothing if not selectable\n  if (!config.data_selection_multiple) {\n    return\n  } // skip when single selection because drag is used for multiple selection\n\n  sx = $$.dragStart[0];\n  sy = $$.dragStart[1];\n  mx = mouse[0];\n  my = mouse[1];\n  minX = Math.min(sx, mx);\n  maxX = Math.max(sx, mx);\n  minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my);\n  maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my);\n\n  main\n    .select('.' + CLASS.dragarea)\n    .attr('x', minX)\n    .attr('y', minY)\n    .attr('width', maxX - minX)\n    .attr('height', maxY - minY);\n  // TODO: binary search when multiple xs\n  main\n    .selectAll('.' + CLASS.shapes)\n    .selectAll('.' + CLASS.shape)\n    .each(function(d, i) {\n      if (!config.data_selection_isselectable(d)) {\n        return\n      }\n      var shape = d3.select(this),\n        isSelected = shape.classed(CLASS.SELECTED),\n        isIncluded = shape.classed(CLASS.INCLUDED),\n        _x,\n        _y,\n        _w,\n        _h,\n        toggle,\n        isWithin = false,\n        box;\n      if (shape.classed(CLASS.circle)) {\n        _x = shape.attr('cx') * 1;\n        _y = shape.attr('cy') * 1;\n        toggle = $$.togglePoint;\n        isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY;\n      } else if (shape.classed(CLASS.bar)) {\n        box = getPathBox(this);\n        _x = box.x;\n        _y = box.y;\n        _w = box.width;\n        _h = box.height;\n        toggle = $$.togglePath;\n        isWithin =\n          !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY);\n      } else {\n        // line/area selection not supported yet\n        return\n      }\n      if (isWithin ^ isIncluded) {\n        shape.classed(CLASS.INCLUDED, !isIncluded);\n        // TODO: included/unincluded callback here\n        shape.classed(CLASS.SELECTED, !isSelected);\n        toggle.call($$, !isSelected, shape, d, i);\n      }\n    });\n};\n\nChartInternal.prototype.dragstart = function(mouse) {\n  var $$ = this,\n    config = $$.config;\n  if ($$.hasArcType()) {\n    return\n  }\n  if (!config.data_selection_enabled) {\n    return\n  } // do nothing if not selectable\n  $$.dragStart = mouse;\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('rect')\n    .attr('class', CLASS.dragarea)\n    .style('opacity', 0.1);\n  $$.dragging = true;\n};\n\nChartInternal.prototype.dragend = function() {\n  var $$ = this,\n    config = $$.config;\n  if ($$.hasArcType()) {\n    return\n  }\n  if (!config.data_selection_enabled) {\n    return\n  } // do nothing if not selectable\n  $$.main\n    .select('.' + CLASS.dragarea)\n    .transition()\n    .duration(100)\n    .style('opacity', 0)\n    .remove();\n  $$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false);\n  $$.dragging = false;\n};\n\nChartInternal.prototype.getYFormat = function(forArc) {\n  var $$ = this,\n    formatForY =\n      forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat,\n    formatForY2 =\n      forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format;\n  return function(v, ratio, id) {\n    var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY;\n    return format.call($$, v, ratio)\n  }\n};\nChartInternal.prototype.yFormat = function(v) {\n  var $$ = this,\n    config = $$.config,\n    format = config.axis_y_tick_format\n      ? config.axis_y_tick_format\n      : $$.defaultValueFormat;\n  return format(v)\n};\nChartInternal.prototype.y2Format = function(v) {\n  var $$ = this,\n    config = $$.config,\n    format = config.axis_y2_tick_format\n      ? config.axis_y2_tick_format\n      : $$.defaultValueFormat;\n  return format(v)\n};\nChartInternal.prototype.defaultValueFormat = function(v) {\n  return isValue(v) ? +v : ''\n};\nChartInternal.prototype.defaultArcValueFormat = function(v, ratio) {\n  return (ratio * 100).toFixed(1) + '%'\n};\nChartInternal.prototype.dataLabelFormat = function(targetId) {\n  var $$ = this,\n    data_labels = $$.config.data_labels,\n    format,\n    defaultFormat = function(v) {\n      return isValue(v) ? +v : ''\n    };\n  // find format according to axis id\n  if (typeof data_labels.format === 'function') {\n    format = data_labels.format;\n  } else if (typeof data_labels.format === 'object') {\n    if (data_labels.format[targetId]) {\n      format =\n        data_labels.format[targetId] === true\n          ? defaultFormat\n          : data_labels.format[targetId];\n    } else {\n      format = function() {\n        return ''\n      };\n    }\n  } else {\n    format = defaultFormat;\n  }\n  return format\n};\n\nChartInternal.prototype.initGrid = function() {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3;\n  $$.grid = $$.main\n    .append('g')\n    .attr('clip-path', $$.clipPathForGrid)\n    .attr('class', CLASS.grid);\n  if (config.grid_x_show) {\n    $$.grid.append('g').attr('class', CLASS.xgrids);\n  }\n  if (config.grid_y_show) {\n    $$.grid.append('g').attr('class', CLASS.ygrids);\n  }\n  if (config.grid_focus_show) {\n    $$.grid\n      .append('g')\n      .attr('class', CLASS.xgridFocus)\n      .append('line')\n      .attr('class', CLASS.xgridFocus);\n  }\n  $$.xgrid = d3.selectAll([]);\n  if (!config.grid_lines_front) {\n    $$.initGridLines();\n  }\n};\nChartInternal.prototype.initGridLines = function() {\n  var $$ = this,\n    d3 = $$.d3;\n  $$.gridLines = $$.main\n    .append('g')\n    .attr('clip-path', $$.clipPathForGrid)\n    .attr('class', CLASS.grid + ' ' + CLASS.gridLines);\n  $$.gridLines.append('g').attr('class', CLASS.xgridLines);\n  $$.gridLines.append('g').attr('class', CLASS.ygridLines);\n  $$.xgridLines = d3.selectAll([]);\n};\nChartInternal.prototype.updateXGrid = function(withoutUpdate) {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3,\n    xgridData = $$.generateGridData(config.grid_x_type, $$.x),\n    tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0;\n\n  $$.xgridAttr = config.axis_rotated\n    ? {\n        x1: 0,\n        x2: $$.width,\n        y1: function(d) {\n          return $$.x(d) - tickOffset\n        },\n        y2: function(d) {\n          return $$.x(d) - tickOffset\n        }\n      }\n    : {\n        x1: function(d) {\n          return $$.x(d) + tickOffset\n        },\n        x2: function(d) {\n          return $$.x(d) + tickOffset\n        },\n        y1: 0,\n        y2: $$.height\n      };\n  $$.xgridAttr.opacity = function() {\n    var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1');\n    return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1\n  };\n\n  var xgrid = $$.main\n    .select('.' + CLASS.xgrids)\n    .selectAll('.' + CLASS.xgrid)\n    .data(xgridData);\n  var xgridEnter = xgrid\n    .enter()\n    .append('line')\n    .attr('class', CLASS.xgrid)\n    .attr('x1', $$.xgridAttr.x1)\n    .attr('x2', $$.xgridAttr.x2)\n    .attr('y1', $$.xgridAttr.y1)\n    .attr('y2', $$.xgridAttr.y2)\n    .style('opacity', 0);\n  $$.xgrid = xgridEnter.merge(xgrid);\n  if (!withoutUpdate) {\n    $$.xgrid\n      .attr('x1', $$.xgridAttr.x1)\n      .attr('x2', $$.xgridAttr.x2)\n      .attr('y1', $$.xgridAttr.y1)\n      .attr('y2', $$.xgridAttr.y2)\n      .style('opacity', $$.xgridAttr.opacity);\n  }\n  xgrid.exit().remove();\n};\n\nChartInternal.prototype.updateYGrid = function() {\n  var $$ = this,\n    config = $$.config,\n    gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks);\n  var ygrid = $$.main\n    .select('.' + CLASS.ygrids)\n    .selectAll('.' + CLASS.ygrid)\n    .data(gridValues);\n  var ygridEnter = ygrid\n    .enter()\n    .append('line')\n    // TODO: x1, x2, y1, y2, opacity need to be set here maybe\n    .attr('class', CLASS.ygrid);\n  $$.ygrid = ygridEnter.merge(ygrid);\n  $$.ygrid\n    .attr('x1', config.axis_rotated ? $$.y : 0)\n    .attr('x2', config.axis_rotated ? $$.y : $$.width)\n    .attr('y1', config.axis_rotated ? 0 : $$.y)\n    .attr('y2', config.axis_rotated ? $$.height : $$.y);\n  ygrid.exit().remove();\n  $$.smoothLines($$.ygrid, 'grid');\n};\n\nChartInternal.prototype.gridTextAnchor = function(d) {\n  return d.position ? d.position : 'end'\n};\nChartInternal.prototype.gridTextDx = function(d) {\n  return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4\n};\nChartInternal.prototype.xGridTextX = function(d) {\n  return d.position === 'start'\n    ? -this.height\n    : d.position === 'middle'\n    ? -this.height / 2\n    : 0\n};\nChartInternal.prototype.yGridTextX = function(d) {\n  return d.position === 'start'\n    ? 0\n    : d.position === 'middle'\n    ? this.width / 2\n    : this.width\n};\nChartInternal.prototype.updateGrid = function(duration) {\n  var $$ = this,\n    main = $$.main,\n    config = $$.config,\n    xgridLine,\n    xgridLineEnter,\n    ygridLine,\n    ygridLineEnter,\n    xv = $$.xv.bind($$),\n    yv = $$.yv.bind($$),\n    xGridTextX = $$.xGridTextX.bind($$),\n    yGridTextX = $$.yGridTextX.bind($$);\n\n  // hide if arc type\n  $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');\n\n  main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden');\n  if (config.grid_x_show) {\n    $$.updateXGrid();\n  }\n  xgridLine = main\n    .select('.' + CLASS.xgridLines)\n    .selectAll('.' + CLASS.xgridLine)\n    .data(config.grid_x_lines);\n  // enter\n  xgridLineEnter = xgridLine\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : '')\n    });\n  xgridLineEnter\n    .append('line')\n    .attr('x1', config.axis_rotated ? 0 : xv)\n    .attr('x2', config.axis_rotated ? $$.width : xv)\n    .attr('y1', config.axis_rotated ? xv : 0)\n    .attr('y2', config.axis_rotated ? xv : $$.height)\n    .style('opacity', 0);\n  xgridLineEnter\n    .append('text')\n    .attr('text-anchor', $$.gridTextAnchor)\n    .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\n    .attr('x', config.axis_rotated ? yGridTextX : xGridTextX)\n    .attr('y', xv)\n    .attr('dx', $$.gridTextDx)\n    .attr('dy', -5)\n    .style('opacity', 0);\n  // udpate\n  $$.xgridLines = xgridLineEnter.merge(xgridLine);\n  // done in d3.transition() of the end of this function\n  // exit\n  xgridLine\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove();\n\n  // Y-Grid\n  if (config.grid_y_show) {\n    $$.updateYGrid();\n  }\n  ygridLine = main\n    .select('.' + CLASS.ygridLines)\n    .selectAll('.' + CLASS.ygridLine)\n    .data(config.grid_y_lines);\n  // enter\n  ygridLineEnter = ygridLine\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : '')\n    });\n  ygridLineEnter\n    .append('line')\n    .attr('x1', config.axis_rotated ? yv : 0)\n    .attr('x2', config.axis_rotated ? yv : $$.width)\n    .attr('y1', config.axis_rotated ? 0 : yv)\n    .attr('y2', config.axis_rotated ? $$.height : yv)\n    .style('opacity', 0);\n  ygridLineEnter\n    .append('text')\n    .attr('text-anchor', $$.gridTextAnchor)\n    .attr('transform', config.axis_rotated ? 'rotate(-90)' : '')\n    .attr('x', config.axis_rotated ? xGridTextX : yGridTextX)\n    .attr('y', yv)\n    .attr('dx', $$.gridTextDx)\n    .attr('dy', -5)\n    .style('opacity', 0);\n  // update\n  $$.ygridLines = ygridLineEnter.merge(ygridLine);\n  $$.ygridLines\n    .select('line')\n    .transition()\n    .duration(duration)\n    .attr('x1', config.axis_rotated ? yv : 0)\n    .attr('x2', config.axis_rotated ? yv : $$.width)\n    .attr('y1', config.axis_rotated ? 0 : yv)\n    .attr('y2', config.axis_rotated ? $$.height : yv)\n    .style('opacity', 1);\n  $$.ygridLines\n    .select('text')\n    .transition()\n    .duration(duration)\n    .attr(\n      'x',\n      config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)\n    )\n    .attr('y', yv)\n    .text(function(d) {\n      return d.text\n    })\n    .style('opacity', 1);\n  // exit\n  ygridLine\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove();\n};\nChartInternal.prototype.redrawGrid = function(withTransition, transition) {\n  var $$ = this,\n    config = $$.config,\n    xv = $$.xv.bind($$),\n    lines = $$.xgridLines.select('line'),\n    texts = $$.xgridLines.select('text');\n  return [\n    (withTransition ? lines.transition(transition) : lines)\n      .attr('x1', config.axis_rotated ? 0 : xv)\n      .attr('x2', config.axis_rotated ? $$.width : xv)\n      .attr('y1', config.axis_rotated ? xv : 0)\n      .attr('y2', config.axis_rotated ? xv : $$.height)\n      .style('opacity', 1),\n    (withTransition ? texts.transition(transition) : texts)\n      .attr(\n        'x',\n        config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)\n      )\n      .attr('y', xv)\n      .text(function(d) {\n        return d.text\n      })\n      .style('opacity', 1)\n  ]\n};\nChartInternal.prototype.showXGridFocus = function(selectedData) {\n  var $$ = this,\n    config = $$.config,\n    dataToShow = selectedData.filter(function(d) {\n      return d && isValue(d.value)\n    }),\n    focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus),\n    xx = $$.xx.bind($$);\n  if (!config.tooltip_show) {\n    return\n  }\n  // Hide when stanford plot exists\n  if ($$.hasType('stanford') || $$.hasArcType()) {\n    return\n  }\n  focusEl\n    .style('visibility', 'visible')\n    .data([dataToShow[0]])\n    .attr(config.axis_rotated ? 'y1' : 'x1', xx)\n    .attr(config.axis_rotated ? 'y2' : 'x2', xx);\n  $$.smoothLines(focusEl, 'grid');\n};\nChartInternal.prototype.hideXGridFocus = function() {\n  this.main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden');\n};\nChartInternal.prototype.updateXgridFocus = function() {\n  var $$ = this,\n    config = $$.config;\n  $$.main\n    .select('line.' + CLASS.xgridFocus)\n    .attr('x1', config.axis_rotated ? 0 : -10)\n    .attr('x2', config.axis_rotated ? $$.width : -10)\n    .attr('y1', config.axis_rotated ? -10 : 0)\n    .attr('y2', config.axis_rotated ? -10 : $$.height);\n};\nChartInternal.prototype.generateGridData = function(type, scale) {\n  var $$ = this,\n    gridData = [],\n    xDomain,\n    firstYear,\n    lastYear,\n    i,\n    tickNum = $$.main\n      .select('.' + CLASS.axisX)\n      .selectAll('.tick')\n      .size();\n  if (type === 'year') {\n    xDomain = $$.getXDomain();\n    firstYear = xDomain[0].getFullYear();\n    lastYear = xDomain[1].getFullYear();\n    for (i = firstYear; i <= lastYear; i++) {\n      gridData.push(new Date(i + '-01-01 00:00:00'));\n    }\n  } else {\n    gridData = scale.ticks(10);\n    if (gridData.length > tickNum) {\n      // use only int\n      gridData = gridData.filter(function(d) {\n        return ('' + d).indexOf('.') < 0\n      });\n    }\n  }\n  return gridData\n};\nChartInternal.prototype.getGridFilterToRemove = function(params) {\n  return params\n    ? function(line) {\n        var found = false\n        ;[].concat(params).forEach(function(param) {\n          if (\n            ('value' in param && line.value === param.value) ||\n            ('class' in param && line['class'] === param['class'])\n          ) {\n            found = true;\n          }\n        });\n        return found\n      }\n    : function() {\n        return true\n      }\n};\nChartInternal.prototype.removeGridLines = function(params, forX) {\n  var $$ = this,\n    config = $$.config,\n    toRemove = $$.getGridFilterToRemove(params),\n    toShow = function(line) {\n      return !toRemove(line)\n    },\n    classLines = forX ? CLASS.xgridLines : CLASS.ygridLines,\n    classLine = forX ? CLASS.xgridLine : CLASS.ygridLine;\n  $$.main\n    .select('.' + classLines)\n    .selectAll('.' + classLine)\n    .filter(toRemove)\n    .transition()\n    .duration(config.transition_duration)\n    .style('opacity', 0)\n    .remove();\n  if (forX) {\n    config.grid_x_lines = config.grid_x_lines.filter(toShow);\n  } else {\n    config.grid_y_lines = config.grid_y_lines.filter(toShow);\n  }\n};\n\nChartInternal.prototype.initEventRect = function() {\n  var $$ = this,\n    config = $$.config;\n\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.eventRects)\n    .style('fill-opacity', 0);\n  $$.eventRect = $$.main\n    .select('.' + CLASS.eventRects)\n    .append('rect')\n    .attr('class', CLASS.eventRect);\n\n  // event rect handle zoom event as well\n  if (config.zoom_enabled && $$.zoom) {\n    $$.eventRect.call($$.zoom).on('dblclick.zoom', null);\n    if (config.zoom_initialRange) {\n      // WORKAROUND: Add transition to apply transform immediately when no subchart\n      $$.eventRect\n        .transition()\n        .duration(0)\n        .call($$.zoom.transform, $$.zoomTransform(config.zoom_initialRange));\n    }\n  }\n};\nChartInternal.prototype.redrawEventRect = function() {\n  const $$ = this,\n    d3 = $$.d3,\n    config = $$.config;\n\n  function mouseout() {\n    $$.svg.select('.' + CLASS.eventRect).style('cursor', null);\n    $$.hideXGridFocus();\n    $$.hideTooltip();\n    $$.unexpandCircles();\n    $$.unexpandBars();\n  }\n\n  const isHoveringDataPoint = (mouse, closest) =>\n    closest &&\n    ($$.isBarType(closest.id) ||\n      $$.dist(closest, mouse) < config.point_sensitivity);\n\n  const withName = d => (d ? $$.addName(Object.assign({}, d)) : null);\n\n  // rects for mouseover\n  $$.main\n    .select('.' + CLASS.eventRects)\n    .style(\n      'cursor',\n      config.zoom_enabled\n        ? config.axis_rotated\n          ? 'ns-resize'\n          : 'ew-resize'\n        : null\n    );\n\n  $$.eventRect\n    .attr('x', 0)\n    .attr('y', 0)\n    .attr('width', $$.width)\n    .attr('height', $$.height)\n    .on(\n      'mouseout',\n      config.interaction_enabled\n        ? function() {\n            if (!config) {\n              return\n            } // chart is destroyed\n            if ($$.hasArcType()) {\n              return\n            }\n            if ($$.mouseover) {\n              config.data_onmouseout.call($$.api, $$.mouseover);\n              $$.mouseover = undefined;\n            }\n            mouseout();\n          }\n        : null\n    )\n    .on(\n      'mousemove',\n      config.interaction_enabled\n        ? function() {\n            // do nothing when dragging\n            if ($$.dragging) {\n              return\n            }\n\n            const targetsToShow = $$.getTargetsToShow();\n\n            // do nothing if arc type\n            if ($$.hasArcType(targetsToShow)) {\n              return\n            }\n\n            const mouse = d3.mouse(this);\n            const closest = withName(\n              $$.findClosestFromTargets(targetsToShow, mouse)\n            );\n            const isMouseCloseToDataPoint = isHoveringDataPoint(mouse, closest);\n\n            // ensure onmouseout is always called if mousemove switch between 2 targets\n            if (\n              $$.mouseover &&\n              (!closest ||\n                closest.id !== $$.mouseover.id ||\n                closest.index !== $$.mouseover.index)\n            ) {\n              config.data_onmouseout.call($$.api, $$.mouseover);\n              $$.mouseover = undefined;\n            }\n            if (closest && !$$.mouseover) {\n              config.data_onmouseover.call($$.api, closest);\n              $$.mouseover = closest;\n            }\n\n            // show cursor as pointer if we're hovering a data point close enough\n            $$.svg\n              .select('.' + CLASS.eventRect)\n              .style('cursor', isMouseCloseToDataPoint ? 'pointer' : null);\n\n            // if tooltip not grouped, we want to display only data from closest data point\n            const showSingleDataPoint =\n              !config.tooltip_grouped || $$.hasType('stanford', targetsToShow);\n\n            // find data to highlight\n            let selectedData;\n            if (showSingleDataPoint) {\n              if (closest) {\n                selectedData = [closest];\n              }\n            } else {\n              let closestByX;\n              if (closest) {\n                // reuse closest value\n                closestByX = closest;\n              } else {\n                // try to find the closest value by X values from the mouse position\n                const mouseX = config.axis_rotated ? mouse[1] : mouse[0];\n                closestByX = $$.findClosestFromTargetsByX(\n                  targetsToShow,\n                  $$.x.invert(mouseX)\n                );\n              }\n\n              // highlight all data for this 'x' value\n              if (closestByX) {\n                selectedData = $$.filterByX(targetsToShow, closestByX.x);\n              }\n            }\n\n            // ensure we have data to show\n            if (!selectedData || selectedData.length === 0) {\n              return mouseout()\n            }\n\n            // inject names for each point\n            selectedData = selectedData.map(withName);\n\n            // show tooltip\n            $$.showTooltip(selectedData, this);\n\n            // expand points\n            if (config.point_focus_expand_enabled) {\n              $$.unexpandCircles();\n              selectedData.forEach(function(d) {\n                $$.expandCircles(d.index, d.id, false);\n              });\n            }\n\n            // expand bars\n            $$.unexpandBars();\n            selectedData.forEach(function(d) {\n              $$.expandBars(d.index, d.id, false);\n            });\n\n            // Show xgrid focus line\n            $$.showXGridFocus(selectedData);\n          }\n        : null\n    )\n    .on(\n      'click',\n      config.interaction_enabled\n        ? function() {\n            const targetsToShow = $$.getTargetsToShow();\n\n            if ($$.hasArcType(targetsToShow)) {\n              return\n            }\n\n            const mouse = d3.mouse(this);\n            const closest = withName(\n              $$.findClosestFromTargets(targetsToShow, mouse)\n            );\n\n            if (!isHoveringDataPoint(mouse, closest)) {\n              return\n            }\n\n            // select if selection enabled\n            let sameXData;\n            if (!config.data_selection_grouped || $$.isStanfordType(closest)) {\n              sameXData = [closest];\n            } else {\n              sameXData = $$.filterByX(targetsToShow, closest.x);\n            }\n\n            // toggle selected state\n            sameXData.forEach(function(d) {\n              $$.main\n                .selectAll(\n                  '.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id)\n                )\n                .selectAll('.' + CLASS.shape + '-' + d.index)\n                .each(function() {\n                  if (\n                    config.data_selection_grouped ||\n                    $$.isWithinShape(this, d)\n                  ) {\n                    $$.toggleShape(this, d, d.index);\n                  }\n                });\n            });\n\n            // call data_onclick on the closest data point\n            if (closest) {\n              const shape = $$.main\n                .selectAll(\n                  '.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id)\n                )\n                .select('.' + CLASS.shape + '-' + closest.index);\n              config.data_onclick.call($$.api, closest, shape.node());\n            }\n          }\n        : null\n    )\n    .call(\n      config.interaction_enabled && config.data_selection_draggable && $$.drag\n        ? d3\n            .drag()\n            .on('drag', function() {\n              $$.drag(d3.mouse(this));\n            })\n            .on('start', function() {\n              $$.dragstart(d3.mouse(this));\n            })\n            .on('end', function() {\n              $$.dragend();\n            })\n        : function() {}\n    );\n};\nChartInternal.prototype.getMousePosition = function(data) {\n  var $$ = this;\n  return [$$.x(data.x), $$.getYScale(data.id)(data.value)]\n};\nChartInternal.prototype.dispatchEvent = function(type, mouse) {\n  var $$ = this,\n    selector = '.' + CLASS.eventRect,\n    eventRect = $$.main.select(selector).node(),\n    box = eventRect.getBoundingClientRect(),\n    x = box.left + (mouse ? mouse[0] : 0),\n    y = box.top + (mouse ? mouse[1] : 0),\n    event = document.createEvent('MouseEvents');\n\n  event.initMouseEvent(\n    type,\n    true,\n    true,\n    window,\n    0,\n    x,\n    y,\n    x,\n    y,\n    false,\n    false,\n    false,\n    false,\n    0,\n    null\n  );\n  eventRect.dispatchEvent(event);\n};\n\nChartInternal.prototype.initLegend = function() {\n  var $$ = this;\n  $$.legendItemTextBox = {};\n  $$.legendHasRendered = false;\n  $$.legend = $$.svg.append('g').attr('transform', $$.getTranslate('legend'));\n  if (!$$.config.legend_show) {\n    $$.legend.style('visibility', 'hidden');\n    $$.hiddenLegendIds = $$.mapToIds($$.data.targets);\n    return\n  }\n  // MEMO: call here to update legend box and tranlate for all\n  // MEMO: translate will be updated by this, so transform not needed in updateLegend()\n  $$.updateLegendWithDefaults();\n};\nChartInternal.prototype.updateLegendWithDefaults = function() {\n  var $$ = this;\n  $$.updateLegend($$.mapToIds($$.data.targets), {\n    withTransform: false,\n    withTransitionForTransform: false,\n    withTransition: false\n  });\n};\nChartInternal.prototype.updateSizeForLegend = function(\n  legendHeight,\n  legendWidth\n) {\n  var $$ = this,\n    config = $$.config,\n    insetLegendPosition = {\n      top: $$.isLegendTop\n        ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5\n        : $$.currentHeight -\n          legendHeight -\n          $$.getCurrentPaddingBottom() -\n          config.legend_inset_y,\n      left: $$.isLegendLeft\n        ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5\n        : $$.currentWidth -\n          legendWidth -\n          $$.getCurrentPaddingRight() -\n          config.legend_inset_x +\n          0.5\n    };\n\n  $$.margin3 = {\n    top: $$.isLegendRight\n      ? 0\n      : $$.isLegendInset\n      ? insetLegendPosition.top\n      : $$.currentHeight - legendHeight,\n    right: NaN,\n    bottom: 0,\n    left: $$.isLegendRight\n      ? $$.currentWidth - legendWidth\n      : $$.isLegendInset\n      ? insetLegendPosition.left\n      : 0\n  };\n};\nChartInternal.prototype.transformLegend = function(withTransition) {\n  var $$ = this\n  ;(withTransition ? $$.legend.transition() : $$.legend).attr(\n    'transform',\n    $$.getTranslate('legend')\n  );\n};\nChartInternal.prototype.updateLegendStep = function(step) {\n  this.legendStep = step;\n};\nChartInternal.prototype.updateLegendItemWidth = function(w) {\n  this.legendItemWidth = w;\n};\nChartInternal.prototype.updateLegendItemHeight = function(h) {\n  this.legendItemHeight = h;\n};\nChartInternal.prototype.getLegendWidth = function() {\n  var $$ = this;\n  return $$.config.legend_show\n    ? $$.isLegendRight || $$.isLegendInset\n      ? $$.legendItemWidth * ($$.legendStep + 1)\n      : $$.currentWidth\n    : 0\n};\nChartInternal.prototype.getLegendHeight = function() {\n  var $$ = this,\n    h = 0;\n  if ($$.config.legend_show) {\n    if ($$.isLegendRight) {\n      h = $$.currentHeight;\n    } else {\n      h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1);\n    }\n  }\n  return h\n};\nChartInternal.prototype.opacityForLegend = function(legendItem) {\n  return legendItem.classed(CLASS.legendItemHidden) ? null : 1\n};\nChartInternal.prototype.opacityForUnfocusedLegend = function(legendItem) {\n  return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3\n};\nChartInternal.prototype.toggleFocusLegend = function(targetIds, focus) {\n  var $$ = this;\n  targetIds = $$.mapToTargetIds(targetIds);\n  $$.legend\n    .selectAll('.' + CLASS.legendItem)\n    .filter(function(id) {\n      return targetIds.indexOf(id) >= 0\n    })\n    .classed(CLASS.legendItemFocused, focus)\n    .transition()\n    .duration(100)\n    .style('opacity', function() {\n      var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend;\n      return opacity.call($$, $$.d3.select(this))\n    });\n};\nChartInternal.prototype.revertLegend = function() {\n  var $$ = this,\n    d3 = $$.d3;\n  $$.legend\n    .selectAll('.' + CLASS.legendItem)\n    .classed(CLASS.legendItemFocused, false)\n    .transition()\n    .duration(100)\n    .style('opacity', function() {\n      return $$.opacityForLegend(d3.select(this))\n    });\n};\nChartInternal.prototype.showLegend = function(targetIds) {\n  var $$ = this,\n    config = $$.config;\n  if (!config.legend_show) {\n    config.legend_show = true;\n    $$.legend.style('visibility', 'visible');\n    if (!$$.legendHasRendered) {\n      $$.updateLegendWithDefaults();\n    }\n  }\n  $$.removeHiddenLegendIds(targetIds);\n  $$.legend\n    .selectAll($$.selectorLegends(targetIds))\n    .style('visibility', 'visible')\n    .transition()\n    .style('opacity', function() {\n      return $$.opacityForLegend($$.d3.select(this))\n    });\n};\nChartInternal.prototype.hideLegend = function(targetIds) {\n  var $$ = this,\n    config = $$.config;\n  if (config.legend_show && isEmpty(targetIds)) {\n    config.legend_show = false;\n    $$.legend.style('visibility', 'hidden');\n  }\n  $$.addHiddenLegendIds(targetIds);\n  $$.legend\n    .selectAll($$.selectorLegends(targetIds))\n    .style('opacity', 0)\n    .style('visibility', 'hidden');\n};\nChartInternal.prototype.clearLegendItemTextBoxCache = function() {\n  this.legendItemTextBox = {};\n};\nChartInternal.prototype.updateLegend = function(\n  targetIds,\n  options,\n  transitions\n) {\n  var $$ = this,\n    config = $$.config;\n  var xForLegend,\n    xForLegendText,\n    xForLegendRect,\n    yForLegend,\n    yForLegendText,\n    yForLegendRect,\n    x1ForLegendTile,\n    x2ForLegendTile,\n    yForLegendTile;\n  var paddingTop = 4,\n    paddingRight = 10,\n    maxWidth = 0,\n    maxHeight = 0,\n    posMin = 10,\n    tileWidth = config.legend_item_tile_width + 5;\n  var l,\n    totalLength = 0,\n    offsets = {},\n    widths = {},\n    heights = {},\n    margins = [0],\n    steps = {},\n    step = 0;\n  var withTransition, withTransitionForTransform;\n  var texts, rects, tiles, background;\n\n  // Skip elements when their name is set to null\n  targetIds = targetIds.filter(function(id) {\n    return !isDefined(config.data_names[id]) || config.data_names[id] !== null\n  });\n\n  options = options || {};\n  withTransition = getOption(options, 'withTransition', true);\n  withTransitionForTransform = getOption(\n    options,\n    'withTransitionForTransform',\n    true\n  );\n\n  function getTextBox(textElement, id) {\n    if (!$$.legendItemTextBox[id]) {\n      $$.legendItemTextBox[id] = $$.getTextRect(\n        textElement.textContent,\n        CLASS.legendItem,\n        textElement\n      );\n    }\n    return $$.legendItemTextBox[id]\n  }\n\n  function updatePositions(textElement, id, index) {\n    var reset = index === 0,\n      isLast = index === targetIds.length - 1,\n      box = getTextBox(textElement, id),\n      itemWidth =\n        box.width +\n        tileWidth +\n        (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) +\n        config.legend_padding,\n      itemHeight = box.height + paddingTop,\n      itemLength =\n        $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth,\n      areaLength =\n        $$.isLegendRight || $$.isLegendInset\n          ? $$.getLegendHeight()\n          : $$.getLegendWidth(),\n      margin,\n      maxLength;\n\n    // MEMO: care about condifion of step, totalLength\n    function updateValues(id, withoutStep) {\n      if (!withoutStep) {\n        margin = (areaLength - totalLength - itemLength) / 2;\n        if (margin < posMin) {\n          margin = (areaLength - itemLength) / 2;\n          totalLength = 0;\n          step++;\n        }\n      }\n      steps[id] = step;\n      margins[step] = $$.isLegendInset ? 10 : margin;\n      offsets[id] = totalLength;\n      totalLength += itemLength;\n    }\n\n    if (reset) {\n      totalLength = 0;\n      step = 0;\n      maxWidth = 0;\n      maxHeight = 0;\n    }\n\n    if (config.legend_show && !$$.isLegendToShow(id)) {\n      widths[id] = heights[id] = steps[id] = offsets[id] = 0;\n      return\n    }\n\n    widths[id] = itemWidth;\n    heights[id] = itemHeight;\n\n    if (!maxWidth || itemWidth >= maxWidth) {\n      maxWidth = itemWidth;\n    }\n    if (!maxHeight || itemHeight >= maxHeight) {\n      maxHeight = itemHeight;\n    }\n    maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth;\n\n    if (config.legend_equally) {\n      Object.keys(widths).forEach(function(id) {\n        widths[id] = maxWidth;\n      });\n      Object.keys(heights).forEach(function(id) {\n        heights[id] = maxHeight;\n      });\n      margin = (areaLength - maxLength * targetIds.length) / 2;\n      if (margin < posMin) {\n        totalLength = 0;\n        step = 0;\n        targetIds.forEach(function(id) {\n          updateValues(id);\n        });\n      } else {\n        updateValues(id, true);\n      }\n    } else {\n      updateValues(id);\n    }\n  }\n\n  if ($$.isLegendInset) {\n    step = config.legend_inset_step\n      ? config.legend_inset_step\n      : targetIds.length;\n    $$.updateLegendStep(step);\n  }\n\n  if ($$.isLegendRight) {\n    xForLegend = function(id) {\n      return maxWidth * steps[id]\n    };\n    yForLegend = function(id) {\n      return margins[steps[id]] + offsets[id]\n    };\n  } else if ($$.isLegendInset) {\n    xForLegend = function(id) {\n      return maxWidth * steps[id] + 10\n    };\n    yForLegend = function(id) {\n      return margins[steps[id]] + offsets[id]\n    };\n  } else {\n    xForLegend = function(id) {\n      return margins[steps[id]] + offsets[id]\n    };\n    yForLegend = function(id) {\n      return maxHeight * steps[id]\n    };\n  }\n  xForLegendText = function(id, i) {\n    return xForLegend(id, i) + 4 + config.legend_item_tile_width\n  };\n  yForLegendText = function(id, i) {\n    return yForLegend(id, i) + 9\n  };\n  xForLegendRect = function(id, i) {\n    return xForLegend(id, i)\n  };\n  yForLegendRect = function(id, i) {\n    return yForLegend(id, i) - 5\n  };\n  x1ForLegendTile = function(id, i) {\n    return xForLegend(id, i) - 2\n  };\n  x2ForLegendTile = function(id, i) {\n    return xForLegend(id, i) - 2 + config.legend_item_tile_width\n  };\n  yForLegendTile = function(id, i) {\n    return yForLegend(id, i) + 4\n  };\n\n  // Define g for legend area\n  l = $$.legend\n    .selectAll('.' + CLASS.legendItem)\n    .data(targetIds)\n    .enter()\n    .append('g')\n    .attr('class', function(id) {\n      return $$.generateClass(CLASS.legendItem, id)\n    })\n    .style('visibility', function(id) {\n      return $$.isLegendToShow(id) ? 'visible' : 'hidden'\n    })\n    .style('cursor', function() {\n      return config.interaction_enabled ? 'pointer' : 'auto'\n    })\n    .on(\n      'click',\n      config.interaction_enabled\n        ? function(id) {\n            if (config.legend_item_onclick) {\n              config.legend_item_onclick.call($$, id);\n            } else {\n              if ($$.d3.event.altKey) {\n                $$.api.hide();\n                $$.api.show(id);\n              } else {\n                $$.api.toggle(id);\n                $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert();\n              }\n            }\n          }\n        : null\n    )\n    .on(\n      'mouseover',\n      config.interaction_enabled\n        ? function(id) {\n            if (config.legend_item_onmouseover) {\n              config.legend_item_onmouseover.call($$, id);\n            } else {\n              $$.d3.select(this).classed(CLASS.legendItemFocused, true);\n              if (!$$.transiting && $$.isTargetToShow(id)) {\n                $$.api.focus(id);\n              }\n            }\n          }\n        : null\n    )\n    .on(\n      'mouseout',\n      config.interaction_enabled\n        ? function(id) {\n            if (config.legend_item_onmouseout) {\n              config.legend_item_onmouseout.call($$, id);\n            } else {\n              $$.d3.select(this).classed(CLASS.legendItemFocused, false);\n              $$.api.revert();\n            }\n          }\n        : null\n    );\n\n  l.append('text')\n    .text(function(id) {\n      return isDefined(config.data_names[id]) ? config.data_names[id] : id\n    })\n    .each(function(id, i) {\n      updatePositions(this, id, i);\n    })\n    .style('pointer-events', 'none')\n    .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200)\n    .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText);\n\n  l.append('rect')\n    .attr('class', CLASS.legendItemEvent)\n    .style('fill-opacity', 0)\n    .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200)\n    .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect);\n\n  l.append('line')\n    .attr('class', CLASS.legendItemTile)\n    .style('stroke', $$.color)\n    .style('pointer-events', 'none')\n    .attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200)\n    .attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile)\n    .attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200)\n    .attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile)\n    .attr('stroke-width', config.legend_item_tile_height);\n\n  // Set background for inset legend\n  background = $$.legend.select('.' + CLASS.legendBackground + ' rect');\n  if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) {\n    background = $$.legend\n      .insert('g', '.' + CLASS.legendItem)\n      .attr('class', CLASS.legendBackground)\n      .append('rect');\n  }\n\n  texts = $$.legend\n    .selectAll('text')\n    .data(targetIds)\n    .text(function(id) {\n      return isDefined(config.data_names[id]) ? config.data_names[id] : id\n    }) // MEMO: needed for update\n    .each(function(id, i) {\n      updatePositions(this, id, i);\n    })\n  ;(withTransition ? texts.transition() : texts)\n    .attr('x', xForLegendText)\n    .attr('y', yForLegendText);\n\n  rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent).data(targetIds)\n  ;(withTransition ? rects.transition() : rects)\n    .attr('width', function(id) {\n      return widths[id]\n    })\n    .attr('height', function(id) {\n      return heights[id]\n    })\n    .attr('x', xForLegendRect)\n    .attr('y', yForLegendRect);\n\n  tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile).data(targetIds)\n  ;(withTransition ? tiles.transition() : tiles)\n    .style(\n      'stroke',\n      $$.levelColor\n        ? function(id) {\n            return $$.levelColor(\n              $$.cache[id].values.reduce(function(total, item) {\n                return total + item.value\n              }, 0)\n            )\n          }\n        : $$.color\n    )\n    .attr('x1', x1ForLegendTile)\n    .attr('y1', yForLegendTile)\n    .attr('x2', x2ForLegendTile)\n    .attr('y2', yForLegendTile);\n\n  if (background) {\n(withTransition ? background.transition() : background)\n      .attr('height', $$.getLegendHeight() - 12)\n      .attr('width', maxWidth * (step + 1) + 10);\n  }\n\n  // toggle legend state\n  $$.legend\n    .selectAll('.' + CLASS.legendItem)\n    .classed(CLASS.legendItemHidden, function(id) {\n      return !$$.isTargetToShow(id)\n    });\n\n  // Update all to reflect change of legend\n  $$.updateLegendItemWidth(maxWidth);\n  $$.updateLegendItemHeight(maxHeight);\n  $$.updateLegendStep(step);\n  // Update size and scale\n  $$.updateSizes();\n  $$.updateScales();\n  $$.updateSvgSize();\n  // Update g positions\n  $$.transformAll(withTransitionForTransform, transitions);\n  $$.legendHasRendered = true;\n};\n\nChartInternal.prototype.initRegion = function() {\n  var $$ = this;\n  $$.region = $$.main\n    .append('g')\n    .attr('clip-path', $$.clipPath)\n    .attr('class', CLASS.regions);\n};\nChartInternal.prototype.updateRegion = function(duration) {\n  var $$ = this,\n    config = $$.config;\n\n  // hide if arc type\n  $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');\n\n  var mainRegion = $$.main\n    .select('.' + CLASS.regions)\n    .selectAll('.' + CLASS.region)\n    .data(config.regions);\n  var g = mainRegion.enter().append('g');\n  g.append('rect')\n    .attr('x', $$.regionX.bind($$))\n    .attr('y', $$.regionY.bind($$))\n    .attr('width', $$.regionWidth.bind($$))\n    .attr('height', $$.regionHeight.bind($$))\n    .style('fill-opacity', function(d) {\n      return isValue(d.opacity) ? d.opacity : 0.1\n    });\n  g.append('text').text($$.labelRegion.bind($$));\n  $$.mainRegion = g.merge(mainRegion).attr('class', $$.classRegion.bind($$));\n  mainRegion\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove();\n};\nChartInternal.prototype.redrawRegion = function(withTransition, transition) {\n  var $$ = this,\n    regions = $$.mainRegion,\n    regionLabels = $$.mainRegion.selectAll('text');\n  return [\n    (withTransition ? regions.transition(transition) : regions)\n      .attr('x', $$.regionX.bind($$))\n      .attr('y', $$.regionY.bind($$))\n      .attr('width', $$.regionWidth.bind($$))\n      .attr('height', $$.regionHeight.bind($$))\n      .style('fill-opacity', function(d) {\n        return isValue(d.opacity) ? d.opacity : 0.1\n      }),\n    (withTransition ? regionLabels.transition(transition) : regionLabels)\n      .attr('x', $$.labelOffsetX.bind($$))\n      .attr('y', $$.labelOffsetY.bind($$))\n      .attr('transform', $$.labelTransform.bind($$))\n      .attr('style', 'text-anchor: left;')\n  ]\n};\nChartInternal.prototype.regionX = function(d) {\n  var $$ = this,\n    config = $$.config,\n    xPos,\n    yScale = d.axis === 'y' ? $$.y : $$.y2;\n  if (d.axis === 'y' || d.axis === 'y2') {\n    xPos = config.axis_rotated ? ('start' in d ? yScale(d.start) : 0) : 0;\n  } else {\n    xPos = config.axis_rotated\n      ? 0\n      : 'start' in d\n      ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start)\n      : 0;\n  }\n  return xPos\n};\nChartInternal.prototype.regionY = function(d) {\n  var $$ = this,\n    config = $$.config,\n    yPos,\n    yScale = d.axis === 'y' ? $$.y : $$.y2;\n  if (d.axis === 'y' || d.axis === 'y2') {\n    yPos = config.axis_rotated ? 0 : 'end' in d ? yScale(d.end) : 0;\n  } else {\n    yPos = config.axis_rotated\n      ? 'start' in d\n        ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start)\n        : 0\n      : 0;\n  }\n  return yPos\n};\nChartInternal.prototype.regionWidth = function(d) {\n  var $$ = this,\n    config = $$.config,\n    start = $$.regionX(d),\n    end,\n    yScale = d.axis === 'y' ? $$.y : $$.y2;\n  if (d.axis === 'y' || d.axis === 'y2') {\n    end = config.axis_rotated\n      ? 'end' in d\n        ? yScale(d.end)\n        : $$.width\n      : $$.width;\n  } else {\n    end = config.axis_rotated\n      ? $$.width\n      : 'end' in d\n      ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end)\n      : $$.width;\n  }\n  return end < start ? 0 : end - start\n};\nChartInternal.prototype.regionHeight = function(d) {\n  var $$ = this,\n    config = $$.config,\n    start = this.regionY(d),\n    end,\n    yScale = d.axis === 'y' ? $$.y : $$.y2;\n  if (d.axis === 'y' || d.axis === 'y2') {\n    end = config.axis_rotated\n      ? $$.height\n      : 'start' in d\n      ? yScale(d.start)\n      : $$.height;\n  } else {\n    end = config.axis_rotated\n      ? 'end' in d\n        ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end)\n        : $$.height\n      : $$.height;\n  }\n  return end < start ? 0 : end - start\n};\nChartInternal.prototype.isRegionOnX = function(d) {\n  return !d.axis || d.axis === 'x'\n};\nChartInternal.prototype.labelRegion = function(d) {\n  return 'label' in d ? d.label : ''\n};\nChartInternal.prototype.labelTransform = function(d) {\n  return 'vertical' in d && d.vertical ? 'rotate(90)' : ''\n};\nChartInternal.prototype.labelOffsetX = function(d) {\n  var paddingX = 'paddingX' in d ? d.paddingX : 3;\n  var paddingY = 'paddingY' in d ? d.paddingY : 3;\n  return 'vertical' in d && d.vertical\n    ? this.regionY(d) + paddingY\n    : this.regionX(d) + paddingX\n};\nChartInternal.prototype.labelOffsetY = function(d) {\n  var paddingX = 'paddingX' in d ? d.paddingX : 3;\n  var paddingY = 'paddingY' in d ? d.paddingY : 3;\n  return 'vertical' in d && d.vertical\n    ? -(this.regionX(d) + paddingX)\n    : this.regionY(d) + 10 + paddingY\n};\n\nfunction c3LogScale(d3, linearScale, logScale) {\n  var PROJECTION = [0.01, 10];\n\n  if (!linearScale) {\n    linearScale = d3.scaleLinear();\n    linearScale.range(PROJECTION);\n  }\n\n  if (!logScale) {\n    logScale = d3.scaleLog();\n    logScale.domain(PROJECTION);\n    logScale.nice();\n  }\n\n  // copied from https://github.com/compute-io/logspace\n  function logspace(a, b, len) {\n    var arr, end, tmp, d;\n\n    if (arguments.length < 3) {\n      len = 10;\n    } else {\n      if (len === 0) {\n        return []\n      }\n    }\n    // Calculate the increment:\n    end = len - 1;\n    d = (b - a) / end;\n\n    // Build the output array...\n    arr = new Array(len);\n    tmp = a;\n    arr[0] = Math.pow(10, tmp);\n    for (var i = 1; i < end; i++) {\n      tmp += d;\n      arr[i] = Math.pow(10, tmp);\n    }\n    arr[end] = Math.pow(10, b);\n    return arr\n  }\n\n  function scale(x) {\n    return logScale(linearScale(x))\n  }\n\n  scale.domain = function(x) {\n    if (!arguments.length) {\n      return linearScale.domain()\n    }\n    linearScale.domain(x);\n    return scale\n  };\n\n  scale.range = function(x) {\n    if (!arguments.length) {\n      return logScale.range()\n    }\n    logScale.range(x);\n    return scale\n  };\n\n  scale.ticks = function(m) {\n    return logspace(-2, 1, m || 10).map(function(v) {\n      return linearScale.invert(v)\n    })\n  };\n\n  scale.copy = function() {\n    return c3LogScale(d3, linearScale.copy(), logScale.copy())\n  };\n\n  return scale\n}\n\nChartInternal.prototype.getScale = function(min, max, forTimeseries) {\n  return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([\n    min,\n    max\n  ])\n};\nChartInternal.prototype.getX = function(min, max, domain, offset) {\n  var $$ = this,\n    scale = $$.getScale(min, max, $$.isTimeSeries()),\n    _scale = domain ? scale.domain(domain) : scale,\n    key;\n  // Define customized scale if categorized axis\n  if ($$.isCategorized()) {\n    offset =\n      offset ||\n      function() {\n        return 0\n      };\n    scale = function(d, raw) {\n      var v = _scale(d) + offset(d);\n      return raw ? v : Math.ceil(v)\n    };\n  } else {\n    scale = function(d, raw) {\n      var v = _scale(d);\n      return raw ? v : Math.ceil(v)\n    };\n  }\n  // define functions\n  for (key in _scale) {\n    scale[key] = _scale[key];\n  }\n  scale.orgDomain = function() {\n    return _scale.domain()\n  };\n  // define custom domain() for categorized axis\n  if ($$.isCategorized()) {\n    scale.domain = function(domain) {\n      if (!arguments.length) {\n        domain = this.orgDomain();\n        return [domain[0], domain[1] + 1]\n      }\n      _scale.domain(domain);\n      return scale\n    };\n  }\n  return scale\n};\n\n/**\n * Creates and configures a D3 scale instance for the given type.\n *\n * By defaults it returns a Linear scale.\n *\n * @param {String} type Type of d3-scale to create. Type can be 'linear', 'time', 'timeseries' or 'log'.\n * @param {Array} domain The scale domain such as [from, to]\n * @param {Array} range The scale's range such as [from, to]\n *\n * @return A d3-scale instance\n */\nChartInternal.prototype.getY = function(type, domain, range) {\n  let scale;\n  if (type === 'timeseries' || type === 'time') {\n    scale = this.d3.scaleTime();\n  } else if (type === 'log') {\n    scale = c3LogScale(this.d3);\n  } else if (type === 'linear' || type === undefined) {\n    scale = this.d3.scaleLinear();\n  } else {\n    throw new Error(`Invalid Y axis type: \"${type}\"`)\n  }\n\n  if (domain) {\n    scale.domain(domain);\n  }\n\n  if (range) {\n    scale.range(range);\n  }\n\n  return scale\n};\nChartInternal.prototype.getYScale = function(id) {\n  return this.axis.getId(id) === 'y2' ? this.y2 : this.y\n};\nChartInternal.prototype.getSubYScale = function(id) {\n  return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY\n};\nChartInternal.prototype.updateScales = function() {\n  var $$ = this,\n    config = $$.config,\n    forInit = !$$.x;\n  // update edges\n  $$.xMin = config.axis_rotated ? 1 : 0;\n  $$.xMax = config.axis_rotated ? $$.height : $$.width;\n  $$.yMin = config.axis_rotated ? 0 : $$.height;\n  $$.yMax = config.axis_rotated ? $$.width : 1;\n  $$.subXMin = $$.xMin;\n  $$.subXMax = $$.xMax;\n  $$.subYMin = config.axis_rotated ? 0 : $$.height2;\n  $$.subYMax = config.axis_rotated ? $$.width2 : 1;\n  // update scales\n  $$.x = $$.getX(\n    $$.xMin,\n    $$.xMax,\n    forInit ? undefined : $$.x.orgDomain(),\n    function() {\n      return $$.xAxis.tickOffset()\n    }\n  );\n  $$.y = $$.getY(\n    config.axis_y_type,\n    forInit ? config.axis_y_default : $$.y.domain(),\n    [$$.yMin, $$.yMax]\n  );\n  $$.y2 = $$.getY(\n    config.axis_y2_type,\n    forInit ? config.axis_y2_default : $$.y2.domain(),\n    [$$.yMin, $$.yMax]\n  );\n  $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function(d) {\n    return d % 1 ? 0 : $$.subXAxis.tickOffset()\n  });\n  $$.subY = $$.getY(\n    config.axis_y_type,\n    forInit ? config.axis_y_default : $$.subY.domain(),\n    [$$.subYMin, $$.subYMax]\n  );\n  $$.subY2 = $$.getY(\n    config.axis_y2_type,\n    forInit ? config.axis_y2_default : $$.subY2.domain(),\n    [$$.subYMin, $$.subYMax]\n  );\n  // update axes\n  $$.xAxisTickFormat = $$.axis.getXAxisTickFormat();\n  $$.xAxisTickValues = $$.axis.getXAxisTickValues();\n  $$.yAxisTickValues = $$.axis.getYAxisTickValues();\n  $$.y2AxisTickValues = $$.axis.getY2AxisTickValues();\n\n  $$.xAxis = $$.axis.getXAxis(\n    $$.x,\n    $$.xOrient,\n    $$.xAxisTickFormat,\n    $$.xAxisTickValues,\n    config.axis_x_tick_outer\n  );\n  $$.subXAxis = $$.axis.getXAxis(\n    $$.subX,\n    $$.subXOrient,\n    $$.xAxisTickFormat,\n    $$.xAxisTickValues,\n    config.axis_x_tick_outer\n  );\n  $$.yAxis = $$.axis.getYAxis(\n    'y',\n    $$.y,\n    $$.yOrient,\n    $$.yAxisTickValues,\n    config.axis_y_tick_outer\n  );\n  $$.y2Axis = $$.axis.getYAxis(\n    'y2',\n    $$.y2,\n    $$.y2Orient,\n    $$.y2AxisTickValues,\n    config.axis_y2_tick_outer\n  );\n\n  // Set initialized scales to brush and zoom\n  if (!forInit) {\n    if ($$.brush) {\n      $$.brush.updateScale($$.subX);\n    }\n  }\n  // update for arc\n  if ($$.updateArc) {\n    $$.updateArc();\n  }\n};\n\nChartInternal.prototype.selectPoint = function(target, d, i) {\n  var $$ = this,\n    config = $$.config,\n    cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$),\n    cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$),\n    r = $$.pointSelectR.bind($$);\n  config.data_onselected.call($$.api, d, target.node());\n  // add selected-circle on low layer g\n  $$.main\n    .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id))\n    .selectAll('.' + CLASS.selectedCircle + '-' + i)\n    .data([d])\n    .enter()\n    .append('circle')\n    .attr('class', function() {\n      return $$.generateClass(CLASS.selectedCircle, i)\n    })\n    .attr('cx', cx)\n    .attr('cy', cy)\n    .attr('stroke', function() {\n      return $$.color(d)\n    })\n    .attr('r', function(d) {\n      return $$.pointSelectR(d) * 1.4\n    })\n    .transition()\n    .duration(100)\n    .attr('r', r);\n};\nChartInternal.prototype.unselectPoint = function(target, d, i) {\n  var $$ = this;\n  $$.config.data_onunselected.call($$.api, d, target.node());\n  // remove selected-circle from low layer g\n  $$.main\n    .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id))\n    .selectAll('.' + CLASS.selectedCircle + '-' + i)\n    .transition()\n    .duration(100)\n    .attr('r', 0)\n    .remove();\n};\nChartInternal.prototype.togglePoint = function(selected, target, d, i) {\n  selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i);\n};\nChartInternal.prototype.selectPath = function(target, d) {\n  var $$ = this;\n  $$.config.data_onselected.call($$, d, target.node());\n  if ($$.config.interaction_brighten) {\n    target\n      .transition()\n      .duration(100)\n      .style('fill', function() {\n        return $$.d3.rgb($$.color(d)).brighter(0.75)\n      });\n  }\n};\nChartInternal.prototype.unselectPath = function(target, d) {\n  var $$ = this;\n  $$.config.data_onunselected.call($$, d, target.node());\n  if ($$.config.interaction_brighten) {\n    target\n      .transition()\n      .duration(100)\n      .style('fill', function() {\n        return $$.color(d)\n      });\n  }\n};\nChartInternal.prototype.togglePath = function(selected, target, d, i) {\n  selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i);\n};\nChartInternal.prototype.getToggle = function(that, d) {\n  var $$ = this,\n    toggle;\n  if (that.nodeName === 'circle') {\n    if ($$.isStepType(d)) {\n      // circle is hidden in step chart, so treat as within the click area\n      toggle = function() {}; // TODO: how to select step chart?\n    } else {\n      toggle = $$.togglePoint;\n    }\n  } else if (that.nodeName === 'path') {\n    toggle = $$.togglePath;\n  }\n  return toggle\n};\nChartInternal.prototype.toggleShape = function(that, d, i) {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    shape = d3.select(that),\n    isSelected = shape.classed(CLASS.SELECTED),\n    toggle = $$.getToggle(that, d).bind($$);\n\n  if (config.data_selection_enabled && config.data_selection_isselectable(d)) {\n    if (!config.data_selection_multiple) {\n      $$.main\n        .selectAll(\n          '.' +\n            CLASS.shapes +\n            (config.data_selection_grouped\n              ? $$.getTargetSelectorSuffix(d.id)\n              : '')\n        )\n        .selectAll('.' + CLASS.shape)\n        .each(function(d, i) {\n          var shape = d3.select(this);\n          if (shape.classed(CLASS.SELECTED)) {\n            toggle(false, shape.classed(CLASS.SELECTED, false), d, i);\n          }\n        });\n    }\n    shape.classed(CLASS.SELECTED, !isSelected);\n    toggle(!isSelected, shape, d, i);\n  }\n};\n\nChartInternal.prototype.initBar = function() {\n  var $$ = this;\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartBars);\n};\nChartInternal.prototype.updateTargetsForBar = function(targets) {\n  var $$ = this,\n    config = $$.config,\n    mainBars,\n    mainBarEnter,\n    classChartBar = $$.classChartBar.bind($$),\n    classBars = $$.classBars.bind($$),\n    classFocus = $$.classFocus.bind($$);\n  mainBars = $$.main\n    .select('.' + CLASS.chartBars)\n    .selectAll('.' + CLASS.chartBar)\n    .data(targets)\n    .attr('class', function(d) {\n      return classChartBar(d) + classFocus(d)\n    });\n  mainBarEnter = mainBars\n    .enter()\n    .append('g')\n    .attr('class', classChartBar)\n    .style('pointer-events', 'none');\n  // Bars for each data\n  mainBarEnter\n    .append('g')\n    .attr('class', classBars)\n    .style('cursor', function(d) {\n      return config.data_selection_isselectable(d) ? 'pointer' : null\n    });\n};\nChartInternal.prototype.updateBar = function(durationForExit) {\n  var $$ = this,\n    barData = $$.barData.bind($$),\n    classBar = $$.classBar.bind($$),\n    initialOpacity = $$.initialOpacity.bind($$),\n    color = function(d) {\n      return $$.color(d.id)\n    };\n  var mainBar = $$.main\n    .selectAll('.' + CLASS.bars)\n    .selectAll('.' + CLASS.bar)\n    .data(barData);\n  var mainBarEnter = mainBar\n    .enter()\n    .append('path')\n    .attr('class', classBar)\n    .style('stroke', color)\n    .style('fill', color);\n  $$.mainBar = mainBarEnter.merge(mainBar).style('opacity', initialOpacity);\n  mainBar\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0);\n};\nChartInternal.prototype.redrawBar = function(\n  drawBar,\n  withTransition,\n  transition\n) {\n  const $$ = this;\n\n  return [\n    (withTransition ? this.mainBar.transition(transition) : this.mainBar)\n      .attr('d', drawBar)\n      .style('stroke', this.color)\n      .style('fill', this.color)\n      .style('opacity', d => ($$.isTargetToShow(d.id) ? 1 : 0))\n  ]\n};\nChartInternal.prototype.getBarW = function(axis, barTargetsNum) {\n  var $$ = this,\n    config = $$.config,\n    w =\n      typeof config.bar_width === 'number'\n        ? config.bar_width\n        : barTargetsNum\n        ? (axis.tickInterval() * config.bar_width_ratio) / barTargetsNum\n        : 0;\n  return config.bar_width_max && w > config.bar_width_max\n    ? config.bar_width_max\n    : w\n};\nChartInternal.prototype.getBars = function(i, id) {\n  var $$ = this;\n  return (id\n    ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id))\n    : $$.main\n  ).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''))\n};\nChartInternal.prototype.expandBars = function(i, id, reset) {\n  var $$ = this;\n  if (reset) {\n    $$.unexpandBars();\n  }\n  $$.getBars(i, id).classed(CLASS.EXPANDED, true);\n};\nChartInternal.prototype.unexpandBars = function(i) {\n  var $$ = this;\n  $$.getBars(i).classed(CLASS.EXPANDED, false);\n};\nChartInternal.prototype.generateDrawBar = function(barIndices, isSub) {\n  var $$ = this,\n    config = $$.config,\n    getPoints = $$.generateGetBarPoints(barIndices, isSub);\n  return function(d, i) {\n    // 4 points that make a bar\n    var points = getPoints(d, i);\n\n    // switch points if axis is rotated, not applicable for sub chart\n    var indexX = config.axis_rotated ? 1 : 0;\n    var indexY = config.axis_rotated ? 0 : 1;\n\n    var path =\n      'M ' +\n      points[0][indexX] +\n      ',' +\n      points[0][indexY] +\n      ' ' +\n      'L' +\n      points[1][indexX] +\n      ',' +\n      points[1][indexY] +\n      ' ' +\n      'L' +\n      points[2][indexX] +\n      ',' +\n      points[2][indexY] +\n      ' ' +\n      'L' +\n      points[3][indexX] +\n      ',' +\n      points[3][indexY] +\n      ' ' +\n      'z';\n\n    return path\n  }\n};\nChartInternal.prototype.generateGetBarPoints = function(barIndices, isSub) {\n  var $$ = this,\n    axis = isSub ? $$.subXAxis : $$.xAxis,\n    barTargetsNum = barIndices.__max__ + 1,\n    barW = $$.getBarW(axis, barTargetsNum),\n    barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub),\n    barY = $$.getShapeY(!!isSub),\n    barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub),\n    barSpaceOffset = barW * ($$.config.bar_space / 2),\n    yScale = isSub ? $$.getSubYScale : $$.getYScale;\n  return function(d, i) {\n    var y0 = yScale.call($$, d.id)(0),\n      offset = barOffset(d, i) || y0, // offset is for stacked bar chart\n      posX = barX(d),\n      posY = barY(d);\n    // fix posY not to overflow opposite quadrant\n    if ($$.config.axis_rotated) {\n      if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\n        posY = y0;\n      }\n    }\n\n    posY -= y0 - offset;\n\n    // 4 points that make a bar\n    return [\n      [posX + barSpaceOffset, offset],\n      [posX + barSpaceOffset, posY],\n      [posX + barW - barSpaceOffset, posY],\n      [posX + barW - barSpaceOffset, offset]\n    ]\n  }\n};\n\n/**\n * Returns whether the data point is within the given bar shape.\n *\n * @param mouse\n * @param barShape\n * @return {boolean}\n */\nChartInternal.prototype.isWithinBar = function(mouse, barShape) {\n  return isWithinBox(mouse, getBBox(barShape), 2)\n};\n\nChartInternal.prototype.getShapeIndices = function(typeFilter) {\n  var $$ = this,\n    config = $$.config,\n    indices = {},\n    i = 0,\n    j,\n    k;\n  $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(\n    function(d) {\n      for (j = 0; j < config.data_groups.length; j++) {\n        if (config.data_groups[j].indexOf(d.id) < 0) {\n          continue\n        }\n        for (k = 0; k < config.data_groups[j].length; k++) {\n          if (config.data_groups[j][k] in indices) {\n            indices[d.id] = indices[config.data_groups[j][k]];\n            break\n          }\n        }\n      }\n      if (isUndefined(indices[d.id])) {\n        indices[d.id] = i++;\n      }\n    }\n  );\n  indices.__max__ = i - 1;\n  return indices\n};\nChartInternal.prototype.getShapeX = function(\n  offset,\n  targetsNum,\n  indices,\n  isSub\n) {\n  var $$ = this,\n    scale = isSub ? $$.subX : $$.x;\n  return function(d) {\n    var index = d.id in indices ? indices[d.id] : 0;\n    return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0\n  }\n};\nChartInternal.prototype.getShapeY = function(isSub) {\n  const $$ = this;\n\n  return function(d) {\n    const scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id);\n    return scale(\n      $$.isTargetNormalized(d.id) ? $$.getRatio('index', d, true) : d.value\n    )\n  }\n};\nChartInternal.prototype.getShapeOffset = function(typeFilter, indices, isSub) {\n  var $$ = this,\n    targets = $$.orderTargets(\n      $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))\n    ),\n    targetIds = targets.map(function(t) {\n      return t.id\n    });\n  return function(d, i) {\n    var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id),\n      y0 = scale(0),\n      offset = y0;\n    targets.forEach(function(t) {\n      const rowValues = $$.isStepType(d)\n        ? $$.convertValuesToStep(t.values)\n        : t.values;\n      const isTargetNormalized = $$.isTargetNormalized(d.id);\n      const values = rowValues.map(v =>\n        isTargetNormalized ? $$.getRatio('index', v, true) : v.value\n      );\n\n      if (t.id === d.id || indices[t.id] !== indices[d.id]) {\n        return\n      }\n      if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) {\n        // check if the x values line up\n        if (isUndefined(rowValues[i]) || +rowValues[i].x !== +d.x) {\n          // \"+\" for timeseries\n          // if not, try to find the value that does line up\n          i = -1;\n          rowValues.forEach(function(v, j) {\n            const x1 = v.x.constructor === Date ? +v.x : v.x;\n            const x2 = d.x.constructor === Date ? +d.x : d.x;\n\n            if (x1 === x2) {\n              i = j;\n            }\n          });\n        }\n        if (i in rowValues && rowValues[i].value * d.value >= 0) {\n          offset += scale(values[i]) - y0;\n        }\n      }\n    });\n    return offset\n  }\n};\nChartInternal.prototype.isWithinShape = function(that, d) {\n  var $$ = this,\n    shape = $$.d3.select(that),\n    isWithin;\n  if (!$$.isTargetToShow(d.id)) {\n    isWithin = false;\n  } else if (that.nodeName === 'circle') {\n    isWithin = $$.isStepType(d)\n      ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value))\n      : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5);\n  } else if (that.nodeName === 'path') {\n    isWithin = shape.classed(CLASS.bar)\n      ? $$.isWithinBar($$.d3.mouse(that), that)\n      : true;\n  }\n  return isWithin\n};\n\nChartInternal.prototype.getInterpolate = function(d) {\n  var $$ = this,\n    d3 = $$.d3,\n    types = {\n      linear: d3.curveLinear,\n      'linear-closed': d3.curveLinearClosed,\n      basis: d3.curveBasis,\n      'basis-open': d3.curveBasisOpen,\n      'basis-closed': d3.curveBasisClosed,\n      bundle: d3.curveBundle,\n      cardinal: d3.curveCardinal,\n      'cardinal-open': d3.curveCardinalOpen,\n      'cardinal-closed': d3.curveCardinalClosed,\n      monotone: d3.curveMonotoneX,\n      step: d3.curveStep,\n      'step-before': d3.curveStepBefore,\n      'step-after': d3.curveStepAfter\n    },\n    type;\n\n  if ($$.isSplineType(d)) {\n    type = types[$$.config.spline_interpolation_type] || types.cardinal;\n  } else if ($$.isStepType(d)) {\n    type = types[$$.config.line_step_type];\n  } else {\n    type = types.linear;\n  }\n  return type\n};\n\nChartInternal.prototype.initLine = function() {\n  var $$ = this;\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartLines);\n};\nChartInternal.prototype.updateTargetsForLine = function(targets) {\n  var $$ = this,\n    config = $$.config,\n    mainLines,\n    mainLineEnter,\n    classChartLine = $$.classChartLine.bind($$),\n    classLines = $$.classLines.bind($$),\n    classAreas = $$.classAreas.bind($$),\n    classCircles = $$.classCircles.bind($$),\n    classFocus = $$.classFocus.bind($$);\n  mainLines = $$.main\n    .select('.' + CLASS.chartLines)\n    .selectAll('.' + CLASS.chartLine)\n    .data(targets)\n    .attr('class', function(d) {\n      return classChartLine(d) + classFocus(d)\n    });\n  mainLineEnter = mainLines\n    .enter()\n    .append('g')\n    .attr('class', classChartLine)\n    .style('opacity', 0)\n    .style('pointer-events', 'none');\n  // Lines for each data\n  mainLineEnter.append('g').attr('class', classLines);\n  // Areas\n  mainLineEnter.append('g').attr('class', classAreas);\n  // Circles for each data point on lines\n  mainLineEnter.append('g').attr('class', function(d) {\n    return $$.generateClass(CLASS.selectedCircles, d.id)\n  });\n  mainLineEnter\n    .append('g')\n    .attr('class', classCircles)\n    .style('cursor', function(d) {\n      return config.data_selection_isselectable(d) ? 'pointer' : null\n    });\n  // Update date for selected circles\n  targets.forEach(function(t) {\n    $$.main\n      .selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id))\n      .selectAll('.' + CLASS.selectedCircle)\n      .each(function(d) {\n        d.value = t.values[d.index].value;\n      });\n  });\n  // MEMO: can not keep same color...\n  //mainLineUpdate.exit().remove();\n};\nChartInternal.prototype.updateLine = function(durationForExit) {\n  var $$ = this;\n  var mainLine = $$.main\n    .selectAll('.' + CLASS.lines)\n    .selectAll('.' + CLASS.line)\n    .data($$.lineData.bind($$));\n  var mainLineEnter = mainLine\n    .enter()\n    .append('path')\n    .attr('class', $$.classLine.bind($$))\n    .style('stroke', $$.color);\n  $$.mainLine = mainLineEnter\n    .merge(mainLine)\n    .style('opacity', $$.initialOpacity.bind($$))\n    .style('shape-rendering', function(d) {\n      return $$.isStepType(d) ? 'crispEdges' : ''\n    })\n    .attr('transform', null);\n  mainLine\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0);\n};\nChartInternal.prototype.redrawLine = function(\n  drawLine,\n  withTransition,\n  transition\n) {\n  return [\n    (withTransition ? this.mainLine.transition(transition) : this.mainLine)\n      .attr('d', drawLine)\n      .style('stroke', this.color)\n      .style('opacity', 1)\n  ]\n};\nChartInternal.prototype.generateDrawLine = function(lineIndices, isSub) {\n  var $$ = this,\n    config = $$.config,\n    line = $$.d3.line(),\n    getPoints = $$.generateGetLinePoints(lineIndices, isSub),\n    yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,\n    xValue = function(d) {\n      return (isSub ? $$.subxx : $$.xx).call($$, d)\n    },\n    yValue = function(d, i) {\n      return config.data_groups.length > 0\n        ? getPoints(d, i)[0][1]\n        : yScaleGetter.call($$, d.id)(d.value)\n    };\n\n  line = config.axis_rotated\n    ? line.x(yValue).y(xValue)\n    : line.x(xValue).y(yValue);\n  if (!config.line_connectNull) {\n    line = line.defined(function(d) {\n      return d.value != null\n    });\n  }\n  return function(d) {\n    var values = config.line_connectNull\n        ? $$.filterRemoveNull(d.values)\n        : d.values,\n      x = isSub ? $$.subX : $$.x,\n      y = yScaleGetter.call($$, d.id),\n      x0 = 0,\n      y0 = 0,\n      path;\n    if ($$.isLineType(d)) {\n      if (config.data_regions[d.id]) {\n        path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]);\n      } else {\n        if ($$.isStepType(d)) {\n          values = $$.convertValuesToStep(values);\n        }\n        path = line.curve($$.getInterpolate(d))(values);\n      }\n    } else {\n      if (values[0]) {\n        x0 = x(values[0].x);\n        y0 = y(values[0].value);\n      }\n      path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0;\n    }\n    return path ? path : 'M 0 0'\n  }\n};\nChartInternal.prototype.generateGetLinePoints = function(lineIndices, isSub) {\n  // partial duplication of generateGetBarPoints\n  var $$ = this,\n    config = $$.config,\n    lineTargetsNum = lineIndices.__max__ + 1,\n    x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub),\n    y = $$.getShapeY(!!isSub),\n    lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub),\n    yScale = isSub ? $$.getSubYScale : $$.getYScale;\n  return function(d, i) {\n    var y0 = yScale.call($$, d.id)(0),\n      offset = lineOffset(d, i) || y0, // offset is for stacked area chart\n      posX = x(d),\n      posY = y(d);\n    // fix posY not to overflow opposite quadrant\n    if (config.axis_rotated) {\n      if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\n        posY = y0;\n      }\n    }\n    // 1 point that marks the line position\n    return [\n      [posX, posY - (y0 - offset)],\n      [posX, posY - (y0 - offset)], // needed for compatibility\n      [posX, posY - (y0 - offset)], // needed for compatibility\n      [posX, posY - (y0 - offset)] // needed for compatibility\n    ]\n  }\n};\n\nChartInternal.prototype.lineWithRegions = function(d, x, y, _regions) {\n  var $$ = this,\n    config = $$.config,\n    prev = -1,\n    i,\n    j,\n    s = 'M',\n    sWithRegion,\n    xp,\n    yp,\n    dx,\n    dy,\n    dd,\n    diff,\n    diffx2,\n    xOffset = $$.isCategorized() ? 0.5 : 0,\n    xValue,\n    yValue,\n    regions = [];\n\n  function isWithinRegions(x, regions) {\n    var i;\n    for (i = 0; i < regions.length; i++) {\n      if (regions[i].start < x && x <= regions[i].end) {\n        return true\n      }\n    }\n    return false\n  }\n\n  // Check start/end of regions\n  if (isDefined(_regions)) {\n    for (i = 0; i < _regions.length; i++) {\n      regions[i] = {};\n      if (isUndefined(_regions[i].start)) {\n        regions[i].start = d[0].x;\n      } else {\n        regions[i].start = $$.isTimeSeries()\n          ? $$.parseDate(_regions[i].start)\n          : _regions[i].start;\n      }\n      if (isUndefined(_regions[i].end)) {\n        regions[i].end = d[d.length - 1].x;\n      } else {\n        regions[i].end = $$.isTimeSeries()\n          ? $$.parseDate(_regions[i].end)\n          : _regions[i].end;\n      }\n    }\n  }\n\n  // Set scales\n  xValue = config.axis_rotated\n    ? function(d) {\n        return y(d.value)\n      }\n    : function(d) {\n        return x(d.x)\n      };\n  yValue = config.axis_rotated\n    ? function(d) {\n        return x(d.x)\n      }\n    : function(d) {\n        return y(d.value)\n      };\n\n  // Define svg generator function for region\n  function generateM(points) {\n    return (\n      'M' +\n      points[0][0] +\n      ' ' +\n      points[0][1] +\n      ' ' +\n      points[1][0] +\n      ' ' +\n      points[1][1]\n    )\n  }\n  if ($$.isTimeSeries()) {\n    sWithRegion = function(d0, d1, j, diff) {\n      var x0 = d0.x.getTime(),\n        x_diff = d1.x - d0.x,\n        xv0 = new Date(x0 + x_diff * j),\n        xv1 = new Date(x0 + x_diff * (j + diff)),\n        points;\n      if (config.axis_rotated) {\n        points = [\n          [y(yp(j)), x(xv0)],\n          [y(yp(j + diff)), x(xv1)]\n        ];\n      } else {\n        points = [\n          [x(xv0), y(yp(j))],\n          [x(xv1), y(yp(j + diff))]\n        ];\n      }\n      return generateM(points)\n    };\n  } else {\n    sWithRegion = function(d0, d1, j, diff) {\n      var points;\n      if (config.axis_rotated) {\n        points = [\n          [y(yp(j), true), x(xp(j))],\n          [y(yp(j + diff), true), x(xp(j + diff))]\n        ];\n      } else {\n        points = [\n          [x(xp(j), true), y(yp(j))],\n          [x(xp(j + diff), true), y(yp(j + diff))]\n        ];\n      }\n      return generateM(points)\n    };\n  }\n\n  // Generate\n  for (i = 0; i < d.length; i++) {\n    // Draw as normal\n    if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) {\n      s += ' ' + xValue(d[i]) + ' ' + yValue(d[i]);\n    }\n    // Draw with region // TODO: Fix for horizotal charts\n    else {\n      xp = $$.getScale(\n        d[i - 1].x + xOffset,\n        d[i].x + xOffset,\n        $$.isTimeSeries()\n      );\n      yp = $$.getScale(d[i - 1].value, d[i].value);\n\n      dx = x(d[i].x) - x(d[i - 1].x);\n      dy = y(d[i].value) - y(d[i - 1].value);\n      dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));\n      diff = 2 / dd;\n      diffx2 = diff * 2;\n\n      for (j = diff; j <= 1; j += diffx2) {\n        s += sWithRegion(d[i - 1], d[i], j, diff);\n      }\n    }\n    prev = d[i].x;\n  }\n\n  return s\n};\n\nChartInternal.prototype.updateArea = function(durationForExit) {\n  var $$ = this,\n    d3 = $$.d3;\n  var mainArea = $$.main\n    .selectAll('.' + CLASS.areas)\n    .selectAll('.' + CLASS.area)\n    .data($$.lineData.bind($$));\n  var mainAreaEnter = mainArea\n    .enter()\n    .append('path')\n    .attr('class', $$.classArea.bind($$))\n    .style('fill', $$.color)\n    .style('opacity', function() {\n      $$.orgAreaOpacity = +d3.select(this).style('opacity');\n      return 0\n    });\n  $$.mainArea = mainAreaEnter\n    .merge(mainArea)\n    .style('opacity', $$.orgAreaOpacity);\n  mainArea\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0);\n};\nChartInternal.prototype.redrawArea = function(\n  drawArea,\n  withTransition,\n  transition\n) {\n  return [\n    (withTransition ? this.mainArea.transition(transition) : this.mainArea)\n      .attr('d', drawArea)\n      .style('fill', this.color)\n      .style('opacity', this.orgAreaOpacity)\n  ]\n};\nChartInternal.prototype.generateDrawArea = function(areaIndices, isSub) {\n  var $$ = this,\n    config = $$.config,\n    area = $$.d3.area(),\n    getPoints = $$.generateGetAreaPoints(areaIndices, isSub),\n    yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,\n    xValue = function(d) {\n      return (isSub ? $$.subxx : $$.xx).call($$, d)\n    },\n    value0 = function(d, i) {\n      return config.data_groups.length > 0\n        ? getPoints(d, i)[0][1]\n        : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id))\n    },\n    value1 = function(d, i) {\n      return config.data_groups.length > 0\n        ? getPoints(d, i)[1][1]\n        : yScaleGetter.call($$, d.id)(d.value)\n    };\n\n  area = config.axis_rotated\n    ? area\n        .x0(value0)\n        .x1(value1)\n        .y(xValue)\n    : area\n        .x(xValue)\n        .y0(config.area_above ? 0 : value0)\n        .y1(value1);\n  if (!config.line_connectNull) {\n    area = area.defined(function(d) {\n      return d.value !== null\n    });\n  }\n\n  return function(d) {\n    var values = config.line_connectNull\n        ? $$.filterRemoveNull(d.values)\n        : d.values,\n      x0 = 0,\n      y0 = 0,\n      path;\n    if ($$.isAreaType(d)) {\n      if ($$.isStepType(d)) {\n        values = $$.convertValuesToStep(values);\n      }\n      path = area.curve($$.getInterpolate(d))(values);\n    } else {\n      if (values[0]) {\n        x0 = $$.x(values[0].x);\n        y0 = $$.getYScale(d.id)(values[0].value);\n      }\n      path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0;\n    }\n    return path ? path : 'M 0 0'\n  }\n};\nChartInternal.prototype.getAreaBaseValue = function() {\n  return 0\n};\nChartInternal.prototype.generateGetAreaPoints = function(areaIndices, isSub) {\n  // partial duplication of generateGetBarPoints\n  var $$ = this,\n    config = $$.config,\n    areaTargetsNum = areaIndices.__max__ + 1,\n    x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub),\n    y = $$.getShapeY(!!isSub),\n    areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub),\n    yScale = isSub ? $$.getSubYScale : $$.getYScale;\n  return function(d, i) {\n    var y0 = yScale.call($$, d.id)(0),\n      offset = areaOffset(d, i) || y0, // offset is for stacked area chart\n      posX = x(d),\n      posY = y(d);\n    // fix posY not to overflow opposite quadrant\n    if (config.axis_rotated) {\n      if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\n        posY = y0;\n      }\n    }\n    // 1 point that marks the area position\n    return [\n      [posX, offset],\n      [posX, posY - (y0 - offset)],\n      [posX, posY - (y0 - offset)], // needed for compatibility\n      [posX, offset] // needed for compatibility\n    ]\n  }\n};\n\nChartInternal.prototype.updateCircle = function(cx, cy) {\n  var $$ = this;\n  var mainCircle = $$.main\n    .selectAll('.' + CLASS.circles)\n    .selectAll('.' + CLASS.circle)\n    .data($$.lineOrScatterOrStanfordData.bind($$));\n\n  var mainCircleEnter = mainCircle\n    .enter()\n    .append('circle')\n    .attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '')\n    .attr('class', $$.classCircle.bind($$))\n    .attr('cx', cx)\n    .attr('cy', cy)\n    .attr('r', $$.pointR.bind($$))\n    .style(\n      'color',\n      $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color\n    );\n\n  $$.mainCircle = mainCircleEnter\n    .merge(mainCircle)\n    .style(\n      'opacity',\n      $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$)\n    );\n\n  mainCircle.exit().style('opacity', 0);\n};\nChartInternal.prototype.redrawCircle = function(\n  cx,\n  cy,\n  withTransition,\n  transition\n) {\n  var $$ = this,\n    selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle);\n  return [\n    (withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle)\n      .style('opacity', this.opacityForCircle.bind($$))\n      .style(\n        'color',\n        $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color\n      )\n      .attr('cx', cx)\n      .attr('cy', cy),\n    (withTransition ? selectedCircles.transition(transition) : selectedCircles)\n      .attr('cx', cx)\n      .attr('cy', cy)\n  ]\n};\nChartInternal.prototype.circleX = function(d) {\n  return d.x || d.x === 0 ? this.x(d.x) : null\n};\nChartInternal.prototype.updateCircleY = function() {\n  var $$ = this,\n    lineIndices,\n    getPoints;\n  if ($$.config.data_groups.length > 0) {\n(lineIndices = $$.getShapeIndices($$.isLineType)),\n      (getPoints = $$.generateGetLinePoints(lineIndices));\n    $$.circleY = function(d, i) {\n      return getPoints(d, i)[0][1]\n    };\n  } else {\n    $$.circleY = function(d) {\n      return $$.getYScale(d.id)(d.value)\n    };\n  }\n};\nChartInternal.prototype.getCircles = function(i, id) {\n  var $$ = this;\n  return (id\n    ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id))\n    : $$.main\n  ).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''))\n};\nChartInternal.prototype.expandCircles = function(i, id, reset) {\n  var $$ = this,\n    r = $$.pointExpandedR.bind($$);\n  if (reset) {\n    $$.unexpandCircles();\n  }\n  $$.getCircles(i, id)\n    .classed(CLASS.EXPANDED, true)\n    .attr('r', r);\n};\nChartInternal.prototype.unexpandCircles = function(i) {\n  var $$ = this,\n    r = $$.pointR.bind($$);\n  $$.getCircles(i)\n    .filter(function() {\n      return $$.d3.select(this).classed(CLASS.EXPANDED)\n    })\n    .classed(CLASS.EXPANDED, false)\n    .attr('r', r);\n};\nChartInternal.prototype.pointR = function(d) {\n  var $$ = this,\n    config = $$.config;\n  return $$.isStepType(d)\n    ? 0\n    : isFunction(config.point_r)\n    ? config.point_r(d)\n    : config.point_r\n};\nChartInternal.prototype.pointExpandedR = function(d) {\n  var $$ = this,\n    config = $$.config;\n  if (config.point_focus_expand_enabled) {\n    return isFunction(config.point_focus_expand_r)\n      ? config.point_focus_expand_r(d)\n      : config.point_focus_expand_r\n      ? config.point_focus_expand_r\n      : $$.pointR(d) * 1.75\n  } else {\n    return $$.pointR(d)\n  }\n};\nChartInternal.prototype.pointSelectR = function(d) {\n  var $$ = this,\n    config = $$.config;\n  return isFunction(config.point_select_r)\n    ? config.point_select_r(d)\n    : config.point_select_r\n    ? config.point_select_r\n    : $$.pointR(d) * 4\n};\nChartInternal.prototype.isWithinCircle = function(that, r) {\n  var d3 = this.d3,\n    mouse = d3.mouse(that),\n    d3_this = d3.select(that),\n    cx = +d3_this.attr('cx'),\n    cy = +d3_this.attr('cy');\n  return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r\n};\nChartInternal.prototype.isWithinStep = function(that, y) {\n  return Math.abs(y - this.d3.mouse(that)[1]) < 30\n};\n\nChartInternal.prototype.getCurrentWidth = function() {\n  var $$ = this,\n    config = $$.config;\n  return config.size_width ? config.size_width : $$.getParentWidth()\n};\nChartInternal.prototype.getCurrentHeight = function() {\n  var $$ = this,\n    config = $$.config,\n    h = config.size_height ? config.size_height : $$.getParentHeight();\n  return h > 0\n    ? h\n    : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1)\n};\nChartInternal.prototype.getCurrentPaddingTop = function() {\n  var $$ = this,\n    config = $$.config,\n    padding = isValue(config.padding_top) ? config.padding_top : 0;\n  if ($$.title && $$.title.node()) {\n    padding += $$.getTitlePadding();\n  }\n  return padding\n};\nChartInternal.prototype.getCurrentPaddingBottom = function() {\n  var config = this.config;\n  return isValue(config.padding_bottom) ? config.padding_bottom : 0\n};\nChartInternal.prototype.getCurrentPaddingLeft = function(withoutRecompute) {\n  var $$ = this,\n    config = $$.config;\n  if (isValue(config.padding_left)) {\n    return config.padding_left\n  } else if (config.axis_rotated) {\n    return !config.axis_x_show || config.axis_x_inner\n      ? 1\n      : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40)\n  } else if (!config.axis_y_show || config.axis_y_inner) {\n    // && !config.axis_rotated\n    return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1\n  } else {\n    return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute))\n  }\n};\nChartInternal.prototype.getCurrentPaddingRight = function() {\n  var $$ = this,\n    config = $$.config,\n    padding = 0,\n    defaultPadding = 10,\n    legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0;\n\n  if (isValue(config.padding_right)) {\n    padding = config.padding_right + 1; // 1 is needed not to hide tick line\n  } else if (config.axis_rotated) {\n    padding = defaultPadding + legendWidthOnRight;\n  } else if (!config.axis_y2_show || config.axis_y2_inner) {\n    // && !config.axis_rotated\n    padding =\n      2 +\n      legendWidthOnRight +\n      ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0);\n  } else {\n    padding = ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight;\n  }\n\n  if ($$.colorScale && $$.colorScale.node()) {\n    padding += $$.getColorScalePadding();\n  }\n\n  return padding\n};\n\nChartInternal.prototype.getParentRectValue = function(key) {\n  var parent = this.selectChart.node(),\n    v;\n  while (parent && parent.tagName !== 'BODY') {\n    try {\n      v = parent.getBoundingClientRect()[key];\n    } catch (e) {\n      if (key === 'width') {\n        // In IE in certain cases getBoundingClientRect\n        // will cause an \"unspecified error\"\n        v = parent.offsetWidth;\n      }\n    }\n    if (v) {\n      break\n    }\n    parent = parent.parentNode;\n  }\n  return v\n};\nChartInternal.prototype.getParentWidth = function() {\n  return this.getParentRectValue('width')\n};\nChartInternal.prototype.getParentHeight = function() {\n  var h = this.selectChart.style('height');\n  return h.indexOf('px') > 0 ? +h.replace('px', '') : 0\n};\n\nChartInternal.prototype.getSvgLeft = function(withoutRecompute) {\n  var $$ = this,\n    config = $$.config,\n    hasLeftAxisRect =\n      config.axis_rotated || (!config.axis_rotated && !config.axis_y_inner),\n    leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY,\n    leftAxis = $$.main.select('.' + leftAxisClass).node(),\n    svgRect =\n      leftAxis && hasLeftAxisRect\n        ? leftAxis.getBoundingClientRect()\n        : { right: 0 },\n    chartRect = $$.selectChart.node().getBoundingClientRect(),\n    hasArc = $$.hasArcType(),\n    svgLeft =\n      svgRect.right -\n      chartRect.left -\n      (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute));\n  return svgLeft > 0 ? svgLeft : 0\n};\n\nChartInternal.prototype.getAxisWidthByAxisId = function(id, withoutRecompute) {\n  var $$ = this,\n    position = $$.axis.getLabelPositionById(id);\n  return (\n    $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40)\n  )\n};\nChartInternal.prototype.getHorizontalAxisHeight = function(axisId) {\n  var $$ = this,\n    config = $$.config,\n    h = 30;\n  if (axisId === 'x' && !config.axis_x_show) {\n    return 8\n  }\n  if (axisId === 'x' && config.axis_x_height) {\n    return config.axis_x_height\n  }\n  if (axisId === 'y' && !config.axis_y_show) {\n    return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1\n  }\n  if (axisId === 'y2' && !config.axis_y2_show) {\n    return $$.rotated_padding_top\n  }\n  // Calculate x axis height when tick rotated\n  if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {\n    h =\n      30 +\n      $$.axis.getMaxTickWidth(axisId) *\n        Math.cos((Math.PI * (90 - Math.abs(config.axis_x_tick_rotate))) / 180);\n  }\n  // Calculate y axis height when tick rotated\n  if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) {\n    h =\n      30 +\n      $$.axis.getMaxTickWidth(axisId) *\n        Math.cos((Math.PI * (90 - Math.abs(config.axis_y_tick_rotate))) / 180);\n  }\n  return (\n    h +\n    ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) +\n    (axisId === 'y2' ? -10 : 0)\n  )\n};\n\nChartInternal.prototype.initBrush = function(scale) {\n  var $$ = this,\n    d3 = $$.d3;\n  // TODO: dynamically change brushY/brushX according to axis_rotated.\n  $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX())\n    .on('brush', function() {\n      var event = d3.event.sourceEvent;\n      if (event && event.type === 'zoom') {\n        return\n      }\n      $$.redrawForBrush();\n    })\n    .on('end', function() {\n      var event = d3.event.sourceEvent;\n      if (event && event.type === 'zoom') {\n        return\n      }\n      if ($$.brush.empty() && event && event.type !== 'end') {\n        $$.brush.clear();\n      }\n    });\n  $$.brush.updateExtent = function() {\n    var range = this.scale.range(),\n      extent;\n    if ($$.config.axis_rotated) {\n      extent = [\n        [0, range[0]],\n        [$$.width2, range[1]]\n      ];\n    } else {\n      extent = [\n        [range[0], 0],\n        [range[1], $$.height2]\n      ];\n    }\n    this.extent(extent);\n    return this\n  };\n  $$.brush.updateScale = function(scale) {\n    this.scale = scale;\n    return this\n  };\n  $$.brush.update = function(scale) {\n    this.updateScale(scale || $$.subX).updateExtent();\n    $$.context.select('.' + CLASS.brush).call(this);\n  };\n  $$.brush.clear = function() {\n    $$.context.select('.' + CLASS.brush).call($$.brush.move, null);\n  };\n  $$.brush.selection = function() {\n    return d3.brushSelection($$.context.select('.' + CLASS.brush).node())\n  };\n  $$.brush.selectionAsValue = function(selectionAsValue, withTransition) {\n    var selection, brush;\n    if (selectionAsValue) {\n      if ($$.context) {\n        selection = [\n          this.scale(selectionAsValue[0]),\n          this.scale(selectionAsValue[1])\n        ];\n        brush = $$.context.select('.' + CLASS.brush);\n        if (withTransition) {\n          brush = brush.transition();\n        }\n        $$.brush.move(brush, selection);\n      }\n      return []\n    }\n    selection = $$.brush.selection() || [0, 0];\n    return [this.scale.invert(selection[0]), this.scale.invert(selection[1])]\n  };\n  $$.brush.empty = function() {\n    var selection = $$.brush.selection();\n    return !selection || selection[0] === selection[1]\n  };\n  return $$.brush.updateScale(scale)\n};\nChartInternal.prototype.initSubchart = function() {\n  var $$ = this,\n    config = $$.config,\n    context = ($$.context = $$.svg\n      .append('g')\n      .attr('transform', $$.getTranslate('context')));\n\n  // set style\n  context.style('visibility', 'visible');\n\n  // Define g for chart area\n  context\n    .append('g')\n    .attr('clip-path', $$.clipPathForSubchart)\n    .attr('class', CLASS.chart);\n\n  // Define g for bar chart area\n  context\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartBars);\n\n  // Define g for line chart area\n  context\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartLines);\n\n  // Add extent rect for Brush\n  context\n    .append('g')\n    .attr('clip-path', $$.clipPath)\n    .attr('class', CLASS.brush);\n\n  // ATTENTION: This must be called AFTER chart added\n  // Add Axis\n  $$.axes.subx = context\n    .append('g')\n    .attr('class', CLASS.axisX)\n    .attr('transform', $$.getTranslate('subx'))\n    .attr('clip-path', config.axis_rotated ? '' : $$.clipPathForXAxis);\n};\nChartInternal.prototype.initSubchartBrush = function() {\n  var $$ = this;\n  // Add extent rect for Brush\n  $$.initBrush($$.subX).updateExtent();\n  $$.context.select('.' + CLASS.brush).call($$.brush);\n};\nChartInternal.prototype.updateTargetsForSubchart = function(targets) {\n  var $$ = this,\n    context = $$.context,\n    config = $$.config,\n    contextLineEnter,\n    contextLine,\n    contextBarEnter,\n    contextBar,\n    classChartBar = $$.classChartBar.bind($$),\n    classBars = $$.classBars.bind($$),\n    classChartLine = $$.classChartLine.bind($$),\n    classLines = $$.classLines.bind($$),\n    classAreas = $$.classAreas.bind($$);\n\n  //-- Bar --//\n  contextBar = context\n    .select('.' + CLASS.chartBars)\n    .selectAll('.' + CLASS.chartBar)\n    .data(targets);\n  contextBarEnter = contextBar\n    .enter()\n    .append('g')\n    .style('opacity', 0);\n  contextBarEnter.merge(contextBar).attr('class', classChartBar);\n  // Bars for each data\n  contextBarEnter.append('g').attr('class', classBars);\n\n  //-- Line --//\n  contextLine = context\n    .select('.' + CLASS.chartLines)\n    .selectAll('.' + CLASS.chartLine)\n    .data(targets);\n  contextLineEnter = contextLine\n    .enter()\n    .append('g')\n    .style('opacity', 0);\n  contextLineEnter.merge(contextLine).attr('class', classChartLine);\n  // Lines for each data\n  contextLineEnter.append('g').attr('class', classLines);\n  // Area\n  contextLineEnter.append('g').attr('class', classAreas);\n\n  //-- Brush --//\n  context\n    .selectAll('.' + CLASS.brush + ' rect')\n    .attr(\n      config.axis_rotated ? 'width' : 'height',\n      config.axis_rotated ? $$.width2 : $$.height2\n    );\n};\nChartInternal.prototype.updateBarForSubchart = function(durationForExit) {\n  var $$ = this;\n  var contextBar = $$.context\n    .selectAll('.' + CLASS.bars)\n    .selectAll('.' + CLASS.bar)\n    .data($$.barData.bind($$));\n  var contextBarEnter = contextBar\n    .enter()\n    .append('path')\n    .attr('class', $$.classBar.bind($$))\n    .style('stroke', 'none')\n    .style('fill', $$.color);\n  contextBar\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n    .remove();\n  $$.contextBar = contextBarEnter\n    .merge(contextBar)\n    .style('opacity', $$.initialOpacity.bind($$));\n};\nChartInternal.prototype.redrawBarForSubchart = function(\n  drawBarOnSub,\n  withTransition,\n  duration\n) {\n(withTransition\n    ? this.contextBar.transition(Math.random().toString()).duration(duration)\n    : this.contextBar\n  )\n    .attr('d', drawBarOnSub)\n    .style('opacity', 1);\n};\nChartInternal.prototype.updateLineForSubchart = function(durationForExit) {\n  var $$ = this;\n  var contextLine = $$.context\n    .selectAll('.' + CLASS.lines)\n    .selectAll('.' + CLASS.line)\n    .data($$.lineData.bind($$));\n  var contextLineEnter = contextLine\n    .enter()\n    .append('path')\n    .attr('class', $$.classLine.bind($$))\n    .style('stroke', $$.color);\n  contextLine\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n    .remove();\n  $$.contextLine = contextLineEnter\n    .merge(contextLine)\n    .style('opacity', $$.initialOpacity.bind($$));\n};\nChartInternal.prototype.redrawLineForSubchart = function(\n  drawLineOnSub,\n  withTransition,\n  duration\n) {\n(withTransition\n    ? this.contextLine.transition(Math.random().toString()).duration(duration)\n    : this.contextLine\n  )\n    .attr('d', drawLineOnSub)\n    .style('opacity', 1);\n};\nChartInternal.prototype.updateAreaForSubchart = function(durationForExit) {\n  var $$ = this,\n    d3 = $$.d3;\n  var contextArea = $$.context\n    .selectAll('.' + CLASS.areas)\n    .selectAll('.' + CLASS.area)\n    .data($$.lineData.bind($$));\n  var contextAreaEnter = contextArea\n    .enter()\n    .append('path')\n    .attr('class', $$.classArea.bind($$))\n    .style('fill', $$.color)\n    .style('opacity', function() {\n      $$.orgAreaOpacity = +d3.select(this).style('opacity');\n      return 0\n    });\n  contextArea\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n    .remove();\n  $$.contextArea = contextAreaEnter.merge(contextArea).style('opacity', 0);\n};\nChartInternal.prototype.redrawAreaForSubchart = function(\n  drawAreaOnSub,\n  withTransition,\n  duration\n) {\n(withTransition\n    ? this.contextArea.transition(Math.random().toString()).duration(duration)\n    : this.contextArea\n  )\n    .attr('d', drawAreaOnSub)\n    .style('fill', this.color)\n    .style('opacity', this.orgAreaOpacity);\n};\nChartInternal.prototype.redrawSubchart = function(\n  withSubchart,\n  transitions,\n  duration,\n  durationForExit,\n  areaIndices,\n  barIndices,\n  lineIndices\n) {\n  var $$ = this,\n    d3 = $$.d3,\n    drawAreaOnSub,\n    drawBarOnSub,\n    drawLineOnSub;\n\n  // reflect main chart to extent on subchart if zoomed\n  if (d3.event && d3.event.type === 'zoom') {\n    $$.brush.selectionAsValue($$.x.orgDomain());\n  }\n  // update subchart elements if needed\n  if (withSubchart) {\n    // extent rect\n    if (!$$.brush.empty()) {\n      $$.brush.selectionAsValue($$.x.orgDomain());\n    }\n    // setup drawer - MEMO: this must be called after axis updated\n    drawAreaOnSub = $$.generateDrawArea(areaIndices, true);\n    drawBarOnSub = $$.generateDrawBar(barIndices, true);\n    drawLineOnSub = $$.generateDrawLine(lineIndices, true);\n\n    $$.updateBarForSubchart(duration);\n    $$.updateLineForSubchart(duration);\n    $$.updateAreaForSubchart(duration);\n\n    $$.redrawBarForSubchart(drawBarOnSub, duration, duration);\n    $$.redrawLineForSubchart(drawLineOnSub, duration, duration);\n    $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration);\n  }\n};\nChartInternal.prototype.redrawForBrush = function() {\n  var $$ = this,\n    x = $$.x,\n    d3 = $$.d3,\n    s;\n  $$.redraw({\n    withTransition: false,\n    withY: $$.config.zoom_rescale,\n    withSubchart: false,\n    withUpdateXDomain: true,\n    withEventRect: false,\n    withDimension: false\n  });\n  // update zoom transation binded to event rect\n  s = d3.event.selection || $$.brush.scale.range();\n  $$.main\n    .select('.' + CLASS.eventRect)\n    .call(\n      $$.zoom.transform,\n      d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0)\n    );\n  $$.config.subchart_onbrush.call($$.api, x.orgDomain());\n};\nChartInternal.prototype.transformContext = function(\n  withTransition,\n  transitions\n) {\n  var $$ = this,\n    subXAxis;\n  if (transitions && transitions.axisSubX) {\n    subXAxis = transitions.axisSubX;\n  } else {\n    subXAxis = $$.context.select('.' + CLASS.axisX);\n    if (withTransition) {\n      subXAxis = subXAxis.transition();\n    }\n  }\n  $$.context.attr('transform', $$.getTranslate('context'));\n  subXAxis.attr('transform', $$.getTranslate('subx'));\n};\nChartInternal.prototype.getDefaultSelection = function() {\n  var $$ = this,\n    config = $$.config,\n    selection = isFunction(config.axis_x_selection)\n      ? config.axis_x_selection($$.getXDomain($$.data.targets))\n      : config.axis_x_selection;\n  if ($$.isTimeSeries()) {\n    selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])];\n  }\n  return selection\n};\n\nChartInternal.prototype.removeSubchart = function() {\n  const $$ = this;\n\n  $$.brush = null;\n  $$.context.remove();\n  $$.context = null;\n};\n\nChartInternal.prototype.initText = function() {\n  var $$ = this;\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartTexts);\n  $$.mainText = $$.d3.selectAll([]);\n};\nChartInternal.prototype.updateTargetsForText = function(targets) {\n  var $$ = this,\n    classChartText = $$.classChartText.bind($$),\n    classTexts = $$.classTexts.bind($$),\n    classFocus = $$.classFocus.bind($$);\n  var mainText = $$.main\n    .select('.' + CLASS.chartTexts)\n    .selectAll('.' + CLASS.chartText)\n    .data(targets);\n  var mainTextEnter = mainText\n    .enter()\n    .append('g')\n    .attr('class', classChartText)\n    .style('opacity', 0)\n    .style('pointer-events', 'none');\n  mainTextEnter.append('g').attr('class', classTexts);\n  mainTextEnter.merge(mainText).attr('class', function(d) {\n    return classChartText(d) + classFocus(d)\n  });\n};\nChartInternal.prototype.updateText = function(\n  xForText,\n  yForText,\n  durationForExit\n) {\n  var $$ = this,\n    config = $$.config,\n    barOrLineData = $$.barOrLineData.bind($$),\n    classText = $$.classText.bind($$);\n  var mainText = $$.main\n    .selectAll('.' + CLASS.texts)\n    .selectAll('.' + CLASS.text)\n    .data(barOrLineData);\n  var mainTextEnter = mainText\n    .enter()\n    .append('text')\n    .attr('class', classText)\n    .attr('text-anchor', function(d) {\n      return config.axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle'\n    })\n    .style('stroke', 'none')\n    .attr('x', xForText)\n    .attr('y', yForText)\n    .style('fill', function(d) {\n      return $$.color(d)\n    })\n    .style('fill-opacity', 0);\n  $$.mainText = mainTextEnter.merge(mainText).text(function(d, i, j) {\n    return $$.dataLabelFormat(d.id)(d.value, d.id, i, j)\n  });\n  mainText\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('fill-opacity', 0)\n    .remove();\n};\nChartInternal.prototype.redrawText = function(\n  xForText,\n  yForText,\n  forFlow,\n  withTransition,\n  transition\n) {\n  return [\n    (withTransition ? this.mainText.transition(transition) : this.mainText)\n      .attr('x', xForText)\n      .attr('y', yForText)\n      .style('fill', this.color)\n      .style('fill-opacity', forFlow ? 0 : this.opacityForText.bind(this))\n  ]\n};\nChartInternal.prototype.getTextRect = function(text, cls, element) {\n  var dummy = this.d3\n      .select('body')\n      .append('div')\n      .classed('c3', true),\n    svg = dummy\n      .append('svg')\n      .style('visibility', 'hidden')\n      .style('position', 'fixed')\n      .style('top', 0)\n      .style('left', 0),\n    font = this.d3.select(element).style('font'),\n    rect;\n  svg\n    .selectAll('.dummy')\n    .data([text])\n    .enter()\n    .append('text')\n    .classed(cls ? cls : '', true)\n    .style('font', font)\n    .text(text)\n    .each(function() {\n      rect = getBBox(this);\n    });\n  dummy.remove();\n  return rect\n};\nChartInternal.prototype.generateXYForText = function(\n  areaIndices,\n  barIndices,\n  lineIndices,\n  forX\n) {\n  var $$ = this,\n    getAreaPoints = $$.generateGetAreaPoints(areaIndices, false),\n    getBarPoints = $$.generateGetBarPoints(barIndices, false),\n    getLinePoints = $$.generateGetLinePoints(lineIndices, false),\n    getter = forX ? $$.getXForText : $$.getYForText;\n  return function(d, i) {\n    var getPoints = $$.isAreaType(d)\n      ? getAreaPoints\n      : $$.isBarType(d)\n      ? getBarPoints\n      : getLinePoints;\n    return getter.call($$, getPoints(d, i), d, this)\n  }\n};\nChartInternal.prototype.getXForText = function(points, d, textElement) {\n  var $$ = this,\n    box = getBBox(textElement),\n    xPos,\n    padding;\n  if ($$.config.axis_rotated) {\n    padding = $$.isBarType(d) ? 4 : 6;\n    xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1);\n  } else {\n    xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0];\n  }\n  // show labels regardless of the domain if value is null\n  if (d.value === null) {\n    if (xPos > $$.width) {\n      xPos = $$.width - box.width;\n    } else if (xPos < 0) {\n      xPos = 4;\n    }\n  }\n  return xPos\n};\nChartInternal.prototype.getYForText = function(points, d, textElement) {\n  var $$ = this,\n    box = getBBox(textElement),\n    yPos;\n  if ($$.config.axis_rotated) {\n    yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2;\n  } else {\n    yPos = points[2][1];\n    if (d.value < 0 || (d.value === 0 && !$$.hasPositiveValue)) {\n      yPos += box.height;\n      if ($$.isBarType(d) && $$.isSafari()) {\n        yPos -= 3;\n      } else if (!$$.isBarType(d) && $$.isChrome()) {\n        yPos += 3;\n      }\n    } else {\n      yPos += $$.isBarType(d) ? -3 : -6;\n    }\n  }\n  // show labels regardless of the domain if value is null\n  if (d.value === null && !$$.config.axis_rotated) {\n    if (yPos < box.height) {\n      yPos = box.height;\n    } else if (yPos > this.height) {\n      yPos = this.height - 4;\n    }\n  }\n  return yPos\n};\n\nChartInternal.prototype.initTitle = function() {\n  var $$ = this;\n  $$.title = $$.svg\n    .append('text')\n    .text($$.config.title_text)\n    .attr('class', $$.CLASS.title);\n};\nChartInternal.prototype.redrawTitle = function() {\n  var $$ = this;\n  $$.title.attr('x', $$.xForTitle.bind($$)).attr('y', $$.yForTitle.bind($$));\n};\nChartInternal.prototype.xForTitle = function() {\n  var $$ = this,\n    config = $$.config,\n    position = config.title_position || 'left',\n    x;\n  if (position.indexOf('right') >= 0) {\n    x =\n      $$.currentWidth -\n      $$.getTextRect(\n        $$.title.node().textContent,\n        $$.CLASS.title,\n        $$.title.node()\n      ).width -\n      config.title_padding.right;\n  } else if (position.indexOf('center') >= 0) {\n    x = Math.max(\n      ($$.currentWidth -\n        $$.getTextRect(\n          $$.title.node().textContent,\n          $$.CLASS.title,\n          $$.title.node()\n        ).width) /\n        2,\n      0\n    );\n  } else {\n    // left\n    x = config.title_padding.left;\n  }\n  return x\n};\nChartInternal.prototype.yForTitle = function() {\n  var $$ = this;\n  return (\n    $$.config.title_padding.top +\n    $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node())\n      .height\n  )\n};\nChartInternal.prototype.getTitlePadding = function() {\n  var $$ = this;\n  return $$.yForTitle() + $$.config.title_padding.bottom\n};\n\nfunction powerOfTen(d) {\n  return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1\n}\n\nChartInternal.prototype.drawColorScale = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    target = $$.data.targets[0],\n    barWidth,\n    barHeight,\n    axis,\n    points,\n    legendAxis,\n    axisScale,\n    inverseScale,\n    height;\n\n  barWidth = !isNaN(config.stanford_scaleWidth)\n    ? config.stanford_scaleWidth\n    : 20;\n  barHeight = 5;\n\n  if (barHeight < 0 || barWidth < 0) {\n    throw Error(\"Colorscale's barheight and barwidth must be greater than 0.\")\n  }\n\n  height =\n    $$.height - config.stanford_padding.bottom - config.stanford_padding.top;\n\n  points = d3.range(config.stanford_padding.bottom, height, barHeight);\n\n  inverseScale = d3\n    .scaleSequential(target.colors)\n    .domain([points[points.length - 1], points[0]]);\n\n  if ($$.colorScale) {\n    $$.colorScale.remove();\n  }\n\n  $$.colorScale = $$.svg\n    .append('g')\n    .attr('width', 50)\n    .attr('height', height)\n    .attr('class', CLASS.colorScale);\n\n  $$.colorScale\n    .append('g')\n    .attr('transform', `translate(0, ${config.stanford_padding.top})`)\n    .selectAll('bars')\n    .data(points)\n    .enter()\n    .append('rect')\n    .attr('y', (d, i) => i * barHeight)\n    .attr('x', 0)\n    .attr('width', barWidth)\n    .attr('height', barHeight)\n    .attr('fill', function(d) {\n      return inverseScale(d)\n    });\n\n  // Legend Axis\n  axisScale = d3\n    .scaleLog()\n    .domain([target.minEpochs, target.maxEpochs])\n    .range([\n      points[0] +\n        config.stanford_padding.top +\n        points[points.length - 1] +\n        barHeight -\n        1,\n      points[0] + config.stanford_padding.top\n    ]);\n\n  legendAxis = d3.axisRight(axisScale);\n\n  if (config.stanford_scaleFormat === 'pow10') {\n    legendAxis.tickValues([1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]);\n  } else if (isFunction(config.stanford_scaleFormat)) {\n    legendAxis.tickFormat(config.stanford_scaleFormat);\n  } else {\n    legendAxis.tickFormat(d3.format('d'));\n  }\n\n  if (isFunction(config.stanford_scaleValues)) {\n    legendAxis.tickValues(\n      config.stanford_scaleValues(target.minEpochs, target.maxEpochs)\n    );\n  }\n\n  // Draw Axis\n  axis = $$.colorScale\n    .append('g')\n    .attr('class', 'legend axis')\n    .attr('transform', `translate(${barWidth},0)`)\n    .call(legendAxis);\n\n  if (config.stanford_scaleFormat === 'pow10') {\n    axis\n      .selectAll('.tick text')\n      .text(null)\n      .filter(powerOfTen)\n      .text(10)\n      .append('tspan')\n      .attr('dy', '-.7em') // https://bl.ocks.org/mbostock/6738229\n      .text(function(d) {\n        return Math.round(Math.log(d) / Math.LN10)\n      });\n  }\n\n  $$.colorScale.attr(\n    'transform',\n    `translate(${$$.currentWidth - $$.xForColorScale()}, 0)`\n  );\n};\n\nChartInternal.prototype.xForColorScale = function() {\n  var $$ = this;\n\n  return $$.config.stanford_padding.right + getBBox($$.colorScale.node()).width\n};\n\nChartInternal.prototype.getColorScalePadding = function() {\n  var $$ = this;\n  return $$.xForColorScale() + $$.config.stanford_padding.left + 20\n};\n\nChartInternal.prototype.isStanfordGraphType = function() {\n  var $$ = this;\n\n  return $$.config.data_type === 'stanford'\n};\n\nChartInternal.prototype.initStanfordData = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    target = $$.data.targets[0],\n    epochs,\n    maxEpochs,\n    minEpochs;\n\n  // Make larger values appear on top\n  target.values.sort(compareEpochs);\n\n  // Get array of epochs\n  epochs = target.values.map(a => a.epochs);\n\n  minEpochs = !isNaN(config.stanford_scaleMin)\n    ? config.stanford_scaleMin\n    : d3.min(epochs);\n  maxEpochs = !isNaN(config.stanford_scaleMax)\n    ? config.stanford_scaleMax\n    : d3.max(epochs);\n\n  if (minEpochs > maxEpochs) {\n    throw Error('Number of minEpochs has to be smaller than maxEpochs')\n  }\n\n  target.colors = isFunction(config.stanford_colors)\n    ? config.stanford_colors\n    : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5));\n\n  target.colorscale = d3\n    .scaleSequentialLog(target.colors)\n    .domain([minEpochs, maxEpochs]);\n\n  target.minEpochs = minEpochs;\n  target.maxEpochs = maxEpochs;\n};\n\nChartInternal.prototype.getStanfordPointColor = function(d) {\n  var $$ = this,\n    target = $$.data.targets[0];\n\n  return target.colorscale(d.epochs)\n};\n\n// http://jsfiddle.net/Xotic750/KtzLq/\nChartInternal.prototype.getCentroid = function(points) {\n  var area = getRegionArea(points);\n\n  var x = 0,\n    y = 0,\n    i,\n    j,\n    f,\n    point1,\n    point2;\n\n  for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {\n    point1 = points[i];\n    point2 = points[j];\n    f = point1.x * point2.y - point2.x * point1.y;\n    x += (point1.x + point2.x) * f;\n    y += (point1.y + point2.y) * f;\n  }\n\n  f = area * 6;\n\n  return {\n    x: x / f,\n    y: y / f\n  }\n};\n\nChartInternal.prototype.getStanfordTooltipTitle = function(d) {\n  var $$ = this,\n    labelX = $$.axis.getLabelText('x'),\n    labelY = $$.axis.getLabelText('y');\n\n  return `\n      <tr><th>${labelX ? sanitise(labelX) : 'x'}</th><th class='value'>${\n    d.x\n  }</th></tr>\n      <tr><th>${labelY ? sanitise(labelY) : 'y'}</th><th class='value'>${\n    d.value\n  }</th></tr>\n    `\n};\n\nChartInternal.prototype.countEpochsInRegion = function(region) {\n  var $$ = this,\n    target = $$.data.targets[0],\n    total,\n    count;\n\n  total = target.values.reduce(\n    (accumulator, currentValue) => accumulator + Number(currentValue.epochs),\n    0\n  );\n\n  count = target.values.reduce((accumulator, currentValue) => {\n    if (pointInRegion(currentValue, region)) {\n      return accumulator + Number(currentValue.epochs)\n    }\n\n    return accumulator\n  }, 0);\n\n  return {\n    value: count,\n    percentage: count !== 0 ? ((count / total) * 100).toFixed(1) : 0\n  }\n};\n\nvar getRegionArea = function(points) {\n  // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript\n  var area = 0,\n    i,\n    j,\n    point1,\n    point2;\n\n  for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {\n    point1 = points[i];\n    point2 = points[j];\n    area += point1.x * point2.y;\n    area -= point1.y * point2.x;\n  }\n\n  area /= 2;\n\n  return area\n};\n\nvar pointInRegion = function(point, region) {\n  // thanks to: http://bl.ocks.org/bycoffe/5575904\n  // ray-casting algorithm based on\n  // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html\n  let xi,\n    yi,\n    yj,\n    xj,\n    intersect,\n    x = point.x,\n    y = point.value,\n    inside = false;\n\n  for (let i = 0, j = region.length - 1; i < region.length; j = i++) {\n    xi = region[i].x;\n    yi = region[i].y;\n\n    xj = region[j].x;\n    yj = region[j].y;\n\n    intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;\n\n    if (intersect) {\n      inside = !inside;\n    }\n  }\n\n  return inside\n};\n\nvar compareEpochs = function(a, b) {\n  if (a.epochs < b.epochs) {\n    return -1\n  }\n  if (a.epochs > b.epochs) {\n    return 1\n  }\n\n  return 0\n};\n\nChartInternal.prototype.initStanfordElements = function() {\n  var $$ = this;\n\n  // Avoid blocking eventRect\n  $$.stanfordElements = $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.stanfordElements);\n\n  $$.stanfordElements.append('g').attr('class', CLASS.stanfordLines);\n  $$.stanfordElements.append('g').attr('class', CLASS.stanfordTexts);\n  $$.stanfordElements.append('g').attr('class', CLASS.stanfordRegions);\n};\n\nChartInternal.prototype.updateStanfordElements = function(duration) {\n  var $$ = this,\n    main = $$.main,\n    config = $$.config,\n    stanfordLine,\n    stanfordLineEnter,\n    stanfordRegion,\n    stanfordRegionEnter,\n    stanfordText,\n    stanfordTextEnter,\n    xvCustom = $$.xvCustom.bind($$),\n    yvCustom = $$.yvCustom.bind($$),\n    countPointsInRegion = $$.countEpochsInRegion.bind($$);\n\n  // Stanford-Lines\n  stanfordLine = main\n    .select('.' + CLASS.stanfordLines)\n    .style('shape-rendering', 'geometricprecision')\n    .selectAll('.' + CLASS.stanfordLine)\n    .data(config.stanford_lines);\n\n  // enter\n  stanfordLineEnter = stanfordLine\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : '')\n    });\n  stanfordLineEnter\n    .append('line')\n    .attr('x1', d =>\n      config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1')\n    )\n    .attr('x2', d =>\n      config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2')\n    )\n    .attr('y1', d =>\n      config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1')\n    )\n    .attr('y2', d =>\n      config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2')\n    )\n    .style('opacity', 0);\n\n  // update\n  $$.stanfordLines = stanfordLineEnter.merge(stanfordLine);\n  $$.stanfordLines\n    .select('line')\n    .transition()\n    .duration(duration)\n    .attr('x1', d =>\n      config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1')\n    )\n    .attr('x2', d =>\n      config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2')\n    )\n    .attr('y1', d =>\n      config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1')\n    )\n    .attr('y2', d =>\n      config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2')\n    )\n    .style('opacity', 1);\n\n  // exit\n  stanfordLine\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove();\n\n  // Stanford-Text\n  stanfordText = main\n    .select('.' + CLASS.stanfordTexts)\n    .selectAll('.' + CLASS.stanfordText)\n    .data(config.stanford_texts);\n\n  // enter\n  stanfordTextEnter = stanfordText\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : '')\n    });\n  stanfordTextEnter\n    .append('text')\n    .attr('x', d => (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')))\n    .attr('y', d => (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')))\n    .style('opacity', 0);\n\n  // update\n  $$.stanfordTexts = stanfordTextEnter.merge(stanfordText);\n  $$.stanfordTexts\n    .select('text')\n    .transition()\n    .duration(duration)\n    .attr('x', d => (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')))\n    .attr('y', d => (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')))\n    .text(function(d) {\n      return d.content\n    })\n    .style('opacity', 1);\n\n  // exit\n  stanfordText\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove();\n\n  // Stanford-Regions\n  stanfordRegion = main\n    .select('.' + CLASS.stanfordRegions)\n    .selectAll('.' + CLASS.stanfordRegion)\n    .data(config.stanford_regions);\n\n  // enter\n  stanfordRegionEnter = stanfordRegion\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : '')\n    });\n  stanfordRegionEnter\n    .append('polygon')\n    .attr('points', d => {\n      return d.points\n        .map(value => {\n          return [\n            config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'),\n            config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')\n          ].join(',')\n        })\n        .join(' ')\n    })\n    .style('opacity', 0);\n  stanfordRegionEnter\n    .append('text')\n    .attr('x', d => $$.getCentroid(d.points).x)\n    .attr('y', d => $$.getCentroid(d.points).y)\n    .style('opacity', 0);\n\n  // update\n  $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion);\n  $$.stanfordRegions\n    .select('polygon')\n    .transition()\n    .duration(duration)\n    .attr('points', d => {\n      return d.points\n        .map(value => {\n          return [\n            config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'),\n            config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')\n          ].join(',')\n        })\n        .join(' ')\n    })\n    .style('opacity', d => {\n      return d.opacity ? d.opacity : 0.2\n    });\n  $$.stanfordRegions\n    .select('text')\n    .transition()\n    .duration(duration)\n    .attr('x', d =>\n      config.axis_rotated\n        ? yvCustom($$.getCentroid(d.points), 'y')\n        : xvCustom($$.getCentroid(d.points), 'x')\n    )\n    .attr('y', d =>\n      config.axis_rotated\n        ? xvCustom($$.getCentroid(d.points), 'x')\n        : yvCustom($$.getCentroid(d.points), 'y')\n    )\n    .text(function(d) {\n      if (d.text) {\n        var value, percentage, temp;\n\n        if ($$.isStanfordGraphType()) {\n          temp = countPointsInRegion(d.points);\n          value = temp.value;\n          percentage = temp.percentage;\n        }\n\n        return d.text(value, percentage)\n      }\n\n      return ''\n    })\n    .attr('text-anchor', 'middle')\n    .attr('dominant-baseline', 'middle')\n    .style('opacity', 1);\n  // exit\n  stanfordRegion\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove();\n};\n\nChartInternal.prototype.initTooltip = function() {\n  var $$ = this,\n    config = $$.config,\n    i;\n  $$.tooltip = $$.selectChart\n    .style('position', 'relative')\n    .append('div')\n    .attr('class', CLASS.tooltipContainer)\n    .style('position', 'absolute')\n    .style('pointer-events', 'none')\n    .style('display', 'none');\n  // Show tooltip if needed\n  if (config.tooltip_init_show) {\n    if ($$.isTimeSeries() && isString(config.tooltip_init_x)) {\n      config.tooltip_init_x = $$.parseDate(config.tooltip_init_x);\n      for (i = 0; i < $$.data.targets[0].values.length; i++) {\n        if ($$.data.targets[0].values[i].x - config.tooltip_init_x === 0) {\n          break\n        }\n      }\n      config.tooltip_init_x = i;\n    }\n    $$.tooltip.html(\n      config.tooltip_contents.call(\n        $$,\n        $$.data.targets.map(function(d) {\n          return $$.addName(d.values[config.tooltip_init_x])\n        }),\n        $$.axis.getXAxisTickFormat(),\n        $$.getYFormat($$.hasArcType()),\n        $$.color\n      )\n    );\n    $$.tooltip\n      .style('top', config.tooltip_init_position.top)\n      .style('left', config.tooltip_init_position.left)\n      .style('display', 'block');\n  }\n};\nChartInternal.prototype.getTooltipSortFunction = function() {\n  var $$ = this,\n    config = $$.config;\n\n  if (config.data_groups.length === 0 || config.tooltip_order !== undefined) {\n    // if data are not grouped or if an order is specified\n    // for the tooltip values we sort them by their values\n\n    var order = config.tooltip_order;\n    if (order === undefined) {\n      order = config.data_order;\n    }\n\n    var valueOf = function(obj) {\n      return obj ? obj.value : null\n    };\n\n    // if data are not grouped, we sort them by their value\n    if (isString(order) && order.toLowerCase() === 'asc') {\n      return function(a, b) {\n        return valueOf(a) - valueOf(b)\n      }\n    } else if (isString(order) && order.toLowerCase() === 'desc') {\n      return function(a, b) {\n        return valueOf(b) - valueOf(a)\n      }\n    } else if (isFunction(order)) {\n      // if the function is from data_order we need\n      // to wrap the returned function in order to format\n      // the sorted value to the expected format\n\n      var sortFunction = order;\n\n      if (config.tooltip_order === undefined) {\n        sortFunction = function(a, b) {\n          return order(\n            a\n              ? {\n                  id: a.id,\n                  values: [a]\n                }\n              : null,\n            b\n              ? {\n                  id: b.id,\n                  values: [b]\n                }\n              : null\n          )\n        };\n      }\n\n      return sortFunction\n    } else if (isArray(order)) {\n      return function(a, b) {\n        return order.indexOf(a.id) - order.indexOf(b.id)\n      }\n    }\n  } else {\n    // if data are grouped, we follow the order of grouped targets\n    var ids = $$.orderTargets($$.data.targets).map(function(i) {\n      return i.id\n    });\n\n    // if it was either asc or desc we need to invert the order\n    // returned by orderTargets\n    if ($$.isOrderAsc() || $$.isOrderDesc()) {\n      ids = ids.reverse();\n    }\n\n    return function(a, b) {\n      return ids.indexOf(a.id) - ids.indexOf(b.id)\n    }\n  }\n};\nChartInternal.prototype.getTooltipContent = function(\n  d,\n  defaultTitleFormat,\n  defaultValueFormat,\n  color\n) {\n  var $$ = this,\n    config = $$.config,\n    titleFormat = config.tooltip_format_title || defaultTitleFormat,\n    nameFormat =\n      config.tooltip_format_name ||\n      function(name) {\n        return name\n      },\n    text,\n    i,\n    title,\n    value,\n    name,\n    bgcolor;\n\n  var valueFormat = config.tooltip_format_value;\n  if (!valueFormat) {\n    valueFormat = $$.isTargetNormalized(d.id)\n      ? (v, ratio) => `${(ratio * 100).toFixed(2)}%`\n      : defaultValueFormat;\n  }\n\n  var tooltipSortFunction = this.getTooltipSortFunction();\n  if (tooltipSortFunction) {\n    d.sort(tooltipSortFunction);\n  }\n\n  for (i = 0; i < d.length; i++) {\n    if (!(d[i] && (d[i].value || d[i].value === 0))) {\n      continue\n    }\n\n    if ($$.isStanfordGraphType()) {\n      // Custom tooltip for stanford plots\n      if (!text) {\n        title = $$.getStanfordTooltipTitle(d[i]);\n        text = \"<table class='\" + $$.CLASS.tooltip + \"'>\" + title;\n      }\n\n      bgcolor = $$.getStanfordPointColor(d[i]);\n      name = sanitise(config.data_epochs); // Epochs key name\n      value = d[i].epochs;\n    } else {\n      // Regular tooltip\n      if (!text) {\n        title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x);\n        text =\n          \"<table class='\" +\n          $$.CLASS.tooltip +\n          \"'>\" +\n          (title || title === 0\n            ? \"<tr><th colspan='2'>\" + title + '</th></tr>'\n            : '');\n      }\n\n      value = sanitise(\n        valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d)\n      );\n      if (value !== undefined) {\n        // Skip elements when their name is set to null\n        if (d[i].name === null) {\n          continue\n        }\n\n        name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index));\n        bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);\n      }\n    }\n\n    if (value !== undefined) {\n      text +=\n        \"<tr class='\" +\n        $$.CLASS.tooltipName +\n        '-' +\n        $$.getTargetSelectorSuffix(d[i].id) +\n        \"'>\";\n      text +=\n        \"<td class='name'><span style='background-color:\" +\n        bgcolor +\n        \"'></span>\" +\n        name +\n        '</td>';\n      text += \"<td class='value'>\" + value + '</td>';\n      text += '</tr>';\n    }\n  }\n  return text + '</table>'\n};\nChartInternal.prototype.tooltipPosition = function(\n  dataToShow,\n  tWidth,\n  tHeight,\n  element\n) {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3;\n  var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight;\n  var forArc = $$.hasArcType(),\n    mouse = d3.mouse(element);\n  // Determin tooltip position\n  if (forArc) {\n    tooltipLeft =\n      ($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2 + mouse[0];\n    tooltipTop =\n      ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20;\n  } else {\n    svgLeft = $$.getSvgLeft(true);\n    if (config.axis_rotated) {\n      tooltipLeft = svgLeft + mouse[0] + 100;\n      tooltipRight = tooltipLeft + tWidth;\n      chartRight = $$.currentWidth - $$.getCurrentPaddingRight();\n      tooltipTop = $$.x(dataToShow[0].x) + 20;\n    } else {\n      tooltipLeft =\n        svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20;\n      tooltipRight = tooltipLeft + tWidth;\n      chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight();\n      tooltipTop = mouse[1] + 15;\n    }\n\n    if (tooltipRight > chartRight) {\n      // 20 is needed for Firefox to keep tooltip width\n      tooltipLeft -= tooltipRight - chartRight + 20;\n    }\n    if (tooltipTop + tHeight > $$.currentHeight) {\n      tooltipTop -= tHeight + 30;\n    }\n  }\n  if (tooltipTop < 0) {\n    tooltipTop = 0;\n  }\n  return {\n    top: tooltipTop,\n    left: tooltipLeft\n  }\n};\nChartInternal.prototype.showTooltip = function(selectedData, element) {\n  var $$ = this,\n    config = $$.config;\n  var tWidth, tHeight, position;\n  var forArc = $$.hasArcType(),\n    dataToShow = selectedData.filter(function(d) {\n      return d && isValue(d.value)\n    }),\n    positionFunction =\n      config.tooltip_position || ChartInternal.prototype.tooltipPosition;\n  if (dataToShow.length === 0 || !config.tooltip_show) {\n    $$.hideTooltip();\n    return\n  }\n  $$.tooltip\n    .html(\n      config.tooltip_contents.call(\n        $$,\n        selectedData,\n        $$.axis.getXAxisTickFormat(),\n        $$.getYFormat(forArc),\n        $$.color\n      )\n    )\n    .style('display', 'block');\n\n  // Get tooltip dimensions\n  tWidth = $$.tooltip.property('offsetWidth');\n  tHeight = $$.tooltip.property('offsetHeight');\n\n  position = positionFunction.call(this, dataToShow, tWidth, tHeight, element);\n  // Set tooltip\n  $$.tooltip\n    .style('top', position.top + 'px')\n    .style('left', position.left + 'px');\n};\nChartInternal.prototype.hideTooltip = function() {\n  this.tooltip.style('display', 'none');\n};\n\nChartInternal.prototype.setTargetType = function(targetIds, type) {\n  var $$ = this,\n    config = $$.config;\n  $$.mapToTargetIds(targetIds).forEach(function(id) {\n    $$.withoutFadeIn[id] = type === config.data_types[id];\n    config.data_types[id] = type;\n  });\n  if (!targetIds) {\n    config.data_type = type;\n  }\n};\nChartInternal.prototype.hasType = function(type, targets) {\n  var $$ = this,\n    types = $$.config.data_types,\n    has = false;\n  targets = targets || $$.data.targets;\n  if (targets && targets.length) {\n    targets.forEach(function(target) {\n      var t = types[target.id];\n      if ((t && t.indexOf(type) >= 0) || (!t && type === 'line')) {\n        has = true;\n      }\n    });\n  } else if (Object.keys(types).length) {\n    Object.keys(types).forEach(function(id) {\n      if (types[id] === type) {\n        has = true;\n      }\n    });\n  } else {\n    has = $$.config.data_type === type;\n  }\n  return has\n};\nChartInternal.prototype.hasArcType = function(targets) {\n  return (\n    this.hasType('pie', targets) ||\n    this.hasType('donut', targets) ||\n    this.hasType('gauge', targets)\n  )\n};\nChartInternal.prototype.isLineType = function(d) {\n  var config = this.config,\n    id = isString(d) ? d : d.id;\n  return (\n    !config.data_types[id] ||\n    ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(\n      config.data_types[id]\n    ) >= 0\n  )\n};\nChartInternal.prototype.isStepType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0\n};\nChartInternal.prototype.isSplineType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0\n};\nChartInternal.prototype.isAreaType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return (\n    ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >=\n    0\n  )\n};\nChartInternal.prototype.isBarType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return this.config.data_types[id] === 'bar'\n};\nChartInternal.prototype.isScatterType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return this.config.data_types[id] === 'scatter'\n};\nChartInternal.prototype.isStanfordType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return this.config.data_types[id] === 'stanford'\n};\nChartInternal.prototype.isPieType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return this.config.data_types[id] === 'pie'\n};\nChartInternal.prototype.isGaugeType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return this.config.data_types[id] === 'gauge'\n};\nChartInternal.prototype.isDonutType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return this.config.data_types[id] === 'donut'\n};\nChartInternal.prototype.isArcType = function(d) {\n  return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d)\n};\nChartInternal.prototype.lineData = function(d) {\n  return this.isLineType(d) ? [d] : []\n};\nChartInternal.prototype.arcData = function(d) {\n  return this.isArcType(d.data) ? [d] : []\n};\n/* not used\n function scatterData(d) {\n return isScatterType(d) ? d.values : [];\n }\n */\nChartInternal.prototype.barData = function(d) {\n  return this.isBarType(d) ? d.values : []\n};\nChartInternal.prototype.lineOrScatterOrStanfordData = function(d) {\n  return this.isLineType(d) || this.isScatterType(d) || this.isStanfordType(d)\n    ? d.values\n    : []\n};\nChartInternal.prototype.barOrLineData = function(d) {\n  return this.isBarType(d) || this.isLineType(d) ? d.values : []\n};\n\nChartInternal.prototype.isSafari = function() {\n  var ua = window.navigator.userAgent;\n  return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0\n};\nChartInternal.prototype.isChrome = function() {\n  var ua = window.navigator.userAgent;\n  return ua.indexOf('Chrome') >= 0\n};\n\nChartInternal.prototype.initZoom = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    startEvent;\n\n  $$.zoom = d3\n    .zoom()\n    .on('start', function() {\n      if (config.zoom_type !== 'scroll') {\n        return\n      }\n\n      var e = d3.event.sourceEvent;\n      if (e && e.type === 'brush') {\n        return\n      }\n      startEvent = e;\n      config.zoom_onzoomstart.call($$.api, e);\n    })\n    .on('zoom', function() {\n      if (config.zoom_type !== 'scroll') {\n        return\n      }\n\n      var e = d3.event.sourceEvent;\n      if (e && e.type === 'brush') {\n        return\n      }\n\n      $$.redrawForZoom();\n\n      config.zoom_onzoom.call($$.api, $$.x.orgDomain());\n    })\n    .on('end', function() {\n      if (config.zoom_type !== 'scroll') {\n        return\n      }\n\n      var e = d3.event.sourceEvent;\n      if (e && e.type === 'brush') {\n        return\n      }\n      // if click, do nothing. otherwise, click interaction will be canceled.\n      if (\n        e &&\n        startEvent.clientX === e.clientX &&\n        startEvent.clientY === e.clientY\n      ) {\n        return\n      }\n      config.zoom_onzoomend.call($$.api, $$.x.orgDomain());\n    });\n\n  $$.zoom.updateDomain = function() {\n    if (d3.event && d3.event.transform) {\n      $$.x.domain(d3.event.transform.rescaleX($$.subX).domain());\n    }\n    return this\n  };\n  $$.zoom.updateExtent = function() {\n    this.scaleExtent([1, Infinity])\n      .translateExtent([\n        [0, 0],\n        [$$.width, $$.height]\n      ])\n      .extent([\n        [0, 0],\n        [$$.width, $$.height]\n      ]);\n    return this\n  };\n  $$.zoom.update = function() {\n    return this.updateExtent().updateDomain()\n  };\n\n  return $$.zoom.updateExtent()\n};\nChartInternal.prototype.zoomTransform = function(range) {\n  var $$ = this,\n    s = [$$.x(range[0]), $$.x(range[1])];\n  return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0)\n};\n\nChartInternal.prototype.initDragZoom = function() {\n  const $$ = this;\n  const d3 = $$.d3;\n  const config = $$.config;\n  const context = ($$.context = $$.svg);\n  const brushXPos = $$.margin.left + 20.5;\n  const brushYPos = $$.margin.top + 0.5;\n\n  if (!(config.zoom_type === 'drag' && config.zoom_enabled)) {\n    return\n  }\n\n  const getZoomedDomain = selection =>\n    selection && selection.map(x => $$.x.invert(x));\n\n  const brush = ($$.dragZoomBrush = d3\n    .brushX()\n    .on('start', () => {\n      $$.api.unzoom();\n\n      $$.svg.select('.' + CLASS.dragZoom).classed('disabled', false);\n\n      config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent);\n    })\n    .on('brush', () => {\n      config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection));\n    })\n    .on('end', () => {\n      if (d3.event.selection == null) {\n        return\n      }\n\n      const zoomedDomain = getZoomedDomain(d3.event.selection);\n\n      if (!config.zoom_disableDefaultBehavior) {\n        $$.api.zoom(zoomedDomain);\n      }\n\n      $$.svg.select('.' + CLASS.dragZoom).classed('disabled', true);\n\n      config.zoom_onzoomend.call($$.api, zoomedDomain);\n    }));\n\n  context\n    .append('g')\n    .classed(CLASS.dragZoom, true)\n    .attr('clip-path', $$.clipPath)\n    .attr('transform', 'translate(' + brushXPos + ',' + brushYPos + ')')\n    .call(brush);\n};\n\nChartInternal.prototype.getZoomDomain = function() {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3,\n    min = d3.min([$$.orgXDomain[0], config.zoom_x_min]),\n    max = d3.max([$$.orgXDomain[1], config.zoom_x_max]);\n  return [min, max]\n};\nChartInternal.prototype.redrawForZoom = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    zoom = $$.zoom,\n    x = $$.x;\n  if (!config.zoom_enabled) {\n    return\n  }\n  if ($$.filterTargetsToShow($$.data.targets).length === 0) {\n    return\n  }\n\n  zoom.update();\n\n  if (config.zoom_disableDefaultBehavior) {\n    return\n  }\n\n  if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) {\n    x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]);\n  }\n\n  $$.redraw({\n    withTransition: false,\n    withY: config.zoom_rescale,\n    withSubchart: false,\n    withEventRect: false,\n    withDimension: false\n  });\n\n  if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') {\n    $$.cancelClick = true;\n  }\n};\n\nexport default c3;\n"
  },
  {
    "path": "c3.js",
    "content": "/* @license C3.js v0.7.20 | (c) C3 Team and other contributors | http://c3js.org/ */\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) :\n  (global = global || self, global.c3 = factory());\n}(this, (function () { 'use strict';\n\n  function ChartInternal(api) {\r\n      var $$ = this;\r\n      // Note: This part will be replaced by rollup-plugin-modify\r\n      // When bundling esm output. Beware of changing this line.\r\n      // TODO: Maybe we should check that the modification by rollup-plugin-modify\r\n      // is valid during unit tests.\r\n      $$.d3 = window.d3\r\n          ? window.d3\r\n          : typeof require !== 'undefined'\r\n              ? require('d3')\r\n              : undefined;\r\n      $$.api = api;\r\n      $$.config = $$.getDefaultConfig();\r\n      $$.data = {};\r\n      $$.cache = {};\r\n      $$.axes = {};\r\n  }\n\n  /**\r\n   * The Chart class\r\n   *\r\n   * The methods of this class is the public APIs of the chart object.\r\n   */\r\n  function Chart(config) {\r\n      this.internal = new ChartInternal(this);\r\n      this.internal.loadConfig(config);\r\n      this.internal.beforeInit(config);\r\n      this.internal.init();\r\n      this.internal.afterInit(config);\r\n      (function bindThis(fn, target, argThis) {\r\n          Object.keys(fn).forEach(function (key) {\r\n              target[key] = fn[key].bind(argThis);\r\n              if (Object.keys(fn[key]).length > 0) {\r\n                  bindThis(fn[key], target[key], argThis);\r\n              }\r\n          });\r\n      })(Chart.prototype, this, this);\r\n  }\n\n  var asHalfPixel = function (n) {\r\n      return Math.ceil(n) + 0.5;\r\n  };\r\n  var ceil10 = function (v) {\r\n      return Math.ceil(v / 10) * 10;\r\n  };\r\n  var diffDomain = function (d) {\r\n      return d[1] - d[0];\r\n  };\r\n  var getOption = function (options, key, defaultValue) {\r\n      return isDefined(options[key]) ? options[key] : defaultValue;\r\n  };\r\n  var getPathBox = function (path) {\r\n      var box = getBBox(path), items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)], minX = items[0].x, minY = Math.min(items[0].y, items[1].y);\r\n      return { x: minX, y: minY, width: box.width, height: box.height };\r\n  };\r\n  var getBBox = function (element) {\r\n      try {\r\n          return element.getBBox();\r\n      }\r\n      catch (ignore) {\r\n          // Firefox will throw an exception if getBBox() is called whereas the\r\n          // element is rendered with display:none\r\n          // See https://github.com/c3js/c3/issues/2692\r\n          // The previous code was using `getBoundingClientRect` which was returning\r\n          // everything at 0 in this case so let's reproduce this behavior here.\r\n          return { x: 0, y: 0, width: 0, height: 0 };\r\n      }\r\n  };\r\n  var hasValue = function (dict, value) {\r\n      var found = false;\r\n      Object.keys(dict).forEach(function (key) {\r\n          if (dict[key] === value) {\r\n              found = true;\r\n          }\r\n      });\r\n      return found;\r\n  };\r\n  var isArray = function (o) {\r\n      return Array.isArray(o);\r\n  };\r\n  var isDefined = function (v) {\r\n      return typeof v !== 'undefined';\r\n  };\r\n  var isEmpty = function (o) {\r\n      return (typeof o === 'undefined' ||\r\n          o === null ||\r\n          (isString(o) && o.length === 0) ||\r\n          (typeof o === 'object' && Object.keys(o).length === 0));\r\n  };\r\n  var isFunction = function (o) {\r\n      return typeof o === 'function';\r\n  };\r\n  var isNumber = function (o) {\r\n      return typeof o === 'number';\r\n  };\r\n  var isString = function (o) {\r\n      return typeof o === 'string';\r\n  };\r\n  var isUndefined = function (v) {\r\n      return typeof v === 'undefined';\r\n  };\r\n  var isValue = function (v) {\r\n      return v || v === 0;\r\n  };\r\n  var notEmpty = function (o) {\r\n      return !isEmpty(o);\r\n  };\r\n  var sanitise = function (str) {\r\n      return typeof str === 'string'\r\n          ? str.replace(/</g, '&lt;').replace(/>/g, '&gt;')\r\n          : str;\r\n  };\r\n  var flattenArray = function (arr) {\r\n      return Array.isArray(arr) ? [].concat.apply([], arr) : [];\r\n  };\r\n  /**\r\n   * Returns whether the point is within the given box.\r\n   *\r\n   * @param {Array} point An [x,y] coordinate\r\n   * @param {Object} box An object with {x, y, width, height} keys\r\n   * @param {Number} sensitivity An offset to ease check on very small boxes\r\n   */\r\n  var isWithinBox = function (point, box, sensitivity) {\r\n      if (sensitivity === void 0) { sensitivity = 0; }\r\n      var xStart = box.x - sensitivity;\r\n      var xEnd = box.x + box.width + sensitivity;\r\n      var yStart = box.y + box.height + sensitivity;\r\n      var yEnd = box.y - sensitivity;\r\n      return (xStart < point[0] && point[0] < xEnd && yEnd < point[1] && point[1] < yStart);\r\n  };\r\n  /**\r\n   * Returns Internet Explorer version number (or false if no Internet Explorer used).\r\n   *\r\n   * @param string agent Optional parameter to specify user agent\r\n   */\r\n  var getIEVersion = function (agent) {\r\n      // https://stackoverflow.com/questions/19999388/check-if-user-is-using-ie\r\n      if (typeof agent === 'undefined') {\r\n          agent = window.navigator.userAgent;\r\n      }\r\n      var pos = agent.indexOf('MSIE '); // up to IE10\r\n      if (pos > 0) {\r\n          return parseInt(agent.substring(pos + 5, agent.indexOf('.', pos)), 10);\r\n      }\r\n      pos = agent.indexOf('Trident/'); // IE11\r\n      if (pos > 0) {\r\n          pos = agent.indexOf('rv:');\r\n          return parseInt(agent.substring(pos + 3, agent.indexOf('.', pos)), 10);\r\n      }\r\n      return false;\r\n  };\r\n  /**\r\n   * Returns whether the used browser is Internet Explorer.\r\n   *\r\n   * @param version Optional parameter to specify IE version\r\n   */\r\n  var isIE = function (version) {\r\n      var ver = getIEVersion();\r\n      if (typeof version === 'undefined') {\r\n          return !!ver;\r\n      }\r\n      return version === ver;\r\n  };\n\n  function AxisInternal(component, params) {\r\n      var internal = this;\r\n      internal.component = component;\r\n      internal.params = params || {};\r\n      internal.d3 = component.d3;\r\n      internal.scale = internal.d3.scaleLinear();\r\n      internal.range;\r\n      internal.orient = 'bottom';\r\n      internal.innerTickSize = 6;\r\n      internal.outerTickSize = this.params.withOuterTick ? 6 : 0;\r\n      internal.tickPadding = 3;\r\n      internal.tickValues = null;\r\n      internal.tickFormat;\r\n      internal.tickArguments;\r\n      internal.tickOffset = 0;\r\n      internal.tickCulling = true;\r\n      internal.tickCentered;\r\n      internal.tickTextCharSize;\r\n      internal.tickTextRotate = internal.params.tickTextRotate;\r\n      internal.tickLength;\r\n      internal.axis = internal.generateAxis();\r\n  }\r\n  AxisInternal.prototype.axisX = function (selection, x, tickOffset) {\r\n      selection.attr('transform', function (d) {\r\n          return 'translate(' + Math.ceil(x(d) + tickOffset) + ', 0)';\r\n      });\r\n  };\r\n  AxisInternal.prototype.axisY = function (selection, y) {\r\n      selection.attr('transform', function (d) {\r\n          return 'translate(0,' + Math.ceil(y(d)) + ')';\r\n      });\r\n  };\r\n  AxisInternal.prototype.scaleExtent = function (domain) {\r\n      var start = domain[0], stop = domain[domain.length - 1];\r\n      return start < stop ? [start, stop] : [stop, start];\r\n  };\r\n  AxisInternal.prototype.generateTicks = function (scale) {\r\n      var internal = this;\r\n      var i, domain, ticks = [];\r\n      if (scale.ticks) {\r\n          return scale.ticks.apply(scale, internal.tickArguments);\r\n      }\r\n      domain = scale.domain();\r\n      for (i = Math.ceil(domain[0]); i < domain[1]; i++) {\r\n          ticks.push(i);\r\n      }\r\n      if (ticks.length > 0 && ticks[0] > 0) {\r\n          ticks.unshift(ticks[0] - (ticks[1] - ticks[0]));\r\n      }\r\n      return ticks;\r\n  };\r\n  AxisInternal.prototype.copyScale = function () {\r\n      var internal = this;\r\n      var newScale = internal.scale.copy(), domain;\r\n      if (internal.params.isCategory) {\r\n          domain = internal.scale.domain();\r\n          newScale.domain([domain[0], domain[1] - 1]);\r\n      }\r\n      return newScale;\r\n  };\r\n  AxisInternal.prototype.textFormatted = function (v) {\r\n      var internal = this, formatted = internal.tickFormat ? internal.tickFormat(v) : v;\r\n      return typeof formatted !== 'undefined' ? formatted : '';\r\n  };\r\n  AxisInternal.prototype.updateRange = function () {\r\n      var internal = this;\r\n      internal.range = internal.scale.rangeExtent\r\n          ? internal.scale.rangeExtent()\r\n          : internal.scaleExtent(internal.scale.range());\r\n      return internal.range;\r\n  };\r\n  AxisInternal.prototype.updateTickTextCharSize = function (tick) {\r\n      var internal = this;\r\n      if (internal.tickTextCharSize) {\r\n          return internal.tickTextCharSize;\r\n      }\r\n      var size = {\r\n          h: 11.5,\r\n          w: 5.5\r\n      };\r\n      tick\r\n          .select('text')\r\n          .text(function (d) {\r\n          return internal.textFormatted(d);\r\n      })\r\n          .each(function (d) {\r\n          var box = getBBox(this), text = internal.textFormatted(d), h = box.height, w = text ? box.width / text.length : undefined;\r\n          if (h && w) {\r\n              size.h = h;\r\n              size.w = w;\r\n          }\r\n      })\r\n          .text('');\r\n      internal.tickTextCharSize = size;\r\n      return size;\r\n  };\r\n  AxisInternal.prototype.isVertical = function () {\r\n      return this.orient === 'left' || this.orient === 'right';\r\n  };\r\n  AxisInternal.prototype.tspanData = function (d, i, scale) {\r\n      var internal = this;\r\n      var splitted = internal.params.tickMultiline\r\n          ? internal.splitTickText(d, scale)\r\n          : [].concat(internal.textFormatted(d));\r\n      if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) {\r\n          splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax);\r\n      }\r\n      return splitted.map(function (s) {\r\n          return { index: i, splitted: s, length: splitted.length };\r\n      });\r\n  };\r\n  AxisInternal.prototype.splitTickText = function (d, scale) {\r\n      var internal = this, tickText = internal.textFormatted(d), maxWidth = internal.params.tickWidth, subtext, spaceIndex, textWidth, splitted = [];\r\n      if (Object.prototype.toString.call(tickText) === '[object Array]') {\r\n          return tickText;\r\n      }\r\n      if (!maxWidth || maxWidth <= 0) {\r\n          maxWidth = internal.isVertical()\r\n              ? 95\r\n              : internal.params.isCategory\r\n                  ? Math.ceil(scale(1) - scale(0)) - 12\r\n                  : 110;\r\n      }\r\n      function split(splitted, text) {\r\n          spaceIndex = undefined;\r\n          for (var i = 1; i < text.length; i++) {\r\n              if (text.charAt(i) === ' ') {\r\n                  spaceIndex = i;\r\n              }\r\n              subtext = text.substr(0, i + 1);\r\n              textWidth = internal.tickTextCharSize.w * subtext.length;\r\n              // if text width gets over tick width, split by space index or crrent index\r\n              if (maxWidth < textWidth) {\r\n                  return split(splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)), text.slice(spaceIndex ? spaceIndex + 1 : i));\r\n              }\r\n          }\r\n          return splitted.concat(text);\r\n      }\r\n      return split(splitted, tickText + '');\r\n  };\r\n  AxisInternal.prototype.ellipsify = function (splitted, max) {\r\n      if (splitted.length <= max) {\r\n          return splitted;\r\n      }\r\n      var ellipsified = splitted.slice(0, max);\r\n      var remaining = 3;\r\n      for (var i = max - 1; i >= 0; i--) {\r\n          var available = ellipsified[i].length;\r\n          ellipsified[i] = ellipsified[i]\r\n              .substr(0, available - remaining)\r\n              .padEnd(available, '.');\r\n          remaining -= available;\r\n          if (remaining <= 0) {\r\n              break;\r\n          }\r\n      }\r\n      return ellipsified;\r\n  };\r\n  AxisInternal.prototype.updateTickLength = function () {\r\n      var internal = this;\r\n      internal.tickLength =\r\n          Math.max(internal.innerTickSize, 0) + internal.tickPadding;\r\n  };\r\n  AxisInternal.prototype.lineY2 = function (d) {\r\n      var internal = this, tickPosition = internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset);\r\n      return internal.range[0] < tickPosition && tickPosition < internal.range[1]\r\n          ? internal.innerTickSize\r\n          : 0;\r\n  };\r\n  AxisInternal.prototype.textY = function () {\r\n      var internal = this, rotate = internal.tickTextRotate;\r\n      return rotate\r\n          ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1)\r\n          : internal.tickLength;\r\n  };\r\n  AxisInternal.prototype.textTransform = function () {\r\n      var internal = this, rotate = internal.tickTextRotate;\r\n      return rotate ? 'rotate(' + rotate + ')' : '';\r\n  };\r\n  AxisInternal.prototype.textTextAnchor = function () {\r\n      var internal = this, rotate = internal.tickTextRotate;\r\n      return rotate ? (rotate > 0 ? 'start' : 'end') : 'middle';\r\n  };\r\n  AxisInternal.prototype.tspanDx = function () {\r\n      var internal = this, rotate = internal.tickTextRotate;\r\n      return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0;\r\n  };\r\n  AxisInternal.prototype.tspanDy = function (d, i) {\r\n      var internal = this, dy = internal.tickTextCharSize.h;\r\n      if (i === 0) {\r\n          if (internal.isVertical()) {\r\n              dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3);\r\n          }\r\n          else {\r\n              dy = '.71em';\r\n          }\r\n      }\r\n      return dy;\r\n  };\r\n  AxisInternal.prototype.generateAxis = function () {\r\n      var internal = this, d3 = internal.d3, params = internal.params;\r\n      function axis(g, transition) {\r\n          var self;\r\n          g.each(function () {\r\n              var g = (axis.g = d3.select(this));\r\n              var scale0 = this.__chart__ || internal.scale, scale1 = (this.__chart__ = internal.copyScale());\r\n              var ticksValues = internal.tickValues\r\n                  ? internal.tickValues\r\n                  : internal.generateTicks(scale1), ticks = g.selectAll('.tick').data(ticksValues, scale1), tickEnter = ticks\r\n                  .enter()\r\n                  .insert('g', '.domain')\r\n                  .attr('class', 'tick')\r\n                  .style('opacity', 1e-6), \r\n              // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks.\r\n              tickExit = ticks.exit().remove(), tickUpdate = ticks.merge(tickEnter), tickTransform, tickX, tickY;\r\n              if (params.isCategory) {\r\n                  internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);\r\n                  tickX = internal.tickCentered ? 0 : internal.tickOffset;\r\n                  tickY = internal.tickCentered ? internal.tickOffset : 0;\r\n              }\r\n              else {\r\n                  internal.tickOffset = tickX = 0;\r\n              }\r\n              internal.updateRange();\r\n              internal.updateTickLength();\r\n              internal.updateTickTextCharSize(g.select('.tick'));\r\n              var lineUpdate = tickUpdate\r\n                  .select('line')\r\n                  .merge(tickEnter.append('line')), textUpdate = tickUpdate.select('text').merge(tickEnter.append('text'));\r\n              var tspans = tickUpdate\r\n                  .selectAll('text')\r\n                  .selectAll('tspan')\r\n                  .data(function (d, i) {\r\n                  return internal.tspanData(d, i, scale1);\r\n              }), tspanEnter = tspans.enter().append('tspan'), tspanUpdate = tspanEnter.merge(tspans).text(function (d) {\r\n                  return d.splitted;\r\n              });\r\n              tspans.exit().remove();\r\n              var path = g.selectAll('.domain').data([0]), pathUpdate = path\r\n                  .enter()\r\n                  .append('path')\r\n                  .merge(path)\r\n                  .attr('class', 'domain');\r\n              // TODO: each attr should be one function and change its behavior by internal.orient, probably\r\n              switch (internal.orient) {\r\n                  case 'bottom': {\r\n                      tickTransform = internal.axisX;\r\n                      lineUpdate\r\n                          .attr('x1', tickX)\r\n                          .attr('x2', tickX)\r\n                          .attr('y2', function (d, i) {\r\n                          return internal.lineY2(d, i);\r\n                      });\r\n                      textUpdate\r\n                          .attr('x', 0)\r\n                          .attr('y', function (d, i) {\r\n                          return internal.textY(d, i);\r\n                      })\r\n                          .attr('transform', function (d, i) {\r\n                          return internal.textTransform(d, i);\r\n                      })\r\n                          .style('text-anchor', function (d, i) {\r\n                          return internal.textTextAnchor(d, i);\r\n                      });\r\n                      tspanUpdate\r\n                          .attr('x', 0)\r\n                          .attr('dy', function (d, i) {\r\n                          return internal.tspanDy(d, i);\r\n                      })\r\n                          .attr('dx', function (d, i) {\r\n                          return internal.tspanDx(d, i);\r\n                      });\r\n                      pathUpdate.attr('d', 'M' +\r\n                          internal.range[0] +\r\n                          ',' +\r\n                          internal.outerTickSize +\r\n                          'V0H' +\r\n                          internal.range[1] +\r\n                          'V' +\r\n                          internal.outerTickSize);\r\n                      break;\r\n                  }\r\n                  case 'top': {\r\n                      // TODO: rotated tick text\r\n                      tickTransform = internal.axisX;\r\n                      lineUpdate\r\n                          .attr('x1', tickX)\r\n                          .attr('x2', tickX)\r\n                          .attr('y2', function (d, i) {\r\n                          return -1 * internal.lineY2(d, i);\r\n                      });\r\n                      textUpdate\r\n                          .attr('x', 0)\r\n                          .attr('y', function (d, i) {\r\n                          return (-1 * internal.textY(d, i) -\r\n                              (params.isCategory ? 2 : internal.tickLength - 2));\r\n                      })\r\n                          .attr('transform', function (d, i) {\r\n                          return internal.textTransform(d, i);\r\n                      })\r\n                          .style('text-anchor', function (d, i) {\r\n                          return internal.textTextAnchor(d, i);\r\n                      });\r\n                      tspanUpdate\r\n                          .attr('x', 0)\r\n                          .attr('dy', function (d, i) {\r\n                          return internal.tspanDy(d, i);\r\n                      })\r\n                          .attr('dx', function (d, i) {\r\n                          return internal.tspanDx(d, i);\r\n                      });\r\n                      pathUpdate.attr('d', 'M' +\r\n                          internal.range[0] +\r\n                          ',' +\r\n                          -internal.outerTickSize +\r\n                          'V0H' +\r\n                          internal.range[1] +\r\n                          'V' +\r\n                          -internal.outerTickSize);\r\n                      break;\r\n                  }\r\n                  case 'left': {\r\n                      tickTransform = internal.axisY;\r\n                      lineUpdate\r\n                          .attr('x2', -internal.innerTickSize)\r\n                          .attr('y1', tickY)\r\n                          .attr('y2', tickY);\r\n                      textUpdate\r\n                          .attr('x', -internal.tickLength)\r\n                          .attr('y', internal.tickOffset)\r\n                          .style('text-anchor', 'end');\r\n                      tspanUpdate\r\n                          .attr('x', -internal.tickLength)\r\n                          .attr('dy', function (d, i) {\r\n                          return internal.tspanDy(d, i);\r\n                      });\r\n                      pathUpdate.attr('d', 'M' +\r\n                          -internal.outerTickSize +\r\n                          ',' +\r\n                          internal.range[0] +\r\n                          'H0V' +\r\n                          internal.range[1] +\r\n                          'H' +\r\n                          -internal.outerTickSize);\r\n                      break;\r\n                  }\r\n                  case 'right': {\r\n                      tickTransform = internal.axisY;\r\n                      lineUpdate\r\n                          .attr('x2', internal.innerTickSize)\r\n                          .attr('y1', tickY)\r\n                          .attr('y2', tickY);\r\n                      textUpdate\r\n                          .attr('x', internal.tickLength)\r\n                          .attr('y', internal.tickOffset)\r\n                          .style('text-anchor', 'start');\r\n                      tspanUpdate.attr('x', internal.tickLength).attr('dy', function (d, i) {\r\n                          return internal.tspanDy(d, i);\r\n                      });\r\n                      pathUpdate.attr('d', 'M' +\r\n                          internal.outerTickSize +\r\n                          ',' +\r\n                          internal.range[0] +\r\n                          'H0V' +\r\n                          internal.range[1] +\r\n                          'H' +\r\n                          internal.outerTickSize);\r\n                      break;\r\n                  }\r\n              }\r\n              if (scale1.rangeBand) {\r\n                  var x = scale1, dx = x.rangeBand() / 2;\r\n                  scale0 = scale1 = function (d) {\r\n                      return x(d) + dx;\r\n                  };\r\n              }\r\n              else if (scale0.rangeBand) {\r\n                  scale0 = scale1;\r\n              }\r\n              else {\r\n                  tickExit.call(tickTransform, scale1, internal.tickOffset);\r\n              }\r\n              tickEnter.call(tickTransform, scale0, internal.tickOffset);\r\n              self = (transition ? tickUpdate.transition(transition) : tickUpdate)\r\n                  .style('opacity', 1)\r\n                  .call(tickTransform, scale1, internal.tickOffset);\r\n          });\r\n          return self;\r\n      }\r\n      axis.scale = function (x) {\r\n          if (!arguments.length) {\r\n              return internal.scale;\r\n          }\r\n          internal.scale = x;\r\n          return axis;\r\n      };\r\n      axis.orient = function (x) {\r\n          if (!arguments.length) {\r\n              return internal.orient;\r\n          }\r\n          internal.orient =\r\n              x in { top: 1, right: 1, bottom: 1, left: 1 } ? x + '' : 'bottom';\r\n          return axis;\r\n      };\r\n      axis.tickFormat = function (format) {\r\n          if (!arguments.length) {\r\n              return internal.tickFormat;\r\n          }\r\n          internal.tickFormat = format;\r\n          return axis;\r\n      };\r\n      axis.tickCentered = function (isCentered) {\r\n          if (!arguments.length) {\r\n              return internal.tickCentered;\r\n          }\r\n          internal.tickCentered = isCentered;\r\n          return axis;\r\n      };\r\n      axis.tickOffset = function () {\r\n          return internal.tickOffset;\r\n      };\r\n      axis.tickInterval = function () {\r\n          var interval, length;\r\n          if (params.isCategory) {\r\n              interval = internal.tickOffset * 2;\r\n          }\r\n          else {\r\n              length =\r\n                  axis.g\r\n                      .select('path.domain')\r\n                      .node()\r\n                      .getTotalLength() -\r\n                      internal.outerTickSize * 2;\r\n              interval = length / axis.g.selectAll('line').size();\r\n          }\r\n          return interval === Infinity ? 0 : interval;\r\n      };\r\n      axis.ticks = function () {\r\n          if (!arguments.length) {\r\n              return internal.tickArguments;\r\n          }\r\n          internal.tickArguments = arguments;\r\n          return axis;\r\n      };\r\n      axis.tickCulling = function (culling) {\r\n          if (!arguments.length) {\r\n              return internal.tickCulling;\r\n          }\r\n          internal.tickCulling = culling;\r\n          return axis;\r\n      };\r\n      axis.tickValues = function (x) {\r\n          if (typeof x === 'function') {\r\n              internal.tickValues = function () {\r\n                  return x(internal.scale.domain());\r\n              };\r\n          }\r\n          else {\r\n              if (!arguments.length) {\r\n                  return internal.tickValues;\r\n              }\r\n              internal.tickValues = x;\r\n          }\r\n          return axis;\r\n      };\r\n      return axis;\r\n  };\n\n  var CLASS = {\r\n      target: 'c3-target',\r\n      chart: 'c3-chart',\r\n      chartLine: 'c3-chart-line',\r\n      chartLines: 'c3-chart-lines',\r\n      chartBar: 'c3-chart-bar',\r\n      chartBars: 'c3-chart-bars',\r\n      chartText: 'c3-chart-text',\r\n      chartTexts: 'c3-chart-texts',\r\n      chartArc: 'c3-chart-arc',\r\n      chartArcs: 'c3-chart-arcs',\r\n      chartArcsTitle: 'c3-chart-arcs-title',\r\n      chartArcsBackground: 'c3-chart-arcs-background',\r\n      chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit',\r\n      chartArcsGaugeMax: 'c3-chart-arcs-gauge-max',\r\n      chartArcsGaugeMin: 'c3-chart-arcs-gauge-min',\r\n      selectedCircle: 'c3-selected-circle',\r\n      selectedCircles: 'c3-selected-circles',\r\n      eventRect: 'c3-event-rect',\r\n      eventRects: 'c3-event-rects',\r\n      eventRectsSingle: 'c3-event-rects-single',\r\n      eventRectsMultiple: 'c3-event-rects-multiple',\r\n      zoomRect: 'c3-zoom-rect',\r\n      brush: 'c3-brush',\r\n      dragZoom: 'c3-drag-zoom',\r\n      focused: 'c3-focused',\r\n      defocused: 'c3-defocused',\r\n      region: 'c3-region',\r\n      regions: 'c3-regions',\r\n      title: 'c3-title',\r\n      tooltipContainer: 'c3-tooltip-container',\r\n      tooltip: 'c3-tooltip',\r\n      tooltipName: 'c3-tooltip-name',\r\n      shape: 'c3-shape',\r\n      shapes: 'c3-shapes',\r\n      line: 'c3-line',\r\n      lines: 'c3-lines',\r\n      bar: 'c3-bar',\r\n      bars: 'c3-bars',\r\n      circle: 'c3-circle',\r\n      circles: 'c3-circles',\r\n      arc: 'c3-arc',\r\n      arcLabelLine: 'c3-arc-label-line',\r\n      arcs: 'c3-arcs',\r\n      area: 'c3-area',\r\n      areas: 'c3-areas',\r\n      empty: 'c3-empty',\r\n      text: 'c3-text',\r\n      texts: 'c3-texts',\r\n      gaugeValue: 'c3-gauge-value',\r\n      grid: 'c3-grid',\r\n      gridLines: 'c3-grid-lines',\r\n      xgrid: 'c3-xgrid',\r\n      xgrids: 'c3-xgrids',\r\n      xgridLine: 'c3-xgrid-line',\r\n      xgridLines: 'c3-xgrid-lines',\r\n      xgridFocus: 'c3-xgrid-focus',\r\n      ygrid: 'c3-ygrid',\r\n      ygrids: 'c3-ygrids',\r\n      ygridLine: 'c3-ygrid-line',\r\n      ygridLines: 'c3-ygrid-lines',\r\n      colorScale: 'c3-colorscale',\r\n      stanfordElements: 'c3-stanford-elements',\r\n      stanfordLine: 'c3-stanford-line',\r\n      stanfordLines: 'c3-stanford-lines',\r\n      stanfordRegion: 'c3-stanford-region',\r\n      stanfordRegions: 'c3-stanford-regions',\r\n      stanfordText: 'c3-stanford-text',\r\n      stanfordTexts: 'c3-stanford-texts',\r\n      axis: 'c3-axis',\r\n      axisX: 'c3-axis-x',\r\n      axisXLabel: 'c3-axis-x-label',\r\n      axisY: 'c3-axis-y',\r\n      axisYLabel: 'c3-axis-y-label',\r\n      axisY2: 'c3-axis-y2',\r\n      axisY2Label: 'c3-axis-y2-label',\r\n      legendBackground: 'c3-legend-background',\r\n      legendItem: 'c3-legend-item',\r\n      legendItemEvent: 'c3-legend-item-event',\r\n      legendItemTile: 'c3-legend-item-tile',\r\n      legendItemHidden: 'c3-legend-item-hidden',\r\n      legendItemFocused: 'c3-legend-item-focused',\r\n      dragarea: 'c3-dragarea',\r\n      EXPANDED: '_expanded_',\r\n      SELECTED: '_selected_',\r\n      INCLUDED: '_included_'\r\n  };\n\n  var AxisClass = /** @class */ (function () {\r\n      function AxisClass(owner) {\r\n          this.owner = owner;\r\n          this.d3 = owner.d3;\r\n          this.internal = AxisInternal;\r\n      }\r\n      return AxisClass;\r\n  }());\r\n  var Axis = AxisClass;\r\n  Axis.prototype.init = function init() {\r\n      var $$ = this.owner, config = $$.config, main = $$.main;\r\n      $$.axes.x = main\r\n          .append('g')\r\n          .attr('class', CLASS.axis + ' ' + CLASS.axisX)\r\n          .attr('clip-path', config.axis_x_inner ? '' : $$.clipPathForXAxis)\r\n          .attr('transform', $$.getTranslate('x'))\r\n          .style('visibility', config.axis_x_show ? 'visible' : 'hidden');\r\n      $$.axes.x\r\n          .append('text')\r\n          .attr('class', CLASS.axisXLabel)\r\n          .attr('transform', config.axis_rotated ? 'rotate(-90)' : '')\r\n          .style('text-anchor', this.textAnchorForXAxisLabel.bind(this));\r\n      $$.axes.y = main\r\n          .append('g')\r\n          .attr('class', CLASS.axis + ' ' + CLASS.axisY)\r\n          .attr('clip-path', config.axis_y_inner ? '' : $$.clipPathForYAxis)\r\n          .attr('transform', $$.getTranslate('y'))\r\n          .style('visibility', config.axis_y_show ? 'visible' : 'hidden');\r\n      $$.axes.y\r\n          .append('text')\r\n          .attr('class', CLASS.axisYLabel)\r\n          .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\r\n          .style('text-anchor', this.textAnchorForYAxisLabel.bind(this));\r\n      $$.axes.y2 = main\r\n          .append('g')\r\n          .attr('class', CLASS.axis + ' ' + CLASS.axisY2)\r\n          // clip-path?\r\n          .attr('transform', $$.getTranslate('y2'))\r\n          .style('visibility', config.axis_y2_show ? 'visible' : 'hidden');\r\n      $$.axes.y2\r\n          .append('text')\r\n          .attr('class', CLASS.axisY2Label)\r\n          .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\r\n          .style('text-anchor', this.textAnchorForY2AxisLabel.bind(this));\r\n  };\r\n  Axis.prototype.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {\r\n      var $$ = this.owner, config = $$.config, axisParams = {\r\n          isCategory: $$.isCategorized(),\r\n          withOuterTick: withOuterTick,\r\n          tickMultiline: config.axis_x_tick_multiline,\r\n          tickMultilineMax: config.axis_x_tick_multiline\r\n              ? Number(config.axis_x_tick_multilineMax)\r\n              : 0,\r\n          tickWidth: config.axis_x_tick_width,\r\n          tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate,\r\n          withoutTransition: withoutTransition\r\n      }, axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient);\r\n      if ($$.isTimeSeries() && tickValues && typeof tickValues !== 'function') {\r\n          tickValues = tickValues.map(function (v) {\r\n              return $$.parseDate(v);\r\n          });\r\n      }\r\n      // Set tick\r\n      axis.tickFormat(tickFormat).tickValues(tickValues);\r\n      if ($$.isCategorized()) {\r\n          axis.tickCentered(config.axis_x_tick_centered);\r\n          if (isEmpty(config.axis_x_tick_culling)) {\r\n              config.axis_x_tick_culling = false;\r\n          }\r\n      }\r\n      return axis;\r\n  };\r\n  Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues(targets, axis) {\r\n      var $$ = this.owner, config = $$.config, tickValues;\r\n      if (config.axis_x_tick_fit || config.axis_x_tick_count) {\r\n          tickValues = this.generateTickValues($$.mapTargetsToUniqueXs(targets), config.axis_x_tick_count, $$.isTimeSeries());\r\n      }\r\n      if (axis) {\r\n          axis.tickValues(tickValues);\r\n      }\r\n      else {\r\n          $$.xAxis.tickValues(tickValues);\r\n          $$.subXAxis.tickValues(tickValues);\r\n      }\r\n      return tickValues;\r\n  };\r\n  Axis.prototype.getYAxis = function getYAxis(axisId, scale, orient, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {\r\n      var $$ = this.owner;\r\n      var config = $$.config;\r\n      var tickFormat = config[\"axis_\" + axisId + \"_tick_format\"];\r\n      if (!tickFormat && $$.isAxisNormalized(axisId)) {\r\n          tickFormat = function (x) { return x + \"%\"; };\r\n      }\r\n      var axis = new this.internal(this, {\r\n          withOuterTick: withOuterTick,\r\n          withoutTransition: withoutTransition,\r\n          tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate\r\n      }).axis\r\n          .scale(scale)\r\n          .orient(orient);\r\n      if (tickFormat) {\r\n          axis.tickFormat(tickFormat);\r\n      }\r\n      if ($$.isTimeSeriesY()) {\r\n          axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval);\r\n      }\r\n      else {\r\n          axis.tickValues(tickValues);\r\n      }\r\n      return axis;\r\n  };\r\n  Axis.prototype.getId = function getId(id) {\r\n      var config = this.owner.config;\r\n      return id in config.data_axes ? config.data_axes[id] : 'y';\r\n  };\r\n  Axis.prototype.getXAxisTickFormat = function getXAxisTickFormat() {\r\n      // #2251 previously set any negative values to a whole number,\r\n      // however both should be truncated according to the users format specification\r\n      var $$ = this.owner, config = $$.config;\r\n      var format = $$.isTimeSeries()\r\n          ? $$.defaultAxisTimeFormat\r\n          : $$.isCategorized()\r\n              ? $$.categoryName\r\n              : function (v) {\r\n                  return v;\r\n              };\r\n      if (config.axis_x_tick_format) {\r\n          if (isFunction(config.axis_x_tick_format)) {\r\n              format = config.axis_x_tick_format;\r\n          }\r\n          else if ($$.isTimeSeries()) {\r\n              format = function (date) {\r\n                  return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : '';\r\n              };\r\n          }\r\n      }\r\n      return isFunction(format)\r\n          ? function (v) {\r\n              return format.call($$, v);\r\n          }\r\n          : format;\r\n  };\r\n  Axis.prototype.getTickValues = function getTickValues(tickValues, axis) {\r\n      return tickValues ? tickValues : axis ? axis.tickValues() : undefined;\r\n  };\r\n  Axis.prototype.getXAxisTickValues = function getXAxisTickValues() {\r\n      return this.getTickValues(this.owner.config.axis_x_tick_values, this.owner.xAxis);\r\n  };\r\n  Axis.prototype.getYAxisTickValues = function getYAxisTickValues() {\r\n      return this.getTickValues(this.owner.config.axis_y_tick_values, this.owner.yAxis);\r\n  };\r\n  Axis.prototype.getY2AxisTickValues = function getY2AxisTickValues() {\r\n      return this.getTickValues(this.owner.config.axis_y2_tick_values, this.owner.y2Axis);\r\n  };\r\n  Axis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(axisId) {\r\n      var $$ = this.owner, config = $$.config, option;\r\n      if (axisId === 'y') {\r\n          option = config.axis_y_label;\r\n      }\r\n      else if (axisId === 'y2') {\r\n          option = config.axis_y2_label;\r\n      }\r\n      else if (axisId === 'x') {\r\n          option = config.axis_x_label;\r\n      }\r\n      return option;\r\n  };\r\n  Axis.prototype.getLabelText = function getLabelText(axisId) {\r\n      var option = this.getLabelOptionByAxisId(axisId);\r\n      return isString(option) ? option : option ? option.text : null;\r\n  };\r\n  Axis.prototype.setLabelText = function setLabelText(axisId, text) {\r\n      var $$ = this.owner, config = $$.config, option = this.getLabelOptionByAxisId(axisId);\r\n      if (isString(option)) {\r\n          if (axisId === 'y') {\r\n              config.axis_y_label = text;\r\n          }\r\n          else if (axisId === 'y2') {\r\n              config.axis_y2_label = text;\r\n          }\r\n          else if (axisId === 'x') {\r\n              config.axis_x_label = text;\r\n          }\r\n      }\r\n      else if (option) {\r\n          option.text = text;\r\n      }\r\n  };\r\n  Axis.prototype.getLabelPosition = function getLabelPosition(axisId, defaultPosition) {\r\n      var option = this.getLabelOptionByAxisId(axisId), position = option && typeof option === 'object' && option.position\r\n          ? option.position\r\n          : defaultPosition;\r\n      return {\r\n          isInner: position.indexOf('inner') >= 0,\r\n          isOuter: position.indexOf('outer') >= 0,\r\n          isLeft: position.indexOf('left') >= 0,\r\n          isCenter: position.indexOf('center') >= 0,\r\n          isRight: position.indexOf('right') >= 0,\r\n          isTop: position.indexOf('top') >= 0,\r\n          isMiddle: position.indexOf('middle') >= 0,\r\n          isBottom: position.indexOf('bottom') >= 0\r\n      };\r\n  };\r\n  Axis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() {\r\n      return this.getLabelPosition('x', this.owner.config.axis_rotated ? 'inner-top' : 'inner-right');\r\n  };\r\n  Axis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() {\r\n      return this.getLabelPosition('y', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');\r\n  };\r\n  Axis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() {\r\n      return this.getLabelPosition('y2', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');\r\n  };\r\n  Axis.prototype.getLabelPositionById = function getLabelPositionById(id) {\r\n      return id === 'y2'\r\n          ? this.getY2AxisLabelPosition()\r\n          : id === 'y'\r\n              ? this.getYAxisLabelPosition()\r\n              : this.getXAxisLabelPosition();\r\n  };\r\n  Axis.prototype.textForXAxisLabel = function textForXAxisLabel() {\r\n      return this.getLabelText('x');\r\n  };\r\n  Axis.prototype.textForYAxisLabel = function textForYAxisLabel() {\r\n      return this.getLabelText('y');\r\n  };\r\n  Axis.prototype.textForY2AxisLabel = function textForY2AxisLabel() {\r\n      return this.getLabelText('y2');\r\n  };\r\n  Axis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) {\r\n      var $$ = this.owner;\r\n      if (forHorizontal) {\r\n          return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width;\r\n      }\r\n      else {\r\n          return position.isBottom\r\n              ? -$$.height\r\n              : position.isMiddle\r\n                  ? -$$.height / 2\r\n                  : 0;\r\n      }\r\n  };\r\n  Axis.prototype.dxForAxisLabel = function dxForAxisLabel(forHorizontal, position) {\r\n      if (forHorizontal) {\r\n          return position.isLeft ? '0.5em' : position.isRight ? '-0.5em' : '0';\r\n      }\r\n      else {\r\n          return position.isTop ? '-0.5em' : position.isBottom ? '0.5em' : '0';\r\n      }\r\n  };\r\n  Axis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(forHorizontal, position) {\r\n      if (forHorizontal) {\r\n          return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end';\r\n      }\r\n      else {\r\n          return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end';\r\n      }\r\n  };\r\n  Axis.prototype.xForXAxisLabel = function xForXAxisLabel() {\r\n      return this.xForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());\r\n  };\r\n  Axis.prototype.xForYAxisLabel = function xForYAxisLabel() {\r\n      return this.xForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());\r\n  };\r\n  Axis.prototype.xForY2AxisLabel = function xForY2AxisLabel() {\r\n      return this.xForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());\r\n  };\r\n  Axis.prototype.dxForXAxisLabel = function dxForXAxisLabel() {\r\n      return this.dxForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());\r\n  };\r\n  Axis.prototype.dxForYAxisLabel = function dxForYAxisLabel() {\r\n      return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());\r\n  };\r\n  Axis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() {\r\n      return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());\r\n  };\r\n  Axis.prototype.dyForXAxisLabel = function dyForXAxisLabel() {\r\n      var $$ = this.owner, config = $$.config, position = this.getXAxisLabelPosition();\r\n      if (config.axis_rotated) {\r\n          return position.isInner\r\n              ? '1.2em'\r\n              : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x'));\r\n      }\r\n      else {\r\n          return position.isInner ? '-0.5em' : $$.getHorizontalAxisHeight('x') - 10;\r\n      }\r\n  };\r\n  Axis.prototype.dyForYAxisLabel = function dyForYAxisLabel() {\r\n      var $$ = this.owner, position = this.getYAxisLabelPosition();\r\n      if ($$.config.axis_rotated) {\r\n          return position.isInner ? '-0.5em' : '3em';\r\n      }\r\n      else {\r\n          return position.isInner\r\n              ? '1.2em'\r\n              : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10);\r\n      }\r\n  };\r\n  Axis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() {\r\n      var $$ = this.owner, position = this.getY2AxisLabelPosition();\r\n      if ($$.config.axis_rotated) {\r\n          return position.isInner ? '1.2em' : '-2.2em';\r\n      }\r\n      else {\r\n          return position.isInner\r\n              ? '-0.5em'\r\n              : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15);\r\n      }\r\n  };\r\n  Axis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() {\r\n      var $$ = this.owner;\r\n      return this.textAnchorForAxisLabel(!$$.config.axis_rotated, this.getXAxisLabelPosition());\r\n  };\r\n  Axis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() {\r\n      var $$ = this.owner;\r\n      return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getYAxisLabelPosition());\r\n  };\r\n  Axis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() {\r\n      var $$ = this.owner;\r\n      return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getY2AxisLabelPosition());\r\n  };\r\n  Axis.prototype.getMaxTickWidth = function getMaxTickWidth(id, withoutRecompute) {\r\n      var $$ = this.owner, maxWidth = 0, targetsToShow, scale, axis, dummy, svg;\r\n      if (withoutRecompute && $$.currentMaxTickWidths[id]) {\r\n          return $$.currentMaxTickWidths[id];\r\n      }\r\n      if ($$.svg) {\r\n          targetsToShow = $$.filterTargetsToShow($$.data.targets);\r\n          if (id === 'y') {\r\n              scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));\r\n              axis = this.getYAxis(id, scale, $$.yOrient, $$.yAxisTickValues, false, true, true);\r\n          }\r\n          else if (id === 'y2') {\r\n              scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));\r\n              axis = this.getYAxis(id, scale, $$.y2Orient, $$.y2AxisTickValues, false, true, true);\r\n          }\r\n          else {\r\n              scale = $$.x.copy().domain($$.getXDomain(targetsToShow));\r\n              axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true);\r\n              this.updateXAxisTickValues(targetsToShow, axis);\r\n          }\r\n          dummy = $$.d3\r\n              .select('body')\r\n              .append('div')\r\n              .classed('c3', true);\r\n          (svg = dummy\r\n              .append('svg')\r\n              .style('visibility', 'hidden')\r\n              .style('position', 'fixed')\r\n              .style('top', 0)\r\n              .style('left', 0)),\r\n              svg\r\n                  .append('g')\r\n                  .call(axis)\r\n                  .each(function () {\r\n                  $$.d3\r\n                      .select(this)\r\n                      .selectAll('text')\r\n                      .each(function () {\r\n                      var box = getBBox(this);\r\n                      if (maxWidth < box.width) {\r\n                          maxWidth = box.width;\r\n                      }\r\n                  });\r\n                  dummy.remove();\r\n              });\r\n      }\r\n      $$.currentMaxTickWidths[id] =\r\n          maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth;\r\n      return $$.currentMaxTickWidths[id];\r\n  };\r\n  Axis.prototype.updateLabels = function updateLabels(withTransition) {\r\n      var $$ = this.owner;\r\n      var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel), axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel), axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label);\r\n      (withTransition ? axisXLabel.transition() : axisXLabel)\r\n          .attr('x', this.xForXAxisLabel.bind(this))\r\n          .attr('dx', this.dxForXAxisLabel.bind(this))\r\n          .attr('dy', this.dyForXAxisLabel.bind(this))\r\n          .text(this.textForXAxisLabel.bind(this));\r\n      (withTransition ? axisYLabel.transition() : axisYLabel)\r\n          .attr('x', this.xForYAxisLabel.bind(this))\r\n          .attr('dx', this.dxForYAxisLabel.bind(this))\r\n          .attr('dy', this.dyForYAxisLabel.bind(this))\r\n          .text(this.textForYAxisLabel.bind(this));\r\n      (withTransition ? axisY2Label.transition() : axisY2Label)\r\n          .attr('x', this.xForY2AxisLabel.bind(this))\r\n          .attr('dx', this.dxForY2AxisLabel.bind(this))\r\n          .attr('dy', this.dyForY2AxisLabel.bind(this))\r\n          .text(this.textForY2AxisLabel.bind(this));\r\n  };\r\n  Axis.prototype.getPadding = function getPadding(padding, key, defaultValue, domainLength) {\r\n      var p = typeof padding === 'number' ? padding : padding[key];\r\n      if (!isValue(p)) {\r\n          return defaultValue;\r\n      }\r\n      if (padding.unit === 'ratio') {\r\n          return padding[key] * domainLength;\r\n      }\r\n      // assume padding is pixels if unit is not specified\r\n      return this.convertPixelsToAxisPadding(p, domainLength);\r\n  };\r\n  Axis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(pixels, domainLength) {\r\n      var $$ = this.owner, length = $$.config.axis_rotated ? $$.width : $$.height;\r\n      return domainLength * (pixels / length);\r\n  };\r\n  Axis.prototype.generateTickValues = function generateTickValues(values, tickCount, forTimeSeries) {\r\n      var tickValues = values, targetCount, start, end, count, interval, i, tickValue;\r\n      if (tickCount) {\r\n          targetCount = isFunction(tickCount) ? tickCount() : tickCount;\r\n          // compute ticks according to tickCount\r\n          if (targetCount === 1) {\r\n              tickValues = [values[0]];\r\n          }\r\n          else if (targetCount === 2) {\r\n              tickValues = [values[0], values[values.length - 1]];\r\n          }\r\n          else if (targetCount > 2) {\r\n              count = targetCount - 2;\r\n              start = values[0];\r\n              end = values[values.length - 1];\r\n              interval = (end - start) / (count + 1);\r\n              // re-construct unique values\r\n              tickValues = [start];\r\n              for (i = 0; i < count; i++) {\r\n                  tickValue = +start + interval * (i + 1);\r\n                  tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue);\r\n              }\r\n              tickValues.push(end);\r\n          }\r\n      }\r\n      if (!forTimeSeries) {\r\n          tickValues = tickValues.sort(function (a, b) {\r\n              return a - b;\r\n          });\r\n      }\r\n      return tickValues;\r\n  };\r\n  Axis.prototype.generateTransitions = function generateTransitions(duration) {\r\n      var $$ = this.owner, axes = $$.axes;\r\n      return {\r\n          axisX: duration ? axes.x.transition().duration(duration) : axes.x,\r\n          axisY: duration ? axes.y.transition().duration(duration) : axes.y,\r\n          axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2,\r\n          axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx\r\n      };\r\n  };\r\n  Axis.prototype.redraw = function redraw(duration, isHidden) {\r\n      var $$ = this.owner, transition = duration ? $$.d3.transition().duration(duration) : null;\r\n      $$.axes.x.style('opacity', isHidden ? 0 : 1).call($$.xAxis, transition);\r\n      $$.axes.y.style('opacity', isHidden ? 0 : 1).call($$.yAxis, transition);\r\n      $$.axes.y2.style('opacity', isHidden ? 0 : 1).call($$.y2Axis, transition);\r\n      $$.axes.subx.style('opacity', isHidden ? 0 : 1).call($$.subXAxis, transition);\r\n  };\n\n  var c3 = {\r\n      version: '0.7.20',\r\n      chart: {\r\n          fn: Chart.prototype,\r\n          internal: {\r\n              fn: ChartInternal.prototype,\r\n              axis: {\r\n                  fn: AxisClass.prototype,\r\n                  internal: {\r\n                      fn: AxisInternal.prototype\r\n                  }\r\n              }\r\n          }\r\n      },\r\n      generate: function (config) {\r\n          return new Chart(config);\r\n      }\r\n  };\r\n  ChartInternal.prototype.beforeInit = function () {\r\n      // can do something\r\n  };\r\n  ChartInternal.prototype.afterInit = function () {\r\n      // can do something\r\n  };\r\n  ChartInternal.prototype.init = function () {\r\n      var $$ = this, config = $$.config;\r\n      $$.initParams();\r\n      if (config.data_url) {\r\n          $$.convertUrlToData(config.data_url, config.data_mimeType, config.data_headers, config.data_keys, $$.initWithData);\r\n      }\r\n      else if (config.data_json) {\r\n          $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));\r\n      }\r\n      else if (config.data_rows) {\r\n          $$.initWithData($$.convertRowsToData(config.data_rows));\r\n      }\r\n      else if (config.data_columns) {\r\n          $$.initWithData($$.convertColumnsToData(config.data_columns));\r\n      }\r\n      else {\r\n          throw Error('url or json or rows or columns is required.');\r\n      }\r\n  };\r\n  ChartInternal.prototype.initParams = function () {\r\n      var $$ = this, d3 = $$.d3, config = $$.config;\r\n      // MEMO: clipId needs to be unique because it conflicts when multiple charts exist\r\n      $$.clipId = 'c3-' + new Date().valueOf() + '-clip';\r\n      $$.clipIdForXAxis = $$.clipId + '-xaxis';\r\n      $$.clipIdForYAxis = $$.clipId + '-yaxis';\r\n      $$.clipIdForGrid = $$.clipId + '-grid';\r\n      $$.clipIdForSubchart = $$.clipId + '-subchart';\r\n      $$.clipPath = $$.getClipPath($$.clipId);\r\n      $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis);\r\n      $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis);\r\n      $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid);\r\n      $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart);\r\n      $$.dragStart = null;\r\n      $$.dragging = false;\r\n      $$.flowing = false;\r\n      $$.cancelClick = false;\r\n      $$.mouseover = undefined;\r\n      $$.transiting = false;\r\n      $$.color = $$.generateColor();\r\n      $$.levelColor = $$.generateLevelColor();\r\n      $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)($$.config.data_xFormat);\r\n      $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat;\r\n      $$.defaultAxisTimeFormat = function (date) {\r\n          if (date.getMilliseconds()) {\r\n              return d3.timeFormat('.%L')(date);\r\n          }\r\n          if (date.getSeconds()) {\r\n              return d3.timeFormat(':%S')(date);\r\n          }\r\n          if (date.getMinutes()) {\r\n              return d3.timeFormat('%I:%M')(date);\r\n          }\r\n          if (date.getHours()) {\r\n              return d3.timeFormat('%I %p')(date);\r\n          }\r\n          if (date.getDay() && date.getDate() !== 1) {\r\n              return d3.timeFormat('%-m/%-d')(date);\r\n          }\r\n          if (date.getDate() !== 1) {\r\n              return d3.timeFormat('%-m/%-d')(date);\r\n          }\r\n          if (date.getMonth()) {\r\n              return d3.timeFormat('%-m/%-d')(date);\r\n          }\r\n          return d3.timeFormat('%Y/%-m/%-d')(date);\r\n      };\r\n      $$.hiddenTargetIds = [];\r\n      $$.hiddenLegendIds = [];\r\n      $$.focusedTargetIds = [];\r\n      $$.defocusedTargetIds = [];\r\n      $$.xOrient = config.axis_rotated\r\n          ? config.axis_x_inner\r\n              ? 'right'\r\n              : 'left'\r\n          : config.axis_x_inner\r\n              ? 'top'\r\n              : 'bottom';\r\n      $$.yOrient = config.axis_rotated\r\n          ? config.axis_y_inner\r\n              ? 'top'\r\n              : 'bottom'\r\n          : config.axis_y_inner\r\n              ? 'right'\r\n              : 'left';\r\n      $$.y2Orient = config.axis_rotated\r\n          ? config.axis_y2_inner\r\n              ? 'bottom'\r\n              : 'top'\r\n          : config.axis_y2_inner\r\n              ? 'left'\r\n              : 'right';\r\n      $$.subXOrient = config.axis_rotated ? 'left' : 'bottom';\r\n      $$.isLegendRight = config.legend_position === 'right';\r\n      $$.isLegendInset = config.legend_position === 'inset';\r\n      $$.isLegendTop =\r\n          config.legend_inset_anchor === 'top-left' ||\r\n              config.legend_inset_anchor === 'top-right';\r\n      $$.isLegendLeft =\r\n          config.legend_inset_anchor === 'top-left' ||\r\n              config.legend_inset_anchor === 'bottom-left';\r\n      $$.legendStep = 0;\r\n      $$.legendItemWidth = 0;\r\n      $$.legendItemHeight = 0;\r\n      $$.currentMaxTickWidths = {\r\n          x: 0,\r\n          y: 0,\r\n          y2: 0\r\n      };\r\n      $$.rotated_padding_left = 30;\r\n      $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30;\r\n      $$.rotated_padding_top = 5;\r\n      $$.withoutFadeIn = {};\r\n      $$.intervalForObserveInserted = undefined;\r\n      $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js\r\n  };\r\n  ChartInternal.prototype.initChartElements = function () {\r\n      if (this.initBar) {\r\n          this.initBar();\r\n      }\r\n      if (this.initLine) {\r\n          this.initLine();\r\n      }\r\n      if (this.initArc) {\r\n          this.initArc();\r\n      }\r\n      if (this.initGauge) {\r\n          this.initGauge();\r\n      }\r\n      if (this.initText) {\r\n          this.initText();\r\n      }\r\n  };\r\n  ChartInternal.prototype.initWithData = function (data) {\r\n      var $$ = this, d3 = $$.d3, config = $$.config;\r\n      var defs, main, binding = true;\r\n      $$.axis = new AxisClass($$);\r\n      if (!config.bindto) {\r\n          $$.selectChart = d3.selectAll([]);\r\n      }\r\n      else if (typeof config.bindto.node === 'function') {\r\n          $$.selectChart = config.bindto;\r\n      }\r\n      else {\r\n          $$.selectChart = d3.select(config.bindto);\r\n      }\r\n      if ($$.selectChart.empty()) {\r\n          $$.selectChart = d3\r\n              .select(document.createElement('div'))\r\n              .style('opacity', 0);\r\n          $$.observeInserted($$.selectChart);\r\n          binding = false;\r\n      }\r\n      $$.selectChart.html('').classed('c3', true);\r\n      // Init data as targets\r\n      $$.data.xs = {};\r\n      $$.data.targets = $$.convertDataToTargets(data);\r\n      if (config.data_filter) {\r\n          $$.data.targets = $$.data.targets.filter(config.data_filter);\r\n      }\r\n      // Set targets to hide if needed\r\n      if (config.data_hide) {\r\n          $$.addHiddenTargetIds(config.data_hide === true\r\n              ? $$.mapToIds($$.data.targets)\r\n              : config.data_hide);\r\n      }\r\n      if (config.legend_hide) {\r\n          $$.addHiddenLegendIds(config.legend_hide === true\r\n              ? $$.mapToIds($$.data.targets)\r\n              : config.legend_hide);\r\n      }\r\n      if ($$.isStanfordGraphType()) {\r\n          $$.initStanfordData();\r\n      }\r\n      // Init sizes and scales\r\n      $$.updateSizes();\r\n      $$.updateScales();\r\n      // Set domains for each scale\r\n      $$.x.domain(d3.extent($$.getXDomain($$.data.targets)));\r\n      $$.y.domain($$.getYDomain($$.data.targets, 'y'));\r\n      $$.y2.domain($$.getYDomain($$.data.targets, 'y2'));\r\n      $$.subX.domain($$.x.domain());\r\n      $$.subY.domain($$.y.domain());\r\n      $$.subY2.domain($$.y2.domain());\r\n      // Save original x domain for zoom update\r\n      $$.orgXDomain = $$.x.domain();\r\n      /*-- Basic Elements --*/\r\n      // Define svgs\r\n      $$.svg = $$.selectChart\r\n          .append('svg')\r\n          .style('overflow', 'hidden')\r\n          .on('mouseenter', function () {\r\n          return config.onmouseover.call($$);\r\n      })\r\n          .on('mouseleave', function () {\r\n          return config.onmouseout.call($$);\r\n      });\r\n      if ($$.config.svg_classname) {\r\n          $$.svg.attr('class', $$.config.svg_classname);\r\n      }\r\n      // Define defs\r\n      defs = $$.svg.append('defs');\r\n      $$.clipChart = $$.appendClip(defs, $$.clipId);\r\n      $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis);\r\n      $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis);\r\n      $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid);\r\n      $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart);\r\n      $$.updateSvgSize();\r\n      // Define regions\r\n      main = $$.main = $$.svg.append('g').attr('transform', $$.getTranslate('main'));\r\n      if ($$.initPie) {\r\n          $$.initPie();\r\n      }\r\n      if ($$.initDragZoom) {\r\n          $$.initDragZoom();\r\n      }\r\n      if (config.subchart_show && $$.initSubchart) {\r\n          $$.initSubchart();\r\n      }\r\n      if ($$.initTooltip) {\r\n          $$.initTooltip();\r\n      }\r\n      if ($$.initLegend) {\r\n          $$.initLegend();\r\n      }\r\n      if ($$.initTitle) {\r\n          $$.initTitle();\r\n      }\r\n      if ($$.initZoom) {\r\n          $$.initZoom();\r\n      }\r\n      if ($$.isStanfordGraphType()) {\r\n          $$.drawColorScale();\r\n      }\r\n      // Update selection based on size and scale\r\n      // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart.\r\n      if (config.subchart_show && $$.initSubchartBrush) {\r\n          $$.initSubchartBrush();\r\n      }\r\n      /*-- Main Region --*/\r\n      // text when empty\r\n      main\r\n          .append('text')\r\n          .attr('class', CLASS.text + ' ' + CLASS.empty)\r\n          .attr('text-anchor', 'middle') // horizontal centering of text at x position in all browsers.\r\n          .attr('dominant-baseline', 'middle'); // vertical centering of text at y position in all browsers, except IE.\r\n      // Regions\r\n      $$.initRegion();\r\n      // Grids\r\n      $$.initGrid();\r\n      // Define g for chart area\r\n      main\r\n          .append('g')\r\n          .attr('clip-path', $$.clipPath)\r\n          .attr('class', CLASS.chart);\r\n      // Grid lines\r\n      if (config.grid_lines_front) {\r\n          $$.initGridLines();\r\n      }\r\n      $$.initStanfordElements();\r\n      // Cover whole with rects for events\r\n      $$.initEventRect();\r\n      // Define g for chart\r\n      $$.initChartElements();\r\n      // Add Axis\r\n      $$.axis.init();\r\n      // Set targets\r\n      $$.updateTargets($$.data.targets);\r\n      // Set default extent if defined\r\n      if (config.axis_x_selection) {\r\n          $$.brush.selectionAsValue($$.getDefaultSelection());\r\n      }\r\n      // Draw with targets\r\n      if (binding) {\r\n          $$.updateDimension();\r\n          $$.config.oninit.call($$);\r\n          $$.redraw({\r\n              withTransition: false,\r\n              withTransform: true,\r\n              withUpdateXDomain: true,\r\n              withUpdateOrgXDomain: true,\r\n              withTransitionForAxis: false\r\n          });\r\n      }\r\n      // Bind to resize event\r\n      $$.bindResize();\r\n      // Bind to window focus event\r\n      $$.bindWindowFocus();\r\n      // export element of the chart\r\n      $$.api.element = $$.selectChart.node();\r\n  };\r\n  ChartInternal.prototype.smoothLines = function (el, type) {\r\n      var $$ = this;\r\n      if (type === 'grid') {\r\n          el.each(function () {\r\n              var g = $$.d3.select(this), x1 = g.attr('x1'), x2 = g.attr('x2'), y1 = g.attr('y1'), y2 = g.attr('y2');\r\n              g.attr({\r\n                  x1: Math.ceil(x1),\r\n                  x2: Math.ceil(x2),\r\n                  y1: Math.ceil(y1),\r\n                  y2: Math.ceil(y2)\r\n              });\r\n          });\r\n      }\r\n  };\r\n  ChartInternal.prototype.updateSizes = function () {\r\n      var $$ = this, config = $$.config;\r\n      var legendHeight = $$.legend ? $$.getLegendHeight() : 0, legendWidth = $$.legend ? $$.getLegendWidth() : 0, legendHeightForBottom = $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight, hasArc = $$.hasArcType(), xAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'), subchartXAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x', true), subchartHeight = config.subchart_show && !hasArc\r\n          ? config.subchart_size_height + subchartXAxisHeight\r\n          : 0;\r\n      $$.currentWidth = $$.getCurrentWidth();\r\n      $$.currentHeight = $$.getCurrentHeight();\r\n      // for main\r\n      $$.margin = config.axis_rotated\r\n          ? {\r\n              top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(),\r\n              right: hasArc ? 0 : $$.getCurrentPaddingRight(),\r\n              bottom: $$.getHorizontalAxisHeight('y') +\r\n                  legendHeightForBottom +\r\n                  $$.getCurrentPaddingBottom(),\r\n              left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft())\r\n          }\r\n          : {\r\n              top: 4 + $$.getCurrentPaddingTop(),\r\n              right: hasArc ? 0 : $$.getCurrentPaddingRight(),\r\n              bottom: xAxisHeight +\r\n                  subchartHeight +\r\n                  legendHeightForBottom +\r\n                  $$.getCurrentPaddingBottom(),\r\n              left: hasArc ? 0 : $$.getCurrentPaddingLeft()\r\n          };\r\n      // for subchart\r\n      $$.margin2 = config.axis_rotated\r\n          ? {\r\n              top: $$.margin.top,\r\n              right: NaN,\r\n              bottom: 20 + legendHeightForBottom,\r\n              left: $$.rotated_padding_left\r\n          }\r\n          : {\r\n              top: $$.currentHeight - subchartHeight - legendHeightForBottom,\r\n              right: NaN,\r\n              bottom: subchartXAxisHeight + legendHeightForBottom,\r\n              left: $$.margin.left\r\n          };\r\n      // for legend\r\n      $$.margin3 = {\r\n          top: 0,\r\n          right: NaN,\r\n          bottom: 0,\r\n          left: 0\r\n      };\r\n      if ($$.updateSizeForLegend) {\r\n          $$.updateSizeForLegend(legendHeight, legendWidth);\r\n      }\r\n      $$.width = $$.currentWidth - $$.margin.left - $$.margin.right;\r\n      $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom;\r\n      if ($$.width < 0) {\r\n          $$.width = 0;\r\n      }\r\n      if ($$.height < 0) {\r\n          $$.height = 0;\r\n      }\r\n      $$.width2 = config.axis_rotated\r\n          ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right\r\n          : $$.width;\r\n      $$.height2 = config.axis_rotated\r\n          ? $$.height\r\n          : $$.currentHeight - $$.margin2.top - $$.margin2.bottom;\r\n      if ($$.width2 < 0) {\r\n          $$.width2 = 0;\r\n      }\r\n      if ($$.height2 < 0) {\r\n          $$.height2 = 0;\r\n      }\r\n      // for arc\r\n      $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0);\r\n      $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10);\r\n      if ($$.hasType('gauge') && !config.gauge_fullCircle) {\r\n          $$.arcHeight += $$.height - $$.getGaugeLabelHeight();\r\n      }\r\n      if ($$.updateRadius) {\r\n          $$.updateRadius();\r\n      }\r\n      if ($$.isLegendRight && hasArc) {\r\n          $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1;\r\n      }\r\n  };\r\n  ChartInternal.prototype.updateTargets = function (targets) {\r\n      var $$ = this, config = $$.config;\r\n      /*-- Main --*/\r\n      //-- Text --//\r\n      $$.updateTargetsForText(targets);\r\n      //-- Bar --//\r\n      $$.updateTargetsForBar(targets);\r\n      //-- Line --//\r\n      $$.updateTargetsForLine(targets);\r\n      //-- Arc --//\r\n      if ($$.hasArcType() && $$.updateTargetsForArc) {\r\n          $$.updateTargetsForArc(targets);\r\n      }\r\n      /*-- Sub --*/\r\n      if (config.subchart_show && $$.updateTargetsForSubchart) {\r\n          $$.updateTargetsForSubchart(targets);\r\n      }\r\n      // Fade-in each chart\r\n      $$.showTargets();\r\n  };\r\n  ChartInternal.prototype.showTargets = function () {\r\n      var $$ = this;\r\n      $$.svg\r\n          .selectAll('.' + CLASS.target)\r\n          .filter(function (d) {\r\n          return $$.isTargetToShow(d.id);\r\n      })\r\n          .transition()\r\n          .duration($$.config.transition_duration)\r\n          .style('opacity', 1);\r\n  };\r\n  ChartInternal.prototype.redraw = function (options, transitions) {\r\n      var $$ = this, main = $$.main, d3 = $$.d3, config = $$.config;\r\n      var areaIndices = $$.getShapeIndices($$.isAreaType), barIndices = $$.getShapeIndices($$.isBarType), lineIndices = $$.getShapeIndices($$.isLineType);\r\n      var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis, withTransform, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain, withLegend, withEventRect, withDimension, withUpdateXAxis;\r\n      var hideAxis = $$.hasArcType();\r\n      var drawArea, drawBar, drawLine, xForText, yForText;\r\n      var duration, durationForExit, durationForAxis;\r\n      var transitionsToWait, waitForDraw, flow, transition;\r\n      var targetsToShow = $$.filterTargetsToShow($$.data.targets), tickValues, i, intervalForCulling, xDomainForZoom;\r\n      var xv = $$.xv.bind($$), cx, cy;\r\n      options = options || {};\r\n      withY = getOption(options, 'withY', true);\r\n      withSubchart = getOption(options, 'withSubchart', true);\r\n      withTransition = getOption(options, 'withTransition', true);\r\n      withTransform = getOption(options, 'withTransform', false);\r\n      withUpdateXDomain = getOption(options, 'withUpdateXDomain', false);\r\n      withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', false);\r\n      withTrimXDomain = getOption(options, 'withTrimXDomain', true);\r\n      withUpdateXAxis = getOption(options, 'withUpdateXAxis', withUpdateXDomain);\r\n      withLegend = getOption(options, 'withLegend', false);\r\n      withEventRect = getOption(options, 'withEventRect', true);\r\n      withDimension = getOption(options, 'withDimension', true);\r\n      withTransitionForExit = getOption(options, 'withTransitionForExit', withTransition);\r\n      withTransitionForAxis = getOption(options, 'withTransitionForAxis', withTransition);\r\n      duration = withTransition ? config.transition_duration : 0;\r\n      durationForExit = withTransitionForExit ? duration : 0;\r\n      durationForAxis = withTransitionForAxis ? duration : 0;\r\n      transitions = transitions || $$.axis.generateTransitions(durationForAxis);\r\n      // update legend and transform each g\r\n      if (withLegend && config.legend_show) {\r\n          $$.updateLegend($$.mapToIds($$.data.targets), options, transitions);\r\n      }\r\n      else if (withDimension) {\r\n          // need to update dimension (e.g. axis.y.tick.values) because y tick values should change\r\n          // no need to update axis in it because they will be updated in redraw()\r\n          $$.updateDimension(true);\r\n      }\r\n      // MEMO: needed for grids calculation\r\n      if ($$.isCategorized() && targetsToShow.length === 0) {\r\n          $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]);\r\n      }\r\n      if (targetsToShow.length) {\r\n          $$.updateXDomain(targetsToShow, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain);\r\n          if (!config.axis_x_tick_values) {\r\n              tickValues = $$.axis.updateXAxisTickValues(targetsToShow);\r\n          }\r\n      }\r\n      else {\r\n          $$.xAxis.tickValues([]);\r\n          $$.subXAxis.tickValues([]);\r\n      }\r\n      if (config.zoom_rescale && !options.flow) {\r\n          xDomainForZoom = $$.x.orgDomain();\r\n      }\r\n      $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom));\r\n      $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom));\r\n      if (!config.axis_y_tick_values && config.axis_y_tick_count) {\r\n          $$.yAxis.tickValues($$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count));\r\n      }\r\n      if (!config.axis_y2_tick_values && config.axis_y2_tick_count) {\r\n          $$.y2Axis.tickValues($$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count));\r\n      }\r\n      // axes\r\n      $$.axis.redraw(durationForAxis, hideAxis);\r\n      // Update axis label\r\n      $$.axis.updateLabels(withTransition);\r\n      // show/hide if manual culling needed\r\n      if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) {\r\n          if (config.axis_x_tick_culling && tickValues) {\r\n              for (i = 1; i < tickValues.length; i++) {\r\n                  if (tickValues.length / i < config.axis_x_tick_culling_max) {\r\n                      intervalForCulling = i;\r\n                      break;\r\n                  }\r\n              }\r\n              $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function (e) {\r\n                  var index = tickValues.indexOf(e);\r\n                  if (index >= 0) {\r\n                      d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block');\r\n                  }\r\n              });\r\n          }\r\n          else {\r\n              $$.svg\r\n                  .selectAll('.' + CLASS.axisX + ' .tick text')\r\n                  .style('display', 'block');\r\n          }\r\n      }\r\n      // setup drawer - MEMO: these must be called after axis updated\r\n      drawArea = $$.generateDrawArea\r\n          ? $$.generateDrawArea(areaIndices, false)\r\n          : undefined;\r\n      drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined;\r\n      drawLine = $$.generateDrawLine\r\n          ? $$.generateDrawLine(lineIndices, false)\r\n          : undefined;\r\n      xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true);\r\n      yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false);\r\n      // update circleY based on updated parameters\r\n      $$.updateCircleY();\r\n      // generate circle x/y functions depending on updated params\r\n      cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$);\r\n      cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$);\r\n      // Update sub domain\r\n      if (withY) {\r\n          $$.subY.domain($$.getYDomain(targetsToShow, 'y'));\r\n          $$.subY2.domain($$.getYDomain(targetsToShow, 'y2'));\r\n      }\r\n      // xgrid focus\r\n      $$.updateXgridFocus();\r\n      // Data empty label positioning and text.\r\n      main\r\n          .select('text.' + CLASS.text + '.' + CLASS.empty)\r\n          .attr('x', $$.width / 2)\r\n          .attr('y', $$.height / 2)\r\n          .text(config.data_empty_label_text)\r\n          .transition()\r\n          .style('opacity', targetsToShow.length ? 0 : 1);\r\n      // event rect\r\n      if (withEventRect) {\r\n          $$.redrawEventRect();\r\n      }\r\n      // grid\r\n      $$.updateGrid(duration);\r\n      $$.updateStanfordElements(duration);\r\n      // rect for regions\r\n      $$.updateRegion(duration);\r\n      // bars\r\n      $$.updateBar(durationForExit);\r\n      // lines, areas and circles\r\n      $$.updateLine(durationForExit);\r\n      $$.updateArea(durationForExit);\r\n      $$.updateCircle(cx, cy);\r\n      // text\r\n      if ($$.hasDataLabel()) {\r\n          $$.updateText(xForText, yForText, durationForExit);\r\n      }\r\n      // title\r\n      if ($$.redrawTitle) {\r\n          $$.redrawTitle();\r\n      }\r\n      // arc\r\n      if ($$.redrawArc) {\r\n          $$.redrawArc(duration, durationForExit, withTransform);\r\n      }\r\n      // subchart\r\n      if (config.subchart_show && $$.redrawSubchart) {\r\n          $$.redrawSubchart(withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices);\r\n      }\r\n      if ($$.isStanfordGraphType()) {\r\n          $$.drawColorScale();\r\n      }\r\n      // circles for select\r\n      main\r\n          .selectAll('.' + CLASS.selectedCircles)\r\n          .filter($$.isBarType.bind($$))\r\n          .selectAll('circle')\r\n          .remove();\r\n      if (options.flow) {\r\n          flow = $$.generateFlow({\r\n              targets: targetsToShow,\r\n              flow: options.flow,\r\n              duration: options.flow.duration,\r\n              drawBar: drawBar,\r\n              drawLine: drawLine,\r\n              drawArea: drawArea,\r\n              cx: cx,\r\n              cy: cy,\r\n              xv: xv,\r\n              xForText: xForText,\r\n              yForText: yForText\r\n          });\r\n      }\r\n      if (duration && $$.isTabVisible()) {\r\n          // Only use transition if tab visible. See #938.\r\n          // transition should be derived from one transition\r\n          transition = d3.transition().duration(duration);\r\n          transitionsToWait = [];\r\n          [\r\n              $$.redrawBar(drawBar, true, transition),\r\n              $$.redrawLine(drawLine, true, transition),\r\n              $$.redrawArea(drawArea, true, transition),\r\n              $$.redrawCircle(cx, cy, true, transition),\r\n              $$.redrawText(xForText, yForText, options.flow, true, transition),\r\n              $$.redrawRegion(true, transition),\r\n              $$.redrawGrid(true, transition)\r\n          ].forEach(function (transitions) {\r\n              transitions.forEach(function (transition) {\r\n                  transitionsToWait.push(transition);\r\n              });\r\n          });\r\n          // Wait for end of transitions to call flow and onrendered callback\r\n          waitForDraw = $$.generateWait();\r\n          transitionsToWait.forEach(function (t) {\r\n              waitForDraw.add(t);\r\n          });\r\n          waitForDraw(function () {\r\n              if (flow) {\r\n                  flow();\r\n              }\r\n              if (config.onrendered) {\r\n                  config.onrendered.call($$);\r\n              }\r\n          });\r\n      }\r\n      else {\r\n          $$.redrawBar(drawBar);\r\n          $$.redrawLine(drawLine);\r\n          $$.redrawArea(drawArea);\r\n          $$.redrawCircle(cx, cy);\r\n          $$.redrawText(xForText, yForText, options.flow);\r\n          $$.redrawRegion();\r\n          $$.redrawGrid();\r\n          if (flow) {\r\n              flow();\r\n          }\r\n          if (config.onrendered) {\r\n              config.onrendered.call($$);\r\n          }\r\n      }\r\n      // update fadein condition\r\n      $$.mapToIds($$.data.targets).forEach(function (id) {\r\n          $$.withoutFadeIn[id] = true;\r\n      });\r\n  };\r\n  ChartInternal.prototype.updateAndRedraw = function (options) {\r\n      var $$ = this, config = $$.config, transitions;\r\n      options = options || {};\r\n      // same with redraw\r\n      options.withTransition = getOption(options, 'withTransition', true);\r\n      options.withTransform = getOption(options, 'withTransform', false);\r\n      options.withLegend = getOption(options, 'withLegend', false);\r\n      // NOT same with redraw\r\n      options.withUpdateXDomain = getOption(options, 'withUpdateXDomain', true);\r\n      options.withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', true);\r\n      options.withTransitionForExit = false;\r\n      options.withTransitionForTransform = getOption(options, 'withTransitionForTransform', options.withTransition);\r\n      // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called)\r\n      $$.updateSizes();\r\n      // MEMO: called in updateLegend in redraw if withLegend\r\n      if (!(options.withLegend && config.legend_show)) {\r\n          transitions = $$.axis.generateTransitions(options.withTransitionForAxis ? config.transition_duration : 0);\r\n          // Update scales\r\n          $$.updateScales();\r\n          $$.updateSvgSize();\r\n          // Update g positions\r\n          $$.transformAll(options.withTransitionForTransform, transitions);\r\n      }\r\n      // Draw with new sizes & scales\r\n      $$.redraw(options, transitions);\r\n  };\r\n  ChartInternal.prototype.redrawWithoutRescale = function () {\r\n      this.redraw({\r\n          withY: false,\r\n          withSubchart: false,\r\n          withEventRect: false,\r\n          withTransitionForAxis: false\r\n      });\r\n  };\r\n  ChartInternal.prototype.isTimeSeries = function () {\r\n      return this.config.axis_x_type === 'timeseries';\r\n  };\r\n  ChartInternal.prototype.isCategorized = function () {\r\n      return this.config.axis_x_type.indexOf('categor') >= 0;\r\n  };\r\n  ChartInternal.prototype.isCustomX = function () {\r\n      var $$ = this, config = $$.config;\r\n      return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs));\r\n  };\r\n  ChartInternal.prototype.isTimeSeriesY = function () {\r\n      return this.config.axis_y_type === 'timeseries';\r\n  };\r\n  ChartInternal.prototype.getTranslate = function (target) {\r\n      var $$ = this, config = $$.config, x, y;\r\n      if (target === 'main') {\r\n          x = asHalfPixel($$.margin.left);\r\n          y = asHalfPixel($$.margin.top);\r\n      }\r\n      else if (target === 'context') {\r\n          x = asHalfPixel($$.margin2.left);\r\n          y = asHalfPixel($$.margin2.top);\r\n      }\r\n      else if (target === 'legend') {\r\n          x = $$.margin3.left;\r\n          y = $$.margin3.top;\r\n      }\r\n      else if (target === 'x') {\r\n          x = 0;\r\n          y = config.axis_rotated ? 0 : $$.height;\r\n      }\r\n      else if (target === 'y') {\r\n          x = 0;\r\n          y = config.axis_rotated ? $$.height : 0;\r\n      }\r\n      else if (target === 'y2') {\r\n          x = config.axis_rotated ? 0 : $$.width;\r\n          y = config.axis_rotated ? 1 : 0;\r\n      }\r\n      else if (target === 'subx') {\r\n          x = 0;\r\n          y = config.axis_rotated ? 0 : $$.height2;\r\n      }\r\n      else if (target === 'arc') {\r\n          x = $$.arcWidth / 2;\r\n          y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label\r\n      }\r\n      return 'translate(' + x + ',' + y + ')';\r\n  };\r\n  ChartInternal.prototype.initialOpacity = function (d) {\r\n      return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0;\r\n  };\r\n  ChartInternal.prototype.initialOpacityForCircle = function (d) {\r\n      return d.value !== null && this.withoutFadeIn[d.id]\r\n          ? this.opacityForCircle(d)\r\n          : 0;\r\n  };\r\n  ChartInternal.prototype.opacityForCircle = function (d) {\r\n      var isPointShouldBeShown = isFunction(this.config.point_show)\r\n          ? this.config.point_show(d)\r\n          : this.config.point_show;\r\n      var opacity = isPointShouldBeShown || this.isStanfordType(d) ? 1 : 0;\r\n      return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0;\r\n  };\r\n  ChartInternal.prototype.opacityForText = function () {\r\n      return this.hasDataLabel() ? 1 : 0;\r\n  };\r\n  ChartInternal.prototype.xx = function (d) {\r\n      return d ? this.x(d.x) : null;\r\n  };\r\n  ChartInternal.prototype.xvCustom = function (d, xyValue) {\r\n      var $$ = this, value = xyValue ? d[xyValue] : d.value;\r\n      if ($$.isTimeSeries()) {\r\n          value = $$.parseDate(d.value);\r\n      }\r\n      else if ($$.isCategorized() && typeof d.value === 'string') {\r\n          value = $$.config.axis_x_categories.indexOf(d.value);\r\n      }\r\n      return Math.ceil($$.x(value));\r\n  };\r\n  ChartInternal.prototype.yvCustom = function (d, xyValue) {\r\n      var $$ = this, yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y, value = xyValue ? d[xyValue] : d.value;\r\n      return Math.ceil(yScale(value));\r\n  };\r\n  ChartInternal.prototype.xv = function (d) {\r\n      var $$ = this, value = d.value;\r\n      if ($$.isTimeSeries()) {\r\n          value = $$.parseDate(d.value);\r\n      }\r\n      else if ($$.isCategorized() && typeof d.value === 'string') {\r\n          value = $$.config.axis_x_categories.indexOf(d.value);\r\n      }\r\n      return Math.ceil($$.x(value));\r\n  };\r\n  ChartInternal.prototype.yv = function (d) {\r\n      var $$ = this, yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y;\r\n      return Math.ceil(yScale(d.value));\r\n  };\r\n  ChartInternal.prototype.subxx = function (d) {\r\n      return d ? this.subX(d.x) : null;\r\n  };\r\n  ChartInternal.prototype.transformMain = function (withTransition, transitions) {\r\n      var $$ = this, xAxis, yAxis, y2Axis;\r\n      if (transitions && transitions.axisX) {\r\n          xAxis = transitions.axisX;\r\n      }\r\n      else {\r\n          xAxis = $$.main.select('.' + CLASS.axisX);\r\n          if (withTransition) {\r\n              xAxis = xAxis.transition();\r\n          }\r\n      }\r\n      if (transitions && transitions.axisY) {\r\n          yAxis = transitions.axisY;\r\n      }\r\n      else {\r\n          yAxis = $$.main.select('.' + CLASS.axisY);\r\n          if (withTransition) {\r\n              yAxis = yAxis.transition();\r\n          }\r\n      }\r\n      if (transitions && transitions.axisY2) {\r\n          y2Axis = transitions.axisY2;\r\n      }\r\n      else {\r\n          y2Axis = $$.main.select('.' + CLASS.axisY2);\r\n          if (withTransition) {\r\n              y2Axis = y2Axis.transition();\r\n          }\r\n      }\r\n      (withTransition ? $$.main.transition() : $$.main).attr('transform', $$.getTranslate('main'));\r\n      xAxis.attr('transform', $$.getTranslate('x'));\r\n      yAxis.attr('transform', $$.getTranslate('y'));\r\n      y2Axis.attr('transform', $$.getTranslate('y2'));\r\n      $$.main\r\n          .select('.' + CLASS.chartArcs)\r\n          .attr('transform', $$.getTranslate('arc'));\r\n  };\r\n  ChartInternal.prototype.transformAll = function (withTransition, transitions) {\r\n      var $$ = this;\r\n      $$.transformMain(withTransition, transitions);\r\n      if ($$.config.subchart_show) {\r\n          $$.transformContext(withTransition, transitions);\r\n      }\r\n      if ($$.legend) {\r\n          $$.transformLegend(withTransition);\r\n      }\r\n  };\r\n  ChartInternal.prototype.updateSvgSize = function () {\r\n      var $$ = this, brush = $$.svg.select(\".\" + CLASS.brush + \" .overlay\");\r\n      $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight);\r\n      $$.svg\r\n          .selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid])\r\n          .select('rect')\r\n          .attr('width', $$.width)\r\n          .attr('height', $$.height);\r\n      $$.svg\r\n          .select('#' + $$.clipIdForXAxis)\r\n          .select('rect')\r\n          .attr('x', $$.getXAxisClipX.bind($$))\r\n          .attr('y', $$.getXAxisClipY.bind($$))\r\n          .attr('width', $$.getXAxisClipWidth.bind($$))\r\n          .attr('height', $$.getXAxisClipHeight.bind($$));\r\n      $$.svg\r\n          .select('#' + $$.clipIdForYAxis)\r\n          .select('rect')\r\n          .attr('x', $$.getYAxisClipX.bind($$))\r\n          .attr('y', $$.getYAxisClipY.bind($$))\r\n          .attr('width', $$.getYAxisClipWidth.bind($$))\r\n          .attr('height', $$.getYAxisClipHeight.bind($$));\r\n      $$.svg\r\n          .select('#' + $$.clipIdForSubchart)\r\n          .select('rect')\r\n          .attr('width', $$.width)\r\n          .attr('height', (brush.size() && brush.attr('height')) || 0);\r\n      // MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>\r\n      $$.selectChart.style('max-height', $$.currentHeight + 'px');\r\n  };\r\n  ChartInternal.prototype.updateDimension = function (withoutAxis) {\r\n      var $$ = this;\r\n      if (!withoutAxis) {\r\n          if ($$.config.axis_rotated) {\r\n              $$.axes.x.call($$.xAxis);\r\n              $$.axes.subx.call($$.subXAxis);\r\n          }\r\n          else {\r\n              $$.axes.y.call($$.yAxis);\r\n              $$.axes.y2.call($$.y2Axis);\r\n          }\r\n      }\r\n      $$.updateSizes();\r\n      $$.updateScales();\r\n      $$.updateSvgSize();\r\n      $$.transformAll(false);\r\n  };\r\n  ChartInternal.prototype.observeInserted = function (selection) {\r\n      var $$ = this, observer;\r\n      if (typeof MutationObserver === 'undefined') {\r\n          window.console.error('MutationObserver not defined.');\r\n          return;\r\n      }\r\n      observer = new MutationObserver(function (mutations) {\r\n          mutations.forEach(function (mutation) {\r\n              if (mutation.type === 'childList' && mutation.previousSibling) {\r\n                  observer.disconnect();\r\n                  // need to wait for completion of load because size calculation requires the actual sizes determined after that completion\r\n                  $$.intervalForObserveInserted = window.setInterval(function () {\r\n                      // parentNode will NOT be null when completed\r\n                      if (selection.node().parentNode) {\r\n                          window.clearInterval($$.intervalForObserveInserted);\r\n                          $$.updateDimension();\r\n                          if ($$.brush) {\r\n                              $$.brush.update();\r\n                          }\r\n                          $$.config.oninit.call($$);\r\n                          $$.redraw({\r\n                              withTransform: true,\r\n                              withUpdateXDomain: true,\r\n                              withUpdateOrgXDomain: true,\r\n                              withTransition: false,\r\n                              withTransitionForTransform: false,\r\n                              withLegend: true\r\n                          });\r\n                          selection.transition().style('opacity', 1);\r\n                      }\r\n                  }, 10);\r\n              }\r\n          });\r\n      });\r\n      observer.observe(selection.node(), {\r\n          attributes: true,\r\n          childList: true,\r\n          characterData: true\r\n      });\r\n  };\r\n  /**\r\n   * Binds handlers to the window resize event.\r\n   */\r\n  ChartInternal.prototype.bindResize = function () {\r\n      var $$ = this, config = $$.config;\r\n      $$.resizeFunction = $$.generateResize(); // need to call .remove\r\n      $$.resizeFunction.add(function () {\r\n          config.onresize.call($$);\r\n      });\r\n      if (config.resize_auto) {\r\n          $$.resizeFunction.add(function () {\r\n              if ($$.resizeTimeout !== undefined) {\r\n                  window.clearTimeout($$.resizeTimeout);\r\n              }\r\n              $$.resizeTimeout = window.setTimeout(function () {\r\n                  delete $$.resizeTimeout;\r\n                  $$.updateAndRedraw({\r\n                      withUpdateXDomain: false,\r\n                      withUpdateOrgXDomain: false,\r\n                      withTransition: false,\r\n                      withTransitionForTransform: false,\r\n                      withLegend: true\r\n                  });\r\n                  if ($$.brush) {\r\n                      $$.brush.update();\r\n                  }\r\n              }, 100);\r\n          });\r\n      }\r\n      $$.resizeFunction.add(function () {\r\n          config.onresized.call($$);\r\n      });\r\n      $$.resizeIfElementDisplayed = function () {\r\n          // if element not displayed skip it\r\n          if ($$.api == null || !$$.api.element.offsetParent) {\r\n              return;\r\n          }\r\n          $$.resizeFunction();\r\n      };\r\n      window.addEventListener('resize', $$.resizeIfElementDisplayed, false);\r\n  };\r\n  /**\r\n   * Binds handlers to the window focus event.\r\n   */\r\n  ChartInternal.prototype.bindWindowFocus = function () {\r\n      var _this = this;\r\n      if (this.windowFocusHandler) {\r\n          // The handler is already set\r\n          return;\r\n      }\r\n      this.windowFocusHandler = function () {\r\n          _this.redraw();\r\n      };\r\n      window.addEventListener('focus', this.windowFocusHandler);\r\n  };\r\n  /**\r\n   * Unbinds from the window focus event.\r\n   */\r\n  ChartInternal.prototype.unbindWindowFocus = function () {\r\n      window.removeEventListener('focus', this.windowFocusHandler);\r\n      delete this.windowFocusHandler;\r\n  };\r\n  ChartInternal.prototype.generateResize = function () {\r\n      var resizeFunctions = [];\r\n      function callResizeFunctions() {\r\n          resizeFunctions.forEach(function (f) {\r\n              f();\r\n          });\r\n      }\r\n      callResizeFunctions.add = function (f) {\r\n          resizeFunctions.push(f);\r\n      };\r\n      callResizeFunctions.remove = function (f) {\r\n          for (var i = 0; i < resizeFunctions.length; i++) {\r\n              if (resizeFunctions[i] === f) {\r\n                  resizeFunctions.splice(i, 1);\r\n                  break;\r\n              }\r\n          }\r\n      };\r\n      return callResizeFunctions;\r\n  };\r\n  ChartInternal.prototype.endall = function (transition, callback) {\r\n      var n = 0;\r\n      transition\r\n          .each(function () {\r\n          ++n;\r\n      })\r\n          .on('end', function () {\r\n          if (!--n) {\r\n              callback.apply(this, arguments);\r\n          }\r\n      });\r\n  };\r\n  ChartInternal.prototype.generateWait = function () {\r\n      var $$ = this;\r\n      var transitionsToWait = [], f = function (callback) {\r\n          var timer = setInterval(function () {\r\n              if (!$$.isTabVisible()) {\r\n                  return;\r\n              }\r\n              var done = 0;\r\n              transitionsToWait.forEach(function (t) {\r\n                  if (t.empty()) {\r\n                      done += 1;\r\n                      return;\r\n                  }\r\n                  try {\r\n                      t.transition();\r\n                  }\r\n                  catch (e) {\r\n                      done += 1;\r\n                  }\r\n              });\r\n              if (done === transitionsToWait.length) {\r\n                  clearInterval(timer);\r\n                  if (callback) {\r\n                      callback();\r\n                  }\r\n              }\r\n          }, 50);\r\n      };\r\n      f.add = function (transition) {\r\n          transitionsToWait.push(transition);\r\n      };\r\n      return f;\r\n  };\r\n  ChartInternal.prototype.parseDate = function (date) {\r\n      var $$ = this, parsedDate;\r\n      if (date instanceof Date) {\r\n          parsedDate = date;\r\n      }\r\n      else if (typeof date === 'string') {\r\n          parsedDate = $$.dataTimeParse(date);\r\n      }\r\n      else if (typeof date === 'object') {\r\n          parsedDate = new Date(+date);\r\n      }\r\n      else if (typeof date === 'number' && !isNaN(date)) {\r\n          parsedDate = new Date(+date);\r\n      }\r\n      if (!parsedDate || isNaN(+parsedDate)) {\r\n          window.console.error(\"Failed to parse x '\" + date + \"' to Date object\");\r\n      }\r\n      return parsedDate;\r\n  };\r\n  ChartInternal.prototype.isTabVisible = function () {\r\n      return !document.hidden;\r\n  };\r\n  ChartInternal.prototype.getPathBox = getPathBox;\r\n  ChartInternal.prototype.CLASS = CLASS;\n\n  /* jshint ignore:start */\r\n  (function () {\r\n      if (!('SVGPathSeg' in window)) {\r\n          // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg\r\n          window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) {\r\n              this.pathSegType = type;\r\n              this.pathSegTypeAsLetter = typeAsLetter;\r\n              this._owningPathSegList = owningPathSegList;\r\n          };\r\n          window.SVGPathSeg.prototype.classname = 'SVGPathSeg';\r\n          window.SVGPathSeg.PATHSEG_UNKNOWN = 0;\r\n          window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;\r\n          window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;\r\n          window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;\r\n          window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;\r\n          window.SVGPathSeg.PATHSEG_LINETO_REL = 5;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;\r\n          window.SVGPathSeg.PATHSEG_ARC_ABS = 10;\r\n          window.SVGPathSeg.PATHSEG_ARC_REL = 11;\r\n          window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;\r\n          window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;\r\n          window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;\r\n          window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;\r\n          // Notify owning PathSegList on any changes so they can be synchronized back to the path element.\r\n          window.SVGPathSeg.prototype._segmentChanged = function () {\r\n              if (this._owningPathSegList)\r\n                  this._owningPathSegList.segmentChanged(this);\r\n          };\r\n          window.SVGPathSegClosePath = function (owningPathSegList) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, 'z', owningPathSegList);\r\n          };\r\n          window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegClosePath.prototype.toString = function () {\r\n              return '[object SVGPathSegClosePath]';\r\n          };\r\n          window.SVGPathSegClosePath.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter;\r\n          };\r\n          window.SVGPathSegClosePath.prototype.clone = function () {\r\n              return new window.SVGPathSegClosePath(undefined);\r\n          };\r\n          window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, 'M', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegMovetoAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegMovetoAbs]';\r\n          };\r\n          window.SVGPathSegMovetoAbs.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegMovetoAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, 'm', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegMovetoRel.prototype.toString = function () {\r\n              return '[object SVGPathSegMovetoRel]';\r\n          };\r\n          window.SVGPathSegMovetoRel.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegMovetoRel.prototype.clone = function () {\r\n              return new window.SVGPathSegMovetoRel(undefined, this._x, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, 'L', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegLinetoAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegLinetoAbs]';\r\n          };\r\n          window.SVGPathSegLinetoAbs.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegLinetoAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, 'l', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegLinetoRel.prototype.toString = function () {\r\n              return '[object SVGPathSegLinetoRel]';\r\n          };\r\n          window.SVGPathSegLinetoRel.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegLinetoRel.prototype.clone = function () {\r\n              return new window.SVGPathSegLinetoRel(undefined, this._x, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, 'C', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._x1 = x1;\r\n              this._y1 = y1;\r\n              this._x2 = x2;\r\n              this._y2 = y2;\r\n          };\r\n          window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoCubicAbs]';\r\n          };\r\n          window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._x1 +\r\n                  ' ' +\r\n                  this._y1 +\r\n                  ' ' +\r\n                  this._x2 +\r\n                  ' ' +\r\n                  this._y2 +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x1', {\r\n              get: function () {\r\n                  return this._x1;\r\n              },\r\n              set: function (x1) {\r\n                  this._x1 = x1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y1', {\r\n              get: function () {\r\n                  return this._y1;\r\n              },\r\n              set: function (y1) {\r\n                  this._y1 = y1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x2', {\r\n              get: function () {\r\n                  return this._x2;\r\n              },\r\n              set: function (x2) {\r\n                  this._x2 = x2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y2', {\r\n              get: function () {\r\n                  return this._y2;\r\n              },\r\n              set: function (y2) {\r\n                  this._y2 = y2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, 'c', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._x1 = x1;\r\n              this._y1 = y1;\r\n              this._x2 = x2;\r\n              this._y2 = y2;\r\n          };\r\n          window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoCubicRel.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoCubicRel]';\r\n          };\r\n          window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._x1 +\r\n                  ' ' +\r\n                  this._y1 +\r\n                  ' ' +\r\n                  this._x2 +\r\n                  ' ' +\r\n                  this._y2 +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegCurvetoCubicRel.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x1', {\r\n              get: function () {\r\n                  return this._x1;\r\n              },\r\n              set: function (x1) {\r\n                  this._x1 = x1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y1', {\r\n              get: function () {\r\n                  return this._y1;\r\n              },\r\n              set: function (y1) {\r\n                  this._y1 = y1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x2', {\r\n              get: function () {\r\n                  return this._x2;\r\n              },\r\n              set: function (x2) {\r\n                  this._x2 = x2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y2', {\r\n              get: function () {\r\n                  return this._y2;\r\n              },\r\n              set: function (y2) {\r\n                  this._y2 = y2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, 'Q', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._x1 = x1;\r\n              this._y1 = y1;\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoQuadraticAbs]';\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._x1 +\r\n                  ' ' +\r\n                  this._y1 +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x1', {\r\n              get: function () {\r\n                  return this._x1;\r\n              },\r\n              set: function (x1) {\r\n                  this._x1 = x1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y1', {\r\n              get: function () {\r\n                  return this._y1;\r\n              },\r\n              set: function (y1) {\r\n                  this._y1 = y1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, 'q', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._x1 = x1;\r\n              this._y1 = y1;\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoQuadraticRel]';\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._x1 +\r\n                  ' ' +\r\n                  this._y1 +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x1', {\r\n              get: function () {\r\n                  return this._x1;\r\n              },\r\n              set: function (x1) {\r\n                  this._x1 = x1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y1', {\r\n              get: function () {\r\n                  return this._y1;\r\n              },\r\n              set: function (y1) {\r\n                  this._y1 = y1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, 'A', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._r1 = r1;\r\n              this._r2 = r2;\r\n              this._angle = angle;\r\n              this._largeArcFlag = largeArcFlag;\r\n              this._sweepFlag = sweepFlag;\r\n          };\r\n          window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegArcAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegArcAbs]';\r\n          };\r\n          window.SVGPathSegArcAbs.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._r1 +\r\n                  ' ' +\r\n                  this._r2 +\r\n                  ' ' +\r\n                  this._angle +\r\n                  ' ' +\r\n                  (this._largeArcFlag ? '1' : '0') +\r\n                  ' ' +\r\n                  (this._sweepFlag ? '1' : '0') +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegArcAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r1', {\r\n              get: function () {\r\n                  return this._r1;\r\n              },\r\n              set: function (r1) {\r\n                  this._r1 = r1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r2', {\r\n              get: function () {\r\n                  return this._r2;\r\n              },\r\n              set: function (r2) {\r\n                  this._r2 = r2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'angle', {\r\n              get: function () {\r\n                  return this._angle;\r\n              },\r\n              set: function (angle) {\r\n                  this._angle = angle;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'largeArcFlag', {\r\n              get: function () {\r\n                  return this._largeArcFlag;\r\n              },\r\n              set: function (largeArcFlag) {\r\n                  this._largeArcFlag = largeArcFlag;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'sweepFlag', {\r\n              get: function () {\r\n                  return this._sweepFlag;\r\n              },\r\n              set: function (sweepFlag) {\r\n                  this._sweepFlag = sweepFlag;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, 'a', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._r1 = r1;\r\n              this._r2 = r2;\r\n              this._angle = angle;\r\n              this._largeArcFlag = largeArcFlag;\r\n              this._sweepFlag = sweepFlag;\r\n          };\r\n          window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegArcRel.prototype.toString = function () {\r\n              return '[object SVGPathSegArcRel]';\r\n          };\r\n          window.SVGPathSegArcRel.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._r1 +\r\n                  ' ' +\r\n                  this._r2 +\r\n                  ' ' +\r\n                  this._angle +\r\n                  ' ' +\r\n                  (this._largeArcFlag ? '1' : '0') +\r\n                  ' ' +\r\n                  (this._sweepFlag ? '1' : '0') +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegArcRel.prototype.clone = function () {\r\n              return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r1', {\r\n              get: function () {\r\n                  return this._r1;\r\n              },\r\n              set: function (r1) {\r\n                  this._r1 = r1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r2', {\r\n              get: function () {\r\n                  return this._r2;\r\n              },\r\n              set: function (r2) {\r\n                  this._r2 = r2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'angle', {\r\n              get: function () {\r\n                  return this._angle;\r\n              },\r\n              set: function (angle) {\r\n                  this._angle = angle;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'largeArcFlag', {\r\n              get: function () {\r\n                  return this._largeArcFlag;\r\n              },\r\n              set: function (largeArcFlag) {\r\n                  this._largeArcFlag = largeArcFlag;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'sweepFlag', {\r\n              get: function () {\r\n                  return this._sweepFlag;\r\n              },\r\n              set: function (sweepFlag) {\r\n                  this._sweepFlag = sweepFlag;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, 'H', owningPathSegList);\r\n              this._x = x;\r\n          };\r\n          window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegLinetoHorizontalAbs]';\r\n          };\r\n          window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x;\r\n          };\r\n          window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, 'h', owningPathSegList);\r\n              this._x = x;\r\n          };\r\n          window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () {\r\n              return '[object SVGPathSegLinetoHorizontalRel]';\r\n          };\r\n          window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x;\r\n          };\r\n          window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () {\r\n              return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, 'V', owningPathSegList);\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegLinetoVerticalAbs]';\r\n          };\r\n          window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, 'v', owningPathSegList);\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegLinetoVerticalRel.prototype.toString = function () {\r\n              return '[object SVGPathSegLinetoVerticalRel]';\r\n          };\r\n          window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegLinetoVerticalRel.prototype.clone = function () {\r\n              return new window.SVGPathSegLinetoVerticalRel(undefined, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, 'S', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._x2 = x2;\r\n              this._y2 = y2;\r\n          };\r\n          window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoCubicSmoothAbs]';\r\n          };\r\n          window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._x2 +\r\n                  ' ' +\r\n                  this._y2 +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'x2', {\r\n              get: function () {\r\n                  return this._x2;\r\n              },\r\n              set: function (x2) {\r\n                  this._x2 = x2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'y2', {\r\n              get: function () {\r\n                  return this._y2;\r\n              },\r\n              set: function (y2) {\r\n                  this._y2 = y2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, 's', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._x2 = x2;\r\n              this._y2 = y2;\r\n          };\r\n          window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoCubicSmoothRel]';\r\n          };\r\n          window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._x2 +\r\n                  ' ' +\r\n                  this._y2 +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'x2', {\r\n              get: function () {\r\n                  return this._x2;\r\n              },\r\n              set: function (x2) {\r\n                  this._x2 = x2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'y2', {\r\n              get: function () {\r\n                  return this._y2;\r\n              },\r\n              set: function (y2) {\r\n                  this._y2 = y2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, 'T', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoQuadraticSmoothAbs]';\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, 't', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoQuadraticSmoothRel]';\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          // Add createSVGPathSeg* functions to window.SVGPathElement.\r\n          // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.\r\n          window.SVGPathElement.prototype.createSVGPathSegClosePath = function () {\r\n              return new window.SVGPathSegClosePath(undefined);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) {\r\n              return new window.SVGPathSegMovetoAbs(undefined, x, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) {\r\n              return new window.SVGPathSegMovetoRel(undefined, x, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) {\r\n              return new window.SVGPathSegLinetoAbs(undefined, x, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) {\r\n              return new window.SVGPathSegLinetoRel(undefined, x, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) {\r\n              return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) {\r\n              return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) {\r\n              return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) {\r\n              return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {\r\n              return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {\r\n              return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) {\r\n              return new window.SVGPathSegLinetoHorizontalAbs(undefined, x);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) {\r\n              return new window.SVGPathSegLinetoHorizontalRel(undefined, x);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) {\r\n              return new window.SVGPathSegLinetoVerticalAbs(undefined, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) {\r\n              return new window.SVGPathSegLinetoVerticalRel(undefined, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) {\r\n              return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) {\r\n              return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) {\r\n              return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) {\r\n              return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y);\r\n          };\r\n          if (!('getPathSegAtLength' in window.SVGPathElement.prototype)) {\r\n              // Add getPathSegAtLength to SVGPathElement.\r\n              // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength\r\n              // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.\r\n              window.SVGPathElement.prototype.getPathSegAtLength = function (distance) {\r\n                  if (distance === undefined || !isFinite(distance))\r\n                      throw 'Invalid arguments.';\r\n                  var measurementElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');\r\n                  measurementElement.setAttribute('d', this.getAttribute('d'));\r\n                  var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1;\r\n                  // If the path is empty, return 0.\r\n                  if (lastPathSegment <= 0)\r\n                      return 0;\r\n                  do {\r\n                      measurementElement.pathSegList.removeItem(lastPathSegment);\r\n                      if (distance > measurementElement.getTotalLength())\r\n                          break;\r\n                      lastPathSegment--;\r\n                  } while (lastPathSegment > 0);\r\n                  return lastPathSegment;\r\n              };\r\n          }\r\n      }\r\n      if (!('SVGPathSegList' in window)) {\r\n          // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList\r\n          window.SVGPathSegList = function (pathElement) {\r\n              this._pathElement = pathElement;\r\n              this._list = this._parsePath(this._pathElement.getAttribute('d'));\r\n              // Use a MutationObserver to catch changes to the path's \"d\" attribute.\r\n              this._mutationObserverConfig = {\r\n                  attributes: true,\r\n                  attributeFilter: ['d']\r\n              };\r\n              this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this));\r\n              this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);\r\n          };\r\n          window.SVGPathSegList.prototype.classname = 'SVGPathSegList';\r\n          Object.defineProperty(window.SVGPathSegList.prototype, 'numberOfItems', {\r\n              get: function () {\r\n                  this._checkPathSynchronizedToList();\r\n                  return this._list.length;\r\n              },\r\n              enumerable: true\r\n          });\r\n          // Add the pathSegList accessors to window.SVGPathElement.\r\n          // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData\r\n          Object.defineProperty(window.SVGPathElement.prototype, 'pathSegList', {\r\n              get: function () {\r\n                  if (!this._pathSegList)\r\n                      this._pathSegList = new window.SVGPathSegList(this);\r\n                  return this._pathSegList;\r\n              },\r\n              enumerable: true\r\n          });\r\n          // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.\r\n          Object.defineProperty(window.SVGPathElement.prototype, 'normalizedPathSegList', {\r\n              get: function () {\r\n                  return this.pathSegList;\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathElement.prototype, 'animatedPathSegList', {\r\n              get: function () {\r\n                  return this.pathSegList;\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathElement.prototype, 'animatedNormalizedPathSegList', {\r\n              get: function () {\r\n                  return this.pathSegList;\r\n              },\r\n              enumerable: true\r\n          });\r\n          // Process any pending mutations to the path element and update the list as needed.\r\n          // This should be the first call of all public functions and is needed because\r\n          // MutationObservers are not synchronous so we can have pending asynchronous mutations.\r\n          window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () {\r\n              this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());\r\n          };\r\n          window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) {\r\n              if (!this._pathElement)\r\n                  return;\r\n              var hasPathMutations = false;\r\n              mutationRecords.forEach(function (record) {\r\n                  if (record.attributeName == 'd')\r\n                      hasPathMutations = true;\r\n              });\r\n              if (hasPathMutations)\r\n                  this._list = this._parsePath(this._pathElement.getAttribute('d'));\r\n          };\r\n          // Serialize the list and update the path's 'd' attribute.\r\n          window.SVGPathSegList.prototype._writeListToPath = function () {\r\n              this._pathElementMutationObserver.disconnect();\r\n              this._pathElement.setAttribute('d', window.SVGPathSegList._pathSegArrayAsString(this._list));\r\n              this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);\r\n          };\r\n          // When a path segment changes the list needs to be synchronized back to the path element.\r\n          window.SVGPathSegList.prototype.segmentChanged = function (pathSeg) {\r\n              this._writeListToPath();\r\n          };\r\n          window.SVGPathSegList.prototype.clear = function () {\r\n              this._checkPathSynchronizedToList();\r\n              this._list.forEach(function (pathSeg) {\r\n                  pathSeg._owningPathSegList = null;\r\n              });\r\n              this._list = [];\r\n              this._writeListToPath();\r\n          };\r\n          window.SVGPathSegList.prototype.initialize = function (newItem) {\r\n              this._checkPathSynchronizedToList();\r\n              this._list = [newItem];\r\n              newItem._owningPathSegList = this;\r\n              this._writeListToPath();\r\n              return newItem;\r\n          };\r\n          window.SVGPathSegList.prototype._checkValidIndex = function (index) {\r\n              if (isNaN(index) || index < 0 || index >= this.numberOfItems)\r\n                  throw 'INDEX_SIZE_ERR';\r\n          };\r\n          window.SVGPathSegList.prototype.getItem = function (index) {\r\n              this._checkPathSynchronizedToList();\r\n              this._checkValidIndex(index);\r\n              return this._list[index];\r\n          };\r\n          window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) {\r\n              this._checkPathSynchronizedToList();\r\n              // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.\r\n              if (index > this.numberOfItems)\r\n                  index = this.numberOfItems;\r\n              if (newItem._owningPathSegList) {\r\n                  // SVG2 spec says to make a copy.\r\n                  newItem = newItem.clone();\r\n              }\r\n              this._list.splice(index, 0, newItem);\r\n              newItem._owningPathSegList = this;\r\n              this._writeListToPath();\r\n              return newItem;\r\n          };\r\n          window.SVGPathSegList.prototype.replaceItem = function (newItem, index) {\r\n              this._checkPathSynchronizedToList();\r\n              if (newItem._owningPathSegList) {\r\n                  // SVG2 spec says to make a copy.\r\n                  newItem = newItem.clone();\r\n              }\r\n              this._checkValidIndex(index);\r\n              this._list[index] = newItem;\r\n              newItem._owningPathSegList = this;\r\n              this._writeListToPath();\r\n              return newItem;\r\n          };\r\n          window.SVGPathSegList.prototype.removeItem = function (index) {\r\n              this._checkPathSynchronizedToList();\r\n              this._checkValidIndex(index);\r\n              var item = this._list[index];\r\n              this._list.splice(index, 1);\r\n              this._writeListToPath();\r\n              return item;\r\n          };\r\n          window.SVGPathSegList.prototype.appendItem = function (newItem) {\r\n              this._checkPathSynchronizedToList();\r\n              if (newItem._owningPathSegList) {\r\n                  // SVG2 spec says to make a copy.\r\n                  newItem = newItem.clone();\r\n              }\r\n              this._list.push(newItem);\r\n              newItem._owningPathSegList = this;\r\n              // TODO: Optimize this to just append to the existing attribute.\r\n              this._writeListToPath();\r\n              return newItem;\r\n          };\r\n          window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) {\r\n              var string = '';\r\n              var first = true;\r\n              pathSegArray.forEach(function (pathSeg) {\r\n                  if (first) {\r\n                      first = false;\r\n                      string += pathSeg._asPathString();\r\n                  }\r\n                  else {\r\n                      string += ' ' + pathSeg._asPathString();\r\n                  }\r\n              });\r\n              return string;\r\n          };\r\n          // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.\r\n          window.SVGPathSegList.prototype._parsePath = function (string) {\r\n              if (!string || string.length == 0)\r\n                  return [];\r\n              var owningPathSegList = this;\r\n              var Builder = function () {\r\n                  this.pathSegList = [];\r\n              };\r\n              Builder.prototype.appendSegment = function (pathSeg) {\r\n                  this.pathSegList.push(pathSeg);\r\n              };\r\n              var Source = function (string) {\r\n                  this._string = string;\r\n                  this._currentIndex = 0;\r\n                  this._endIndex = this._string.length;\r\n                  this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;\r\n                  this._skipOptionalSpaces();\r\n              };\r\n              Source.prototype._isCurrentSpace = function () {\r\n                  var character = this._string[this._currentIndex];\r\n                  return (character <= ' ' &&\r\n                      (character == ' ' ||\r\n                          character == '\\n' ||\r\n                          character == '\\t' ||\r\n                          character == '\\r' ||\r\n                          character == '\\f'));\r\n              };\r\n              Source.prototype._skipOptionalSpaces = function () {\r\n                  while (this._currentIndex < this._endIndex && this._isCurrentSpace())\r\n                      this._currentIndex++;\r\n                  return this._currentIndex < this._endIndex;\r\n              };\r\n              Source.prototype._skipOptionalSpacesOrDelimiter = function () {\r\n                  if (this._currentIndex < this._endIndex &&\r\n                      !this._isCurrentSpace() &&\r\n                      this._string.charAt(this._currentIndex) != ',')\r\n                      return false;\r\n                  if (this._skipOptionalSpaces()) {\r\n                      if (this._currentIndex < this._endIndex &&\r\n                          this._string.charAt(this._currentIndex) == ',') {\r\n                          this._currentIndex++;\r\n                          this._skipOptionalSpaces();\r\n                      }\r\n                  }\r\n                  return this._currentIndex < this._endIndex;\r\n              };\r\n              Source.prototype.hasMoreData = function () {\r\n                  return this._currentIndex < this._endIndex;\r\n              };\r\n              Source.prototype.peekSegmentType = function () {\r\n                  var lookahead = this._string[this._currentIndex];\r\n                  return this._pathSegTypeFromChar(lookahead);\r\n              };\r\n              Source.prototype._pathSegTypeFromChar = function (lookahead) {\r\n                  switch (lookahead) {\r\n                      case 'Z':\r\n                      case 'z':\r\n                          return window.SVGPathSeg.PATHSEG_CLOSEPATH;\r\n                      case 'M':\r\n                          return window.SVGPathSeg.PATHSEG_MOVETO_ABS;\r\n                      case 'm':\r\n                          return window.SVGPathSeg.PATHSEG_MOVETO_REL;\r\n                      case 'L':\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_ABS;\r\n                      case 'l':\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_REL;\r\n                      case 'C':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;\r\n                      case 'c':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;\r\n                      case 'Q':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;\r\n                      case 'q':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;\r\n                      case 'A':\r\n                          return window.SVGPathSeg.PATHSEG_ARC_ABS;\r\n                      case 'a':\r\n                          return window.SVGPathSeg.PATHSEG_ARC_REL;\r\n                      case 'H':\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;\r\n                      case 'h':\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;\r\n                      case 'V':\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;\r\n                      case 'v':\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;\r\n                      case 'S':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;\r\n                      case 's':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;\r\n                      case 'T':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;\r\n                      case 't':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;\r\n                      default:\r\n                          return window.SVGPathSeg.PATHSEG_UNKNOWN;\r\n                  }\r\n              };\r\n              Source.prototype._nextCommandHelper = function (lookahead, previousCommand) {\r\n                  // Check for remaining coordinates in the current command.\r\n                  if ((lookahead == '+' ||\r\n                      lookahead == '-' ||\r\n                      lookahead == '.' ||\r\n                      (lookahead >= '0' && lookahead <= '9')) &&\r\n                      previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) {\r\n                      if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS)\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_ABS;\r\n                      if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL)\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_REL;\r\n                      return previousCommand;\r\n                  }\r\n                  return window.SVGPathSeg.PATHSEG_UNKNOWN;\r\n              };\r\n              Source.prototype.initialCommandIsMoveTo = function () {\r\n                  // If the path is empty it is still valid, so return true.\r\n                  if (!this.hasMoreData())\r\n                      return true;\r\n                  var command = this.peekSegmentType();\r\n                  // Path must start with moveTo.\r\n                  return (command == window.SVGPathSeg.PATHSEG_MOVETO_ABS ||\r\n                      command == window.SVGPathSeg.PATHSEG_MOVETO_REL);\r\n              };\r\n              // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.\r\n              // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF\r\n              Source.prototype._parseNumber = function () {\r\n                  var exponent = 0;\r\n                  var integer = 0;\r\n                  var frac = 1;\r\n                  var decimal = 0;\r\n                  var sign = 1;\r\n                  var expsign = 1;\r\n                  var startIndex = this._currentIndex;\r\n                  this._skipOptionalSpaces();\r\n                  // Read the sign.\r\n                  if (this._currentIndex < this._endIndex &&\r\n                      this._string.charAt(this._currentIndex) == '+')\r\n                      this._currentIndex++;\r\n                  else if (this._currentIndex < this._endIndex &&\r\n                      this._string.charAt(this._currentIndex) == '-') {\r\n                      this._currentIndex++;\r\n                      sign = -1;\r\n                  }\r\n                  if (this._currentIndex == this._endIndex ||\r\n                      ((this._string.charAt(this._currentIndex) < '0' ||\r\n                          this._string.charAt(this._currentIndex) > '9') &&\r\n                          this._string.charAt(this._currentIndex) != '.'))\r\n                      // The first character of a number must be one of [0-9+-.].\r\n                      return undefined;\r\n                  // Read the integer part, build right-to-left.\r\n                  var startIntPartIndex = this._currentIndex;\r\n                  while (this._currentIndex < this._endIndex &&\r\n                      this._string.charAt(this._currentIndex) >= '0' &&\r\n                      this._string.charAt(this._currentIndex) <= '9')\r\n                      this._currentIndex++; // Advance to first non-digit.\r\n                  if (this._currentIndex != startIntPartIndex) {\r\n                      var scanIntPartIndex = this._currentIndex - 1;\r\n                      var multiplier = 1;\r\n                      while (scanIntPartIndex >= startIntPartIndex) {\r\n                          integer +=\r\n                              multiplier * (this._string.charAt(scanIntPartIndex--) - '0');\r\n                          multiplier *= 10;\r\n                      }\r\n                  }\r\n                  // Read the decimals.\r\n                  if (this._currentIndex < this._endIndex &&\r\n                      this._string.charAt(this._currentIndex) == '.') {\r\n                      this._currentIndex++;\r\n                      // There must be a least one digit following the .\r\n                      if (this._currentIndex >= this._endIndex ||\r\n                          this._string.charAt(this._currentIndex) < '0' ||\r\n                          this._string.charAt(this._currentIndex) > '9')\r\n                          return undefined;\r\n                      while (this._currentIndex < this._endIndex &&\r\n                          this._string.charAt(this._currentIndex) >= '0' &&\r\n                          this._string.charAt(this._currentIndex) <= '9') {\r\n                          frac *= 10;\r\n                          decimal += (this._string.charAt(this._currentIndex) - '0') / frac;\r\n                          this._currentIndex += 1;\r\n                      }\r\n                  }\r\n                  // Read the exponent part.\r\n                  if (this._currentIndex != startIndex &&\r\n                      this._currentIndex + 1 < this._endIndex &&\r\n                      (this._string.charAt(this._currentIndex) == 'e' ||\r\n                          this._string.charAt(this._currentIndex) == 'E') &&\r\n                      this._string.charAt(this._currentIndex + 1) != 'x' &&\r\n                      this._string.charAt(this._currentIndex + 1) != 'm') {\r\n                      this._currentIndex++;\r\n                      // Read the sign of the exponent.\r\n                      if (this._string.charAt(this._currentIndex) == '+') {\r\n                          this._currentIndex++;\r\n                      }\r\n                      else if (this._string.charAt(this._currentIndex) == '-') {\r\n                          this._currentIndex++;\r\n                          expsign = -1;\r\n                      }\r\n                      // There must be an exponent.\r\n                      if (this._currentIndex >= this._endIndex ||\r\n                          this._string.charAt(this._currentIndex) < '0' ||\r\n                          this._string.charAt(this._currentIndex) > '9')\r\n                          return undefined;\r\n                      while (this._currentIndex < this._endIndex &&\r\n                          this._string.charAt(this._currentIndex) >= '0' &&\r\n                          this._string.charAt(this._currentIndex) <= '9') {\r\n                          exponent *= 10;\r\n                          exponent += this._string.charAt(this._currentIndex) - '0';\r\n                          this._currentIndex++;\r\n                      }\r\n                  }\r\n                  var number = integer + decimal;\r\n                  number *= sign;\r\n                  if (exponent)\r\n                      number *= Math.pow(10, expsign * exponent);\r\n                  if (startIndex == this._currentIndex)\r\n                      return undefined;\r\n                  this._skipOptionalSpacesOrDelimiter();\r\n                  return number;\r\n              };\r\n              Source.prototype._parseArcFlag = function () {\r\n                  if (this._currentIndex >= this._endIndex)\r\n                      return undefined;\r\n                  var flag = false;\r\n                  var flagChar = this._string.charAt(this._currentIndex++);\r\n                  if (flagChar == '0')\r\n                      flag = false;\r\n                  else if (flagChar == '1')\r\n                      flag = true;\r\n                  else\r\n                      return undefined;\r\n                  this._skipOptionalSpacesOrDelimiter();\r\n                  return flag;\r\n              };\r\n              Source.prototype.parseSegment = function () {\r\n                  var lookahead = this._string[this._currentIndex];\r\n                  var command = this._pathSegTypeFromChar(lookahead);\r\n                  if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {\r\n                      // Possibly an implicit command. Not allowed if this is the first command.\r\n                      if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN)\r\n                          return null;\r\n                      command = this._nextCommandHelper(lookahead, this._previousCommand);\r\n                      if (command == window.SVGPathSeg.PATHSEG_UNKNOWN)\r\n                          return null;\r\n                  }\r\n                  else {\r\n                      this._currentIndex++;\r\n                  }\r\n                  this._previousCommand = command;\r\n                  switch (command) {\r\n                      case window.SVGPathSeg.PATHSEG_MOVETO_REL:\r\n                          return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_MOVETO_ABS:\r\n                          return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_LINETO_REL:\r\n                          return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_LINETO_ABS:\r\n                          return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:\r\n                          return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:\r\n                          return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:\r\n                          return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:\r\n                          return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_CLOSEPATH:\r\n                          this._skipOptionalSpaces();\r\n                          return new window.SVGPathSegClosePath(owningPathSegList);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:\r\n                          var points = {\r\n                              x1: this._parseNumber(),\r\n                              y1: this._parseNumber(),\r\n                              x2: this._parseNumber(),\r\n                              y2: this._parseNumber(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:\r\n                          var points = {\r\n                              x1: this._parseNumber(),\r\n                              y1: this._parseNumber(),\r\n                              x2: this._parseNumber(),\r\n                              y2: this._parseNumber(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:\r\n                          var points = {\r\n                              x2: this._parseNumber(),\r\n                              y2: this._parseNumber(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:\r\n                          var points = {\r\n                              x2: this._parseNumber(),\r\n                              y2: this._parseNumber(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:\r\n                          var points = {\r\n                              x1: this._parseNumber(),\r\n                              y1: this._parseNumber(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:\r\n                          var points = {\r\n                              x1: this._parseNumber(),\r\n                              y1: this._parseNumber(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:\r\n                          return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:\r\n                          return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_ARC_REL:\r\n                          var points = {\r\n                              x1: this._parseNumber(),\r\n                              y1: this._parseNumber(),\r\n                              arcAngle: this._parseNumber(),\r\n                              arcLarge: this._parseArcFlag(),\r\n                              arcSweep: this._parseArcFlag(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);\r\n                      case window.SVGPathSeg.PATHSEG_ARC_ABS:\r\n                          var points = {\r\n                              x1: this._parseNumber(),\r\n                              y1: this._parseNumber(),\r\n                              arcAngle: this._parseNumber(),\r\n                              arcLarge: this._parseArcFlag(),\r\n                              arcSweep: this._parseArcFlag(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);\r\n                      default:\r\n                          throw 'Unknown path seg type.';\r\n                  }\r\n              };\r\n              var builder = new Builder();\r\n              var source = new Source(string);\r\n              if (!source.initialCommandIsMoveTo())\r\n                  return [];\r\n              while (source.hasMoreData()) {\r\n                  var pathSeg = source.parseSegment();\r\n                  if (!pathSeg)\r\n                      return [];\r\n                  builder.appendSegment(pathSeg);\r\n              }\r\n              return builder.pathSegList;\r\n          };\r\n      }\r\n  })();\r\n  // String.padEnd polyfill for IE11\r\n  //\r\n  // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js\r\n  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd\r\n  if (!String.prototype.padEnd) {\r\n      String.prototype.padEnd = function padEnd(targetLength, padString) {\r\n          targetLength = targetLength >> 0; //floor if number or convert non-number to 0;\r\n          padString = String(typeof padString !== 'undefined' ? padString : ' ');\r\n          if (this.length > targetLength) {\r\n              return String(this);\r\n          }\r\n          else {\r\n              targetLength = targetLength - this.length;\r\n              if (targetLength > padString.length) {\r\n                  padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed\r\n              }\r\n              return String(this) + padString.slice(0, targetLength);\r\n          }\r\n      };\r\n  }\r\n  // Object.assign polyfill for IE11\r\n  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill\r\n  if (typeof Object.assign !== 'function') {\r\n      // Must be writable: true, enumerable: false, configurable: true\r\n      Object.defineProperty(Object, 'assign', {\r\n          value: function assign(target, varArgs) {\r\n              if (target === null || target === undefined) {\r\n                  throw new TypeError('Cannot convert undefined or null to object');\r\n              }\r\n              var to = Object(target);\r\n              for (var index = 1; index < arguments.length; index++) {\r\n                  var nextSource = arguments[index];\r\n                  if (nextSource !== null && nextSource !== undefined) {\r\n                      for (var nextKey in nextSource) {\r\n                          // Avoid bugs when hasOwnProperty is shadowed\r\n                          if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\r\n                              to[nextKey] = nextSource[nextKey];\r\n                          }\r\n                      }\r\n                  }\r\n              }\r\n              return to;\r\n          },\r\n          writable: true,\r\n          configurable: true\r\n      });\r\n  }\r\n  /* jshint ignore:end */\n\n  Chart.prototype.axis = function () { };\r\n  Chart.prototype.axis.labels = function (labels) {\r\n      var $$ = this.internal;\r\n      if (arguments.length) {\r\n          Object.keys(labels).forEach(function (axisId) {\r\n              $$.axis.setLabelText(axisId, labels[axisId]);\r\n          });\r\n          $$.axis.updateLabels();\r\n      }\r\n      // TODO: return some values?\r\n  };\r\n  Chart.prototype.axis.max = function (max) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (arguments.length) {\r\n          if (typeof max === 'object') {\r\n              if (isValue(max.x)) {\r\n                  config.axis_x_max = max.x;\r\n              }\r\n              if (isValue(max.y)) {\r\n                  config.axis_y_max = max.y;\r\n              }\r\n              if (isValue(max.y2)) {\r\n                  config.axis_y2_max = max.y2;\r\n              }\r\n          }\r\n          else {\r\n              config.axis_y_max = config.axis_y2_max = max;\r\n          }\r\n          $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\r\n      }\r\n      else {\r\n          return {\r\n              x: config.axis_x_max,\r\n              y: config.axis_y_max,\r\n              y2: config.axis_y2_max\r\n          };\r\n      }\r\n  };\r\n  Chart.prototype.axis.min = function (min) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (arguments.length) {\r\n          if (typeof min === 'object') {\r\n              if (isValue(min.x)) {\r\n                  config.axis_x_min = min.x;\r\n              }\r\n              if (isValue(min.y)) {\r\n                  config.axis_y_min = min.y;\r\n              }\r\n              if (isValue(min.y2)) {\r\n                  config.axis_y2_min = min.y2;\r\n              }\r\n          }\r\n          else {\r\n              config.axis_y_min = config.axis_y2_min = min;\r\n          }\r\n          $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\r\n      }\r\n      else {\r\n          return {\r\n              x: config.axis_x_min,\r\n              y: config.axis_y_min,\r\n              y2: config.axis_y2_min\r\n          };\r\n      }\r\n  };\r\n  Chart.prototype.axis.range = function (range) {\r\n      if (arguments.length) {\r\n          if (isDefined(range.max)) {\r\n              this.axis.max(range.max);\r\n          }\r\n          if (isDefined(range.min)) {\r\n              this.axis.min(range.min);\r\n          }\r\n      }\r\n      else {\r\n          return {\r\n              max: this.axis.max(),\r\n              min: this.axis.min()\r\n          };\r\n      }\r\n  };\r\n  Chart.prototype.axis.types = function (types) {\r\n      var $$ = this.internal;\r\n      if (types === undefined) {\r\n          return {\r\n              y: $$.config.axis_y_type,\r\n              y2: $$.config.axis_y2_type\r\n          };\r\n      }\r\n      else {\r\n          if (isDefined(types.y)) {\r\n              $$.config.axis_y_type = types.y;\r\n          }\r\n          if (isDefined(types.y2)) {\r\n              $$.config.axis_y2_type = types.y2;\r\n          }\r\n          $$.updateScales();\r\n          $$.redraw();\r\n      }\r\n  };\n\n  Chart.prototype.category = function (i, category) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (arguments.length > 1) {\r\n          config.axis_x_categories[i] = category;\r\n          $$.redraw();\r\n      }\r\n      return config.axis_x_categories[i];\r\n  };\r\n  Chart.prototype.categories = function (categories) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (!arguments.length) {\r\n          return config.axis_x_categories;\r\n      }\r\n      config.axis_x_categories = categories;\r\n      $$.redraw();\r\n      return config.axis_x_categories;\r\n  };\n\n  Chart.prototype.resize = function (size) {\r\n      var $$ = this.internal, config = $$.config;\r\n      config.size_width = size ? size.width : null;\r\n      config.size_height = size ? size.height : null;\r\n      this.flush();\r\n  };\r\n  Chart.prototype.flush = function () {\r\n      var $$ = this.internal;\r\n      $$.updateAndRedraw({\r\n          withLegend: true,\r\n          withTransition: false,\r\n          withTransitionForTransform: false\r\n      });\r\n  };\r\n  Chart.prototype.destroy = function () {\r\n      var $$ = this.internal;\r\n      window.clearInterval($$.intervalForObserveInserted);\r\n      if ($$.resizeTimeout !== undefined) {\r\n          window.clearTimeout($$.resizeTimeout);\r\n      }\r\n      window.removeEventListener('resize', $$.resizeIfElementDisplayed);\r\n      // Removes the inner resize functions\r\n      $$.resizeFunction.remove();\r\n      // Unbinds from the window focus event\r\n      $$.unbindWindowFocus();\r\n      $$.selectChart.classed('c3', false).html('');\r\n      // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen.\r\n      Object.keys($$).forEach(function (key) {\r\n          $$[key] = null;\r\n      });\r\n      return null;\r\n  };\n\n  // TODO: fix\r\n  Chart.prototype.color = function (id) {\r\n      var $$ = this.internal;\r\n      return $$.color(id); // more patterns\r\n  };\n\n  Chart.prototype.data = function (targetIds) {\r\n      var targets = this.internal.data.targets;\r\n      return typeof targetIds === 'undefined'\r\n          ? targets\r\n          : targets.filter(function (t) {\r\n              return [].concat(targetIds).indexOf(t.id) >= 0;\r\n          });\r\n  };\r\n  Chart.prototype.data.shown = function (targetIds) {\r\n      return this.internal.filterTargetsToShow(this.data(targetIds));\r\n  };\r\n  /**\r\n   * Get values of the data loaded in the chart.\r\n   *\r\n   * @param {String|Array} targetId This API returns the value of specified target.\r\n   * @param flat\r\n   * @return {Array} Data values\r\n   */\r\n  Chart.prototype.data.values = function (targetId, flat) {\r\n      if (flat === void 0) { flat = true; }\r\n      var values = null;\r\n      if (targetId) {\r\n          var targets = this.data(targetId);\r\n          if (targets && isArray(targets)) {\r\n              values = targets.reduce(function (ret, v) {\r\n                  var dataValue = v.values.map(function (d) { return d.value; });\r\n                  if (flat) {\r\n                      ret = ret.concat(dataValue);\r\n                  }\r\n                  else {\r\n                      ret.push(dataValue);\r\n                  }\r\n                  return ret;\r\n              }, []);\r\n          }\r\n      }\r\n      return values;\r\n  };\r\n  Chart.prototype.data.names = function (names) {\r\n      this.internal.clearLegendItemTextBoxCache();\r\n      return this.internal.updateDataAttributes('names', names);\r\n  };\r\n  Chart.prototype.data.colors = function (colors) {\r\n      return this.internal.updateDataAttributes('colors', colors);\r\n  };\r\n  Chart.prototype.data.axes = function (axes) {\r\n      return this.internal.updateDataAttributes('axes', axes);\r\n  };\r\n  Chart.prototype.data.stackNormalized = function (normalized) {\r\n      if (normalized === undefined) {\r\n          return this.internal.isStackNormalized();\r\n      }\r\n      this.internal.config.data_stack_normalize = !!normalized;\r\n      this.internal.redraw();\r\n  };\n\n  Chart.prototype.donut = function () { };\r\n  Chart.prototype.donut.padAngle = function (padAngle) {\r\n      if (padAngle === undefined) {\r\n          return this.internal.config.donut_padAngle;\r\n      }\r\n      this.internal.config.donut_padAngle = padAngle;\r\n      this.flush();\r\n  };\n\n  Chart.prototype.flow = function (args) {\r\n      var $$ = this.internal, targets, data, notfoundIds = [], orgDataCount = $$.getMaxDataCount(), dataCount, domain, baseTarget, baseValue, length = 0, tail = 0, diff, to;\r\n      if (args.json) {\r\n          data = $$.convertJsonToData(args.json, args.keys);\r\n      }\r\n      else if (args.rows) {\r\n          data = $$.convertRowsToData(args.rows);\r\n      }\r\n      else if (args.columns) {\r\n          data = $$.convertColumnsToData(args.columns);\r\n      }\r\n      else {\r\n          return;\r\n      }\r\n      targets = $$.convertDataToTargets(data, true);\r\n      // Update/Add data\r\n      $$.data.targets.forEach(function (t) {\r\n          var found = false, i, j;\r\n          for (i = 0; i < targets.length; i++) {\r\n              if (t.id === targets[i].id) {\r\n                  found = true;\r\n                  if (t.values[t.values.length - 1]) {\r\n                      tail = t.values[t.values.length - 1].index + 1;\r\n                  }\r\n                  length = targets[i].values.length;\r\n                  for (j = 0; j < length; j++) {\r\n                      targets[i].values[j].index = tail + j;\r\n                      if (!$$.isTimeSeries()) {\r\n                          targets[i].values[j].x = tail + j;\r\n                      }\r\n                  }\r\n                  t.values = t.values.concat(targets[i].values);\r\n                  targets.splice(i, 1);\r\n                  break;\r\n              }\r\n          }\r\n          if (!found) {\r\n              notfoundIds.push(t.id);\r\n          }\r\n      });\r\n      // Append null for not found targets\r\n      $$.data.targets.forEach(function (t) {\r\n          var i, j;\r\n          for (i = 0; i < notfoundIds.length; i++) {\r\n              if (t.id === notfoundIds[i]) {\r\n                  tail = t.values[t.values.length - 1].index + 1;\r\n                  for (j = 0; j < length; j++) {\r\n                      t.values.push({\r\n                          id: t.id,\r\n                          index: tail + j,\r\n                          x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,\r\n                          value: null\r\n                      });\r\n                  }\r\n              }\r\n          }\r\n      });\r\n      // Generate null values for new target\r\n      if ($$.data.targets.length) {\r\n          targets.forEach(function (t) {\r\n              var i, missing = [];\r\n              for (i = $$.data.targets[0].values[0].index; i < tail; i++) {\r\n                  missing.push({\r\n                      id: t.id,\r\n                      index: i,\r\n                      x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,\r\n                      value: null\r\n                  });\r\n              }\r\n              t.values.forEach(function (v) {\r\n                  v.index += tail;\r\n                  if (!$$.isTimeSeries()) {\r\n                      v.x += tail;\r\n                  }\r\n              });\r\n              t.values = missing.concat(t.values);\r\n          });\r\n      }\r\n      $$.data.targets = $$.data.targets.concat(targets); // add remained\r\n      // check data count because behavior needs to change when it's only one\r\n      dataCount = $$.getMaxDataCount();\r\n      baseTarget = $$.data.targets[0];\r\n      baseValue = baseTarget.values[0];\r\n      // Update length to flow if needed\r\n      if (isDefined(args.to)) {\r\n          length = 0;\r\n          to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to;\r\n          baseTarget.values.forEach(function (v) {\r\n              if (v.x < to) {\r\n                  length++;\r\n              }\r\n          });\r\n      }\r\n      else if (isDefined(args.length)) {\r\n          length = args.length;\r\n      }\r\n      // If only one data, update the domain to flow from left edge of the chart\r\n      if (!orgDataCount) {\r\n          if ($$.isTimeSeries()) {\r\n              if (baseTarget.values.length > 1) {\r\n                  diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x;\r\n              }\r\n              else {\r\n                  diff = baseValue.x - $$.getXDomain($$.data.targets)[0];\r\n              }\r\n          }\r\n          else {\r\n              diff = 1;\r\n          }\r\n          domain = [baseValue.x - diff, baseValue.x];\r\n          $$.updateXDomain(null, true, true, false, domain);\r\n      }\r\n      else if (orgDataCount === 1) {\r\n          if ($$.isTimeSeries()) {\r\n              diff =\r\n                  (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;\r\n              domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];\r\n              $$.updateXDomain(null, true, true, false, domain);\r\n          }\r\n      }\r\n      // Set targets\r\n      $$.updateTargets($$.data.targets);\r\n      // Redraw with new targets\r\n      $$.redraw({\r\n          flow: {\r\n              index: baseValue.index,\r\n              length: length,\r\n              duration: isValue(args.duration)\r\n                  ? args.duration\r\n                  : $$.config.transition_duration,\r\n              done: args.done,\r\n              orgDataCount: orgDataCount\r\n          },\r\n          withLegend: true,\r\n          withTransition: orgDataCount > 1,\r\n          withTrimXDomain: false,\r\n          withUpdateXAxis: true\r\n      });\r\n  };\r\n  ChartInternal.prototype.generateFlow = function (args) {\r\n      var $$ = this, config = $$.config, d3 = $$.d3;\r\n      return function () {\r\n          var targets = args.targets, flow = args.flow, drawBar = args.drawBar, drawLine = args.drawLine, drawArea = args.drawArea, cx = args.cx, cy = args.cy, xv = args.xv, xForText = args.xForText, yForText = args.yForText, duration = args.duration;\r\n          var translateX, scaleX = 1, transform, flowIndex = flow.index, flowLength = flow.length, flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex), flowEnd = $$.getValueOnIndex($$.data.targets[0].values, flowIndex + flowLength), orgDomain = $$.x.domain(), domain, durationForFlow = flow.duration || duration, done = flow.done || function () { }, wait = $$.generateWait();\r\n          var xgrid, xgridLines, mainRegion, mainText, mainBar, mainLine, mainArea, mainCircle;\r\n          // set flag\r\n          $$.flowing = true;\r\n          // remove head data after rendered\r\n          $$.data.targets.forEach(function (d) {\r\n              d.values.splice(0, flowLength);\r\n          });\r\n          // update x domain to generate axis elements for flow\r\n          domain = $$.updateXDomain(targets, true, true);\r\n          // update elements related to x scale\r\n          if ($$.updateXGrid) {\r\n              $$.updateXGrid(true);\r\n          }\r\n          xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid\r\n          xgridLines = $$.xgridLines || d3.selectAll([]);\r\n          mainRegion = $$.mainRegion || d3.selectAll([]);\r\n          mainText = $$.mainText || d3.selectAll([]);\r\n          mainBar = $$.mainBar || d3.selectAll([]);\r\n          mainLine = $$.mainLine || d3.selectAll([]);\r\n          mainArea = $$.mainArea || d3.selectAll([]);\r\n          mainCircle = $$.mainCircle || d3.selectAll([]);\r\n          // generate transform to flow\r\n          if (!flow.orgDataCount) {\r\n              // if empty\r\n              if ($$.data.targets[0].values.length !== 1) {\r\n                  translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);\r\n              }\r\n              else {\r\n                  if ($$.isTimeSeries()) {\r\n                      flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0);\r\n                      flowEnd = $$.getValueOnIndex($$.data.targets[0].values, $$.data.targets[0].values.length - 1);\r\n                      translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);\r\n                  }\r\n                  else {\r\n                      translateX = diffDomain(domain) / 2;\r\n                  }\r\n              }\r\n          }\r\n          else if (flow.orgDataCount === 1 ||\r\n              (flowStart && flowStart.x) === (flowEnd && flowEnd.x)) {\r\n              translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);\r\n          }\r\n          else {\r\n              if ($$.isTimeSeries()) {\r\n                  translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);\r\n              }\r\n              else {\r\n                  translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);\r\n              }\r\n          }\r\n          scaleX = diffDomain(orgDomain) / diffDomain(domain);\r\n          transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)';\r\n          $$.hideXGridFocus();\r\n          var flowTransition = d3\r\n              .transition()\r\n              .ease(d3.easeLinear)\r\n              .duration(durationForFlow);\r\n          wait.add($$.xAxis($$.axes.x, flowTransition));\r\n          wait.add(mainBar.transition(flowTransition).attr('transform', transform));\r\n          wait.add(mainLine.transition(flowTransition).attr('transform', transform));\r\n          wait.add(mainArea.transition(flowTransition).attr('transform', transform));\r\n          wait.add(mainCircle.transition(flowTransition).attr('transform', transform));\r\n          wait.add(mainText.transition(flowTransition).attr('transform', transform));\r\n          wait.add(mainRegion\r\n              .filter($$.isRegionOnX)\r\n              .transition(flowTransition)\r\n              .attr('transform', transform));\r\n          wait.add(xgrid.transition(flowTransition).attr('transform', transform));\r\n          wait.add(xgridLines.transition(flowTransition).attr('transform', transform));\r\n          wait(function () {\r\n              var i, shapes = [], texts = [];\r\n              // remove flowed elements\r\n              if (flowLength) {\r\n                  for (i = 0; i < flowLength; i++) {\r\n                      shapes.push('.' + CLASS.shape + '-' + (flowIndex + i));\r\n                      texts.push('.' + CLASS.text + '-' + (flowIndex + i));\r\n                  }\r\n                  $$.svg\r\n                      .selectAll('.' + CLASS.shapes)\r\n                      .selectAll(shapes)\r\n                      .remove();\r\n                  $$.svg\r\n                      .selectAll('.' + CLASS.texts)\r\n                      .selectAll(texts)\r\n                      .remove();\r\n                  $$.svg.select('.' + CLASS.xgrid).remove();\r\n              }\r\n              // draw again for removing flowed elements and reverting attr\r\n              xgrid\r\n                  .attr('transform', null)\r\n                  .attr('x1', $$.xgridAttr.x1)\r\n                  .attr('x2', $$.xgridAttr.x2)\r\n                  .attr('y1', $$.xgridAttr.y1)\r\n                  .attr('y2', $$.xgridAttr.y2)\r\n                  .style('opacity', $$.xgridAttr.opacity);\r\n              xgridLines.attr('transform', null);\r\n              xgridLines\r\n                  .select('line')\r\n                  .attr('x1', config.axis_rotated ? 0 : xv)\r\n                  .attr('x2', config.axis_rotated ? $$.width : xv);\r\n              xgridLines\r\n                  .select('text')\r\n                  .attr('x', config.axis_rotated ? $$.width : 0)\r\n                  .attr('y', xv);\r\n              mainBar.attr('transform', null).attr('d', drawBar);\r\n              mainLine.attr('transform', null).attr('d', drawLine);\r\n              mainArea.attr('transform', null).attr('d', drawArea);\r\n              mainCircle\r\n                  .attr('transform', null)\r\n                  .attr('cx', cx)\r\n                  .attr('cy', cy);\r\n              mainText\r\n                  .attr('transform', null)\r\n                  .attr('x', xForText)\r\n                  .attr('y', yForText)\r\n                  .style('fill-opacity', $$.opacityForText.bind($$));\r\n              mainRegion.attr('transform', null);\r\n              mainRegion\r\n                  .filter($$.isRegionOnX)\r\n                  .attr('x', $$.regionX.bind($$))\r\n                  .attr('width', $$.regionWidth.bind($$));\r\n              // callback for end of flow\r\n              done();\r\n              $$.flowing = false;\r\n          });\r\n      };\r\n  };\n\n  Chart.prototype.focus = function (targetIds) {\r\n      var $$ = this.internal, candidates;\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      (candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$)))),\r\n          this.revert();\r\n      this.defocus();\r\n      candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false);\r\n      if ($$.hasArcType()) {\r\n          $$.expandArc(targetIds);\r\n      }\r\n      $$.toggleFocusLegend(targetIds, true);\r\n      $$.focusedTargetIds = targetIds;\r\n      $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function (id) {\r\n          return targetIds.indexOf(id) < 0;\r\n      });\r\n  };\r\n  Chart.prototype.defocus = function (targetIds) {\r\n      var $$ = this.internal, candidates;\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      (candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$)))),\r\n          candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true);\r\n      if ($$.hasArcType()) {\r\n          $$.unexpandArc(targetIds);\r\n      }\r\n      $$.toggleFocusLegend(targetIds, false);\r\n      $$.focusedTargetIds = $$.focusedTargetIds.filter(function (id) {\r\n          return targetIds.indexOf(id) < 0;\r\n      });\r\n      $$.defocusedTargetIds = targetIds;\r\n  };\r\n  Chart.prototype.revert = function (targetIds) {\r\n      var $$ = this.internal, candidates;\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets\r\n      candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false);\r\n      if ($$.hasArcType()) {\r\n          $$.unexpandArc(targetIds);\r\n      }\r\n      if ($$.config.legend_show) {\r\n          $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$)));\r\n          $$.legend\r\n              .selectAll($$.selectorLegends(targetIds))\r\n              .filter(function () {\r\n              return $$.d3.select(this).classed(CLASS.legendItemFocused);\r\n          })\r\n              .classed(CLASS.legendItemFocused, false);\r\n      }\r\n      $$.focusedTargetIds = [];\r\n      $$.defocusedTargetIds = [];\r\n  };\n\n  Chart.prototype.xgrids = function (grids) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (!grids) {\r\n          return config.grid_x_lines;\r\n      }\r\n      config.grid_x_lines = grids;\r\n      $$.redrawWithoutRescale();\r\n      return config.grid_x_lines;\r\n  };\r\n  Chart.prototype.xgrids.add = function (grids) {\r\n      var $$ = this.internal;\r\n      return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : []));\r\n  };\r\n  Chart.prototype.xgrids.remove = function (params) {\r\n      // TODO: multiple\r\n      var $$ = this.internal;\r\n      $$.removeGridLines(params, true);\r\n  };\r\n  Chart.prototype.ygrids = function (grids) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (!grids) {\r\n          return config.grid_y_lines;\r\n      }\r\n      config.grid_y_lines = grids;\r\n      $$.redrawWithoutRescale();\r\n      return config.grid_y_lines;\r\n  };\r\n  Chart.prototype.ygrids.add = function (grids) {\r\n      var $$ = this.internal;\r\n      return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : []));\r\n  };\r\n  Chart.prototype.ygrids.remove = function (params) {\r\n      // TODO: multiple\r\n      var $$ = this.internal;\r\n      $$.removeGridLines(params, false);\r\n  };\n\n  Chart.prototype.groups = function (groups) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (isUndefined(groups)) {\r\n          return config.data_groups;\r\n      }\r\n      config.data_groups = groups;\r\n      $$.redraw();\r\n      return config.data_groups;\r\n  };\n\n  Chart.prototype.legend = function () { };\r\n  Chart.prototype.legend.show = function (targetIds) {\r\n      var $$ = this.internal;\r\n      $$.showLegend($$.mapToTargetIds(targetIds));\r\n      $$.updateAndRedraw({ withLegend: true });\r\n  };\r\n  Chart.prototype.legend.hide = function (targetIds) {\r\n      var $$ = this.internal;\r\n      $$.hideLegend($$.mapToTargetIds(targetIds));\r\n      $$.updateAndRedraw({ withLegend: false });\r\n  };\n\n  Chart.prototype.load = function (args) {\r\n      var $$ = this.internal, config = $$.config;\r\n      // update xs if specified\r\n      if (args.xs) {\r\n          $$.addXs(args.xs);\r\n      }\r\n      // update names if exists\r\n      if ('names' in args) {\r\n          Chart.prototype.data.names.bind(this)(args.names);\r\n      }\r\n      // update classes if exists\r\n      if ('classes' in args) {\r\n          Object.keys(args.classes).forEach(function (id) {\r\n              config.data_classes[id] = args.classes[id];\r\n          });\r\n      }\r\n      // update categories if exists\r\n      if ('categories' in args && $$.isCategorized()) {\r\n          config.axis_x_categories = args.categories;\r\n      }\r\n      // update axes if exists\r\n      if ('axes' in args) {\r\n          Object.keys(args.axes).forEach(function (id) {\r\n              config.data_axes[id] = args.axes[id];\r\n          });\r\n      }\r\n      // update colors if exists\r\n      if ('colors' in args) {\r\n          Object.keys(args.colors).forEach(function (id) {\r\n              config.data_colors[id] = args.colors[id];\r\n          });\r\n      }\r\n      // use cache if exists\r\n      if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) {\r\n          $$.load($$.getCaches(args.cacheIds), args.done);\r\n          return;\r\n      }\r\n      // unload if needed\r\n      if (args.unload) {\r\n          // TODO: do not unload if target will load (included in url/rows/columns)\r\n          $$.unload($$.mapToTargetIds(args.unload === true ? null : args.unload), function () {\r\n              $$.loadFromArgs(args);\r\n          });\r\n      }\r\n      else {\r\n          $$.loadFromArgs(args);\r\n      }\r\n  };\r\n  Chart.prototype.unload = function (args) {\r\n      var $$ = this.internal;\r\n      args = args || {};\r\n      if (args instanceof Array) {\r\n          args = { ids: args };\r\n      }\r\n      else if (typeof args === 'string') {\r\n          args = { ids: [args] };\r\n      }\r\n      $$.unload($$.mapToTargetIds(args.ids), function () {\r\n          $$.redraw({\r\n              withUpdateOrgXDomain: true,\r\n              withUpdateXDomain: true,\r\n              withLegend: true\r\n          });\r\n          if (args.done) {\r\n              args.done();\r\n          }\r\n      });\r\n  };\n\n  Chart.prototype.pie = function () { };\r\n  Chart.prototype.pie.padAngle = function (padAngle) {\r\n      if (padAngle === undefined) {\r\n          return this.internal.config.pie_padAngle;\r\n      }\r\n      this.internal.config.pie_padAngle = padAngle;\r\n      this.flush();\r\n  };\n\n  Chart.prototype.regions = function (regions) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (!regions) {\r\n          return config.regions;\r\n      }\r\n      config.regions = regions;\r\n      $$.redrawWithoutRescale();\r\n      return config.regions;\r\n  };\r\n  Chart.prototype.regions.add = function (regions) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (!regions) {\r\n          return config.regions;\r\n      }\r\n      config.regions = config.regions.concat(regions);\r\n      $$.redrawWithoutRescale();\r\n      return config.regions;\r\n  };\r\n  Chart.prototype.regions.remove = function (options) {\r\n      var $$ = this.internal, config = $$.config, duration, classes, regions;\r\n      options = options || {};\r\n      duration = getOption(options, 'duration', config.transition_duration);\r\n      classes = getOption(options, 'classes', [CLASS.region]);\r\n      regions = $$.main.select('.' + CLASS.regions).selectAll(classes.map(function (c) {\r\n          return '.' + c;\r\n      }));\r\n      (duration ? regions.transition().duration(duration) : regions)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      config.regions = config.regions.filter(function (region) {\r\n          var found = false;\r\n          if (!region['class']) {\r\n              return true;\r\n          }\r\n          region['class'].split(' ').forEach(function (c) {\r\n              if (classes.indexOf(c) >= 0) {\r\n                  found = true;\r\n              }\r\n          });\r\n          return !found;\r\n      });\r\n      return config.regions;\r\n  };\n\n  Chart.prototype.selected = function (targetId) {\r\n      var $$ = this.internal, d3 = $$.d3;\r\n      return $$.main\r\n          .selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId))\r\n          .selectAll('.' + CLASS.shape)\r\n          .filter(function () {\r\n          return d3.select(this).classed(CLASS.SELECTED);\r\n      })\r\n          .nodes()\r\n          .map(function (d) {\r\n          var data = d.__data__;\r\n          return data.data ? data.data : data;\r\n      });\r\n  };\r\n  Chart.prototype.select = function (ids, indices, resetOther) {\r\n      var $$ = this.internal, d3 = $$.d3, config = $$.config;\r\n      if (!config.data_selection_enabled) {\r\n          return;\r\n      }\r\n      $$.main\r\n          .selectAll('.' + CLASS.shapes)\r\n          .selectAll('.' + CLASS.shape)\r\n          .each(function (d, i) {\r\n          var shape = d3.select(this), id = d.data ? d.data.id : d.id, toggle = $$.getToggle(this, d).bind($$), isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, isTargetIndex = !indices || indices.indexOf(i) >= 0, isSelected = shape.classed(CLASS.SELECTED);\r\n          // line/area selection not supported yet\r\n          if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {\r\n              return;\r\n          }\r\n          if (isTargetId && isTargetIndex) {\r\n              if (config.data_selection_isselectable(d) && !isSelected) {\r\n                  toggle(true, shape.classed(CLASS.SELECTED, true), d, i);\r\n              }\r\n          }\r\n          else if (isDefined(resetOther) && resetOther) {\r\n              if (isSelected) {\r\n                  toggle(false, shape.classed(CLASS.SELECTED, false), d, i);\r\n              }\r\n          }\r\n      });\r\n  };\r\n  Chart.prototype.unselect = function (ids, indices) {\r\n      var $$ = this.internal, d3 = $$.d3, config = $$.config;\r\n      if (!config.data_selection_enabled) {\r\n          return;\r\n      }\r\n      $$.main\r\n          .selectAll('.' + CLASS.shapes)\r\n          .selectAll('.' + CLASS.shape)\r\n          .each(function (d, i) {\r\n          var shape = d3.select(this), id = d.data ? d.data.id : d.id, toggle = $$.getToggle(this, d).bind($$), isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, isTargetIndex = !indices || indices.indexOf(i) >= 0, isSelected = shape.classed(CLASS.SELECTED);\r\n          // line/area selection not supported yet\r\n          if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {\r\n              return;\r\n          }\r\n          if (isTargetId && isTargetIndex) {\r\n              if (config.data_selection_isselectable(d)) {\r\n                  if (isSelected) {\r\n                      toggle(false, shape.classed(CLASS.SELECTED, false), d, i);\r\n                  }\r\n              }\r\n          }\r\n      });\r\n  };\n\n  Chart.prototype.show = function (targetIds, options) {\r\n      var $$ = this.internal, targets;\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      options = options || {};\r\n      $$.removeHiddenTargetIds(targetIds);\r\n      targets = $$.svg.selectAll($$.selectorTargets(targetIds));\r\n      targets\r\n          .transition()\r\n          .style('display', isIE() ? 'block' : 'initial', 'important')\r\n          .style('opacity', 1, 'important')\r\n          .call($$.endall, function () {\r\n          targets.style('opacity', null).style('opacity', 1);\r\n      });\r\n      if (options.withLegend) {\r\n          $$.showLegend(targetIds);\r\n      }\r\n      $$.redraw({\r\n          withUpdateOrgXDomain: true,\r\n          withUpdateXDomain: true,\r\n          withLegend: true\r\n      });\r\n  };\r\n  Chart.prototype.hide = function (targetIds, options) {\r\n      var $$ = this.internal, targets;\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      options = options || {};\r\n      $$.addHiddenTargetIds(targetIds);\r\n      targets = $$.svg.selectAll($$.selectorTargets(targetIds));\r\n      targets\r\n          .transition()\r\n          .style('opacity', 0, 'important')\r\n          .call($$.endall, function () {\r\n          targets.style('opacity', null).style('opacity', 0);\r\n          targets.style('display', 'none');\r\n      });\r\n      if (options.withLegend) {\r\n          $$.hideLegend(targetIds);\r\n      }\r\n      $$.redraw({\r\n          withUpdateOrgXDomain: true,\r\n          withUpdateXDomain: true,\r\n          withLegend: true\r\n      });\r\n  };\r\n  Chart.prototype.toggle = function (targetIds, options) {\r\n      var that = this, $$ = this.internal;\r\n      $$.mapToTargetIds(targetIds).forEach(function (targetId) {\r\n          $$.isTargetToShow(targetId)\r\n              ? that.hide(targetId, options)\r\n              : that.show(targetId, options);\r\n      });\r\n  };\n\n  Chart.prototype.subchart = function () { };\r\n  Chart.prototype.subchart.isShown = function () {\r\n      var $$ = this.internal;\r\n      return $$.config.subchart_show;\r\n  };\r\n  Chart.prototype.subchart.show = function () {\r\n      var $$ = this.internal;\r\n      if ($$.config.subchart_show) {\r\n          return;\r\n      }\r\n      $$.config.subchart_show = true;\r\n      // insert DOM\r\n      $$.initSubchart();\r\n      // update dimensions with sub chart now visible\r\n      $$.updateDimension();\r\n      // insert brush (depends on sizes previously updated)\r\n      $$.initSubchartBrush();\r\n      // attach data\r\n      $$.updateTargetsForSubchart($$.getTargets());\r\n      // reset fade-in state\r\n      $$.mapToIds($$.data.targets).forEach(function (id) {\r\n          $$.withoutFadeIn[id] = false;\r\n      });\r\n      // redraw chart !\r\n      $$.updateAndRedraw();\r\n      // update visible targets !\r\n      $$.showTargets();\r\n  };\r\n  Chart.prototype.subchart.hide = function () {\r\n      var $$ = this.internal;\r\n      if (!$$.config.subchart_show) {\r\n          return;\r\n      }\r\n      $$.config.subchart_show = false;\r\n      // remove DOM\r\n      $$.removeSubchart();\r\n      // re-render chart\r\n      $$.redraw();\r\n  };\n\n  Chart.prototype.tooltip = function () { };\r\n  Chart.prototype.tooltip.show = function (args) {\r\n      var $$ = this.internal, targets, data, mouse = {};\r\n      // determine mouse position on the chart\r\n      if (args.mouse) {\r\n          mouse = args.mouse;\r\n      }\r\n      else {\r\n          // determine focus data\r\n          if (args.data) {\r\n              data = args.data;\r\n          }\r\n          else if (typeof args.x !== 'undefined') {\r\n              if (args.id) {\r\n                  targets = $$.data.targets.filter(function (t) {\r\n                      return t.id === args.id;\r\n                  });\r\n              }\r\n              else {\r\n                  targets = $$.data.targets;\r\n              }\r\n              data = $$.filterByX(targets, args.x).slice(0, 1)[0];\r\n          }\r\n          mouse = data ? $$.getMousePosition(data) : null;\r\n      }\r\n      // emulate mouse events to show\r\n      $$.dispatchEvent('mousemove', mouse);\r\n      $$.config.tooltip_onshow.call($$, data);\r\n  };\r\n  Chart.prototype.tooltip.hide = function () {\r\n      // TODO: get target data by checking the state of focus\r\n      this.internal.dispatchEvent('mouseout', 0);\r\n      this.internal.config.tooltip_onhide.call(this);\r\n  };\n\n  Chart.prototype.transform = function (type, targetIds) {\r\n      var $$ = this.internal, options = ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null;\r\n      $$.transformTo(targetIds, type, options);\r\n  };\r\n  ChartInternal.prototype.transformTo = function (targetIds, type, optionsForRedraw) {\r\n      var $$ = this, withTransitionForAxis = !$$.hasArcType(), options = optionsForRedraw || {\r\n          withTransitionForAxis: withTransitionForAxis\r\n      };\r\n      options.withTransitionForTransform = false;\r\n      $$.transiting = false;\r\n      $$.setTargetType(targetIds, type);\r\n      $$.updateTargets($$.data.targets); // this is needed when transforming to arc\r\n      $$.updateAndRedraw(options);\r\n  };\n\n  Chart.prototype.x = function (x) {\r\n      var $$ = this.internal;\r\n      if (arguments.length) {\r\n          $$.updateTargetX($$.data.targets, x);\r\n          $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\r\n      }\r\n      return $$.data.xs;\r\n  };\r\n  Chart.prototype.xs = function (xs) {\r\n      var $$ = this.internal;\r\n      if (arguments.length) {\r\n          $$.updateTargetXs($$.data.targets, xs);\r\n          $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\r\n      }\r\n      return $$.data.xs;\r\n  };\n\n  Chart.prototype.zoom = function (domain) {\r\n      var $$ = this.internal;\r\n      if (domain) {\r\n          if ($$.isTimeSeries()) {\r\n              domain = domain.map(function (x) {\r\n                  return $$.parseDate(x);\r\n              });\r\n          }\r\n          if ($$.config.subchart_show) {\r\n              $$.brush.selectionAsValue(domain, true);\r\n          }\r\n          else {\r\n              $$.updateXDomain(null, true, false, false, domain);\r\n              $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false });\r\n          }\r\n          $$.config.zoom_onzoom.call(this, $$.x.orgDomain());\r\n          return domain;\r\n      }\r\n      else {\r\n          return $$.x.domain();\r\n      }\r\n  };\r\n  Chart.prototype.zoom.enable = function (enabled) {\r\n      var $$ = this.internal;\r\n      $$.config.zoom_enabled = enabled;\r\n      $$.updateAndRedraw();\r\n  };\r\n  Chart.prototype.unzoom = function () {\r\n      var $$ = this.internal;\r\n      if ($$.config.subchart_show) {\r\n          $$.brush.clear();\r\n      }\r\n      else {\r\n          $$.updateXDomain(null, true, false, false, $$.subX.domain());\r\n          $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false });\r\n      }\r\n  };\r\n  Chart.prototype.zoom.max = function (max) {\r\n      var $$ = this.internal, config = $$.config, d3 = $$.d3;\r\n      if (max === 0 || max) {\r\n          config.zoom_x_max = d3.max([$$.orgXDomain[1], max]);\r\n      }\r\n      else {\r\n          return config.zoom_x_max;\r\n      }\r\n  };\r\n  Chart.prototype.zoom.min = function (min) {\r\n      var $$ = this.internal, config = $$.config, d3 = $$.d3;\r\n      if (min === 0 || min) {\r\n          config.zoom_x_min = d3.min([$$.orgXDomain[0], min]);\r\n      }\r\n      else {\r\n          return config.zoom_x_min;\r\n      }\r\n  };\r\n  Chart.prototype.zoom.range = function (range) {\r\n      if (arguments.length) {\r\n          if (isDefined(range.max)) {\r\n              this.domain.max(range.max);\r\n          }\r\n          if (isDefined(range.min)) {\r\n              this.domain.min(range.min);\r\n          }\r\n      }\r\n      else {\r\n          return {\r\n              max: this.domain.max(),\r\n              min: this.domain.min()\r\n          };\r\n      }\r\n  };\n\n  ChartInternal.prototype.initPie = function () {\r\n      var $$ = this, d3 = $$.d3;\r\n      $$.pie = d3\r\n          .pie()\r\n          .padAngle(this.getPadAngle.bind(this))\r\n          .value(function (d) {\r\n          return d.values.reduce(function (a, b) {\r\n              return a + b.value;\r\n          }, 0);\r\n      });\r\n      var orderFct = $$.getOrderFunction();\r\n      // we need to reverse the returned order if asc or desc to have the slice in expected order.\r\n      if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) {\r\n          var defaultSort_1 = orderFct;\r\n          orderFct = function (t1, t2) { return defaultSort_1(t1, t2) * -1; };\r\n      }\r\n      $$.pie.sort(orderFct || null);\r\n  };\r\n  ChartInternal.prototype.updateRadius = function () {\r\n      var $$ = this, config = $$.config, w = config.gauge_width || config.donut_width, gaugeArcWidth = $$.filterTargetsToShow($$.data.targets).length *\r\n          $$.config.gauge_arcs_minWidth;\r\n      $$.radiusExpanded =\r\n          (Math.min($$.arcWidth, $$.arcHeight) / 2) * ($$.hasType('gauge') ? 0.85 : 1);\r\n      $$.radius = $$.radiusExpanded * 0.95;\r\n      $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6;\r\n      $$.innerRadius =\r\n          $$.hasType('donut') || $$.hasType('gauge')\r\n              ? $$.radius * $$.innerRadiusRatio\r\n              : 0;\r\n      $$.gaugeArcWidth = w\r\n          ? w\r\n          : gaugeArcWidth <= $$.radius - $$.innerRadius\r\n              ? $$.radius - $$.innerRadius\r\n              : gaugeArcWidth <= $$.radius\r\n                  ? gaugeArcWidth\r\n                  : $$.radius;\r\n  };\r\n  ChartInternal.prototype.getPadAngle = function () {\r\n      if (this.hasType('pie')) {\r\n          return this.config.pie_padAngle || 0;\r\n      }\r\n      else if (this.hasType('donut')) {\r\n          return this.config.donut_padAngle || 0;\r\n      }\r\n      else {\r\n          return 0;\r\n      }\r\n  };\r\n  ChartInternal.prototype.updateArc = function () {\r\n      var $$ = this;\r\n      $$.svgArc = $$.getSvgArc();\r\n      $$.svgArcExpanded = $$.getSvgArcExpanded();\r\n      $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98);\r\n  };\r\n  ChartInternal.prototype.updateAngle = function (d) {\r\n      var $$ = this, config = $$.config, found = false, index = 0, gMin, gMax, gTic, gValue;\r\n      if (!config) {\r\n          return null;\r\n      }\r\n      $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function (t) {\r\n          if (!found && t.data.id === d.data.id) {\r\n              found = true;\r\n              d = t;\r\n              d.index = index;\r\n          }\r\n          index++;\r\n      });\r\n      if (isNaN(d.startAngle)) {\r\n          d.startAngle = 0;\r\n      }\r\n      if (isNaN(d.endAngle)) {\r\n          d.endAngle = d.startAngle;\r\n      }\r\n      if ($$.isGaugeType(d.data)) {\r\n          gMin = config.gauge_min;\r\n          gMax = config.gauge_max;\r\n          gTic = (Math.PI * (config.gauge_fullCircle ? 2 : 1)) / (gMax - gMin);\r\n          gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin;\r\n          d.startAngle = config.gauge_startingAngle;\r\n          d.endAngle = d.startAngle + gTic * gValue;\r\n      }\r\n      return found ? d : null;\r\n  };\r\n  ChartInternal.prototype.getSvgArc = function () {\r\n      var $$ = this, hasGaugeType = $$.hasType('gauge'), singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, arc = $$.d3\r\n          .arc()\r\n          .outerRadius(function (d) {\r\n          return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius;\r\n      })\r\n          .innerRadius(function (d) {\r\n          return hasGaugeType\r\n              ? $$.radius - singleArcWidth * (d.index + 1)\r\n              : $$.innerRadius;\r\n      }), newArc = function (d, withoutUpdate) {\r\n          var updated;\r\n          if (withoutUpdate) {\r\n              return arc(d);\r\n          } // for interpolate\r\n          updated = $$.updateAngle(d);\r\n          return updated ? arc(updated) : 'M 0 0';\r\n      };\r\n      newArc.centroid = arc.centroid;\r\n      return newArc;\r\n  };\r\n  ChartInternal.prototype.getSvgArcExpanded = function (rate) {\r\n      rate = rate || 1;\r\n      var $$ = this, hasGaugeType = $$.hasType('gauge'), singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, expandWidth = Math.min($$.radiusExpanded * rate - $$.radius, singleArcWidth * 0.8 - (1 - rate) * 100), arc = $$.d3\r\n          .arc()\r\n          .outerRadius(function (d) {\r\n          return hasGaugeType\r\n              ? $$.radius - singleArcWidth * d.index + expandWidth\r\n              : $$.radiusExpanded * rate;\r\n      })\r\n          .innerRadius(function (d) {\r\n          return hasGaugeType\r\n              ? $$.radius - singleArcWidth * (d.index + 1)\r\n              : $$.innerRadius;\r\n      });\r\n      return function (d) {\r\n          var updated = $$.updateAngle(d);\r\n          return updated ? arc(updated) : 'M 0 0';\r\n      };\r\n  };\r\n  ChartInternal.prototype.getArc = function (d, withoutUpdate, force) {\r\n      return force || this.isArcType(d.data)\r\n          ? this.svgArc(d, withoutUpdate)\r\n          : 'M 0 0';\r\n  };\r\n  ChartInternal.prototype.transformForArcLabel = function (d) {\r\n      var $$ = this, config = $$.config, updated = $$.updateAngle(d), c, x, y, h, ratio, translate = '', hasGauge = $$.hasType('gauge');\r\n      if (updated && !hasGauge) {\r\n          c = this.svgArc.centroid(updated);\r\n          x = isNaN(c[0]) ? 0 : c[0];\r\n          y = isNaN(c[1]) ? 0 : c[1];\r\n          h = Math.sqrt(x * x + y * y);\r\n          if ($$.hasType('donut') && config.donut_label_ratio) {\r\n              ratio = isFunction(config.donut_label_ratio)\r\n                  ? config.donut_label_ratio(d, $$.radius, h)\r\n                  : config.donut_label_ratio;\r\n          }\r\n          else if ($$.hasType('pie') && config.pie_label_ratio) {\r\n              ratio = isFunction(config.pie_label_ratio)\r\n                  ? config.pie_label_ratio(d, $$.radius, h)\r\n                  : config.pie_label_ratio;\r\n          }\r\n          else {\r\n              ratio =\r\n                  $$.radius && h\r\n                      ? ((36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) *\r\n                          $$.radius) /\r\n                          h\r\n                      : 0;\r\n          }\r\n          translate = 'translate(' + x * ratio + ',' + y * ratio + ')';\r\n      }\r\n      else if (updated &&\r\n          hasGauge &&\r\n          $$.filterTargetsToShow($$.data.targets).length > 1) {\r\n          var y1 = Math.sin(updated.endAngle - Math.PI / 2);\r\n          x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25);\r\n          y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3;\r\n          translate = 'translate(' + x + ',' + y + ')';\r\n      }\r\n      return translate;\r\n  };\r\n  /**\r\n   * @deprecated Use `getRatio('arc', d)` instead.\r\n   */\r\n  ChartInternal.prototype.getArcRatio = function (d) {\r\n      return this.getRatio('arc', d);\r\n  };\r\n  ChartInternal.prototype.convertToArcData = function (d) {\r\n      return this.addName({\r\n          id: d.data.id,\r\n          value: d.value,\r\n          ratio: this.getRatio('arc', d),\r\n          index: d.index\r\n      });\r\n  };\r\n  ChartInternal.prototype.textForArcLabel = function (d) {\r\n      var $$ = this, updated, value, ratio, id, format;\r\n      if (!$$.shouldShowArcLabel()) {\r\n          return '';\r\n      }\r\n      updated = $$.updateAngle(d);\r\n      value = updated ? updated.value : null;\r\n      ratio = $$.getRatio('arc', updated);\r\n      id = d.data.id;\r\n      if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) {\r\n          return '';\r\n      }\r\n      format = $$.getArcLabelFormat();\r\n      return format\r\n          ? format(value, ratio, id)\r\n          : $$.defaultArcValueFormat(value, ratio);\r\n  };\r\n  ChartInternal.prototype.textForGaugeMinMax = function (value, isMax) {\r\n      var $$ = this, format = $$.getGaugeLabelExtents();\r\n      return format ? format(value, isMax) : value;\r\n  };\r\n  ChartInternal.prototype.expandArc = function (targetIds) {\r\n      var $$ = this, interval;\r\n      // MEMO: avoid to cancel transition\r\n      if ($$.transiting) {\r\n          interval = window.setInterval(function () {\r\n              if (!$$.transiting) {\r\n                  window.clearInterval(interval);\r\n                  if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) {\r\n                      $$.expandArc(targetIds);\r\n                  }\r\n              }\r\n          }, 10);\r\n          return;\r\n      }\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      $$.svg\r\n          .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc))\r\n          .each(function (d) {\r\n          if (!$$.shouldExpand(d.data.id)) {\r\n              return;\r\n          }\r\n          $$.d3\r\n              .select(this)\r\n              .selectAll('path')\r\n              .transition()\r\n              .duration($$.expandDuration(d.data.id))\r\n              .attr('d', $$.svgArcExpanded)\r\n              .transition()\r\n              .duration($$.expandDuration(d.data.id) * 2)\r\n              .attr('d', $$.svgArcExpandedSub)\r\n              .each(function (d) {\r\n              if ($$.isDonutType(d.data)) ;\r\n          });\r\n      });\r\n  };\r\n  ChartInternal.prototype.unexpandArc = function (targetIds) {\r\n      var $$ = this;\r\n      if ($$.transiting) {\r\n          return;\r\n      }\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      $$.svg\r\n          .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc))\r\n          .selectAll('path')\r\n          .transition()\r\n          .duration(function (d) {\r\n          return $$.expandDuration(d.data.id);\r\n      })\r\n          .attr('d', $$.svgArc);\r\n      $$.svg.selectAll('.' + CLASS.arc);\r\n  };\r\n  ChartInternal.prototype.expandDuration = function (id) {\r\n      var $$ = this, config = $$.config;\r\n      if ($$.isDonutType(id)) {\r\n          return config.donut_expand_duration;\r\n      }\r\n      else if ($$.isGaugeType(id)) {\r\n          return config.gauge_expand_duration;\r\n      }\r\n      else if ($$.isPieType(id)) {\r\n          return config.pie_expand_duration;\r\n      }\r\n      else {\r\n          return 50;\r\n      }\r\n  };\r\n  ChartInternal.prototype.shouldExpand = function (id) {\r\n      var $$ = this, config = $$.config;\r\n      return (($$.isDonutType(id) && config.donut_expand) ||\r\n          ($$.isGaugeType(id) && config.gauge_expand) ||\r\n          ($$.isPieType(id) && config.pie_expand));\r\n  };\r\n  ChartInternal.prototype.shouldShowArcLabel = function () {\r\n      var $$ = this, config = $$.config, shouldShow = true;\r\n      if ($$.hasType('donut')) {\r\n          shouldShow = config.donut_label_show;\r\n      }\r\n      else if ($$.hasType('pie')) {\r\n          shouldShow = config.pie_label_show;\r\n      }\r\n      // when gauge, always true\r\n      return shouldShow;\r\n  };\r\n  ChartInternal.prototype.meetsArcLabelThreshold = function (ratio) {\r\n      var $$ = this, config = $$.config, threshold = $$.hasType('donut')\r\n          ? config.donut_label_threshold\r\n          : config.pie_label_threshold;\r\n      return ratio >= threshold;\r\n  };\r\n  ChartInternal.prototype.getArcLabelFormat = function () {\r\n      var $$ = this, config = $$.config, format = config.pie_label_format;\r\n      if ($$.hasType('gauge')) {\r\n          format = config.gauge_label_format;\r\n      }\r\n      else if ($$.hasType('donut')) {\r\n          format = config.donut_label_format;\r\n      }\r\n      return format;\r\n  };\r\n  ChartInternal.prototype.getGaugeLabelExtents = function () {\r\n      var $$ = this, config = $$.config;\r\n      return config.gauge_label_extents;\r\n  };\r\n  ChartInternal.prototype.getArcTitle = function () {\r\n      var $$ = this;\r\n      return $$.hasType('donut') ? $$.config.donut_title : '';\r\n  };\r\n  ChartInternal.prototype.updateTargetsForArc = function (targets) {\r\n      var $$ = this, main = $$.main, mainPies, mainPieEnter, classChartArc = $$.classChartArc.bind($$), classArcs = $$.classArcs.bind($$), classFocus = $$.classFocus.bind($$);\r\n      mainPies = main\r\n          .select('.' + CLASS.chartArcs)\r\n          .selectAll('.' + CLASS.chartArc)\r\n          .data($$.pie(targets))\r\n          .attr('class', function (d) {\r\n          return classChartArc(d) + classFocus(d.data);\r\n      });\r\n      mainPieEnter = mainPies\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', classChartArc);\r\n      mainPieEnter.append('g').attr('class', classArcs);\r\n      mainPieEnter\r\n          .append('text')\r\n          .attr('dy', $$.hasType('gauge') ? '-.1em' : '.35em')\r\n          .style('opacity', 0)\r\n          .style('text-anchor', 'middle')\r\n          .style('pointer-events', 'none');\r\n      // MEMO: can not keep same color..., but not bad to update color in redraw\r\n      //mainPieUpdate.exit().remove();\r\n  };\r\n  ChartInternal.prototype.initArc = function () {\r\n      var $$ = this;\r\n      $$.arcs = $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.chartArcs)\r\n          .attr('transform', $$.getTranslate('arc'));\r\n      $$.arcs\r\n          .append('text')\r\n          .attr('class', CLASS.chartArcsTitle)\r\n          .style('text-anchor', 'middle')\r\n          .text($$.getArcTitle());\r\n  };\r\n  ChartInternal.prototype.redrawArc = function (duration, durationForExit, withTransform) {\r\n      var $$ = this, d3 = $$.d3, config = $$.config, main = $$.main, arcs, mainArc, arcLabelLines, mainArcLabelLine, hasGaugeType = $$.hasType('gauge');\r\n      arcs = main\r\n          .selectAll('.' + CLASS.arcs)\r\n          .selectAll('.' + CLASS.arc)\r\n          .data($$.arcData.bind($$));\r\n      mainArc = arcs\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', $$.classArc.bind($$))\r\n          .style('fill', function (d) {\r\n          return $$.color(d.data);\r\n      })\r\n          .style('cursor', function (d) {\r\n          return config.interaction_enabled && config.data_selection_isselectable(d)\r\n              ? 'pointer'\r\n              : null;\r\n      })\r\n          .each(function (d) {\r\n          if ($$.isGaugeType(d.data)) {\r\n              d.startAngle = d.endAngle = config.gauge_startingAngle;\r\n          }\r\n          this._current = d;\r\n      })\r\n          .merge(arcs);\r\n      if (hasGaugeType) {\r\n          arcLabelLines = main\r\n              .selectAll('.' + CLASS.arcs)\r\n              .selectAll('.' + CLASS.arcLabelLine)\r\n              .data($$.arcData.bind($$));\r\n          mainArcLabelLine = arcLabelLines\r\n              .enter()\r\n              .append('rect')\r\n              .attr('class', function (d) {\r\n              return (CLASS.arcLabelLine +\r\n                  ' ' +\r\n                  CLASS.target +\r\n                  ' ' +\r\n                  CLASS.target +\r\n                  '-' +\r\n                  d.data.id);\r\n          })\r\n              .merge(arcLabelLines);\r\n          if ($$.filterTargetsToShow($$.data.targets).length === 1) {\r\n              mainArcLabelLine.style('display', 'none');\r\n          }\r\n          else {\r\n              mainArcLabelLine\r\n                  .style('fill', function (d) {\r\n                  return $$.levelColor\r\n                      ? $$.levelColor(d.data.values.reduce(function (total, item) {\r\n                          return total + item.value;\r\n                      }, 0))\r\n                      : $$.color(d.data);\r\n              })\r\n                  .style('display', config.gauge_labelLine_show ? '' : 'none')\r\n                  .each(function (d) {\r\n                  var lineLength = 0, lineThickness = 2, x = 0, y = 0, transform = '';\r\n                  if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) {\r\n                      var updated = $$.updateAngle(d), innerLineLength = ($$.gaugeArcWidth /\r\n                          $$.filterTargetsToShow($$.data.targets).length) *\r\n                          (updated.index + 1), lineAngle = updated.endAngle - Math.PI / 2, arcInnerRadius = $$.radius - innerLineLength, linePositioningAngle = lineAngle - (arcInnerRadius === 0 ? 0 : 1 / arcInnerRadius);\r\n                      lineLength = $$.radiusExpanded - $$.radius + innerLineLength;\r\n                      x = Math.cos(linePositioningAngle) * arcInnerRadius;\r\n                      y = Math.sin(linePositioningAngle) * arcInnerRadius;\r\n                      transform =\r\n                          'rotate(' +\r\n                              (lineAngle * 180) / Math.PI +\r\n                              ', ' +\r\n                              x +\r\n                              ', ' +\r\n                              y +\r\n                              ')';\r\n                  }\r\n                  d3.select(this)\r\n                      .attr('x', x)\r\n                      .attr('y', y)\r\n                      .attr('width', lineLength)\r\n                      .attr('height', lineThickness)\r\n                      .attr('transform', transform)\r\n                      .style('stroke-dasharray', '0, ' + (lineLength + lineThickness) + ', 0');\r\n              });\r\n          }\r\n      }\r\n      mainArc\r\n          .attr('transform', function (d) {\r\n          return !$$.isGaugeType(d.data) && withTransform ? 'scale(0)' : '';\r\n      })\r\n          .on('mouseover', config.interaction_enabled\r\n          ? function (d) {\r\n              var updated, arcData;\r\n              if ($$.transiting) {\r\n                  // skip while transiting\r\n                  return;\r\n              }\r\n              updated = $$.updateAngle(d);\r\n              if (updated) {\r\n                  arcData = $$.convertToArcData(updated);\r\n                  // transitions\r\n                  $$.expandArc(updated.data.id);\r\n                  $$.api.focus(updated.data.id);\r\n                  $$.toggleFocusLegend(updated.data.id, true);\r\n                  $$.config.data_onmouseover(arcData, this);\r\n              }\r\n          }\r\n          : null)\r\n          .on('mousemove', config.interaction_enabled\r\n          ? function (d) {\r\n              var updated = $$.updateAngle(d), arcData, selectedData;\r\n              if (updated) {\r\n                  (arcData = $$.convertToArcData(updated)),\r\n                      (selectedData = [arcData]);\r\n                  $$.showTooltip(selectedData, this);\r\n              }\r\n          }\r\n          : null)\r\n          .on('mouseout', config.interaction_enabled\r\n          ? function (d) {\r\n              var updated, arcData;\r\n              if ($$.transiting) {\r\n                  // skip while transiting\r\n                  return;\r\n              }\r\n              updated = $$.updateAngle(d);\r\n              if (updated) {\r\n                  arcData = $$.convertToArcData(updated);\r\n                  // transitions\r\n                  $$.unexpandArc(updated.data.id);\r\n                  $$.api.revert();\r\n                  $$.revertLegend();\r\n                  $$.hideTooltip();\r\n                  $$.config.data_onmouseout(arcData, this);\r\n              }\r\n          }\r\n          : null)\r\n          .on('click', config.interaction_enabled\r\n          ? function (d, i) {\r\n              var updated = $$.updateAngle(d), arcData;\r\n              if (updated) {\r\n                  arcData = $$.convertToArcData(updated);\r\n                  if ($$.toggleShape) {\r\n                      $$.toggleShape(this, arcData, i);\r\n                  }\r\n                  $$.config.data_onclick.call($$.api, arcData, this);\r\n              }\r\n          }\r\n          : null)\r\n          .each(function () {\r\n          $$.transiting = true;\r\n      })\r\n          .transition()\r\n          .duration(duration)\r\n          .attrTween('d', function (d) {\r\n          var updated = $$.updateAngle(d), interpolate;\r\n          if (!updated) {\r\n              return function () {\r\n                  return 'M 0 0';\r\n              };\r\n          }\r\n          //                if (this._current === d) {\r\n          //                    this._current = {\r\n          //                        startAngle: Math.PI*2,\r\n          //                        endAngle: Math.PI*2,\r\n          //                    };\r\n          //                }\r\n          if (isNaN(this._current.startAngle)) {\r\n              this._current.startAngle = 0;\r\n          }\r\n          if (isNaN(this._current.endAngle)) {\r\n              this._current.endAngle = this._current.startAngle;\r\n          }\r\n          interpolate = d3.interpolate(this._current, updated);\r\n          this._current = interpolate(0);\r\n          return function (t) {\r\n              // prevents crashing the charts once in transition and chart.destroy() has been called\r\n              if ($$.config === null) {\r\n                  return 'M 0 0';\r\n              }\r\n              var interpolated = interpolate(t);\r\n              interpolated.data = d.data; // data.id will be updated by interporator\r\n              return $$.getArc(interpolated, true);\r\n          };\r\n      })\r\n          .attr('transform', withTransform ? 'scale(1)' : '')\r\n          .style('fill', function (d) {\r\n          return $$.levelColor\r\n              ? $$.levelColor(d.data.values.reduce(function (total, item) {\r\n                  return total + item.value;\r\n              }, 0))\r\n              : $$.color(d.data.id);\r\n      }) // Where gauge reading color would receive customization.\r\n          .call($$.endall, function () {\r\n          $$.transiting = false;\r\n      });\r\n      arcs\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      main\r\n          .selectAll('.' + CLASS.chartArc)\r\n          .select('text')\r\n          .style('opacity', 0)\r\n          .attr('class', function (d) {\r\n          return $$.isGaugeType(d.data) ? CLASS.gaugeValue : '';\r\n      })\r\n          .text($$.textForArcLabel.bind($$))\r\n          .attr('transform', $$.transformForArcLabel.bind($$))\r\n          .style('font-size', function (d) {\r\n          return $$.isGaugeType(d.data) &&\r\n              $$.filterTargetsToShow($$.data.targets).length === 1\r\n              ? Math.round($$.radius / 5) + 'px'\r\n              : '';\r\n      })\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', function (d) {\r\n          return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0;\r\n      });\r\n      main\r\n          .select('.' + CLASS.chartArcsTitle)\r\n          .style('opacity', $$.hasType('donut') || hasGaugeType ? 1 : 0);\r\n      if (hasGaugeType) {\r\n          var index_1 = 0;\r\n          var backgroundArc = $$.arcs\r\n              .select('g.' + CLASS.chartArcsBackground)\r\n              .selectAll('path.' + CLASS.chartArcsBackground)\r\n              .data($$.data.targets);\r\n          backgroundArc\r\n              .enter()\r\n              .append('path')\r\n              .attr('class', function (d, i) {\r\n              return CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i;\r\n          })\r\n              .merge(backgroundArc)\r\n              .attr('d', function (d1) {\r\n              if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) {\r\n                  return 'M 0 0';\r\n              }\r\n              var d = {\r\n                  data: [{ value: config.gauge_max }],\r\n                  startAngle: config.gauge_startingAngle,\r\n                  endAngle: -1 *\r\n                      config.gauge_startingAngle *\r\n                      (config.gauge_fullCircle ? Math.PI : 1),\r\n                  index: index_1++\r\n              };\r\n              return $$.getArc(d, true, true);\r\n          });\r\n          backgroundArc.exit().remove();\r\n          $$.arcs\r\n              .select('.' + CLASS.chartArcsGaugeUnit)\r\n              .attr('dy', '.75em')\r\n              .text(config.gauge_label_show ? config.gauge_units : '');\r\n          $$.arcs\r\n              .select('.' + CLASS.chartArcsGaugeMin)\r\n              .attr('dx', -1 *\r\n              ($$.innerRadius +\r\n                  ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) +\r\n              'px')\r\n              .attr('dy', '1.2em')\r\n              .text(config.gauge_label_show\r\n              ? $$.textForGaugeMinMax(config.gauge_min, false)\r\n              : '');\r\n          $$.arcs\r\n              .select('.' + CLASS.chartArcsGaugeMax)\r\n              .attr('dx', $$.innerRadius +\r\n              ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) +\r\n              'px')\r\n              .attr('dy', '1.2em')\r\n              .text(config.gauge_label_show\r\n              ? $$.textForGaugeMinMax(config.gauge_max, true)\r\n              : '');\r\n      }\r\n  };\r\n  ChartInternal.prototype.initGauge = function () {\r\n      var arcs = this.arcs;\r\n      if (this.hasType('gauge')) {\r\n          arcs.append('g').attr('class', CLASS.chartArcsBackground);\r\n          arcs\r\n              .append('text')\r\n              .attr('class', CLASS.chartArcsGaugeUnit)\r\n              .style('text-anchor', 'middle')\r\n              .style('pointer-events', 'none');\r\n          arcs\r\n              .append('text')\r\n              .attr('class', CLASS.chartArcsGaugeMin)\r\n              .style('text-anchor', 'middle')\r\n              .style('pointer-events', 'none');\r\n          arcs\r\n              .append('text')\r\n              .attr('class', CLASS.chartArcsGaugeMax)\r\n              .style('text-anchor', 'middle')\r\n              .style('pointer-events', 'none');\r\n      }\r\n  };\r\n  ChartInternal.prototype.getGaugeLabelHeight = function () {\r\n      return this.config.gauge_label_show ? 20 : 0;\r\n  };\n\n  /**\r\n   * Store value into cache\r\n   *\r\n   * @param key\r\n   * @param value\r\n   */\r\n  ChartInternal.prototype.addToCache = function (key, value) {\r\n      this.cache[\"$\" + key] = value;\r\n  };\r\n  /**\r\n   * Returns a cached value or undefined\r\n   *\r\n   * @param key\r\n   * @return {*}\r\n   */\r\n  ChartInternal.prototype.getFromCache = function (key) {\r\n      return this.cache[\"$\" + key];\r\n  };\r\n  /**\r\n   * Reset cached data\r\n   */\r\n  ChartInternal.prototype.resetCache = function () {\r\n      var _this = this;\r\n      Object.keys(this.cache)\r\n          .filter(function (key) { return /^\\$/.test(key); })\r\n          .forEach(function (key) {\r\n          delete _this.cache[key];\r\n      });\r\n  };\r\n  // Old API that stores Targets\r\n  ChartInternal.prototype.hasCaches = function (ids) {\r\n      for (var i = 0; i < ids.length; i++) {\r\n          if (!(ids[i] in this.cache)) {\r\n              return false;\r\n          }\r\n      }\r\n      return true;\r\n  };\r\n  ChartInternal.prototype.addCache = function (id, target) {\r\n      this.cache[id] = this.cloneTarget(target);\r\n  };\r\n  ChartInternal.prototype.getCaches = function (ids) {\r\n      var targets = [], i;\r\n      for (i = 0; i < ids.length; i++) {\r\n          if (ids[i] in this.cache) {\r\n              targets.push(this.cloneTarget(this.cache[ids[i]]));\r\n          }\r\n      }\r\n      return targets;\r\n  };\n\n  ChartInternal.prototype.categoryName = function (i) {\r\n      var config = this.config;\r\n      return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i;\r\n  };\n\n  ChartInternal.prototype.generateTargetClass = function (targetId) {\r\n      return targetId || targetId === 0 ? ('-' + targetId).replace(/\\s/g, '-') : '';\r\n  };\r\n  ChartInternal.prototype.generateClass = function (prefix, targetId) {\r\n      return ' ' + prefix + ' ' + prefix + this.generateTargetClass(targetId);\r\n  };\r\n  ChartInternal.prototype.classText = function (d) {\r\n      return this.generateClass(CLASS.text, d.index);\r\n  };\r\n  ChartInternal.prototype.classTexts = function (d) {\r\n      return this.generateClass(CLASS.texts, d.id);\r\n  };\r\n  ChartInternal.prototype.classShape = function (d) {\r\n      return this.generateClass(CLASS.shape, d.index);\r\n  };\r\n  ChartInternal.prototype.classShapes = function (d) {\r\n      return this.generateClass(CLASS.shapes, d.id);\r\n  };\r\n  ChartInternal.prototype.classLine = function (d) {\r\n      return this.classShape(d) + this.generateClass(CLASS.line, d.id);\r\n  };\r\n  ChartInternal.prototype.classLines = function (d) {\r\n      return this.classShapes(d) + this.generateClass(CLASS.lines, d.id);\r\n  };\r\n  ChartInternal.prototype.classCircle = function (d) {\r\n      return this.classShape(d) + this.generateClass(CLASS.circle, d.index);\r\n  };\r\n  ChartInternal.prototype.classCircles = function (d) {\r\n      return this.classShapes(d) + this.generateClass(CLASS.circles, d.id);\r\n  };\r\n  ChartInternal.prototype.classBar = function (d) {\r\n      return this.classShape(d) + this.generateClass(CLASS.bar, d.index);\r\n  };\r\n  ChartInternal.prototype.classBars = function (d) {\r\n      return this.classShapes(d) + this.generateClass(CLASS.bars, d.id);\r\n  };\r\n  ChartInternal.prototype.classArc = function (d) {\r\n      return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id);\r\n  };\r\n  ChartInternal.prototype.classArcs = function (d) {\r\n      return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id);\r\n  };\r\n  ChartInternal.prototype.classArea = function (d) {\r\n      return this.classShape(d) + this.generateClass(CLASS.area, d.id);\r\n  };\r\n  ChartInternal.prototype.classAreas = function (d) {\r\n      return this.classShapes(d) + this.generateClass(CLASS.areas, d.id);\r\n  };\r\n  ChartInternal.prototype.classRegion = function (d, i) {\r\n      return (this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : ''));\r\n  };\r\n  ChartInternal.prototype.classEvent = function (d) {\r\n      return this.generateClass(CLASS.eventRect, d.index);\r\n  };\r\n  ChartInternal.prototype.classTarget = function (id) {\r\n      var $$ = this;\r\n      var additionalClassSuffix = $$.config.data_classes[id], additionalClass = '';\r\n      if (additionalClassSuffix) {\r\n          additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix;\r\n      }\r\n      return $$.generateClass(CLASS.target, id) + additionalClass;\r\n  };\r\n  ChartInternal.prototype.classFocus = function (d) {\r\n      return this.classFocused(d) + this.classDefocused(d);\r\n  };\r\n  ChartInternal.prototype.classFocused = function (d) {\r\n      return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '');\r\n  };\r\n  ChartInternal.prototype.classDefocused = function (d) {\r\n      return (' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : ''));\r\n  };\r\n  ChartInternal.prototype.classChartText = function (d) {\r\n      return CLASS.chartText + this.classTarget(d.id);\r\n  };\r\n  ChartInternal.prototype.classChartLine = function (d) {\r\n      return CLASS.chartLine + this.classTarget(d.id);\r\n  };\r\n  ChartInternal.prototype.classChartBar = function (d) {\r\n      return CLASS.chartBar + this.classTarget(d.id);\r\n  };\r\n  ChartInternal.prototype.classChartArc = function (d) {\r\n      return CLASS.chartArc + this.classTarget(d.data.id);\r\n  };\r\n  ChartInternal.prototype.getTargetSelectorSuffix = function (targetId) {\r\n      var targetClass = this.generateTargetClass(targetId);\r\n      if (window.CSS && window.CSS.escape) {\r\n          return window.CSS.escape(targetClass);\r\n      }\r\n      // fallback on imperfect method for old browsers (does not handles unicode)\r\n      return targetClass.replace(/([?!@#$%^&*()=+,.<>'\":;\\[\\]\\/|~`{}\\\\])/g, '\\\\$1');\r\n  };\r\n  ChartInternal.prototype.selectorTarget = function (id, prefix) {\r\n      return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id);\r\n  };\r\n  ChartInternal.prototype.selectorTargets = function (ids, prefix) {\r\n      var $$ = this;\r\n      ids = ids || [];\r\n      return ids.length\r\n          ? ids.map(function (id) {\r\n              return $$.selectorTarget(id, prefix);\r\n          })\r\n          : null;\r\n  };\r\n  ChartInternal.prototype.selectorLegend = function (id) {\r\n      return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id);\r\n  };\r\n  ChartInternal.prototype.selectorLegends = function (ids) {\r\n      var $$ = this;\r\n      return ids && ids.length\r\n          ? ids.map(function (id) {\r\n              return $$.selectorLegend(id);\r\n          })\r\n          : null;\r\n  };\n\n  ChartInternal.prototype.getClipPath = function (id) {\r\n      return 'url(' + (isIE(9) ? '' : document.URL.split('#')[0]) + '#' + id + ')';\r\n  };\r\n  ChartInternal.prototype.appendClip = function (parent, id) {\r\n      return parent\r\n          .append('clipPath')\r\n          .attr('id', id)\r\n          .append('rect');\r\n  };\r\n  ChartInternal.prototype.getAxisClipX = function (forHorizontal) {\r\n      // axis line width + padding for left\r\n      var left = Math.max(30, this.margin.left);\r\n      return forHorizontal ? -(1 + left) : -(left - 1);\r\n  };\r\n  ChartInternal.prototype.getAxisClipY = function (forHorizontal) {\r\n      return forHorizontal ? -20 : -this.margin.top;\r\n  };\r\n  ChartInternal.prototype.getXAxisClipX = function () {\r\n      var $$ = this;\r\n      return $$.getAxisClipX(!$$.config.axis_rotated);\r\n  };\r\n  ChartInternal.prototype.getXAxisClipY = function () {\r\n      var $$ = this;\r\n      return $$.getAxisClipY(!$$.config.axis_rotated);\r\n  };\r\n  ChartInternal.prototype.getYAxisClipX = function () {\r\n      var $$ = this;\r\n      return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated);\r\n  };\r\n  ChartInternal.prototype.getYAxisClipY = function () {\r\n      var $$ = this;\r\n      return $$.getAxisClipY($$.config.axis_rotated);\r\n  };\r\n  ChartInternal.prototype.getAxisClipWidth = function (forHorizontal) {\r\n      var $$ = this, left = Math.max(30, $$.margin.left), right = Math.max(30, $$.margin.right);\r\n      // width + axis line width + padding for left/right\r\n      return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20;\r\n  };\r\n  ChartInternal.prototype.getAxisClipHeight = function (forHorizontal) {\r\n      // less than 20 is not enough to show the axis label 'outer' without legend\r\n      return ((forHorizontal ? this.margin.bottom : this.margin.top + this.height) + 20);\r\n  };\r\n  ChartInternal.prototype.getXAxisClipWidth = function () {\r\n      var $$ = this;\r\n      return $$.getAxisClipWidth(!$$.config.axis_rotated);\r\n  };\r\n  ChartInternal.prototype.getXAxisClipHeight = function () {\r\n      var $$ = this;\r\n      return $$.getAxisClipHeight(!$$.config.axis_rotated);\r\n  };\r\n  ChartInternal.prototype.getYAxisClipWidth = function () {\r\n      var $$ = this;\r\n      return ($$.getAxisClipWidth($$.config.axis_rotated) +\r\n          ($$.config.axis_y_inner ? 20 : 0));\r\n  };\r\n  ChartInternal.prototype.getYAxisClipHeight = function () {\r\n      var $$ = this;\r\n      return $$.getAxisClipHeight($$.config.axis_rotated);\r\n  };\n\n  ChartInternal.prototype.generateColor = function () {\r\n      var $$ = this, config = $$.config, d3 = $$.d3, colors = config.data_colors, pattern = notEmpty(config.color_pattern)\r\n          ? config.color_pattern\r\n          : d3.schemeCategory10, callback = config.data_color, ids = [];\r\n      return function (d) {\r\n          var id = d.id || (d.data && d.data.id) || d, color;\r\n          // if callback function is provided\r\n          if (colors[id] instanceof Function) {\r\n              color = colors[id](d);\r\n          }\r\n          // if specified, choose that color\r\n          else if (colors[id]) {\r\n              color = colors[id];\r\n          }\r\n          // if not specified, choose from pattern\r\n          else {\r\n              if (ids.indexOf(id) < 0) {\r\n                  ids.push(id);\r\n              }\r\n              color = pattern[ids.indexOf(id) % pattern.length];\r\n              colors[id] = color;\r\n          }\r\n          return callback instanceof Function ? callback(color, d) : color;\r\n      };\r\n  };\r\n  ChartInternal.prototype.generateLevelColor = function () {\r\n      var $$ = this, config = $$.config, colors = config.color_pattern, threshold = config.color_threshold, asValue = threshold.unit === 'value', values = threshold.values && threshold.values.length ? threshold.values : [], max = threshold.max || 100;\r\n      return notEmpty(threshold) && notEmpty(colors)\r\n          ? function (value) {\r\n              var i, v, color = colors[colors.length - 1];\r\n              for (i = 0; i < values.length; i++) {\r\n                  v = asValue ? value : (value * 100) / max;\r\n                  if (v < values[i]) {\r\n                      color = colors[i];\r\n                      break;\r\n                  }\r\n              }\r\n              return color;\r\n          }\r\n          : null;\r\n  };\n\n  ChartInternal.prototype.getDefaultConfig = function () {\r\n      var config = {\r\n          bindto: '#chart',\r\n          svg_classname: undefined,\r\n          size_width: undefined,\r\n          size_height: undefined,\r\n          padding_left: undefined,\r\n          padding_right: undefined,\r\n          padding_top: undefined,\r\n          padding_bottom: undefined,\r\n          resize_auto: true,\r\n          zoom_enabled: false,\r\n          zoom_initialRange: undefined,\r\n          zoom_type: 'scroll',\r\n          zoom_disableDefaultBehavior: false,\r\n          zoom_privileged: false,\r\n          zoom_rescale: false,\r\n          zoom_onzoom: function () { },\r\n          zoom_onzoomstart: function () { },\r\n          zoom_onzoomend: function () { },\r\n          zoom_x_min: undefined,\r\n          zoom_x_max: undefined,\r\n          interaction_brighten: true,\r\n          interaction_enabled: true,\r\n          onmouseover: function () { },\r\n          onmouseout: function () { },\r\n          onresize: function () { },\r\n          onresized: function () { },\r\n          oninit: function () { },\r\n          onrendered: function () { },\r\n          transition_duration: 350,\r\n          data_epochs: 'epochs',\r\n          data_x: undefined,\r\n          data_xs: {},\r\n          data_xFormat: '%Y-%m-%d',\r\n          data_xLocaltime: true,\r\n          data_xSort: true,\r\n          data_idConverter: function (id) {\r\n              return id;\r\n          },\r\n          data_names: {},\r\n          data_classes: {},\r\n          data_groups: [],\r\n          data_axes: {},\r\n          data_type: undefined,\r\n          data_types: {},\r\n          data_labels: {},\r\n          data_order: 'desc',\r\n          data_regions: {},\r\n          data_color: undefined,\r\n          data_colors: {},\r\n          data_hide: false,\r\n          data_filter: undefined,\r\n          data_selection_enabled: false,\r\n          data_selection_grouped: false,\r\n          data_selection_isselectable: function () {\r\n              return true;\r\n          },\r\n          data_selection_multiple: true,\r\n          data_selection_draggable: false,\r\n          data_stack_normalize: false,\r\n          data_onclick: function () { },\r\n          data_onmouseover: function () { },\r\n          data_onmouseout: function () { },\r\n          data_onselected: function () { },\r\n          data_onunselected: function () { },\r\n          data_url: undefined,\r\n          data_headers: undefined,\r\n          data_json: undefined,\r\n          data_rows: undefined,\r\n          data_columns: undefined,\r\n          data_mimeType: undefined,\r\n          data_keys: undefined,\r\n          // configuration for no plot-able data supplied.\r\n          data_empty_label_text: '',\r\n          // subchart\r\n          subchart_show: false,\r\n          subchart_size_height: 60,\r\n          subchart_axis_x_show: true,\r\n          subchart_onbrush: function () { },\r\n          // color\r\n          color_pattern: [],\r\n          color_threshold: {},\r\n          // legend\r\n          legend_show: true,\r\n          legend_hide: false,\r\n          legend_position: 'bottom',\r\n          legend_inset_anchor: 'top-left',\r\n          legend_inset_x: 10,\r\n          legend_inset_y: 0,\r\n          legend_inset_step: undefined,\r\n          legend_item_onclick: undefined,\r\n          legend_item_onmouseover: undefined,\r\n          legend_item_onmouseout: undefined,\r\n          legend_equally: false,\r\n          legend_padding: 0,\r\n          legend_item_tile_width: 10,\r\n          legend_item_tile_height: 10,\r\n          // axis\r\n          axis_rotated: false,\r\n          axis_x_show: true,\r\n          axis_x_type: 'indexed',\r\n          axis_x_localtime: true,\r\n          axis_x_categories: [],\r\n          axis_x_tick_centered: false,\r\n          axis_x_tick_format: undefined,\r\n          axis_x_tick_culling: {},\r\n          axis_x_tick_culling_max: 10,\r\n          axis_x_tick_count: undefined,\r\n          axis_x_tick_fit: true,\r\n          axis_x_tick_values: null,\r\n          axis_x_tick_rotate: 0,\r\n          axis_x_tick_outer: true,\r\n          axis_x_tick_multiline: true,\r\n          axis_x_tick_multilineMax: 0,\r\n          axis_x_tick_width: null,\r\n          axis_x_max: undefined,\r\n          axis_x_min: undefined,\r\n          axis_x_padding: {},\r\n          axis_x_height: undefined,\r\n          axis_x_selection: undefined,\r\n          axis_x_label: {},\r\n          axis_x_inner: undefined,\r\n          axis_y_show: true,\r\n          axis_y_type: 'linear',\r\n          axis_y_max: undefined,\r\n          axis_y_min: undefined,\r\n          axis_y_inverted: false,\r\n          axis_y_center: undefined,\r\n          axis_y_inner: undefined,\r\n          axis_y_label: {},\r\n          axis_y_tick_format: undefined,\r\n          axis_y_tick_outer: true,\r\n          axis_y_tick_values: null,\r\n          axis_y_tick_rotate: 0,\r\n          axis_y_tick_count: undefined,\r\n          axis_y_tick_time_type: undefined,\r\n          axis_y_tick_time_interval: undefined,\r\n          axis_y_padding: {},\r\n          axis_y_default: undefined,\r\n          axis_y2_show: false,\r\n          axis_y2_type: 'linear',\r\n          axis_y2_max: undefined,\r\n          axis_y2_min: undefined,\r\n          axis_y2_inverted: false,\r\n          axis_y2_center: undefined,\r\n          axis_y2_inner: undefined,\r\n          axis_y2_label: {},\r\n          axis_y2_tick_format: undefined,\r\n          axis_y2_tick_outer: true,\r\n          axis_y2_tick_values: null,\r\n          axis_y2_tick_count: undefined,\r\n          axis_y2_padding: {},\r\n          axis_y2_default: undefined,\r\n          // grid\r\n          grid_x_show: false,\r\n          grid_x_type: 'tick',\r\n          grid_x_lines: [],\r\n          grid_y_show: false,\r\n          // not used\r\n          // grid_y_type: 'tick',\r\n          grid_y_lines: [],\r\n          grid_y_ticks: 10,\r\n          grid_focus_show: true,\r\n          grid_lines_front: true,\r\n          // point - point of each data\r\n          point_show: true,\r\n          point_r: 2.5,\r\n          point_sensitivity: 10,\r\n          point_focus_expand_enabled: true,\r\n          point_focus_expand_r: undefined,\r\n          point_select_r: undefined,\r\n          // line\r\n          line_connectNull: false,\r\n          line_step_type: 'step',\r\n          // bar\r\n          bar_width: undefined,\r\n          bar_width_ratio: 0.6,\r\n          bar_width_max: undefined,\r\n          bar_zerobased: true,\r\n          bar_space: 0,\r\n          // area\r\n          area_zerobased: true,\r\n          area_above: false,\r\n          // pie\r\n          pie_label_show: true,\r\n          pie_label_format: undefined,\r\n          pie_label_threshold: 0.05,\r\n          pie_label_ratio: undefined,\r\n          pie_expand: {},\r\n          pie_expand_duration: 50,\r\n          pie_padAngle: 0,\r\n          // gauge\r\n          gauge_fullCircle: false,\r\n          gauge_label_show: true,\r\n          gauge_labelLine_show: true,\r\n          gauge_label_format: undefined,\r\n          gauge_min: 0,\r\n          gauge_max: 100,\r\n          gauge_startingAngle: (-1 * Math.PI) / 2,\r\n          gauge_label_extents: undefined,\r\n          gauge_units: undefined,\r\n          gauge_width: undefined,\r\n          gauge_arcs_minWidth: 5,\r\n          gauge_expand: {},\r\n          gauge_expand_duration: 50,\r\n          // donut\r\n          donut_label_show: true,\r\n          donut_label_format: undefined,\r\n          donut_label_threshold: 0.05,\r\n          donut_label_ratio: undefined,\r\n          donut_width: undefined,\r\n          donut_title: '',\r\n          donut_expand: {},\r\n          donut_expand_duration: 50,\r\n          donut_padAngle: 0,\r\n          // spline\r\n          spline_interpolation_type: 'cardinal',\r\n          // stanford\r\n          stanford_lines: [],\r\n          stanford_regions: [],\r\n          stanford_texts: [],\r\n          stanford_scaleMin: undefined,\r\n          stanford_scaleMax: undefined,\r\n          stanford_scaleWidth: undefined,\r\n          stanford_scaleFormat: undefined,\r\n          stanford_scaleValues: undefined,\r\n          stanford_colors: undefined,\r\n          stanford_padding: {\r\n              top: 0,\r\n              right: 0,\r\n              bottom: 0,\r\n              left: 0\r\n          },\r\n          // region - region to change style\r\n          regions: [],\r\n          // tooltip - show when mouseover on each data\r\n          tooltip_show: true,\r\n          tooltip_grouped: true,\r\n          tooltip_order: undefined,\r\n          tooltip_format_title: undefined,\r\n          tooltip_format_name: undefined,\r\n          tooltip_format_value: undefined,\r\n          tooltip_horizontal: undefined,\r\n          tooltip_position: undefined,\r\n          tooltip_contents: function (d, defaultTitleFormat, defaultValueFormat, color) {\r\n              return this.getTooltipContent\r\n                  ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color)\r\n                  : '';\r\n          },\r\n          tooltip_init_show: false,\r\n          tooltip_init_x: 0,\r\n          tooltip_init_position: { top: '0px', left: '50px' },\r\n          tooltip_onshow: function () { },\r\n          tooltip_onhide: function () { },\r\n          // title\r\n          title_text: undefined,\r\n          title_padding: {\r\n              top: 0,\r\n              right: 0,\r\n              bottom: 0,\r\n              left: 0\r\n          },\r\n          title_position: 'top-center'\r\n      };\r\n      Object.keys(this.additionalConfig).forEach(function (key) {\r\n          config[key] = this.additionalConfig[key];\r\n      }, this);\r\n      return config;\r\n  };\r\n  ChartInternal.prototype.additionalConfig = {};\r\n  ChartInternal.prototype.loadConfig = function (config) {\r\n      var this_config = this.config, target, keys, read;\r\n      function find() {\r\n          var key = keys.shift();\r\n          //        console.log(\"key =>\", key, \", target =>\", target);\r\n          if (key && target && typeof target === 'object' && key in target) {\r\n              target = target[key];\r\n              return find();\r\n          }\r\n          else if (!key) {\r\n              return target;\r\n          }\r\n          else {\r\n              return undefined;\r\n          }\r\n      }\r\n      Object.keys(this_config).forEach(function (key) {\r\n          target = config;\r\n          keys = key.split('_');\r\n          read = find();\r\n          //        console.log(\"CONFIG : \", key, read);\r\n          if (isDefined(read)) {\r\n              this_config[key] = read;\r\n          }\r\n      });\r\n  };\n\n  ChartInternal.prototype.convertUrlToData = function (url, mimeType, headers, keys, done) {\r\n      var $$ = this, type = mimeType ? mimeType : 'csv', f, converter;\r\n      if (type === 'json') {\r\n          f = $$.d3.json;\r\n          converter = $$.convertJsonToData;\r\n      }\r\n      else if (type === 'tsv') {\r\n          f = $$.d3.tsv;\r\n          converter = $$.convertXsvToData;\r\n      }\r\n      else {\r\n          f = $$.d3.csv;\r\n          converter = $$.convertXsvToData;\r\n      }\r\n      f(url, headers)\r\n          .then(function (data) {\r\n          done.call($$, converter.call($$, data, keys));\r\n      })\r\n          .catch(function (error) {\r\n          throw error;\r\n      });\r\n  };\r\n  ChartInternal.prototype.convertXsvToData = function (xsv) {\r\n      var keys = xsv.columns, rows = xsv;\r\n      if (rows.length === 0) {\r\n          return {\r\n              keys: keys,\r\n              rows: [keys.reduce(function (row, key) {\r\n                      var _a;\r\n                      return Object.assign(row, (_a = {}, _a[key] = null, _a));\r\n                  }, {})]\r\n          };\r\n      }\r\n      else {\r\n          // [].concat() is to convert result into a plain array otherwise\r\n          // test is not happy because rows have properties.\r\n          return { keys: keys, rows: [].concat(xsv) };\r\n      }\r\n  };\r\n  ChartInternal.prototype.convertJsonToData = function (json, keys) {\r\n      var $$ = this, new_rows = [], targetKeys, data;\r\n      if (keys) {\r\n          // when keys specified, json would be an array that includes objects\r\n          if (keys.x) {\r\n              targetKeys = keys.value.concat(keys.x);\r\n              $$.config.data_x = keys.x;\r\n          }\r\n          else {\r\n              targetKeys = keys.value;\r\n          }\r\n          new_rows.push(targetKeys);\r\n          json.forEach(function (o) {\r\n              var new_row = [];\r\n              targetKeys.forEach(function (key) {\r\n                  // convert undefined to null because undefined data will be removed in convertDataToTargets()\r\n                  var v = $$.findValueInJson(o, key);\r\n                  if (isUndefined(v)) {\r\n                      v = null;\r\n                  }\r\n                  new_row.push(v);\r\n              });\r\n              new_rows.push(new_row);\r\n          });\r\n          data = $$.convertRowsToData(new_rows);\r\n      }\r\n      else {\r\n          Object.keys(json).forEach(function (key) {\r\n              new_rows.push([key].concat(json[key]));\r\n          });\r\n          data = $$.convertColumnsToData(new_rows);\r\n      }\r\n      return data;\r\n  };\r\n  /**\r\n   * Finds value from the given nested object by the given path.\r\n   * If it's not found, then this returns undefined.\r\n   * @param {Object} object the object\r\n   * @param {string} path the path\r\n   */\r\n  ChartInternal.prototype.findValueInJson = function (object, path) {\r\n      if (path in object) {\r\n          // If object has a key that contains . or [], return the key's value\r\n          // instead of searching for an inner object.\r\n          // See https://github.com/c3js/c3/issues/1691 for details.\r\n          return object[path];\r\n      }\r\n      path = path.replace(/\\[(\\w+)\\]/g, '.$1'); // convert indexes to properties (replace [] with .)\r\n      path = path.replace(/^\\./, ''); // strip a leading dot\r\n      var pathArray = path.split('.');\r\n      for (var i = 0; i < pathArray.length; ++i) {\r\n          var k = pathArray[i];\r\n          if (k in object) {\r\n              object = object[k];\r\n          }\r\n          else {\r\n              return;\r\n          }\r\n      }\r\n      return object;\r\n  };\r\n  /**\r\n   * Converts the rows to normalized data.\r\n   * @param {any[][]} rows The row data\r\n   * @return {Object}\r\n   */\r\n  ChartInternal.prototype.convertRowsToData = function (rows) {\r\n      var newRows = [];\r\n      var keys = rows[0];\r\n      for (var i = 1; i < rows.length; i++) {\r\n          var newRow = {};\r\n          for (var j = 0; j < rows[i].length; j++) {\r\n              if (isUndefined(rows[i][j])) {\r\n                  throw new Error('Source data is missing a component at (' + i + ',' + j + ')!');\r\n              }\r\n              newRow[keys[j]] = rows[i][j];\r\n          }\r\n          newRows.push(newRow);\r\n      }\r\n      return { keys: keys, rows: newRows };\r\n  };\r\n  /**\r\n   * Converts the columns to normalized data.\r\n   * @param {any[][]} columns The column data\r\n   * @return {Object}\r\n   */\r\n  ChartInternal.prototype.convertColumnsToData = function (columns) {\r\n      var newRows = [];\r\n      var keys = [];\r\n      for (var i = 0; i < columns.length; i++) {\r\n          var key = columns[i][0];\r\n          for (var j = 1; j < columns[i].length; j++) {\r\n              if (isUndefined(newRows[j - 1])) {\r\n                  newRows[j - 1] = {};\r\n              }\r\n              if (isUndefined(columns[i][j])) {\r\n                  throw new Error('Source data is missing a component at (' + i + ',' + j + ')!');\r\n              }\r\n              newRows[j - 1][key] = columns[i][j];\r\n          }\r\n          keys.push(key);\r\n      }\r\n      return { keys: keys, rows: newRows };\r\n  };\r\n  /**\r\n   * Converts the data format into the target format.\r\n   * @param {!Object} data\r\n   * @param {!Array} data.keys Ordered list of target IDs.\r\n   * @param {!Array} data.rows Rows of data to convert.\r\n   * @param {boolean} appendXs True to append to $$.data.xs, False to replace.\r\n   * @return {!Array}\r\n   */\r\n  ChartInternal.prototype.convertDataToTargets = function (data, appendXs) {\r\n      var $$ = this, config = $$.config, targets, ids, xs, keys, epochs;\r\n      // handles format where keys are not orderly provided\r\n      if (isArray(data)) {\r\n          keys = Object.keys(data[0]);\r\n      }\r\n      else {\r\n          keys = data.keys;\r\n          data = data.rows;\r\n      }\r\n      xs = keys.filter($$.isX, $$);\r\n      if (!$$.isStanfordGraphType()) {\r\n          ids = keys.filter($$.isNotX, $$);\r\n      }\r\n      else {\r\n          epochs = keys.filter($$.isEpochs, $$);\r\n          ids = keys.filter($$.isNotXAndNotEpochs, $$);\r\n          if (xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) {\r\n              throw new Error(\"You must define the 'x' key name and the 'epochs' for Stanford Diagrams\");\r\n          }\r\n      }\r\n      // save x for update data by load when custom x and c3.x API\r\n      ids.forEach(function (id) {\r\n          var xKey = $$.getXKey(id);\r\n          if ($$.isCustomX() || $$.isTimeSeries()) {\r\n              // if included in input data\r\n              if (xs.indexOf(xKey) >= 0) {\r\n                  $$.data.xs[id] = (appendXs && $$.data.xs[id]\r\n                      ? $$.data.xs[id]\r\n                      : []).concat(data\r\n                      .map(function (d) {\r\n                      return d[xKey];\r\n                  })\r\n                      .filter(isValue)\r\n                      .map(function (rawX, i) {\r\n                      return $$.generateTargetX(rawX, id, i);\r\n                  }));\r\n              }\r\n              // if not included in input data, find from preloaded data of other id's x\r\n              else if (config.data_x) {\r\n                  $$.data.xs[id] = $$.getOtherTargetXs();\r\n              }\r\n              // if not included in input data, find from preloaded data\r\n              else if (notEmpty(config.data_xs)) {\r\n                  $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets);\r\n              }\r\n              // MEMO: if no x included, use same x of current will be used\r\n          }\r\n          else {\r\n              $$.data.xs[id] = data.map(function (d, i) {\r\n                  return i;\r\n              });\r\n          }\r\n      });\r\n      // check x is defined\r\n      ids.forEach(function (id) {\r\n          if (!$$.data.xs[id]) {\r\n              throw new Error('x is not defined for id = \"' + id + '\".');\r\n          }\r\n      });\r\n      // convert to target\r\n      targets = ids.map(function (id, index) {\r\n          var convertedId = config.data_idConverter(id);\r\n          return {\r\n              id: convertedId,\r\n              id_org: id,\r\n              values: data\r\n                  .map(function (d, i) {\r\n                  var xKey = $$.getXKey(id), rawX = d[xKey], value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null, x, returnData;\r\n                  // use x as categories if custom x and categorized\r\n                  if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) {\r\n                      if (index === 0 && i === 0) {\r\n                          config.axis_x_categories = [];\r\n                      }\r\n                      x = config.axis_x_categories.indexOf(rawX);\r\n                      if (x === -1) {\r\n                          x = config.axis_x_categories.length;\r\n                          config.axis_x_categories.push(rawX);\r\n                      }\r\n                  }\r\n                  else {\r\n                      x = $$.generateTargetX(rawX, id, i);\r\n                  }\r\n                  // mark as x = undefined if value is undefined and filter to remove after mapped\r\n                  if (isUndefined(d[id]) || $$.data.xs[id].length <= i) {\r\n                      x = undefined;\r\n                  }\r\n                  returnData = { x: x, value: value, id: convertedId };\r\n                  if ($$.isStanfordGraphType()) {\r\n                      returnData.epochs = d[epochs];\r\n                  }\r\n                  return returnData;\r\n              })\r\n                  .filter(function (v) {\r\n                  return isDefined(v.x);\r\n              })\r\n          };\r\n      });\r\n      // finish targets\r\n      targets.forEach(function (t) {\r\n          var i;\r\n          // sort values by its x\r\n          if (config.data_xSort) {\r\n              t.values = t.values.sort(function (v1, v2) {\r\n                  var x1 = v1.x || v1.x === 0 ? v1.x : Infinity, x2 = v2.x || v2.x === 0 ? v2.x : Infinity;\r\n                  return x1 - x2;\r\n              });\r\n          }\r\n          // indexing each value\r\n          i = 0;\r\n          t.values.forEach(function (v) {\r\n              v.index = i++;\r\n          });\r\n          // this needs to be sorted because its index and value.index is identical\r\n          $$.data.xs[t.id].sort(function (v1, v2) {\r\n              return v1 - v2;\r\n          });\r\n      });\r\n      // cache information about values\r\n      $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets);\r\n      $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets);\r\n      // set target types\r\n      if (config.data_type) {\r\n          $$.setTargetType($$.mapToIds(targets).filter(function (id) {\r\n              return !(id in config.data_types);\r\n          }), config.data_type);\r\n      }\r\n      // cache as original id keyed\r\n      targets.forEach(function (d) {\r\n          $$.addCache(d.id_org, d);\r\n      });\r\n      return targets;\r\n  };\n\n  ChartInternal.prototype.isEpochs = function (key) {\r\n      var $$ = this, config = $$.config;\r\n      return config.data_epochs && key === config.data_epochs;\r\n  };\r\n  ChartInternal.prototype.isX = function (key) {\r\n      var $$ = this, config = $$.config;\r\n      return ((config.data_x && key === config.data_x) ||\r\n          (notEmpty(config.data_xs) && hasValue(config.data_xs, key)));\r\n  };\r\n  ChartInternal.prototype.isNotX = function (key) {\r\n      return !this.isX(key);\r\n  };\r\n  ChartInternal.prototype.isNotXAndNotEpochs = function (key) {\r\n      return !this.isX(key) && !this.isEpochs(key);\r\n  };\r\n  /**\r\n   * Returns whether the normalized stack option is enabled or not.\r\n   *\r\n   * To be enabled it must also have data.groups defined.\r\n   *\r\n   * @return {boolean}\r\n   */\r\n  ChartInternal.prototype.isStackNormalized = function () {\r\n      return this.config.data_stack_normalize && this.config.data_groups.length > 0;\r\n  };\r\n  /**\r\n   * Returns whether the axis is normalized or not.\r\n   *\r\n   * An axis is normalized as long as one of its associated target\r\n   * is normalized.\r\n   *\r\n   * @param axisId Axis ID (y or y2)\r\n   * @return {Boolean}\r\n   */\r\n  ChartInternal.prototype.isAxisNormalized = function (axisId) {\r\n      var $$ = this;\r\n      if (!$$.isStackNormalized()) {\r\n          // shortcut\r\n          return false;\r\n      }\r\n      return $$.data.targets\r\n          .filter(function (target) { return $$.axis.getId(target.id) === axisId; })\r\n          .some(function (target) { return $$.isTargetNormalized(target.id); });\r\n  };\r\n  /**\r\n   * Returns whether the values for this target ID is normalized or not.\r\n   *\r\n   * To be normalized the option needs to be enabled and target needs\r\n   * to be defined in `data.groups`.\r\n   *\r\n   * @param targetId ID of the target\r\n   * @return {Boolean} True if the target is normalized, false otherwise.\r\n   */\r\n  ChartInternal.prototype.isTargetNormalized = function (targetId) {\r\n      var $$ = this;\r\n      return ($$.isStackNormalized() &&\r\n          $$.config.data_groups.some(function (group) { return group.includes(targetId); }));\r\n  };\r\n  ChartInternal.prototype.getXKey = function (id) {\r\n      var $$ = this, config = $$.config;\r\n      return config.data_x\r\n          ? config.data_x\r\n          : notEmpty(config.data_xs)\r\n              ? config.data_xs[id]\r\n              : null;\r\n  };\r\n  /**\r\n   * Get sum of visible data per index for given axis.\r\n   *\r\n   * Expect axisId to be either 'y' or 'y2'.\r\n   *\r\n   * @private\r\n   * @param axisId Compute sum for data associated to given axis.\r\n   * @return {Array}\r\n   */\r\n  ChartInternal.prototype.getTotalPerIndex = function (axisId) {\r\n      var $$ = this;\r\n      if (!$$.isStackNormalized()) {\r\n          return null;\r\n      }\r\n      var cached = $$.getFromCache('getTotalPerIndex');\r\n      if (cached !== undefined) {\r\n          return cached[axisId];\r\n      }\r\n      var sum = { y: [], y2: [] };\r\n      $$.data.targets\r\n          // keep only target that are normalized\r\n          .filter(function (target) { return $$.isTargetNormalized(target.id); })\r\n          // keep only target that are visible\r\n          .filter(function (target) { return $$.isTargetToShow(target.id); })\r\n          // compute sum per axis\r\n          .forEach(function (target) {\r\n          var sumByAxis = sum[$$.axis.getId(target.id)];\r\n          target.values.forEach(function (v, i) {\r\n              if (!sumByAxis[i]) {\r\n                  sumByAxis[i] = 0;\r\n              }\r\n              sumByAxis[i] += isNumber(v.value) ? v.value : 0;\r\n          });\r\n      });\r\n      $$.addToCache('getTotalPerIndex', sum);\r\n      return sum[axisId];\r\n  };\r\n  /**\r\n   * Get sum of visible data.\r\n   *\r\n   * Should be used for normalised data only since all values\r\n   * are expected to be positive.\r\n   *\r\n   * @private\r\n   * @return {Number}\r\n   */\r\n  ChartInternal.prototype.getTotalDataSum = function () {\r\n      var $$ = this;\r\n      var cached = $$.getFromCache('getTotalDataSum');\r\n      if (cached !== undefined) {\r\n          return cached;\r\n      }\r\n      var totalDataSum = flattenArray($$.data.targets\r\n          .filter(function (target) { return $$.isTargetToShow(target.id); })\r\n          .map(function (target) { return target.values; }))\r\n          .map(function (d) { return d.value; })\r\n          .reduce(function (p, c) { return p + c; }, 0);\r\n      $$.addToCache('getTotalDataSum', totalDataSum);\r\n      return totalDataSum;\r\n  };\r\n  ChartInternal.prototype.getXValuesOfXKey = function (key, targets) {\r\n      var $$ = this, xValues, ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : [];\r\n      ids.forEach(function (id) {\r\n          if ($$.getXKey(id) === key) {\r\n              xValues = $$.data.xs[id];\r\n          }\r\n      });\r\n      return xValues;\r\n  };\r\n  ChartInternal.prototype.getXValue = function (id, i) {\r\n      var $$ = this;\r\n      return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i])\r\n          ? $$.data.xs[id][i]\r\n          : i;\r\n  };\r\n  ChartInternal.prototype.getOtherTargetXs = function () {\r\n      var $$ = this, idsForX = Object.keys($$.data.xs);\r\n      return idsForX.length ? $$.data.xs[idsForX[0]] : null;\r\n  };\r\n  ChartInternal.prototype.getOtherTargetX = function (index) {\r\n      var xs = this.getOtherTargetXs();\r\n      return xs && index < xs.length ? xs[index] : null;\r\n  };\r\n  ChartInternal.prototype.addXs = function (xs) {\r\n      var $$ = this;\r\n      Object.keys(xs).forEach(function (id) {\r\n          $$.config.data_xs[id] = xs[id];\r\n      });\r\n  };\r\n  ChartInternal.prototype.addName = function (data) {\r\n      var $$ = this, name;\r\n      if (data) {\r\n          name = $$.config.data_names[data.id];\r\n          data.name = name !== undefined ? name : data.id;\r\n      }\r\n      return data;\r\n  };\r\n  ChartInternal.prototype.getValueOnIndex = function (values, index) {\r\n      var valueOnIndex = values.filter(function (v) {\r\n          return v.index === index;\r\n      });\r\n      return valueOnIndex.length ? valueOnIndex[0] : null;\r\n  };\r\n  ChartInternal.prototype.updateTargetX = function (targets, x) {\r\n      var $$ = this;\r\n      targets.forEach(function (t) {\r\n          t.values.forEach(function (v, i) {\r\n              v.x = $$.generateTargetX(x[i], t.id, i);\r\n          });\r\n          $$.data.xs[t.id] = x;\r\n      });\r\n  };\r\n  ChartInternal.prototype.updateTargetXs = function (targets, xs) {\r\n      var $$ = this;\r\n      targets.forEach(function (t) {\r\n          if (xs[t.id]) {\r\n              $$.updateTargetX([t], xs[t.id]);\r\n          }\r\n      });\r\n  };\r\n  ChartInternal.prototype.generateTargetX = function (rawX, id, index) {\r\n      var $$ = this, x;\r\n      if ($$.isTimeSeries()) {\r\n          x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index));\r\n      }\r\n      else if ($$.isCustomX() && !$$.isCategorized()) {\r\n          x = isValue(rawX) ? +rawX : $$.getXValue(id, index);\r\n      }\r\n      else {\r\n          x = index;\r\n      }\r\n      return x;\r\n  };\r\n  ChartInternal.prototype.cloneTarget = function (target) {\r\n      return {\r\n          id: target.id,\r\n          id_org: target.id_org,\r\n          values: target.values.map(function (d) {\r\n              return {\r\n                  x: d.x,\r\n                  value: d.value,\r\n                  id: d.id\r\n              };\r\n          })\r\n      };\r\n  };\r\n  ChartInternal.prototype.getMaxDataCount = function () {\r\n      var $$ = this;\r\n      return $$.d3.max($$.data.targets, function (t) {\r\n          return t.values.length;\r\n      });\r\n  };\r\n  ChartInternal.prototype.mapToIds = function (targets) {\r\n      return targets.map(function (d) {\r\n          return d.id;\r\n      });\r\n  };\r\n  ChartInternal.prototype.mapToTargetIds = function (ids) {\r\n      var $$ = this;\r\n      return ids ? [].concat(ids) : $$.mapToIds($$.data.targets);\r\n  };\r\n  ChartInternal.prototype.hasTarget = function (targets, id) {\r\n      var ids = this.mapToIds(targets), i;\r\n      for (i = 0; i < ids.length; i++) {\r\n          if (ids[i] === id) {\r\n              return true;\r\n          }\r\n      }\r\n      return false;\r\n  };\r\n  ChartInternal.prototype.isTargetToShow = function (targetId) {\r\n      return this.hiddenTargetIds.indexOf(targetId) < 0;\r\n  };\r\n  ChartInternal.prototype.isLegendToShow = function (targetId) {\r\n      return this.hiddenLegendIds.indexOf(targetId) < 0;\r\n  };\r\n  /**\r\n   * Returns only visible targets.\r\n   *\r\n   * This is the same as calling {@link filterTargetsToShow} on $$.data.targets.\r\n   *\r\n   * @return {Array}\r\n   */\r\n  ChartInternal.prototype.getTargetsToShow = function () {\r\n      var $$ = this;\r\n      return $$.filterTargetsToShow($$.data.targets);\r\n  };\r\n  ChartInternal.prototype.filterTargetsToShow = function (targets) {\r\n      var $$ = this;\r\n      return targets.filter(function (t) {\r\n          return $$.isTargetToShow(t.id);\r\n      });\r\n  };\r\n  /**\r\n   * @return {Array} Returns all the targets attached to the chart, visible or not\r\n   */\r\n  ChartInternal.prototype.getTargets = function () {\r\n      var $$ = this;\r\n      return $$.data.targets;\r\n  };\r\n  ChartInternal.prototype.mapTargetsToUniqueXs = function (targets) {\r\n      var $$ = this;\r\n      var xs = $$.d3\r\n          .set($$.d3.merge(targets.map(function (t) {\r\n          return t.values.map(function (v) {\r\n              return +v.x;\r\n          });\r\n      })))\r\n          .values();\r\n      xs = $$.isTimeSeries()\r\n          ? xs.map(function (x) {\r\n              return new Date(+x);\r\n          })\r\n          : xs.map(function (x) {\r\n              return +x;\r\n          });\r\n      return xs.sort(function (a, b) {\r\n          return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\r\n      });\r\n  };\r\n  ChartInternal.prototype.addHiddenTargetIds = function (targetIds) {\r\n      targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);\r\n      for (var i = 0; i < targetIds.length; i++) {\r\n          if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) {\r\n              this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]);\r\n          }\r\n      }\r\n      this.resetCache();\r\n  };\r\n  ChartInternal.prototype.removeHiddenTargetIds = function (targetIds) {\r\n      this.hiddenTargetIds = this.hiddenTargetIds.filter(function (id) {\r\n          return targetIds.indexOf(id) < 0;\r\n      });\r\n      this.resetCache();\r\n  };\r\n  ChartInternal.prototype.addHiddenLegendIds = function (targetIds) {\r\n      targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);\r\n      for (var i = 0; i < targetIds.length; i++) {\r\n          if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) {\r\n              this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]);\r\n          }\r\n      }\r\n  };\r\n  ChartInternal.prototype.removeHiddenLegendIds = function (targetIds) {\r\n      this.hiddenLegendIds = this.hiddenLegendIds.filter(function (id) {\r\n          return targetIds.indexOf(id) < 0;\r\n      });\r\n  };\r\n  ChartInternal.prototype.getValuesAsIdKeyed = function (targets) {\r\n      var ys = {};\r\n      targets.forEach(function (t) {\r\n          ys[t.id] = [];\r\n          t.values.forEach(function (v) {\r\n              ys[t.id].push(v.value);\r\n          });\r\n      });\r\n      return ys;\r\n  };\r\n  ChartInternal.prototype.checkValueInTargets = function (targets, checker) {\r\n      var ids = Object.keys(targets), i, j, values;\r\n      for (i = 0; i < ids.length; i++) {\r\n          values = targets[ids[i]].values;\r\n          for (j = 0; j < values.length; j++) {\r\n              if (checker(values[j].value)) {\r\n                  return true;\r\n              }\r\n          }\r\n      }\r\n      return false;\r\n  };\r\n  ChartInternal.prototype.hasNegativeValueInTargets = function (targets) {\r\n      return this.checkValueInTargets(targets, function (v) {\r\n          return v < 0;\r\n      });\r\n  };\r\n  ChartInternal.prototype.hasPositiveValueInTargets = function (targets) {\r\n      return this.checkValueInTargets(targets, function (v) {\r\n          return v > 0;\r\n      });\r\n  };\r\n  ChartInternal.prototype.isOrderDesc = function () {\r\n      var config = this.config;\r\n      return (typeof config.data_order === 'string' &&\r\n          config.data_order.toLowerCase() === 'desc');\r\n  };\r\n  ChartInternal.prototype.isOrderAsc = function () {\r\n      var config = this.config;\r\n      return (typeof config.data_order === 'string' &&\r\n          config.data_order.toLowerCase() === 'asc');\r\n  };\r\n  ChartInternal.prototype.getOrderFunction = function () {\r\n      var $$ = this, config = $$.config, orderAsc = $$.isOrderAsc(), orderDesc = $$.isOrderDesc();\r\n      if (orderAsc || orderDesc) {\r\n          var reducer = function (p, c) {\r\n              return p + Math.abs(c.value);\r\n          };\r\n          return function (t1, t2) {\r\n              var t1Sum = t1.values.reduce(reducer, 0), t2Sum = t2.values.reduce(reducer, 0);\r\n              return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum;\r\n          };\r\n      }\r\n      else if (isFunction(config.data_order)) {\r\n          return config.data_order;\r\n      }\r\n      else if (isArray(config.data_order)) {\r\n          var order = config.data_order;\r\n          return function (t1, t2) {\r\n              return order.indexOf(t1.id) - order.indexOf(t2.id);\r\n          };\r\n      }\r\n  };\r\n  ChartInternal.prototype.orderTargets = function (targets) {\r\n      var fct = this.getOrderFunction();\r\n      if (fct) {\r\n          targets.sort(fct);\r\n      }\r\n      return targets;\r\n  };\r\n  /**\r\n   * Returns all the values from the given targets at the given index.\r\n   *\r\n   * @param {Array} targets\r\n   * @param {Number} index\r\n   * @return {Array}\r\n   */\r\n  ChartInternal.prototype.filterByIndex = function (targets, index) {\r\n      return this.d3.merge(targets.map(function (t) { return t.values.filter(function (v) { return v.index === index; }); }));\r\n  };\r\n  ChartInternal.prototype.filterByX = function (targets, x) {\r\n      return this.d3\r\n          .merge(targets.map(function (t) {\r\n          return t.values;\r\n      }))\r\n          .filter(function (v) {\r\n          return v.x - x === 0;\r\n      });\r\n  };\r\n  ChartInternal.prototype.filterRemoveNull = function (data) {\r\n      return data.filter(function (d) {\r\n          return isValue(d.value);\r\n      });\r\n  };\r\n  ChartInternal.prototype.filterByXDomain = function (targets, xDomain) {\r\n      return targets.map(function (t) {\r\n          return {\r\n              id: t.id,\r\n              id_org: t.id_org,\r\n              values: t.values.filter(function (v) {\r\n                  return xDomain[0] <= v.x && v.x <= xDomain[1];\r\n              })\r\n          };\r\n      });\r\n  };\r\n  ChartInternal.prototype.hasDataLabel = function () {\r\n      var config = this.config;\r\n      if (typeof config.data_labels === 'boolean' && config.data_labels) {\r\n          return true;\r\n      }\r\n      else if (typeof config.data_labels === 'object' &&\r\n          notEmpty(config.data_labels)) {\r\n          return true;\r\n      }\r\n      return false;\r\n  };\r\n  ChartInternal.prototype.getDataLabelLength = function (min, max, key) {\r\n      var $$ = this, lengths = [0, 0], paddingCoef = 1.3;\r\n      $$.selectChart\r\n          .select('svg')\r\n          .selectAll('.dummy')\r\n          .data([min, max])\r\n          .enter()\r\n          .append('text')\r\n          .text(function (d) {\r\n          return $$.dataLabelFormat(d.id)(d);\r\n      })\r\n          .each(function (d, i) {\r\n          lengths[i] = getBBox(this)[key] * paddingCoef;\r\n      })\r\n          .remove();\r\n      return lengths;\r\n  };\r\n  /**\r\n   * Returns true if the given data point is not arc type, otherwise false.\r\n   * @param {Object} d The data point\r\n   * @return {boolean}\r\n   */\r\n  ChartInternal.prototype.isNoneArc = function (d) {\r\n      return this.hasTarget(this.data.targets, d.id);\r\n  };\r\n  /**\r\n   * Returns true if the given data point is arc type, otherwise false.\r\n   * @param {Object} d The data point\r\n   * @return {boolean}\r\n   */\r\n  ChartInternal.prototype.isArc = function (d) {\r\n      return 'data' in d && this.hasTarget(this.data.targets, d.data.id);\r\n  };\r\n  /**\r\n   * Find the closest point from the given pos among the given targets or\r\n   * undefined if none satisfies conditions.\r\n   *\r\n   * @param {Array} targets\r\n   * @param {Array} pos An [x,y] coordinate\r\n   * @return {Object|undefined}\r\n   */\r\n  ChartInternal.prototype.findClosestFromTargets = function (targets, pos) {\r\n      var $$ = this;\r\n      // for each target, find the closest point\r\n      var candidates = targets\r\n          .map(function (t) {\r\n          return $$.findClosest(t.values, pos, $$.config.tooltip_horizontal\r\n              ? $$.horizontalDistance.bind($$)\r\n              : $$.dist.bind($$), $$.config.point_sensitivity);\r\n      })\r\n          .filter(function (v) { return v; });\r\n      // returns the closest of candidates\r\n      if (candidates.length === 0) {\r\n          return undefined;\r\n      }\r\n      else if (candidates.length === 1) {\r\n          return candidates[0];\r\n      }\r\n      else {\r\n          return $$.findClosest(candidates, pos, $$.dist.bind($$));\r\n      }\r\n  };\r\n  /**\r\n   * Find the closest point from the x value or undefined if none satisfies conditions.\r\n   *\r\n   * @param {Array} targets\r\n   * @param {Array} x A value on X axis\r\n   * @return {Object|undefined}\r\n   */\r\n  ChartInternal.prototype.findClosestFromTargetsByX = function (targets, x) {\r\n      var closest;\r\n      var diff;\r\n      targets.forEach(function (t) {\r\n          t.values.forEach(function (d) {\r\n              var newDiff = Math.abs(x - d.x);\r\n              if (diff === undefined || newDiff < diff) {\r\n                  closest = d;\r\n                  diff = newDiff;\r\n              }\r\n          });\r\n      });\r\n      return closest;\r\n  };\r\n  /**\r\n   * Using given compute distance method, returns the closest data point from the\r\n   * given position.\r\n   *\r\n   * Giving optionally a minimum distance to satisfy.\r\n   *\r\n   * @param {Array} dataPoints List of DataPoints\r\n   * @param {Array} pos An [x,y] coordinate\r\n   * @param {Function} computeDist Function to compute distance between 2 points\r\n   * @param {Number} minDist Minimal distance to satisfy\r\n   * @return {Object|undefined} Closest data point\r\n   */\r\n  ChartInternal.prototype.findClosest = function (dataPoints, pos, computeDist, minDist) {\r\n      if (minDist === void 0) { minDist = Infinity; }\r\n      var $$ = this;\r\n      var closest;\r\n      // find closest bar\r\n      dataPoints\r\n          .filter(function (v) { return v && $$.isBarType(v.id); })\r\n          .forEach(function (v) {\r\n          if (!closest) {\r\n              var shape = $$.main\r\n                  .select('.' +\r\n                  CLASS.bars +\r\n                  $$.getTargetSelectorSuffix(v.id) +\r\n                  ' .' +\r\n                  CLASS.bar +\r\n                  '-' +\r\n                  v.index)\r\n                  .node();\r\n              if ($$.isWithinBar(pos, shape)) {\r\n                  closest = v;\r\n              }\r\n          }\r\n      });\r\n      // find closest point from non-bar\r\n      dataPoints\r\n          .filter(function (v) { return v && !$$.isBarType(v.id); })\r\n          .forEach(function (v) {\r\n          var d = computeDist(v, pos);\r\n          if (d < minDist) {\r\n              minDist = d;\r\n              closest = v;\r\n          }\r\n      });\r\n      return closest;\r\n  };\r\n  ChartInternal.prototype.dist = function (data, pos) {\r\n      var $$ = this, config = $$.config, xIndex = config.axis_rotated ? 1 : 0, yIndex = config.axis_rotated ? 0 : 1, y = $$.circleY(data, data.index), x = $$.x(data.x);\r\n      return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2));\r\n  };\r\n  ChartInternal.prototype.horizontalDistance = function (data, pos) {\r\n      var $$ = this, config = $$.config, xIndex = config.axis_rotated ? 1 : 0, x = $$.x(data.x);\r\n      return Math.abs(x - pos[xIndex]);\r\n  };\r\n  ChartInternal.prototype.convertValuesToStep = function (values) {\r\n      var converted = [].concat(values), i;\r\n      if (!this.isCategorized()) {\r\n          return values;\r\n      }\r\n      for (i = values.length + 1; 0 < i; i--) {\r\n          converted[i] = converted[i - 1];\r\n      }\r\n      converted[0] = {\r\n          x: converted[0].x - 1,\r\n          value: converted[0].value,\r\n          id: converted[0].id\r\n      };\r\n      converted[values.length + 1] = {\r\n          x: converted[values.length].x + 1,\r\n          value: converted[values.length].value,\r\n          id: converted[values.length].id\r\n      };\r\n      return converted;\r\n  };\r\n  /**\r\n   * Get ratio value\r\n   *\r\n   * @param {String} type Ratio for given type\r\n   * @param {Object} d Data value object\r\n   * @param {Boolean} asPercent Convert the return as percent or not\r\n   * @return {Number} Ratio value\r\n   * @private\r\n   */\r\n  ChartInternal.prototype.getRatio = function (type, d, asPercent) {\r\n      if (asPercent === void 0) { asPercent = false; }\r\n      var $$ = this;\r\n      var api = $$.api;\r\n      var ratio = 0;\r\n      if (d && api.data.shown.call(api).length) {\r\n          ratio = d.ratio || d.value;\r\n          if (type === 'arc') {\r\n              if ($$.hasType('gauge')) {\r\n                  ratio =\r\n                      (d.endAngle - d.startAngle) /\r\n                          (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1));\r\n              }\r\n              else {\r\n                  var total = $$.getTotalDataSum();\r\n                  ratio = d.value / total;\r\n              }\r\n          }\r\n          else if (type === 'index') {\r\n              var total = $$.getTotalPerIndex($$.axis.getId(d.id));\r\n              d.ratio =\r\n                  isNumber(d.value) && total && total[d.index] > 0\r\n                      ? d.value / total[d.index]\r\n                      : 0;\r\n              ratio = d.ratio;\r\n          }\r\n      }\r\n      return asPercent && ratio ? ratio * 100 : ratio;\r\n  };\r\n  ChartInternal.prototype.updateDataAttributes = function (name, attrs) {\r\n      var $$ = this, config = $$.config, current = config['data_' + name];\r\n      if (typeof attrs === 'undefined') {\r\n          return current;\r\n      }\r\n      Object.keys(attrs).forEach(function (id) {\r\n          current[id] = attrs[id];\r\n      });\r\n      $$.redraw({\r\n          withLegend: true\r\n      });\r\n      return current;\r\n  };\n\n  ChartInternal.prototype.load = function (targets, args) {\r\n      var $$ = this;\r\n      if (targets) {\r\n          // filter loading targets if needed\r\n          if (args.filter) {\r\n              targets = targets.filter(args.filter);\r\n          }\r\n          // set type if args.types || args.type specified\r\n          if (args.type || args.types) {\r\n              targets.forEach(function (t) {\r\n                  var type = args.types && args.types[t.id] ? args.types[t.id] : args.type;\r\n                  $$.setTargetType(t.id, type);\r\n              });\r\n          }\r\n          // Update/Add data\r\n          $$.data.targets.forEach(function (d) {\r\n              for (var i = 0; i < targets.length; i++) {\r\n                  if (d.id === targets[i].id) {\r\n                      d.values = targets[i].values;\r\n                      targets.splice(i, 1);\r\n                      break;\r\n                  }\r\n              }\r\n          });\r\n          $$.data.targets = $$.data.targets.concat(targets); // add remained\r\n      }\r\n      // Set targets\r\n      $$.updateTargets($$.data.targets);\r\n      // Redraw with new targets\r\n      $$.redraw({\r\n          withUpdateOrgXDomain: true,\r\n          withUpdateXDomain: true,\r\n          withLegend: true\r\n      });\r\n      if (args.done) {\r\n          args.done();\r\n      }\r\n  };\r\n  ChartInternal.prototype.loadFromArgs = function (args) {\r\n      var $$ = this;\r\n      $$.resetCache();\r\n      if (args.data) {\r\n          $$.load($$.convertDataToTargets(args.data), args);\r\n      }\r\n      else if (args.url) {\r\n          $$.convertUrlToData(args.url, args.mimeType, args.headers, args.keys, function (data) {\r\n              $$.load($$.convertDataToTargets(data), args);\r\n          });\r\n      }\r\n      else if (args.json) {\r\n          $$.load($$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), args);\r\n      }\r\n      else if (args.rows) {\r\n          $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args);\r\n      }\r\n      else if (args.columns) {\r\n          $$.load($$.convertDataToTargets($$.convertColumnsToData(args.columns)), args);\r\n      }\r\n      else {\r\n          $$.load(null, args);\r\n      }\r\n  };\r\n  ChartInternal.prototype.unload = function (targetIds, done) {\r\n      var $$ = this;\r\n      $$.resetCache();\r\n      if (!done) {\r\n          done = function () { };\r\n      }\r\n      // filter existing target\r\n      targetIds = targetIds.filter(function (id) {\r\n          return $$.hasTarget($$.data.targets, id);\r\n      });\r\n      // If no target, call done and return\r\n      if (!targetIds || targetIds.length === 0) {\r\n          done();\r\n          return;\r\n      }\r\n      $$.svg\r\n          .selectAll(targetIds.map(function (id) {\r\n          return $$.selectorTarget(id);\r\n      }))\r\n          .transition()\r\n          .style('opacity', 0)\r\n          .remove()\r\n          .call($$.endall, done);\r\n      targetIds.forEach(function (id) {\r\n          // Reset fadein for future load\r\n          $$.withoutFadeIn[id] = false;\r\n          // Remove target's elements\r\n          if ($$.legend) {\r\n              $$.legend\r\n                  .selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id))\r\n                  .remove();\r\n          }\r\n          // Remove target\r\n          $$.data.targets = $$.data.targets.filter(function (t) {\r\n              return t.id !== id;\r\n          });\r\n      });\r\n  };\n\n  ChartInternal.prototype.getYDomainMin = function (targets) {\r\n      var $$ = this, config = $$.config, ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets), j, k, baseId, idsInGroup, id, hasNegativeValue;\r\n      if (config.data_groups.length > 0) {\r\n          hasNegativeValue = $$.hasNegativeValueInTargets(targets);\r\n          for (j = 0; j < config.data_groups.length; j++) {\r\n              // Determine baseId\r\n              idsInGroup = config.data_groups[j].filter(function (id) {\r\n                  return ids.indexOf(id) >= 0;\r\n              });\r\n              if (idsInGroup.length === 0) {\r\n                  continue;\r\n              }\r\n              baseId = idsInGroup[0];\r\n              // Consider negative values\r\n              if (hasNegativeValue && ys[baseId]) {\r\n                  ys[baseId].forEach(function (v, i) {\r\n                      ys[baseId][i] = v < 0 ? v : 0;\r\n                  });\r\n              }\r\n              // Compute min\r\n              for (k = 1; k < idsInGroup.length; k++) {\r\n                  id = idsInGroup[k];\r\n                  if (!ys[id]) {\r\n                      continue;\r\n                  }\r\n                  ys[id].forEach(function (v, i) {\r\n                      if ($$.axis.getId(id) === $$.axis.getId(baseId) &&\r\n                          ys[baseId] &&\r\n                          !(hasNegativeValue && +v > 0)) {\r\n                          ys[baseId][i] += +v;\r\n                      }\r\n                  });\r\n              }\r\n          }\r\n      }\r\n      return $$.d3.min(Object.keys(ys).map(function (key) {\r\n          return $$.d3.min(ys[key]);\r\n      }));\r\n  };\r\n  ChartInternal.prototype.getYDomainMax = function (targets) {\r\n      var $$ = this, config = $$.config, ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets), j, k, baseId, idsInGroup, id, hasPositiveValue;\r\n      if (config.data_groups.length > 0) {\r\n          hasPositiveValue = $$.hasPositiveValueInTargets(targets);\r\n          for (j = 0; j < config.data_groups.length; j++) {\r\n              // Determine baseId\r\n              idsInGroup = config.data_groups[j].filter(function (id) {\r\n                  return ids.indexOf(id) >= 0;\r\n              });\r\n              if (idsInGroup.length === 0) {\r\n                  continue;\r\n              }\r\n              baseId = idsInGroup[0];\r\n              // Consider positive values\r\n              if (hasPositiveValue && ys[baseId]) {\r\n                  ys[baseId].forEach(function (v, i) {\r\n                      ys[baseId][i] = v > 0 ? v : 0;\r\n                  });\r\n              }\r\n              // Compute max\r\n              for (k = 1; k < idsInGroup.length; k++) {\r\n                  id = idsInGroup[k];\r\n                  if (!ys[id]) {\r\n                      continue;\r\n                  }\r\n                  ys[id].forEach(function (v, i) {\r\n                      if ($$.axis.getId(id) === $$.axis.getId(baseId) &&\r\n                          ys[baseId] &&\r\n                          !(hasPositiveValue && +v < 0)) {\r\n                          ys[baseId][i] += +v;\r\n                      }\r\n                  });\r\n              }\r\n          }\r\n      }\r\n      return $$.d3.max(Object.keys(ys).map(function (key) {\r\n          return $$.d3.max(ys[key]);\r\n      }));\r\n  };\r\n  ChartInternal.prototype.getYDomain = function (targets, axisId, xDomain) {\r\n      var $$ = this, config = $$.config;\r\n      if ($$.isAxisNormalized(axisId)) {\r\n          return [0, 100];\r\n      }\r\n      var targetsByAxisId = targets.filter(function (t) {\r\n          return $$.axis.getId(t.id) === axisId;\r\n      }), yTargets = xDomain\r\n          ? $$.filterByXDomain(targetsByAxisId, xDomain)\r\n          : targetsByAxisId, yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min, yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max, yDomainMin = $$.getYDomainMin(yTargets), yDomainMax = $$.getYDomainMax(yTargets), domain, domainLength, padding_top, padding_bottom, center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center, yDomainAbs, lengths, diff, ratio, isAllPositive, isAllNegative, isZeroBased = ($$.hasType('bar', yTargets) && config.bar_zerobased) ||\r\n          ($$.hasType('area', yTargets) && config.area_zerobased), isInverted = axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted, showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated, showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated;\r\n      // MEMO: avoid inverting domain unexpectedly\r\n      yDomainMin = isValue(yMin)\r\n          ? yMin\r\n          : isValue(yMax)\r\n              ? yDomainMin < yMax\r\n                  ? yDomainMin\r\n                  : yMax - 10\r\n              : yDomainMin;\r\n      yDomainMax = isValue(yMax)\r\n          ? yMax\r\n          : isValue(yMin)\r\n              ? yMin < yDomainMax\r\n                  ? yDomainMax\r\n                  : yMin + 10\r\n              : yDomainMax;\r\n      if (yTargets.length === 0) {\r\n          // use current domain if target of axisId is none\r\n          return axisId === 'y2' ? $$.y2.domain() : $$.y.domain();\r\n      }\r\n      if (isNaN(yDomainMin)) {\r\n          // set minimum to zero when not number\r\n          yDomainMin = 0;\r\n      }\r\n      if (isNaN(yDomainMax)) {\r\n          // set maximum to have same value as yDomainMin\r\n          yDomainMax = yDomainMin;\r\n      }\r\n      if (yDomainMin === yDomainMax) {\r\n          yDomainMin < 0 ? (yDomainMax = 0) : (yDomainMin = 0);\r\n      }\r\n      isAllPositive = yDomainMin >= 0 && yDomainMax >= 0;\r\n      isAllNegative = yDomainMin <= 0 && yDomainMax <= 0;\r\n      // Cancel zerobased if axis_*_min / axis_*_max specified\r\n      if ((isValue(yMin) && isAllPositive) || (isValue(yMax) && isAllNegative)) {\r\n          isZeroBased = false;\r\n      }\r\n      // Bar/Area chart should be 0-based if all positive|negative\r\n      if (isZeroBased) {\r\n          if (isAllPositive) {\r\n              yDomainMin = 0;\r\n          }\r\n          if (isAllNegative) {\r\n              yDomainMax = 0;\r\n          }\r\n      }\r\n      domainLength = Math.abs(yDomainMax - yDomainMin);\r\n      padding_top = padding_bottom = domainLength * 0.1;\r\n      if (typeof center !== 'undefined') {\r\n          yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax));\r\n          yDomainMax = center + yDomainAbs;\r\n          yDomainMin = center - yDomainAbs;\r\n      }\r\n      // add padding for data label\r\n      if (showHorizontalDataLabel) {\r\n          lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width');\r\n          diff = diffDomain($$.y.range());\r\n          ratio = [lengths[0] / diff, lengths[1] / diff];\r\n          padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1]));\r\n          padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1]));\r\n      }\r\n      else if (showVerticalDataLabel) {\r\n          lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height');\r\n          var pixelsToAxisPadding = $$.getY(config[\"axis_\" + axisId + \"_type\"], \r\n          // input domain as pixels\r\n          [0, config.axis_rotated ? $$.width : $$.height], \r\n          // output range as axis padding\r\n          [0, domainLength]);\r\n          padding_top += pixelsToAxisPadding(lengths[1]);\r\n          padding_bottom += pixelsToAxisPadding(lengths[0]);\r\n      }\r\n      if (axisId === 'y' && notEmpty(config.axis_y_padding)) {\r\n          padding_top = $$.axis.getPadding(config.axis_y_padding, 'top', padding_top, domainLength);\r\n          padding_bottom = $$.axis.getPadding(config.axis_y_padding, 'bottom', padding_bottom, domainLength);\r\n      }\r\n      if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) {\r\n          padding_top = $$.axis.getPadding(config.axis_y2_padding, 'top', padding_top, domainLength);\r\n          padding_bottom = $$.axis.getPadding(config.axis_y2_padding, 'bottom', padding_bottom, domainLength);\r\n      }\r\n      // Bar/Area chart should be 0-based if all positive|negative\r\n      if (isZeroBased) {\r\n          if (isAllPositive) {\r\n              padding_bottom = yDomainMin;\r\n          }\r\n          if (isAllNegative) {\r\n              padding_top = -yDomainMax;\r\n          }\r\n      }\r\n      domain = [yDomainMin - padding_bottom, yDomainMax + padding_top];\r\n      return isInverted ? domain.reverse() : domain;\r\n  };\r\n  ChartInternal.prototype.getXDomainMin = function (targets) {\r\n      var $$ = this, config = $$.config;\r\n      return isDefined(config.axis_x_min)\r\n          ? $$.isTimeSeries()\r\n              ? this.parseDate(config.axis_x_min)\r\n              : config.axis_x_min\r\n          : $$.d3.min(targets, function (t) {\r\n              return $$.d3.min(t.values, function (v) {\r\n                  return v.x;\r\n              });\r\n          });\r\n  };\r\n  ChartInternal.prototype.getXDomainMax = function (targets) {\r\n      var $$ = this, config = $$.config;\r\n      return isDefined(config.axis_x_max)\r\n          ? $$.isTimeSeries()\r\n              ? this.parseDate(config.axis_x_max)\r\n              : config.axis_x_max\r\n          : $$.d3.max(targets, function (t) {\r\n              return $$.d3.max(t.values, function (v) {\r\n                  return v.x;\r\n              });\r\n          });\r\n  };\r\n  ChartInternal.prototype.getXDomainPadding = function (domain) {\r\n      var $$ = this, config = $$.config, diff = domain[1] - domain[0], maxDataCount, padding, paddingLeft, paddingRight;\r\n      if ($$.isCategorized()) {\r\n          padding = 0;\r\n      }\r\n      else if ($$.hasType('bar')) {\r\n          maxDataCount = $$.getMaxDataCount();\r\n          padding = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : 0.5;\r\n      }\r\n      else {\r\n          padding = diff * 0.01;\r\n      }\r\n      if (typeof config.axis_x_padding === 'object' &&\r\n          notEmpty(config.axis_x_padding)) {\r\n          paddingLeft = isValue(config.axis_x_padding.left)\r\n              ? config.axis_x_padding.left\r\n              : padding;\r\n          paddingRight = isValue(config.axis_x_padding.right)\r\n              ? config.axis_x_padding.right\r\n              : padding;\r\n      }\r\n      else if (typeof config.axis_x_padding === 'number') {\r\n          paddingLeft = paddingRight = config.axis_x_padding;\r\n      }\r\n      else {\r\n          paddingLeft = paddingRight = padding;\r\n      }\r\n      return { left: paddingLeft, right: paddingRight };\r\n  };\r\n  ChartInternal.prototype.getXDomain = function (targets) {\r\n      var $$ = this, xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)], firstX = xDomain[0], lastX = xDomain[1], padding = $$.getXDomainPadding(xDomain), min = 0, max = 0;\r\n      // show center of x domain if min and max are the same\r\n      if (firstX - lastX === 0 && !$$.isCategorized()) {\r\n          if ($$.isTimeSeries()) {\r\n              firstX = new Date(firstX.getTime() * 0.5);\r\n              lastX = new Date(lastX.getTime() * 1.5);\r\n          }\r\n          else {\r\n              firstX = firstX === 0 ? 1 : firstX * 0.5;\r\n              lastX = lastX === 0 ? -1 : lastX * 1.5;\r\n          }\r\n      }\r\n      if (firstX || firstX === 0) {\r\n          min = $$.isTimeSeries()\r\n              ? new Date(firstX.getTime() - padding.left)\r\n              : firstX - padding.left;\r\n      }\r\n      if (lastX || lastX === 0) {\r\n          max = $$.isTimeSeries()\r\n              ? new Date(lastX.getTime() + padding.right)\r\n              : lastX + padding.right;\r\n      }\r\n      return [min, max];\r\n  };\r\n  ChartInternal.prototype.updateXDomain = function (targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) {\r\n      var $$ = this, config = $$.config;\r\n      if (withUpdateOrgXDomain) {\r\n          $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets)));\r\n          $$.orgXDomain = $$.x.domain();\r\n          if (config.zoom_enabled) {\r\n              $$.zoom.update();\r\n          }\r\n          $$.subX.domain($$.x.domain());\r\n          if ($$.brush) {\r\n              $$.brush.updateScale($$.subX);\r\n          }\r\n      }\r\n      if (withUpdateXDomain) {\r\n          $$.x.domain(domain\r\n              ? domain\r\n              : !$$.brush || $$.brush.empty()\r\n                  ? $$.orgXDomain\r\n                  : $$.brush.selectionAsValue());\r\n      }\r\n      // Trim domain when too big by zoom mousemove event\r\n      if (withTrim) {\r\n          $$.x.domain($$.trimXDomain($$.x.orgDomain()));\r\n      }\r\n      return $$.x.domain();\r\n  };\r\n  ChartInternal.prototype.trimXDomain = function (domain) {\r\n      var zoomDomain = this.getZoomDomain(), min = zoomDomain[0], max = zoomDomain[1];\r\n      if (domain[0] <= min) {\r\n          domain[1] = +domain[1] + (min - domain[0]);\r\n          domain[0] = min;\r\n      }\r\n      if (max <= domain[1]) {\r\n          domain[0] = +domain[0] - (domain[1] - max);\r\n          domain[1] = max;\r\n      }\r\n      return domain;\r\n  };\n\n  ChartInternal.prototype.drag = function (mouse) {\r\n      var $$ = this, config = $$.config, main = $$.main, d3 = $$.d3;\r\n      var sx, sy, mx, my, minX, maxX, minY, maxY;\r\n      if ($$.hasArcType()) {\r\n          return;\r\n      }\r\n      if (!config.data_selection_enabled) {\r\n          return;\r\n      } // do nothing if not selectable\r\n      if (!config.data_selection_multiple) {\r\n          return;\r\n      } // skip when single selection because drag is used for multiple selection\r\n      sx = $$.dragStart[0];\r\n      sy = $$.dragStart[1];\r\n      mx = mouse[0];\r\n      my = mouse[1];\r\n      minX = Math.min(sx, mx);\r\n      maxX = Math.max(sx, mx);\r\n      minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my);\r\n      maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my);\r\n      main\r\n          .select('.' + CLASS.dragarea)\r\n          .attr('x', minX)\r\n          .attr('y', minY)\r\n          .attr('width', maxX - minX)\r\n          .attr('height', maxY - minY);\r\n      // TODO: binary search when multiple xs\r\n      main\r\n          .selectAll('.' + CLASS.shapes)\r\n          .selectAll('.' + CLASS.shape)\r\n          .each(function (d, i) {\r\n          if (!config.data_selection_isselectable(d)) {\r\n              return;\r\n          }\r\n          var shape = d3.select(this), isSelected = shape.classed(CLASS.SELECTED), isIncluded = shape.classed(CLASS.INCLUDED), _x, _y, _w, _h, toggle, isWithin = false, box;\r\n          if (shape.classed(CLASS.circle)) {\r\n              _x = shape.attr('cx') * 1;\r\n              _y = shape.attr('cy') * 1;\r\n              toggle = $$.togglePoint;\r\n              isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY;\r\n          }\r\n          else if (shape.classed(CLASS.bar)) {\r\n              box = getPathBox(this);\r\n              _x = box.x;\r\n              _y = box.y;\r\n              _w = box.width;\r\n              _h = box.height;\r\n              toggle = $$.togglePath;\r\n              isWithin =\r\n                  !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY);\r\n          }\r\n          else {\r\n              // line/area selection not supported yet\r\n              return;\r\n          }\r\n          if (isWithin ^ isIncluded) {\r\n              shape.classed(CLASS.INCLUDED, !isIncluded);\r\n              // TODO: included/unincluded callback here\r\n              shape.classed(CLASS.SELECTED, !isSelected);\r\n              toggle.call($$, !isSelected, shape, d, i);\r\n          }\r\n      });\r\n  };\r\n  ChartInternal.prototype.dragstart = function (mouse) {\r\n      var $$ = this, config = $$.config;\r\n      if ($$.hasArcType()) {\r\n          return;\r\n      }\r\n      if (!config.data_selection_enabled) {\r\n          return;\r\n      } // do nothing if not selectable\r\n      $$.dragStart = mouse;\r\n      $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('rect')\r\n          .attr('class', CLASS.dragarea)\r\n          .style('opacity', 0.1);\r\n      $$.dragging = true;\r\n  };\r\n  ChartInternal.prototype.dragend = function () {\r\n      var $$ = this, config = $$.config;\r\n      if ($$.hasArcType()) {\r\n          return;\r\n      }\r\n      if (!config.data_selection_enabled) {\r\n          return;\r\n      } // do nothing if not selectable\r\n      $$.main\r\n          .select('.' + CLASS.dragarea)\r\n          .transition()\r\n          .duration(100)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      $$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false);\r\n      $$.dragging = false;\r\n  };\n\n  ChartInternal.prototype.getYFormat = function (forArc) {\r\n      var $$ = this, formatForY = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat, formatForY2 = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format;\r\n      return function (v, ratio, id) {\r\n          var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY;\r\n          return format.call($$, v, ratio);\r\n      };\r\n  };\r\n  ChartInternal.prototype.yFormat = function (v) {\r\n      var $$ = this, config = $$.config, format = config.axis_y_tick_format\r\n          ? config.axis_y_tick_format\r\n          : $$.defaultValueFormat;\r\n      return format(v);\r\n  };\r\n  ChartInternal.prototype.y2Format = function (v) {\r\n      var $$ = this, config = $$.config, format = config.axis_y2_tick_format\r\n          ? config.axis_y2_tick_format\r\n          : $$.defaultValueFormat;\r\n      return format(v);\r\n  };\r\n  ChartInternal.prototype.defaultValueFormat = function (v) {\r\n      return isValue(v) ? +v : '';\r\n  };\r\n  ChartInternal.prototype.defaultArcValueFormat = function (v, ratio) {\r\n      return (ratio * 100).toFixed(1) + '%';\r\n  };\r\n  ChartInternal.prototype.dataLabelFormat = function (targetId) {\r\n      var $$ = this, data_labels = $$.config.data_labels, format, defaultFormat = function (v) {\r\n          return isValue(v) ? +v : '';\r\n      };\r\n      // find format according to axis id\r\n      if (typeof data_labels.format === 'function') {\r\n          format = data_labels.format;\r\n      }\r\n      else if (typeof data_labels.format === 'object') {\r\n          if (data_labels.format[targetId]) {\r\n              format =\r\n                  data_labels.format[targetId] === true\r\n                      ? defaultFormat\r\n                      : data_labels.format[targetId];\r\n          }\r\n          else {\r\n              format = function () {\r\n                  return '';\r\n              };\r\n          }\r\n      }\r\n      else {\r\n          format = defaultFormat;\r\n      }\r\n      return format;\r\n  };\n\n  ChartInternal.prototype.initGrid = function () {\r\n      var $$ = this, config = $$.config, d3 = $$.d3;\r\n      $$.grid = $$.main\r\n          .append('g')\r\n          .attr('clip-path', $$.clipPathForGrid)\r\n          .attr('class', CLASS.grid);\r\n      if (config.grid_x_show) {\r\n          $$.grid.append('g').attr('class', CLASS.xgrids);\r\n      }\r\n      if (config.grid_y_show) {\r\n          $$.grid.append('g').attr('class', CLASS.ygrids);\r\n      }\r\n      if (config.grid_focus_show) {\r\n          $$.grid\r\n              .append('g')\r\n              .attr('class', CLASS.xgridFocus)\r\n              .append('line')\r\n              .attr('class', CLASS.xgridFocus);\r\n      }\r\n      $$.xgrid = d3.selectAll([]);\r\n      if (!config.grid_lines_front) {\r\n          $$.initGridLines();\r\n      }\r\n  };\r\n  ChartInternal.prototype.initGridLines = function () {\r\n      var $$ = this, d3 = $$.d3;\r\n      $$.gridLines = $$.main\r\n          .append('g')\r\n          .attr('clip-path', $$.clipPathForGrid)\r\n          .attr('class', CLASS.grid + ' ' + CLASS.gridLines);\r\n      $$.gridLines.append('g').attr('class', CLASS.xgridLines);\r\n      $$.gridLines.append('g').attr('class', CLASS.ygridLines);\r\n      $$.xgridLines = d3.selectAll([]);\r\n  };\r\n  ChartInternal.prototype.updateXGrid = function (withoutUpdate) {\r\n      var $$ = this, config = $$.config, d3 = $$.d3, xgridData = $$.generateGridData(config.grid_x_type, $$.x), tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0;\r\n      $$.xgridAttr = config.axis_rotated\r\n          ? {\r\n              x1: 0,\r\n              x2: $$.width,\r\n              y1: function (d) {\r\n                  return $$.x(d) - tickOffset;\r\n              },\r\n              y2: function (d) {\r\n                  return $$.x(d) - tickOffset;\r\n              }\r\n          }\r\n          : {\r\n              x1: function (d) {\r\n                  return $$.x(d) + tickOffset;\r\n              },\r\n              x2: function (d) {\r\n                  return $$.x(d) + tickOffset;\r\n              },\r\n              y1: 0,\r\n              y2: $$.height\r\n          };\r\n      $$.xgridAttr.opacity = function () {\r\n          var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1');\r\n          return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1;\r\n      };\r\n      var xgrid = $$.main\r\n          .select('.' + CLASS.xgrids)\r\n          .selectAll('.' + CLASS.xgrid)\r\n          .data(xgridData);\r\n      var xgridEnter = xgrid\r\n          .enter()\r\n          .append('line')\r\n          .attr('class', CLASS.xgrid)\r\n          .attr('x1', $$.xgridAttr.x1)\r\n          .attr('x2', $$.xgridAttr.x2)\r\n          .attr('y1', $$.xgridAttr.y1)\r\n          .attr('y2', $$.xgridAttr.y2)\r\n          .style('opacity', 0);\r\n      $$.xgrid = xgridEnter.merge(xgrid);\r\n      if (!withoutUpdate) {\r\n          $$.xgrid\r\n              .attr('x1', $$.xgridAttr.x1)\r\n              .attr('x2', $$.xgridAttr.x2)\r\n              .attr('y1', $$.xgridAttr.y1)\r\n              .attr('y2', $$.xgridAttr.y2)\r\n              .style('opacity', $$.xgridAttr.opacity);\r\n      }\r\n      xgrid.exit().remove();\r\n  };\r\n  ChartInternal.prototype.updateYGrid = function () {\r\n      var $$ = this, config = $$.config, gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks);\r\n      var ygrid = $$.main\r\n          .select('.' + CLASS.ygrids)\r\n          .selectAll('.' + CLASS.ygrid)\r\n          .data(gridValues);\r\n      var ygridEnter = ygrid\r\n          .enter()\r\n          .append('line')\r\n          // TODO: x1, x2, y1, y2, opacity need to be set here maybe\r\n          .attr('class', CLASS.ygrid);\r\n      $$.ygrid = ygridEnter.merge(ygrid);\r\n      $$.ygrid\r\n          .attr('x1', config.axis_rotated ? $$.y : 0)\r\n          .attr('x2', config.axis_rotated ? $$.y : $$.width)\r\n          .attr('y1', config.axis_rotated ? 0 : $$.y)\r\n          .attr('y2', config.axis_rotated ? $$.height : $$.y);\r\n      ygrid.exit().remove();\r\n      $$.smoothLines($$.ygrid, 'grid');\r\n  };\r\n  ChartInternal.prototype.gridTextAnchor = function (d) {\r\n      return d.position ? d.position : 'end';\r\n  };\r\n  ChartInternal.prototype.gridTextDx = function (d) {\r\n      return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4;\r\n  };\r\n  ChartInternal.prototype.xGridTextX = function (d) {\r\n      return d.position === 'start'\r\n          ? -this.height\r\n          : d.position === 'middle'\r\n              ? -this.height / 2\r\n              : 0;\r\n  };\r\n  ChartInternal.prototype.yGridTextX = function (d) {\r\n      return d.position === 'start'\r\n          ? 0\r\n          : d.position === 'middle'\r\n              ? this.width / 2\r\n              : this.width;\r\n  };\r\n  ChartInternal.prototype.updateGrid = function (duration) {\r\n      var $$ = this, main = $$.main, config = $$.config, xgridLine, xgridLineEnter, ygridLine, ygridLineEnter, xv = $$.xv.bind($$), yv = $$.yv.bind($$), xGridTextX = $$.xGridTextX.bind($$), yGridTextX = $$.yGridTextX.bind($$);\r\n      // hide if arc type\r\n      $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');\r\n      main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden');\r\n      if (config.grid_x_show) {\r\n          $$.updateXGrid();\r\n      }\r\n      xgridLine = main\r\n          .select('.' + CLASS.xgridLines)\r\n          .selectAll('.' + CLASS.xgridLine)\r\n          .data(config.grid_x_lines);\r\n      // enter\r\n      xgridLineEnter = xgridLine\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', function (d) {\r\n          return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : '');\r\n      });\r\n      xgridLineEnter\r\n          .append('line')\r\n          .attr('x1', config.axis_rotated ? 0 : xv)\r\n          .attr('x2', config.axis_rotated ? $$.width : xv)\r\n          .attr('y1', config.axis_rotated ? xv : 0)\r\n          .attr('y2', config.axis_rotated ? xv : $$.height)\r\n          .style('opacity', 0);\r\n      xgridLineEnter\r\n          .append('text')\r\n          .attr('text-anchor', $$.gridTextAnchor)\r\n          .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\r\n          .attr('x', config.axis_rotated ? yGridTextX : xGridTextX)\r\n          .attr('y', xv)\r\n          .attr('dx', $$.gridTextDx)\r\n          .attr('dy', -5)\r\n          .style('opacity', 0);\r\n      // udpate\r\n      $$.xgridLines = xgridLineEnter.merge(xgridLine);\r\n      // done in d3.transition() of the end of this function\r\n      // exit\r\n      xgridLine\r\n          .exit()\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      // Y-Grid\r\n      if (config.grid_y_show) {\r\n          $$.updateYGrid();\r\n      }\r\n      ygridLine = main\r\n          .select('.' + CLASS.ygridLines)\r\n          .selectAll('.' + CLASS.ygridLine)\r\n          .data(config.grid_y_lines);\r\n      // enter\r\n      ygridLineEnter = ygridLine\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', function (d) {\r\n          return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : '');\r\n      });\r\n      ygridLineEnter\r\n          .append('line')\r\n          .attr('x1', config.axis_rotated ? yv : 0)\r\n          .attr('x2', config.axis_rotated ? yv : $$.width)\r\n          .attr('y1', config.axis_rotated ? 0 : yv)\r\n          .attr('y2', config.axis_rotated ? $$.height : yv)\r\n          .style('opacity', 0);\r\n      ygridLineEnter\r\n          .append('text')\r\n          .attr('text-anchor', $$.gridTextAnchor)\r\n          .attr('transform', config.axis_rotated ? 'rotate(-90)' : '')\r\n          .attr('x', config.axis_rotated ? xGridTextX : yGridTextX)\r\n          .attr('y', yv)\r\n          .attr('dx', $$.gridTextDx)\r\n          .attr('dy', -5)\r\n          .style('opacity', 0);\r\n      // update\r\n      $$.ygridLines = ygridLineEnter.merge(ygridLine);\r\n      $$.ygridLines\r\n          .select('line')\r\n          .transition()\r\n          .duration(duration)\r\n          .attr('x1', config.axis_rotated ? yv : 0)\r\n          .attr('x2', config.axis_rotated ? yv : $$.width)\r\n          .attr('y1', config.axis_rotated ? 0 : yv)\r\n          .attr('y2', config.axis_rotated ? $$.height : yv)\r\n          .style('opacity', 1);\r\n      $$.ygridLines\r\n          .select('text')\r\n          .transition()\r\n          .duration(duration)\r\n          .attr('x', config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$))\r\n          .attr('y', yv)\r\n          .text(function (d) {\r\n          return d.text;\r\n      })\r\n          .style('opacity', 1);\r\n      // exit\r\n      ygridLine\r\n          .exit()\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n  };\r\n  ChartInternal.prototype.redrawGrid = function (withTransition, transition) {\r\n      var $$ = this, config = $$.config, xv = $$.xv.bind($$), lines = $$.xgridLines.select('line'), texts = $$.xgridLines.select('text');\r\n      return [\r\n          (withTransition ? lines.transition(transition) : lines)\r\n              .attr('x1', config.axis_rotated ? 0 : xv)\r\n              .attr('x2', config.axis_rotated ? $$.width : xv)\r\n              .attr('y1', config.axis_rotated ? xv : 0)\r\n              .attr('y2', config.axis_rotated ? xv : $$.height)\r\n              .style('opacity', 1),\r\n          (withTransition ? texts.transition(transition) : texts)\r\n              .attr('x', config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$))\r\n              .attr('y', xv)\r\n              .text(function (d) {\r\n              return d.text;\r\n          })\r\n              .style('opacity', 1)\r\n      ];\r\n  };\r\n  ChartInternal.prototype.showXGridFocus = function (selectedData) {\r\n      var $$ = this, config = $$.config, dataToShow = selectedData.filter(function (d) {\r\n          return d && isValue(d.value);\r\n      }), focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus), xx = $$.xx.bind($$);\r\n      if (!config.tooltip_show) {\r\n          return;\r\n      }\r\n      // Hide when stanford plot exists\r\n      if ($$.hasType('stanford') || $$.hasArcType()) {\r\n          return;\r\n      }\r\n      focusEl\r\n          .style('visibility', 'visible')\r\n          .data([dataToShow[0]])\r\n          .attr(config.axis_rotated ? 'y1' : 'x1', xx)\r\n          .attr(config.axis_rotated ? 'y2' : 'x2', xx);\r\n      $$.smoothLines(focusEl, 'grid');\r\n  };\r\n  ChartInternal.prototype.hideXGridFocus = function () {\r\n      this.main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden');\r\n  };\r\n  ChartInternal.prototype.updateXgridFocus = function () {\r\n      var $$ = this, config = $$.config;\r\n      $$.main\r\n          .select('line.' + CLASS.xgridFocus)\r\n          .attr('x1', config.axis_rotated ? 0 : -10)\r\n          .attr('x2', config.axis_rotated ? $$.width : -10)\r\n          .attr('y1', config.axis_rotated ? -10 : 0)\r\n          .attr('y2', config.axis_rotated ? -10 : $$.height);\r\n  };\r\n  ChartInternal.prototype.generateGridData = function (type, scale) {\r\n      var $$ = this, gridData = [], xDomain, firstYear, lastYear, i, tickNum = $$.main\r\n          .select('.' + CLASS.axisX)\r\n          .selectAll('.tick')\r\n          .size();\r\n      if (type === 'year') {\r\n          xDomain = $$.getXDomain();\r\n          firstYear = xDomain[0].getFullYear();\r\n          lastYear = xDomain[1].getFullYear();\r\n          for (i = firstYear; i <= lastYear; i++) {\r\n              gridData.push(new Date(i + '-01-01 00:00:00'));\r\n          }\r\n      }\r\n      else {\r\n          gridData = scale.ticks(10);\r\n          if (gridData.length > tickNum) {\r\n              // use only int\r\n              gridData = gridData.filter(function (d) {\r\n                  return ('' + d).indexOf('.') < 0;\r\n              });\r\n          }\r\n      }\r\n      return gridData;\r\n  };\r\n  ChartInternal.prototype.getGridFilterToRemove = function (params) {\r\n      return params\r\n          ? function (line) {\r\n              var found = false;\r\n              [].concat(params).forEach(function (param) {\r\n                  if (('value' in param && line.value === param.value) ||\r\n                      ('class' in param && line['class'] === param['class'])) {\r\n                      found = true;\r\n                  }\r\n              });\r\n              return found;\r\n          }\r\n          : function () {\r\n              return true;\r\n          };\r\n  };\r\n  ChartInternal.prototype.removeGridLines = function (params, forX) {\r\n      var $$ = this, config = $$.config, toRemove = $$.getGridFilterToRemove(params), toShow = function (line) {\r\n          return !toRemove(line);\r\n      }, classLines = forX ? CLASS.xgridLines : CLASS.ygridLines, classLine = forX ? CLASS.xgridLine : CLASS.ygridLine;\r\n      $$.main\r\n          .select('.' + classLines)\r\n          .selectAll('.' + classLine)\r\n          .filter(toRemove)\r\n          .transition()\r\n          .duration(config.transition_duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      if (forX) {\r\n          config.grid_x_lines = config.grid_x_lines.filter(toShow);\r\n      }\r\n      else {\r\n          config.grid_y_lines = config.grid_y_lines.filter(toShow);\r\n      }\r\n  };\n\n  ChartInternal.prototype.initEventRect = function () {\r\n      var $$ = this, config = $$.config;\r\n      $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.eventRects)\r\n          .style('fill-opacity', 0);\r\n      $$.eventRect = $$.main\r\n          .select('.' + CLASS.eventRects)\r\n          .append('rect')\r\n          .attr('class', CLASS.eventRect);\r\n      // event rect handle zoom event as well\r\n      if (config.zoom_enabled && $$.zoom) {\r\n          $$.eventRect.call($$.zoom).on('dblclick.zoom', null);\r\n          if (config.zoom_initialRange) {\r\n              // WORKAROUND: Add transition to apply transform immediately when no subchart\r\n              $$.eventRect\r\n                  .transition()\r\n                  .duration(0)\r\n                  .call($$.zoom.transform, $$.zoomTransform(config.zoom_initialRange));\r\n          }\r\n      }\r\n  };\r\n  ChartInternal.prototype.redrawEventRect = function () {\r\n      var $$ = this, d3 = $$.d3, config = $$.config;\r\n      function mouseout() {\r\n          $$.svg.select('.' + CLASS.eventRect).style('cursor', null);\r\n          $$.hideXGridFocus();\r\n          $$.hideTooltip();\r\n          $$.unexpandCircles();\r\n          $$.unexpandBars();\r\n      }\r\n      var isHoveringDataPoint = function (mouse, closest) {\r\n          return closest &&\r\n              ($$.isBarType(closest.id) ||\r\n                  $$.dist(closest, mouse) < config.point_sensitivity);\r\n      };\r\n      var withName = function (d) { return (d ? $$.addName(Object.assign({}, d)) : null); };\r\n      // rects for mouseover\r\n      $$.main\r\n          .select('.' + CLASS.eventRects)\r\n          .style('cursor', config.zoom_enabled\r\n          ? config.axis_rotated\r\n              ? 'ns-resize'\r\n              : 'ew-resize'\r\n          : null);\r\n      $$.eventRect\r\n          .attr('x', 0)\r\n          .attr('y', 0)\r\n          .attr('width', $$.width)\r\n          .attr('height', $$.height)\r\n          .on('mouseout', config.interaction_enabled\r\n          ? function () {\r\n              if (!config) {\r\n                  return;\r\n              } // chart is destroyed\r\n              if ($$.hasArcType()) {\r\n                  return;\r\n              }\r\n              if ($$.mouseover) {\r\n                  config.data_onmouseout.call($$.api, $$.mouseover);\r\n                  $$.mouseover = undefined;\r\n              }\r\n              mouseout();\r\n          }\r\n          : null)\r\n          .on('mousemove', config.interaction_enabled\r\n          ? function () {\r\n              // do nothing when dragging\r\n              if ($$.dragging) {\r\n                  return;\r\n              }\r\n              var targetsToShow = $$.getTargetsToShow();\r\n              // do nothing if arc type\r\n              if ($$.hasArcType(targetsToShow)) {\r\n                  return;\r\n              }\r\n              var mouse = d3.mouse(this);\r\n              var closest = withName($$.findClosestFromTargets(targetsToShow, mouse));\r\n              var isMouseCloseToDataPoint = isHoveringDataPoint(mouse, closest);\r\n              // ensure onmouseout is always called if mousemove switch between 2 targets\r\n              if ($$.mouseover &&\r\n                  (!closest ||\r\n                      closest.id !== $$.mouseover.id ||\r\n                      closest.index !== $$.mouseover.index)) {\r\n                  config.data_onmouseout.call($$.api, $$.mouseover);\r\n                  $$.mouseover = undefined;\r\n              }\r\n              if (closest && !$$.mouseover) {\r\n                  config.data_onmouseover.call($$.api, closest);\r\n                  $$.mouseover = closest;\r\n              }\r\n              // show cursor as pointer if we're hovering a data point close enough\r\n              $$.svg\r\n                  .select('.' + CLASS.eventRect)\r\n                  .style('cursor', isMouseCloseToDataPoint ? 'pointer' : null);\r\n              // if tooltip not grouped, we want to display only data from closest data point\r\n              var showSingleDataPoint = !config.tooltip_grouped || $$.hasType('stanford', targetsToShow);\r\n              // find data to highlight\r\n              var selectedData;\r\n              if (showSingleDataPoint) {\r\n                  if (closest) {\r\n                      selectedData = [closest];\r\n                  }\r\n              }\r\n              else {\r\n                  var closestByX = void 0;\r\n                  if (closest) {\r\n                      // reuse closest value\r\n                      closestByX = closest;\r\n                  }\r\n                  else {\r\n                      // try to find the closest value by X values from the mouse position\r\n                      var mouseX = config.axis_rotated ? mouse[1] : mouse[0];\r\n                      closestByX = $$.findClosestFromTargetsByX(targetsToShow, $$.x.invert(mouseX));\r\n                  }\r\n                  // highlight all data for this 'x' value\r\n                  if (closestByX) {\r\n                      selectedData = $$.filterByX(targetsToShow, closestByX.x);\r\n                  }\r\n              }\r\n              // ensure we have data to show\r\n              if (!selectedData || selectedData.length === 0) {\r\n                  return mouseout();\r\n              }\r\n              // inject names for each point\r\n              selectedData = selectedData.map(withName);\r\n              // show tooltip\r\n              $$.showTooltip(selectedData, this);\r\n              // expand points\r\n              if (config.point_focus_expand_enabled) {\r\n                  $$.unexpandCircles();\r\n                  selectedData.forEach(function (d) {\r\n                      $$.expandCircles(d.index, d.id, false);\r\n                  });\r\n              }\r\n              // expand bars\r\n              $$.unexpandBars();\r\n              selectedData.forEach(function (d) {\r\n                  $$.expandBars(d.index, d.id, false);\r\n              });\r\n              // Show xgrid focus line\r\n              $$.showXGridFocus(selectedData);\r\n          }\r\n          : null)\r\n          .on('click', config.interaction_enabled\r\n          ? function () {\r\n              var targetsToShow = $$.getTargetsToShow();\r\n              if ($$.hasArcType(targetsToShow)) {\r\n                  return;\r\n              }\r\n              var mouse = d3.mouse(this);\r\n              var closest = withName($$.findClosestFromTargets(targetsToShow, mouse));\r\n              if (!isHoveringDataPoint(mouse, closest)) {\r\n                  return;\r\n              }\r\n              // select if selection enabled\r\n              var sameXData;\r\n              if (!config.data_selection_grouped || $$.isStanfordType(closest)) {\r\n                  sameXData = [closest];\r\n              }\r\n              else {\r\n                  sameXData = $$.filterByX(targetsToShow, closest.x);\r\n              }\r\n              // toggle selected state\r\n              sameXData.forEach(function (d) {\r\n                  $$.main\r\n                      .selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id))\r\n                      .selectAll('.' + CLASS.shape + '-' + d.index)\r\n                      .each(function () {\r\n                      if (config.data_selection_grouped ||\r\n                          $$.isWithinShape(this, d)) {\r\n                          $$.toggleShape(this, d, d.index);\r\n                      }\r\n                  });\r\n              });\r\n              // call data_onclick on the closest data point\r\n              if (closest) {\r\n                  var shape = $$.main\r\n                      .selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id))\r\n                      .select('.' + CLASS.shape + '-' + closest.index);\r\n                  config.data_onclick.call($$.api, closest, shape.node());\r\n              }\r\n          }\r\n          : null)\r\n          .call(config.interaction_enabled && config.data_selection_draggable && $$.drag\r\n          ? d3\r\n              .drag()\r\n              .on('drag', function () {\r\n              $$.drag(d3.mouse(this));\r\n          })\r\n              .on('start', function () {\r\n              $$.dragstart(d3.mouse(this));\r\n          })\r\n              .on('end', function () {\r\n              $$.dragend();\r\n          })\r\n          : function () { });\r\n  };\r\n  ChartInternal.prototype.getMousePosition = function (data) {\r\n      var $$ = this;\r\n      return [$$.x(data.x), $$.getYScale(data.id)(data.value)];\r\n  };\r\n  ChartInternal.prototype.dispatchEvent = function (type, mouse) {\r\n      var $$ = this, selector = '.' + CLASS.eventRect, eventRect = $$.main.select(selector).node(), box = eventRect.getBoundingClientRect(), x = box.left + (mouse ? mouse[0] : 0), y = box.top + (mouse ? mouse[1] : 0), event = document.createEvent('MouseEvents');\r\n      event.initMouseEvent(type, true, true, window, 0, x, y, x, y, false, false, false, false, 0, null);\r\n      eventRect.dispatchEvent(event);\r\n  };\n\n  ChartInternal.prototype.initLegend = function () {\r\n      var $$ = this;\r\n      $$.legendItemTextBox = {};\r\n      $$.legendHasRendered = false;\r\n      $$.legend = $$.svg.append('g').attr('transform', $$.getTranslate('legend'));\r\n      if (!$$.config.legend_show) {\r\n          $$.legend.style('visibility', 'hidden');\r\n          $$.hiddenLegendIds = $$.mapToIds($$.data.targets);\r\n          return;\r\n      }\r\n      // MEMO: call here to update legend box and tranlate for all\r\n      // MEMO: translate will be updated by this, so transform not needed in updateLegend()\r\n      $$.updateLegendWithDefaults();\r\n  };\r\n  ChartInternal.prototype.updateLegendWithDefaults = function () {\r\n      var $$ = this;\r\n      $$.updateLegend($$.mapToIds($$.data.targets), {\r\n          withTransform: false,\r\n          withTransitionForTransform: false,\r\n          withTransition: false\r\n      });\r\n  };\r\n  ChartInternal.prototype.updateSizeForLegend = function (legendHeight, legendWidth) {\r\n      var $$ = this, config = $$.config, insetLegendPosition = {\r\n          top: $$.isLegendTop\r\n              ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5\r\n              : $$.currentHeight -\r\n                  legendHeight -\r\n                  $$.getCurrentPaddingBottom() -\r\n                  config.legend_inset_y,\r\n          left: $$.isLegendLeft\r\n              ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5\r\n              : $$.currentWidth -\r\n                  legendWidth -\r\n                  $$.getCurrentPaddingRight() -\r\n                  config.legend_inset_x +\r\n                  0.5\r\n      };\r\n      $$.margin3 = {\r\n          top: $$.isLegendRight\r\n              ? 0\r\n              : $$.isLegendInset\r\n                  ? insetLegendPosition.top\r\n                  : $$.currentHeight - legendHeight,\r\n          right: NaN,\r\n          bottom: 0,\r\n          left: $$.isLegendRight\r\n              ? $$.currentWidth - legendWidth\r\n              : $$.isLegendInset\r\n                  ? insetLegendPosition.left\r\n                  : 0\r\n      };\r\n  };\r\n  ChartInternal.prototype.transformLegend = function (withTransition) {\r\n      var $$ = this;\r\n      (withTransition ? $$.legend.transition() : $$.legend).attr('transform', $$.getTranslate('legend'));\r\n  };\r\n  ChartInternal.prototype.updateLegendStep = function (step) {\r\n      this.legendStep = step;\r\n  };\r\n  ChartInternal.prototype.updateLegendItemWidth = function (w) {\r\n      this.legendItemWidth = w;\r\n  };\r\n  ChartInternal.prototype.updateLegendItemHeight = function (h) {\r\n      this.legendItemHeight = h;\r\n  };\r\n  ChartInternal.prototype.getLegendWidth = function () {\r\n      var $$ = this;\r\n      return $$.config.legend_show\r\n          ? $$.isLegendRight || $$.isLegendInset\r\n              ? $$.legendItemWidth * ($$.legendStep + 1)\r\n              : $$.currentWidth\r\n          : 0;\r\n  };\r\n  ChartInternal.prototype.getLegendHeight = function () {\r\n      var $$ = this, h = 0;\r\n      if ($$.config.legend_show) {\r\n          if ($$.isLegendRight) {\r\n              h = $$.currentHeight;\r\n          }\r\n          else {\r\n              h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1);\r\n          }\r\n      }\r\n      return h;\r\n  };\r\n  ChartInternal.prototype.opacityForLegend = function (legendItem) {\r\n      return legendItem.classed(CLASS.legendItemHidden) ? null : 1;\r\n  };\r\n  ChartInternal.prototype.opacityForUnfocusedLegend = function (legendItem) {\r\n      return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3;\r\n  };\r\n  ChartInternal.prototype.toggleFocusLegend = function (targetIds, focus) {\r\n      var $$ = this;\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      $$.legend\r\n          .selectAll('.' + CLASS.legendItem)\r\n          .filter(function (id) {\r\n          return targetIds.indexOf(id) >= 0;\r\n      })\r\n          .classed(CLASS.legendItemFocused, focus)\r\n          .transition()\r\n          .duration(100)\r\n          .style('opacity', function () {\r\n          var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend;\r\n          return opacity.call($$, $$.d3.select(this));\r\n      });\r\n  };\r\n  ChartInternal.prototype.revertLegend = function () {\r\n      var $$ = this, d3 = $$.d3;\r\n      $$.legend\r\n          .selectAll('.' + CLASS.legendItem)\r\n          .classed(CLASS.legendItemFocused, false)\r\n          .transition()\r\n          .duration(100)\r\n          .style('opacity', function () {\r\n          return $$.opacityForLegend(d3.select(this));\r\n      });\r\n  };\r\n  ChartInternal.prototype.showLegend = function (targetIds) {\r\n      var $$ = this, config = $$.config;\r\n      if (!config.legend_show) {\r\n          config.legend_show = true;\r\n          $$.legend.style('visibility', 'visible');\r\n          if (!$$.legendHasRendered) {\r\n              $$.updateLegendWithDefaults();\r\n          }\r\n      }\r\n      $$.removeHiddenLegendIds(targetIds);\r\n      $$.legend\r\n          .selectAll($$.selectorLegends(targetIds))\r\n          .style('visibility', 'visible')\r\n          .transition()\r\n          .style('opacity', function () {\r\n          return $$.opacityForLegend($$.d3.select(this));\r\n      });\r\n  };\r\n  ChartInternal.prototype.hideLegend = function (targetIds) {\r\n      var $$ = this, config = $$.config;\r\n      if (config.legend_show && isEmpty(targetIds)) {\r\n          config.legend_show = false;\r\n          $$.legend.style('visibility', 'hidden');\r\n      }\r\n      $$.addHiddenLegendIds(targetIds);\r\n      $$.legend\r\n          .selectAll($$.selectorLegends(targetIds))\r\n          .style('opacity', 0)\r\n          .style('visibility', 'hidden');\r\n  };\r\n  ChartInternal.prototype.clearLegendItemTextBoxCache = function () {\r\n      this.legendItemTextBox = {};\r\n  };\r\n  ChartInternal.prototype.updateLegend = function (targetIds, options, transitions) {\r\n      var $$ = this, config = $$.config;\r\n      var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect, x1ForLegendTile, x2ForLegendTile, yForLegendTile;\r\n      var paddingTop = 4, paddingRight = 10, maxWidth = 0, maxHeight = 0, posMin = 10, tileWidth = config.legend_item_tile_width + 5;\r\n      var l, totalLength = 0, offsets = {}, widths = {}, heights = {}, margins = [0], steps = {}, step = 0;\r\n      var withTransition, withTransitionForTransform;\r\n      var texts, rects, tiles, background;\r\n      // Skip elements when their name is set to null\r\n      targetIds = targetIds.filter(function (id) {\r\n          return !isDefined(config.data_names[id]) || config.data_names[id] !== null;\r\n      });\r\n      options = options || {};\r\n      withTransition = getOption(options, 'withTransition', true);\r\n      withTransitionForTransform = getOption(options, 'withTransitionForTransform', true);\r\n      function getTextBox(textElement, id) {\r\n          if (!$$.legendItemTextBox[id]) {\r\n              $$.legendItemTextBox[id] = $$.getTextRect(textElement.textContent, CLASS.legendItem, textElement);\r\n          }\r\n          return $$.legendItemTextBox[id];\r\n      }\r\n      function updatePositions(textElement, id, index) {\r\n          var reset = index === 0, isLast = index === targetIds.length - 1, box = getTextBox(textElement, id), itemWidth = box.width +\r\n              tileWidth +\r\n              (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) +\r\n              config.legend_padding, itemHeight = box.height + paddingTop, itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth, areaLength = $$.isLegendRight || $$.isLegendInset\r\n              ? $$.getLegendHeight()\r\n              : $$.getLegendWidth(), margin, maxLength;\r\n          // MEMO: care about condifion of step, totalLength\r\n          function updateValues(id, withoutStep) {\r\n              if (!withoutStep) {\r\n                  margin = (areaLength - totalLength - itemLength) / 2;\r\n                  if (margin < posMin) {\r\n                      margin = (areaLength - itemLength) / 2;\r\n                      totalLength = 0;\r\n                      step++;\r\n                  }\r\n              }\r\n              steps[id] = step;\r\n              margins[step] = $$.isLegendInset ? 10 : margin;\r\n              offsets[id] = totalLength;\r\n              totalLength += itemLength;\r\n          }\r\n          if (reset) {\r\n              totalLength = 0;\r\n              step = 0;\r\n              maxWidth = 0;\r\n              maxHeight = 0;\r\n          }\r\n          if (config.legend_show && !$$.isLegendToShow(id)) {\r\n              widths[id] = heights[id] = steps[id] = offsets[id] = 0;\r\n              return;\r\n          }\r\n          widths[id] = itemWidth;\r\n          heights[id] = itemHeight;\r\n          if (!maxWidth || itemWidth >= maxWidth) {\r\n              maxWidth = itemWidth;\r\n          }\r\n          if (!maxHeight || itemHeight >= maxHeight) {\r\n              maxHeight = itemHeight;\r\n          }\r\n          maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth;\r\n          if (config.legend_equally) {\r\n              Object.keys(widths).forEach(function (id) {\r\n                  widths[id] = maxWidth;\r\n              });\r\n              Object.keys(heights).forEach(function (id) {\r\n                  heights[id] = maxHeight;\r\n              });\r\n              margin = (areaLength - maxLength * targetIds.length) / 2;\r\n              if (margin < posMin) {\r\n                  totalLength = 0;\r\n                  step = 0;\r\n                  targetIds.forEach(function (id) {\r\n                      updateValues(id);\r\n                  });\r\n              }\r\n              else {\r\n                  updateValues(id, true);\r\n              }\r\n          }\r\n          else {\r\n              updateValues(id);\r\n          }\r\n      }\r\n      if ($$.isLegendInset) {\r\n          step = config.legend_inset_step\r\n              ? config.legend_inset_step\r\n              : targetIds.length;\r\n          $$.updateLegendStep(step);\r\n      }\r\n      if ($$.isLegendRight) {\r\n          xForLegend = function (id) {\r\n              return maxWidth * steps[id];\r\n          };\r\n          yForLegend = function (id) {\r\n              return margins[steps[id]] + offsets[id];\r\n          };\r\n      }\r\n      else if ($$.isLegendInset) {\r\n          xForLegend = function (id) {\r\n              return maxWidth * steps[id] + 10;\r\n          };\r\n          yForLegend = function (id) {\r\n              return margins[steps[id]] + offsets[id];\r\n          };\r\n      }\r\n      else {\r\n          xForLegend = function (id) {\r\n              return margins[steps[id]] + offsets[id];\r\n          };\r\n          yForLegend = function (id) {\r\n              return maxHeight * steps[id];\r\n          };\r\n      }\r\n      xForLegendText = function (id, i) {\r\n          return xForLegend(id, i) + 4 + config.legend_item_tile_width;\r\n      };\r\n      yForLegendText = function (id, i) {\r\n          return yForLegend(id, i) + 9;\r\n      };\r\n      xForLegendRect = function (id, i) {\r\n          return xForLegend(id, i);\r\n      };\r\n      yForLegendRect = function (id, i) {\r\n          return yForLegend(id, i) - 5;\r\n      };\r\n      x1ForLegendTile = function (id, i) {\r\n          return xForLegend(id, i) - 2;\r\n      };\r\n      x2ForLegendTile = function (id, i) {\r\n          return xForLegend(id, i) - 2 + config.legend_item_tile_width;\r\n      };\r\n      yForLegendTile = function (id, i) {\r\n          return yForLegend(id, i) + 4;\r\n      };\r\n      // Define g for legend area\r\n      l = $$.legend\r\n          .selectAll('.' + CLASS.legendItem)\r\n          .data(targetIds)\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', function (id) {\r\n          return $$.generateClass(CLASS.legendItem, id);\r\n      })\r\n          .style('visibility', function (id) {\r\n          return $$.isLegendToShow(id) ? 'visible' : 'hidden';\r\n      })\r\n          .style('cursor', function () {\r\n          return config.interaction_enabled ? 'pointer' : 'auto';\r\n      })\r\n          .on('click', config.interaction_enabled\r\n          ? function (id) {\r\n              if (config.legend_item_onclick) {\r\n                  config.legend_item_onclick.call($$, id);\r\n              }\r\n              else {\r\n                  if ($$.d3.event.altKey) {\r\n                      $$.api.hide();\r\n                      $$.api.show(id);\r\n                  }\r\n                  else {\r\n                      $$.api.toggle(id);\r\n                      $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert();\r\n                  }\r\n              }\r\n          }\r\n          : null)\r\n          .on('mouseover', config.interaction_enabled\r\n          ? function (id) {\r\n              if (config.legend_item_onmouseover) {\r\n                  config.legend_item_onmouseover.call($$, id);\r\n              }\r\n              else {\r\n                  $$.d3.select(this).classed(CLASS.legendItemFocused, true);\r\n                  if (!$$.transiting && $$.isTargetToShow(id)) {\r\n                      $$.api.focus(id);\r\n                  }\r\n              }\r\n          }\r\n          : null)\r\n          .on('mouseout', config.interaction_enabled\r\n          ? function (id) {\r\n              if (config.legend_item_onmouseout) {\r\n                  config.legend_item_onmouseout.call($$, id);\r\n              }\r\n              else {\r\n                  $$.d3.select(this).classed(CLASS.legendItemFocused, false);\r\n                  $$.api.revert();\r\n              }\r\n          }\r\n          : null);\r\n      l.append('text')\r\n          .text(function (id) {\r\n          return isDefined(config.data_names[id]) ? config.data_names[id] : id;\r\n      })\r\n          .each(function (id, i) {\r\n          updatePositions(this, id, i);\r\n      })\r\n          .style('pointer-events', 'none')\r\n          .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200)\r\n          .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText);\r\n      l.append('rect')\r\n          .attr('class', CLASS.legendItemEvent)\r\n          .style('fill-opacity', 0)\r\n          .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200)\r\n          .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect);\r\n      l.append('line')\r\n          .attr('class', CLASS.legendItemTile)\r\n          .style('stroke', $$.color)\r\n          .style('pointer-events', 'none')\r\n          .attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200)\r\n          .attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile)\r\n          .attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200)\r\n          .attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile)\r\n          .attr('stroke-width', config.legend_item_tile_height);\r\n      // Set background for inset legend\r\n      background = $$.legend.select('.' + CLASS.legendBackground + ' rect');\r\n      if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) {\r\n          background = $$.legend\r\n              .insert('g', '.' + CLASS.legendItem)\r\n              .attr('class', CLASS.legendBackground)\r\n              .append('rect');\r\n      }\r\n      texts = $$.legend\r\n          .selectAll('text')\r\n          .data(targetIds)\r\n          .text(function (id) {\r\n          return isDefined(config.data_names[id]) ? config.data_names[id] : id;\r\n      }) // MEMO: needed for update\r\n          .each(function (id, i) {\r\n          updatePositions(this, id, i);\r\n      });\r\n      (withTransition ? texts.transition() : texts)\r\n          .attr('x', xForLegendText)\r\n          .attr('y', yForLegendText);\r\n      rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent).data(targetIds);\r\n      (withTransition ? rects.transition() : rects)\r\n          .attr('width', function (id) {\r\n          return widths[id];\r\n      })\r\n          .attr('height', function (id) {\r\n          return heights[id];\r\n      })\r\n          .attr('x', xForLegendRect)\r\n          .attr('y', yForLegendRect);\r\n      tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile).data(targetIds);\r\n      (withTransition ? tiles.transition() : tiles)\r\n          .style('stroke', $$.levelColor\r\n          ? function (id) {\r\n              return $$.levelColor($$.cache[id].values.reduce(function (total, item) {\r\n                  return total + item.value;\r\n              }, 0));\r\n          }\r\n          : $$.color)\r\n          .attr('x1', x1ForLegendTile)\r\n          .attr('y1', yForLegendTile)\r\n          .attr('x2', x2ForLegendTile)\r\n          .attr('y2', yForLegendTile);\r\n      if (background) {\r\n          (withTransition ? background.transition() : background)\r\n              .attr('height', $$.getLegendHeight() - 12)\r\n              .attr('width', maxWidth * (step + 1) + 10);\r\n      }\r\n      // toggle legend state\r\n      $$.legend\r\n          .selectAll('.' + CLASS.legendItem)\r\n          .classed(CLASS.legendItemHidden, function (id) {\r\n          return !$$.isTargetToShow(id);\r\n      });\r\n      // Update all to reflect change of legend\r\n      $$.updateLegendItemWidth(maxWidth);\r\n      $$.updateLegendItemHeight(maxHeight);\r\n      $$.updateLegendStep(step);\r\n      // Update size and scale\r\n      $$.updateSizes();\r\n      $$.updateScales();\r\n      $$.updateSvgSize();\r\n      // Update g positions\r\n      $$.transformAll(withTransitionForTransform, transitions);\r\n      $$.legendHasRendered = true;\r\n  };\n\n  ChartInternal.prototype.initRegion = function () {\r\n      var $$ = this;\r\n      $$.region = $$.main\r\n          .append('g')\r\n          .attr('clip-path', $$.clipPath)\r\n          .attr('class', CLASS.regions);\r\n  };\r\n  ChartInternal.prototype.updateRegion = function (duration) {\r\n      var $$ = this, config = $$.config;\r\n      // hide if arc type\r\n      $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');\r\n      var mainRegion = $$.main\r\n          .select('.' + CLASS.regions)\r\n          .selectAll('.' + CLASS.region)\r\n          .data(config.regions);\r\n      var g = mainRegion.enter().append('g');\r\n      g.append('rect')\r\n          .attr('x', $$.regionX.bind($$))\r\n          .attr('y', $$.regionY.bind($$))\r\n          .attr('width', $$.regionWidth.bind($$))\r\n          .attr('height', $$.regionHeight.bind($$))\r\n          .style('fill-opacity', function (d) {\r\n          return isValue(d.opacity) ? d.opacity : 0.1;\r\n      });\r\n      g.append('text').text($$.labelRegion.bind($$));\r\n      $$.mainRegion = g.merge(mainRegion).attr('class', $$.classRegion.bind($$));\r\n      mainRegion\r\n          .exit()\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n  };\r\n  ChartInternal.prototype.redrawRegion = function (withTransition, transition) {\r\n      var $$ = this, regions = $$.mainRegion, regionLabels = $$.mainRegion.selectAll('text');\r\n      return [\r\n          (withTransition ? regions.transition(transition) : regions)\r\n              .attr('x', $$.regionX.bind($$))\r\n              .attr('y', $$.regionY.bind($$))\r\n              .attr('width', $$.regionWidth.bind($$))\r\n              .attr('height', $$.regionHeight.bind($$))\r\n              .style('fill-opacity', function (d) {\r\n              return isValue(d.opacity) ? d.opacity : 0.1;\r\n          }),\r\n          (withTransition ? regionLabels.transition(transition) : regionLabels)\r\n              .attr('x', $$.labelOffsetX.bind($$))\r\n              .attr('y', $$.labelOffsetY.bind($$))\r\n              .attr('transform', $$.labelTransform.bind($$))\r\n              .attr('style', 'text-anchor: left;')\r\n      ];\r\n  };\r\n  ChartInternal.prototype.regionX = function (d) {\r\n      var $$ = this, config = $$.config, xPos, yScale = d.axis === 'y' ? $$.y : $$.y2;\r\n      if (d.axis === 'y' || d.axis === 'y2') {\r\n          xPos = config.axis_rotated ? ('start' in d ? yScale(d.start) : 0) : 0;\r\n      }\r\n      else {\r\n          xPos = config.axis_rotated\r\n              ? 0\r\n              : 'start' in d\r\n                  ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start)\r\n                  : 0;\r\n      }\r\n      return xPos;\r\n  };\r\n  ChartInternal.prototype.regionY = function (d) {\r\n      var $$ = this, config = $$.config, yPos, yScale = d.axis === 'y' ? $$.y : $$.y2;\r\n      if (d.axis === 'y' || d.axis === 'y2') {\r\n          yPos = config.axis_rotated ? 0 : 'end' in d ? yScale(d.end) : 0;\r\n      }\r\n      else {\r\n          yPos = config.axis_rotated\r\n              ? 'start' in d\r\n                  ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start)\r\n                  : 0\r\n              : 0;\r\n      }\r\n      return yPos;\r\n  };\r\n  ChartInternal.prototype.regionWidth = function (d) {\r\n      var $$ = this, config = $$.config, start = $$.regionX(d), end, yScale = d.axis === 'y' ? $$.y : $$.y2;\r\n      if (d.axis === 'y' || d.axis === 'y2') {\r\n          end = config.axis_rotated\r\n              ? 'end' in d\r\n                  ? yScale(d.end)\r\n                  : $$.width\r\n              : $$.width;\r\n      }\r\n      else {\r\n          end = config.axis_rotated\r\n              ? $$.width\r\n              : 'end' in d\r\n                  ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end)\r\n                  : $$.width;\r\n      }\r\n      return end < start ? 0 : end - start;\r\n  };\r\n  ChartInternal.prototype.regionHeight = function (d) {\r\n      var $$ = this, config = $$.config, start = this.regionY(d), end, yScale = d.axis === 'y' ? $$.y : $$.y2;\r\n      if (d.axis === 'y' || d.axis === 'y2') {\r\n          end = config.axis_rotated\r\n              ? $$.height\r\n              : 'start' in d\r\n                  ? yScale(d.start)\r\n                  : $$.height;\r\n      }\r\n      else {\r\n          end = config.axis_rotated\r\n              ? 'end' in d\r\n                  ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end)\r\n                  : $$.height\r\n              : $$.height;\r\n      }\r\n      return end < start ? 0 : end - start;\r\n  };\r\n  ChartInternal.prototype.isRegionOnX = function (d) {\r\n      return !d.axis || d.axis === 'x';\r\n  };\r\n  ChartInternal.prototype.labelRegion = function (d) {\r\n      return 'label' in d ? d.label : '';\r\n  };\r\n  ChartInternal.prototype.labelTransform = function (d) {\r\n      return 'vertical' in d && d.vertical ? 'rotate(90)' : '';\r\n  };\r\n  ChartInternal.prototype.labelOffsetX = function (d) {\r\n      var paddingX = 'paddingX' in d ? d.paddingX : 3;\r\n      var paddingY = 'paddingY' in d ? d.paddingY : 3;\r\n      return 'vertical' in d && d.vertical\r\n          ? this.regionY(d) + paddingY\r\n          : this.regionX(d) + paddingX;\r\n  };\r\n  ChartInternal.prototype.labelOffsetY = function (d) {\r\n      var paddingX = 'paddingX' in d ? d.paddingX : 3;\r\n      var paddingY = 'paddingY' in d ? d.paddingY : 3;\r\n      return 'vertical' in d && d.vertical\r\n          ? -(this.regionX(d) + paddingX)\r\n          : this.regionY(d) + 10 + paddingY;\r\n  };\n\n  function c3LogScale(d3, linearScale, logScale) {\r\n      var PROJECTION = [0.01, 10];\r\n      if (!linearScale) {\r\n          linearScale = d3.scaleLinear();\r\n          linearScale.range(PROJECTION);\r\n      }\r\n      if (!logScale) {\r\n          logScale = d3.scaleLog();\r\n          logScale.domain(PROJECTION);\r\n          logScale.nice();\r\n      }\r\n      // copied from https://github.com/compute-io/logspace\r\n      function logspace(a, b, len) {\r\n          var arr, end, tmp, d;\r\n          if (arguments.length < 3) {\r\n              len = 10;\r\n          }\r\n          else {\r\n              if (len === 0) {\r\n                  return [];\r\n              }\r\n          }\r\n          // Calculate the increment:\r\n          end = len - 1;\r\n          d = (b - a) / end;\r\n          // Build the output array...\r\n          arr = new Array(len);\r\n          tmp = a;\r\n          arr[0] = Math.pow(10, tmp);\r\n          for (var i = 1; i < end; i++) {\r\n              tmp += d;\r\n              arr[i] = Math.pow(10, tmp);\r\n          }\r\n          arr[end] = Math.pow(10, b);\r\n          return arr;\r\n      }\r\n      function scale(x) {\r\n          return logScale(linearScale(x));\r\n      }\r\n      scale.domain = function (x) {\r\n          if (!arguments.length) {\r\n              return linearScale.domain();\r\n          }\r\n          linearScale.domain(x);\r\n          return scale;\r\n      };\r\n      scale.range = function (x) {\r\n          if (!arguments.length) {\r\n              return logScale.range();\r\n          }\r\n          logScale.range(x);\r\n          return scale;\r\n      };\r\n      scale.ticks = function (m) {\r\n          return logspace(-2, 1, m || 10).map(function (v) {\r\n              return linearScale.invert(v);\r\n          });\r\n      };\r\n      scale.copy = function () {\r\n          return c3LogScale(d3, linearScale.copy(), logScale.copy());\r\n      };\r\n      return scale;\r\n  }\r\n  ChartInternal.prototype.getScale = function (min, max, forTimeseries) {\r\n      return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([\r\n          min,\r\n          max\r\n      ]);\r\n  };\r\n  ChartInternal.prototype.getX = function (min, max, domain, offset) {\r\n      var $$ = this, scale = $$.getScale(min, max, $$.isTimeSeries()), _scale = domain ? scale.domain(domain) : scale, key;\r\n      // Define customized scale if categorized axis\r\n      if ($$.isCategorized()) {\r\n          offset =\r\n              offset ||\r\n                  function () {\r\n                      return 0;\r\n                  };\r\n          scale = function (d, raw) {\r\n              var v = _scale(d) + offset(d);\r\n              return raw ? v : Math.ceil(v);\r\n          };\r\n      }\r\n      else {\r\n          scale = function (d, raw) {\r\n              var v = _scale(d);\r\n              return raw ? v : Math.ceil(v);\r\n          };\r\n      }\r\n      // define functions\r\n      for (key in _scale) {\r\n          scale[key] = _scale[key];\r\n      }\r\n      scale.orgDomain = function () {\r\n          return _scale.domain();\r\n      };\r\n      // define custom domain() for categorized axis\r\n      if ($$.isCategorized()) {\r\n          scale.domain = function (domain) {\r\n              if (!arguments.length) {\r\n                  domain = this.orgDomain();\r\n                  return [domain[0], domain[1] + 1];\r\n              }\r\n              _scale.domain(domain);\r\n              return scale;\r\n          };\r\n      }\r\n      return scale;\r\n  };\r\n  /**\r\n   * Creates and configures a D3 scale instance for the given type.\r\n   *\r\n   * By defaults it returns a Linear scale.\r\n   *\r\n   * @param {String} type Type of d3-scale to create. Type can be 'linear', 'time', 'timeseries' or 'log'.\r\n   * @param {Array} domain The scale domain such as [from, to]\r\n   * @param {Array} range The scale's range such as [from, to]\r\n   *\r\n   * @return A d3-scale instance\r\n   */\r\n  ChartInternal.prototype.getY = function (type, domain, range) {\r\n      var scale;\r\n      if (type === 'timeseries' || type === 'time') {\r\n          scale = this.d3.scaleTime();\r\n      }\r\n      else if (type === 'log') {\r\n          scale = c3LogScale(this.d3);\r\n      }\r\n      else if (type === 'linear' || type === undefined) {\r\n          scale = this.d3.scaleLinear();\r\n      }\r\n      else {\r\n          throw new Error(\"Invalid Y axis type: \\\"\" + type + \"\\\"\");\r\n      }\r\n      if (domain) {\r\n          scale.domain(domain);\r\n      }\r\n      if (range) {\r\n          scale.range(range);\r\n      }\r\n      return scale;\r\n  };\r\n  ChartInternal.prototype.getYScale = function (id) {\r\n      return this.axis.getId(id) === 'y2' ? this.y2 : this.y;\r\n  };\r\n  ChartInternal.prototype.getSubYScale = function (id) {\r\n      return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY;\r\n  };\r\n  ChartInternal.prototype.updateScales = function () {\r\n      var $$ = this, config = $$.config, forInit = !$$.x;\r\n      // update edges\r\n      $$.xMin = config.axis_rotated ? 1 : 0;\r\n      $$.xMax = config.axis_rotated ? $$.height : $$.width;\r\n      $$.yMin = config.axis_rotated ? 0 : $$.height;\r\n      $$.yMax = config.axis_rotated ? $$.width : 1;\r\n      $$.subXMin = $$.xMin;\r\n      $$.subXMax = $$.xMax;\r\n      $$.subYMin = config.axis_rotated ? 0 : $$.height2;\r\n      $$.subYMax = config.axis_rotated ? $$.width2 : 1;\r\n      // update scales\r\n      $$.x = $$.getX($$.xMin, $$.xMax, forInit ? undefined : $$.x.orgDomain(), function () {\r\n          return $$.xAxis.tickOffset();\r\n      });\r\n      $$.y = $$.getY(config.axis_y_type, forInit ? config.axis_y_default : $$.y.domain(), [$$.yMin, $$.yMax]);\r\n      $$.y2 = $$.getY(config.axis_y2_type, forInit ? config.axis_y2_default : $$.y2.domain(), [$$.yMin, $$.yMax]);\r\n      $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function (d) {\r\n          return d % 1 ? 0 : $$.subXAxis.tickOffset();\r\n      });\r\n      $$.subY = $$.getY(config.axis_y_type, forInit ? config.axis_y_default : $$.subY.domain(), [$$.subYMin, $$.subYMax]);\r\n      $$.subY2 = $$.getY(config.axis_y2_type, forInit ? config.axis_y2_default : $$.subY2.domain(), [$$.subYMin, $$.subYMax]);\r\n      // update axes\r\n      $$.xAxisTickFormat = $$.axis.getXAxisTickFormat();\r\n      $$.xAxisTickValues = $$.axis.getXAxisTickValues();\r\n      $$.yAxisTickValues = $$.axis.getYAxisTickValues();\r\n      $$.y2AxisTickValues = $$.axis.getY2AxisTickValues();\r\n      $$.xAxis = $$.axis.getXAxis($$.x, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);\r\n      $$.subXAxis = $$.axis.getXAxis($$.subX, $$.subXOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);\r\n      $$.yAxis = $$.axis.getYAxis('y', $$.y, $$.yOrient, $$.yAxisTickValues, config.axis_y_tick_outer);\r\n      $$.y2Axis = $$.axis.getYAxis('y2', $$.y2, $$.y2Orient, $$.y2AxisTickValues, config.axis_y2_tick_outer);\r\n      // Set initialized scales to brush and zoom\r\n      if (!forInit) {\r\n          if ($$.brush) {\r\n              $$.brush.updateScale($$.subX);\r\n          }\r\n      }\r\n      // update for arc\r\n      if ($$.updateArc) {\r\n          $$.updateArc();\r\n      }\r\n  };\n\n  ChartInternal.prototype.selectPoint = function (target, d, i) {\r\n      var $$ = this, config = $$.config, cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$), cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$), r = $$.pointSelectR.bind($$);\r\n      config.data_onselected.call($$.api, d, target.node());\r\n      // add selected-circle on low layer g\r\n      $$.main\r\n          .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id))\r\n          .selectAll('.' + CLASS.selectedCircle + '-' + i)\r\n          .data([d])\r\n          .enter()\r\n          .append('circle')\r\n          .attr('class', function () {\r\n          return $$.generateClass(CLASS.selectedCircle, i);\r\n      })\r\n          .attr('cx', cx)\r\n          .attr('cy', cy)\r\n          .attr('stroke', function () {\r\n          return $$.color(d);\r\n      })\r\n          .attr('r', function (d) {\r\n          return $$.pointSelectR(d) * 1.4;\r\n      })\r\n          .transition()\r\n          .duration(100)\r\n          .attr('r', r);\r\n  };\r\n  ChartInternal.prototype.unselectPoint = function (target, d, i) {\r\n      var $$ = this;\r\n      $$.config.data_onunselected.call($$.api, d, target.node());\r\n      // remove selected-circle from low layer g\r\n      $$.main\r\n          .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id))\r\n          .selectAll('.' + CLASS.selectedCircle + '-' + i)\r\n          .transition()\r\n          .duration(100)\r\n          .attr('r', 0)\r\n          .remove();\r\n  };\r\n  ChartInternal.prototype.togglePoint = function (selected, target, d, i) {\r\n      selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i);\r\n  };\r\n  ChartInternal.prototype.selectPath = function (target, d) {\r\n      var $$ = this;\r\n      $$.config.data_onselected.call($$, d, target.node());\r\n      if ($$.config.interaction_brighten) {\r\n          target\r\n              .transition()\r\n              .duration(100)\r\n              .style('fill', function () {\r\n              return $$.d3.rgb($$.color(d)).brighter(0.75);\r\n          });\r\n      }\r\n  };\r\n  ChartInternal.prototype.unselectPath = function (target, d) {\r\n      var $$ = this;\r\n      $$.config.data_onunselected.call($$, d, target.node());\r\n      if ($$.config.interaction_brighten) {\r\n          target\r\n              .transition()\r\n              .duration(100)\r\n              .style('fill', function () {\r\n              return $$.color(d);\r\n          });\r\n      }\r\n  };\r\n  ChartInternal.prototype.togglePath = function (selected, target, d, i) {\r\n      selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i);\r\n  };\r\n  ChartInternal.prototype.getToggle = function (that, d) {\r\n      var $$ = this, toggle;\r\n      if (that.nodeName === 'circle') {\r\n          if ($$.isStepType(d)) {\r\n              // circle is hidden in step chart, so treat as within the click area\r\n              toggle = function () { }; // TODO: how to select step chart?\r\n          }\r\n          else {\r\n              toggle = $$.togglePoint;\r\n          }\r\n      }\r\n      else if (that.nodeName === 'path') {\r\n          toggle = $$.togglePath;\r\n      }\r\n      return toggle;\r\n  };\r\n  ChartInternal.prototype.toggleShape = function (that, d, i) {\r\n      var $$ = this, d3 = $$.d3, config = $$.config, shape = d3.select(that), isSelected = shape.classed(CLASS.SELECTED), toggle = $$.getToggle(that, d).bind($$);\r\n      if (config.data_selection_enabled && config.data_selection_isselectable(d)) {\r\n          if (!config.data_selection_multiple) {\r\n              $$.main\r\n                  .selectAll('.' +\r\n                  CLASS.shapes +\r\n                  (config.data_selection_grouped\r\n                      ? $$.getTargetSelectorSuffix(d.id)\r\n                      : ''))\r\n                  .selectAll('.' + CLASS.shape)\r\n                  .each(function (d, i) {\r\n                  var shape = d3.select(this);\r\n                  if (shape.classed(CLASS.SELECTED)) {\r\n                      toggle(false, shape.classed(CLASS.SELECTED, false), d, i);\r\n                  }\r\n              });\r\n          }\r\n          shape.classed(CLASS.SELECTED, !isSelected);\r\n          toggle(!isSelected, shape, d, i);\r\n      }\r\n  };\n\n  ChartInternal.prototype.initBar = function () {\r\n      var $$ = this;\r\n      $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.chartBars);\r\n  };\r\n  ChartInternal.prototype.updateTargetsForBar = function (targets) {\r\n      var $$ = this, config = $$.config, mainBars, mainBarEnter, classChartBar = $$.classChartBar.bind($$), classBars = $$.classBars.bind($$), classFocus = $$.classFocus.bind($$);\r\n      mainBars = $$.main\r\n          .select('.' + CLASS.chartBars)\r\n          .selectAll('.' + CLASS.chartBar)\r\n          .data(targets)\r\n          .attr('class', function (d) {\r\n          return classChartBar(d) + classFocus(d);\r\n      });\r\n      mainBarEnter = mainBars\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', classChartBar)\r\n          .style('pointer-events', 'none');\r\n      // Bars for each data\r\n      mainBarEnter\r\n          .append('g')\r\n          .attr('class', classBars)\r\n          .style('cursor', function (d) {\r\n          return config.data_selection_isselectable(d) ? 'pointer' : null;\r\n      });\r\n  };\r\n  ChartInternal.prototype.updateBar = function (durationForExit) {\r\n      var $$ = this, barData = $$.barData.bind($$), classBar = $$.classBar.bind($$), initialOpacity = $$.initialOpacity.bind($$), color = function (d) {\r\n          return $$.color(d.id);\r\n      };\r\n      var mainBar = $$.main\r\n          .selectAll('.' + CLASS.bars)\r\n          .selectAll('.' + CLASS.bar)\r\n          .data(barData);\r\n      var mainBarEnter = mainBar\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', classBar)\r\n          .style('stroke', color)\r\n          .style('fill', color);\r\n      $$.mainBar = mainBarEnter.merge(mainBar).style('opacity', initialOpacity);\r\n      mainBar\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0);\r\n  };\r\n  ChartInternal.prototype.redrawBar = function (drawBar, withTransition, transition) {\r\n      var $$ = this;\r\n      return [\r\n          (withTransition ? this.mainBar.transition(transition) : this.mainBar)\r\n              .attr('d', drawBar)\r\n              .style('stroke', this.color)\r\n              .style('fill', this.color)\r\n              .style('opacity', function (d) { return ($$.isTargetToShow(d.id) ? 1 : 0); })\r\n      ];\r\n  };\r\n  ChartInternal.prototype.getBarW = function (axis, barTargetsNum) {\r\n      var $$ = this, config = $$.config, w = typeof config.bar_width === 'number'\r\n          ? config.bar_width\r\n          : barTargetsNum\r\n              ? (axis.tickInterval() * config.bar_width_ratio) / barTargetsNum\r\n              : 0;\r\n      return config.bar_width_max && w > config.bar_width_max\r\n          ? config.bar_width_max\r\n          : w;\r\n  };\r\n  ChartInternal.prototype.getBars = function (i, id) {\r\n      var $$ = this;\r\n      return (id\r\n          ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id))\r\n          : $$.main).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''));\r\n  };\r\n  ChartInternal.prototype.expandBars = function (i, id, reset) {\r\n      var $$ = this;\r\n      if (reset) {\r\n          $$.unexpandBars();\r\n      }\r\n      $$.getBars(i, id).classed(CLASS.EXPANDED, true);\r\n  };\r\n  ChartInternal.prototype.unexpandBars = function (i) {\r\n      var $$ = this;\r\n      $$.getBars(i).classed(CLASS.EXPANDED, false);\r\n  };\r\n  ChartInternal.prototype.generateDrawBar = function (barIndices, isSub) {\r\n      var $$ = this, config = $$.config, getPoints = $$.generateGetBarPoints(barIndices, isSub);\r\n      return function (d, i) {\r\n          // 4 points that make a bar\r\n          var points = getPoints(d, i);\r\n          // switch points if axis is rotated, not applicable for sub chart\r\n          var indexX = config.axis_rotated ? 1 : 0;\r\n          var indexY = config.axis_rotated ? 0 : 1;\r\n          var path = 'M ' +\r\n              points[0][indexX] +\r\n              ',' +\r\n              points[0][indexY] +\r\n              ' ' +\r\n              'L' +\r\n              points[1][indexX] +\r\n              ',' +\r\n              points[1][indexY] +\r\n              ' ' +\r\n              'L' +\r\n              points[2][indexX] +\r\n              ',' +\r\n              points[2][indexY] +\r\n              ' ' +\r\n              'L' +\r\n              points[3][indexX] +\r\n              ',' +\r\n              points[3][indexY] +\r\n              ' ' +\r\n              'z';\r\n          return path;\r\n      };\r\n  };\r\n  ChartInternal.prototype.generateGetBarPoints = function (barIndices, isSub) {\r\n      var $$ = this, axis = isSub ? $$.subXAxis : $$.xAxis, barTargetsNum = barIndices.__max__ + 1, barW = $$.getBarW(axis, barTargetsNum), barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub), barY = $$.getShapeY(!!isSub), barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub), barSpaceOffset = barW * ($$.config.bar_space / 2), yScale = isSub ? $$.getSubYScale : $$.getYScale;\r\n      return function (d, i) {\r\n          var y0 = yScale.call($$, d.id)(0), offset = barOffset(d, i) || y0, // offset is for stacked bar chart\r\n          posX = barX(d), posY = barY(d);\r\n          // fix posY not to overflow opposite quadrant\r\n          if ($$.config.axis_rotated) {\r\n              if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\r\n                  posY = y0;\r\n              }\r\n          }\r\n          posY -= y0 - offset;\r\n          // 4 points that make a bar\r\n          return [\r\n              [posX + barSpaceOffset, offset],\r\n              [posX + barSpaceOffset, posY],\r\n              [posX + barW - barSpaceOffset, posY],\r\n              [posX + barW - barSpaceOffset, offset]\r\n          ];\r\n      };\r\n  };\r\n  /**\r\n   * Returns whether the data point is within the given bar shape.\r\n   *\r\n   * @param mouse\r\n   * @param barShape\r\n   * @return {boolean}\r\n   */\r\n  ChartInternal.prototype.isWithinBar = function (mouse, barShape) {\r\n      return isWithinBox(mouse, getBBox(barShape), 2);\r\n  };\n\n  ChartInternal.prototype.getShapeIndices = function (typeFilter) {\r\n      var $$ = this, config = $$.config, indices = {}, i = 0, j, k;\r\n      $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) {\r\n          for (j = 0; j < config.data_groups.length; j++) {\r\n              if (config.data_groups[j].indexOf(d.id) < 0) {\r\n                  continue;\r\n              }\r\n              for (k = 0; k < config.data_groups[j].length; k++) {\r\n                  if (config.data_groups[j][k] in indices) {\r\n                      indices[d.id] = indices[config.data_groups[j][k]];\r\n                      break;\r\n                  }\r\n              }\r\n          }\r\n          if (isUndefined(indices[d.id])) {\r\n              indices[d.id] = i++;\r\n          }\r\n      });\r\n      indices.__max__ = i - 1;\r\n      return indices;\r\n  };\r\n  ChartInternal.prototype.getShapeX = function (offset, targetsNum, indices, isSub) {\r\n      var $$ = this, scale = isSub ? $$.subX : $$.x;\r\n      return function (d) {\r\n          var index = d.id in indices ? indices[d.id] : 0;\r\n          return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0;\r\n      };\r\n  };\r\n  ChartInternal.prototype.getShapeY = function (isSub) {\r\n      var $$ = this;\r\n      return function (d) {\r\n          var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id);\r\n          return scale($$.isTargetNormalized(d.id) ? $$.getRatio('index', d, true) : d.value);\r\n      };\r\n  };\r\n  ChartInternal.prototype.getShapeOffset = function (typeFilter, indices, isSub) {\r\n      var $$ = this, targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))), targetIds = targets.map(function (t) {\r\n          return t.id;\r\n      });\r\n      return function (d, i) {\r\n          var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id), y0 = scale(0), offset = y0;\r\n          targets.forEach(function (t) {\r\n              var rowValues = $$.isStepType(d)\r\n                  ? $$.convertValuesToStep(t.values)\r\n                  : t.values;\r\n              var isTargetNormalized = $$.isTargetNormalized(d.id);\r\n              var values = rowValues.map(function (v) {\r\n                  return isTargetNormalized ? $$.getRatio('index', v, true) : v.value;\r\n              });\r\n              if (t.id === d.id || indices[t.id] !== indices[d.id]) {\r\n                  return;\r\n              }\r\n              if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) {\r\n                  // check if the x values line up\r\n                  if (isUndefined(rowValues[i]) || +rowValues[i].x !== +d.x) {\r\n                      // \"+\" for timeseries\r\n                      // if not, try to find the value that does line up\r\n                      i = -1;\r\n                      rowValues.forEach(function (v, j) {\r\n                          var x1 = v.x.constructor === Date ? +v.x : v.x;\r\n                          var x2 = d.x.constructor === Date ? +d.x : d.x;\r\n                          if (x1 === x2) {\r\n                              i = j;\r\n                          }\r\n                      });\r\n                  }\r\n                  if (i in rowValues && rowValues[i].value * d.value >= 0) {\r\n                      offset += scale(values[i]) - y0;\r\n                  }\r\n              }\r\n          });\r\n          return offset;\r\n      };\r\n  };\r\n  ChartInternal.prototype.isWithinShape = function (that, d) {\r\n      var $$ = this, shape = $$.d3.select(that), isWithin;\r\n      if (!$$.isTargetToShow(d.id)) {\r\n          isWithin = false;\r\n      }\r\n      else if (that.nodeName === 'circle') {\r\n          isWithin = $$.isStepType(d)\r\n              ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value))\r\n              : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5);\r\n      }\r\n      else if (that.nodeName === 'path') {\r\n          isWithin = shape.classed(CLASS.bar)\r\n              ? $$.isWithinBar($$.d3.mouse(that), that)\r\n              : true;\r\n      }\r\n      return isWithin;\r\n  };\r\n  ChartInternal.prototype.getInterpolate = function (d) {\r\n      var $$ = this, d3 = $$.d3, types = {\r\n          linear: d3.curveLinear,\r\n          'linear-closed': d3.curveLinearClosed,\r\n          basis: d3.curveBasis,\r\n          'basis-open': d3.curveBasisOpen,\r\n          'basis-closed': d3.curveBasisClosed,\r\n          bundle: d3.curveBundle,\r\n          cardinal: d3.curveCardinal,\r\n          'cardinal-open': d3.curveCardinalOpen,\r\n          'cardinal-closed': d3.curveCardinalClosed,\r\n          monotone: d3.curveMonotoneX,\r\n          step: d3.curveStep,\r\n          'step-before': d3.curveStepBefore,\r\n          'step-after': d3.curveStepAfter\r\n      }, type;\r\n      if ($$.isSplineType(d)) {\r\n          type = types[$$.config.spline_interpolation_type] || types.cardinal;\r\n      }\r\n      else if ($$.isStepType(d)) {\r\n          type = types[$$.config.line_step_type];\r\n      }\r\n      else {\r\n          type = types.linear;\r\n      }\r\n      return type;\r\n  };\n\n  ChartInternal.prototype.initLine = function () {\r\n      var $$ = this;\r\n      $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.chartLines);\r\n  };\r\n  ChartInternal.prototype.updateTargetsForLine = function (targets) {\r\n      var $$ = this, config = $$.config, mainLines, mainLineEnter, classChartLine = $$.classChartLine.bind($$), classLines = $$.classLines.bind($$), classAreas = $$.classAreas.bind($$), classCircles = $$.classCircles.bind($$), classFocus = $$.classFocus.bind($$);\r\n      mainLines = $$.main\r\n          .select('.' + CLASS.chartLines)\r\n          .selectAll('.' + CLASS.chartLine)\r\n          .data(targets)\r\n          .attr('class', function (d) {\r\n          return classChartLine(d) + classFocus(d);\r\n      });\r\n      mainLineEnter = mainLines\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', classChartLine)\r\n          .style('opacity', 0)\r\n          .style('pointer-events', 'none');\r\n      // Lines for each data\r\n      mainLineEnter.append('g').attr('class', classLines);\r\n      // Areas\r\n      mainLineEnter.append('g').attr('class', classAreas);\r\n      // Circles for each data point on lines\r\n      mainLineEnter.append('g').attr('class', function (d) {\r\n          return $$.generateClass(CLASS.selectedCircles, d.id);\r\n      });\r\n      mainLineEnter\r\n          .append('g')\r\n          .attr('class', classCircles)\r\n          .style('cursor', function (d) {\r\n          return config.data_selection_isselectable(d) ? 'pointer' : null;\r\n      });\r\n      // Update date for selected circles\r\n      targets.forEach(function (t) {\r\n          $$.main\r\n              .selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id))\r\n              .selectAll('.' + CLASS.selectedCircle)\r\n              .each(function (d) {\r\n              d.value = t.values[d.index].value;\r\n          });\r\n      });\r\n      // MEMO: can not keep same color...\r\n      //mainLineUpdate.exit().remove();\r\n  };\r\n  ChartInternal.prototype.updateLine = function (durationForExit) {\r\n      var $$ = this;\r\n      var mainLine = $$.main\r\n          .selectAll('.' + CLASS.lines)\r\n          .selectAll('.' + CLASS.line)\r\n          .data($$.lineData.bind($$));\r\n      var mainLineEnter = mainLine\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', $$.classLine.bind($$))\r\n          .style('stroke', $$.color);\r\n      $$.mainLine = mainLineEnter\r\n          .merge(mainLine)\r\n          .style('opacity', $$.initialOpacity.bind($$))\r\n          .style('shape-rendering', function (d) {\r\n          return $$.isStepType(d) ? 'crispEdges' : '';\r\n      })\r\n          .attr('transform', null);\r\n      mainLine\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0);\r\n  };\r\n  ChartInternal.prototype.redrawLine = function (drawLine, withTransition, transition) {\r\n      return [\r\n          (withTransition ? this.mainLine.transition(transition) : this.mainLine)\r\n              .attr('d', drawLine)\r\n              .style('stroke', this.color)\r\n              .style('opacity', 1)\r\n      ];\r\n  };\r\n  ChartInternal.prototype.generateDrawLine = function (lineIndices, isSub) {\r\n      var $$ = this, config = $$.config, line = $$.d3.line(), getPoints = $$.generateGetLinePoints(lineIndices, isSub), yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, xValue = function (d) {\r\n          return (isSub ? $$.subxx : $$.xx).call($$, d);\r\n      }, yValue = function (d, i) {\r\n          return config.data_groups.length > 0\r\n              ? getPoints(d, i)[0][1]\r\n              : yScaleGetter.call($$, d.id)(d.value);\r\n      };\r\n      line = config.axis_rotated\r\n          ? line.x(yValue).y(xValue)\r\n          : line.x(xValue).y(yValue);\r\n      if (!config.line_connectNull) {\r\n          line = line.defined(function (d) {\r\n              return d.value != null;\r\n          });\r\n      }\r\n      return function (d) {\r\n          var values = config.line_connectNull\r\n              ? $$.filterRemoveNull(d.values)\r\n              : d.values, x = isSub ? $$.subX : $$.x, y = yScaleGetter.call($$, d.id), x0 = 0, y0 = 0, path;\r\n          if ($$.isLineType(d)) {\r\n              if (config.data_regions[d.id]) {\r\n                  path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]);\r\n              }\r\n              else {\r\n                  if ($$.isStepType(d)) {\r\n                      values = $$.convertValuesToStep(values);\r\n                  }\r\n                  path = line.curve($$.getInterpolate(d))(values);\r\n              }\r\n          }\r\n          else {\r\n              if (values[0]) {\r\n                  x0 = x(values[0].x);\r\n                  y0 = y(values[0].value);\r\n              }\r\n              path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0;\r\n          }\r\n          return path ? path : 'M 0 0';\r\n      };\r\n  };\r\n  ChartInternal.prototype.generateGetLinePoints = function (lineIndices, isSub) {\r\n      // partial duplication of generateGetBarPoints\r\n      var $$ = this, config = $$.config, lineTargetsNum = lineIndices.__max__ + 1, x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub), y = $$.getShapeY(!!isSub), lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub), yScale = isSub ? $$.getSubYScale : $$.getYScale;\r\n      return function (d, i) {\r\n          var y0 = yScale.call($$, d.id)(0), offset = lineOffset(d, i) || y0, // offset is for stacked area chart\r\n          posX = x(d), posY = y(d);\r\n          // fix posY not to overflow opposite quadrant\r\n          if (config.axis_rotated) {\r\n              if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\r\n                  posY = y0;\r\n              }\r\n          }\r\n          // 1 point that marks the line position\r\n          return [\r\n              [posX, posY - (y0 - offset)],\r\n              [posX, posY - (y0 - offset)],\r\n              [posX, posY - (y0 - offset)],\r\n              [posX, posY - (y0 - offset)] // needed for compatibility\r\n          ];\r\n      };\r\n  };\r\n  ChartInternal.prototype.lineWithRegions = function (d, x, y, _regions) {\r\n      var $$ = this, config = $$.config, prev = -1, i, j, s = 'M', sWithRegion, xp, yp, dx, dy, dd, diff, diffx2, xOffset = $$.isCategorized() ? 0.5 : 0, xValue, yValue, regions = [];\r\n      function isWithinRegions(x, regions) {\r\n          var i;\r\n          for (i = 0; i < regions.length; i++) {\r\n              if (regions[i].start < x && x <= regions[i].end) {\r\n                  return true;\r\n              }\r\n          }\r\n          return false;\r\n      }\r\n      // Check start/end of regions\r\n      if (isDefined(_regions)) {\r\n          for (i = 0; i < _regions.length; i++) {\r\n              regions[i] = {};\r\n              if (isUndefined(_regions[i].start)) {\r\n                  regions[i].start = d[0].x;\r\n              }\r\n              else {\r\n                  regions[i].start = $$.isTimeSeries()\r\n                      ? $$.parseDate(_regions[i].start)\r\n                      : _regions[i].start;\r\n              }\r\n              if (isUndefined(_regions[i].end)) {\r\n                  regions[i].end = d[d.length - 1].x;\r\n              }\r\n              else {\r\n                  regions[i].end = $$.isTimeSeries()\r\n                      ? $$.parseDate(_regions[i].end)\r\n                      : _regions[i].end;\r\n              }\r\n          }\r\n      }\r\n      // Set scales\r\n      xValue = config.axis_rotated\r\n          ? function (d) {\r\n              return y(d.value);\r\n          }\r\n          : function (d) {\r\n              return x(d.x);\r\n          };\r\n      yValue = config.axis_rotated\r\n          ? function (d) {\r\n              return x(d.x);\r\n          }\r\n          : function (d) {\r\n              return y(d.value);\r\n          };\r\n      // Define svg generator function for region\r\n      function generateM(points) {\r\n          return ('M' +\r\n              points[0][0] +\r\n              ' ' +\r\n              points[0][1] +\r\n              ' ' +\r\n              points[1][0] +\r\n              ' ' +\r\n              points[1][1]);\r\n      }\r\n      if ($$.isTimeSeries()) {\r\n          sWithRegion = function (d0, d1, j, diff) {\r\n              var x0 = d0.x.getTime(), x_diff = d1.x - d0.x, xv0 = new Date(x0 + x_diff * j), xv1 = new Date(x0 + x_diff * (j + diff)), points;\r\n              if (config.axis_rotated) {\r\n                  points = [\r\n                      [y(yp(j)), x(xv0)],\r\n                      [y(yp(j + diff)), x(xv1)]\r\n                  ];\r\n              }\r\n              else {\r\n                  points = [\r\n                      [x(xv0), y(yp(j))],\r\n                      [x(xv1), y(yp(j + diff))]\r\n                  ];\r\n              }\r\n              return generateM(points);\r\n          };\r\n      }\r\n      else {\r\n          sWithRegion = function (d0, d1, j, diff) {\r\n              var points;\r\n              if (config.axis_rotated) {\r\n                  points = [\r\n                      [y(yp(j), true), x(xp(j))],\r\n                      [y(yp(j + diff), true), x(xp(j + diff))]\r\n                  ];\r\n              }\r\n              else {\r\n                  points = [\r\n                      [x(xp(j), true), y(yp(j))],\r\n                      [x(xp(j + diff), true), y(yp(j + diff))]\r\n                  ];\r\n              }\r\n              return generateM(points);\r\n          };\r\n      }\r\n      // Generate\r\n      for (i = 0; i < d.length; i++) {\r\n          // Draw as normal\r\n          if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) {\r\n              s += ' ' + xValue(d[i]) + ' ' + yValue(d[i]);\r\n          }\r\n          // Draw with region // TODO: Fix for horizotal charts\r\n          else {\r\n              xp = $$.getScale(d[i - 1].x + xOffset, d[i].x + xOffset, $$.isTimeSeries());\r\n              yp = $$.getScale(d[i - 1].value, d[i].value);\r\n              dx = x(d[i].x) - x(d[i - 1].x);\r\n              dy = y(d[i].value) - y(d[i - 1].value);\r\n              dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));\r\n              diff = 2 / dd;\r\n              diffx2 = diff * 2;\r\n              for (j = diff; j <= 1; j += diffx2) {\r\n                  s += sWithRegion(d[i - 1], d[i], j, diff);\r\n              }\r\n          }\r\n          prev = d[i].x;\r\n      }\r\n      return s;\r\n  };\r\n  ChartInternal.prototype.updateArea = function (durationForExit) {\r\n      var $$ = this, d3 = $$.d3;\r\n      var mainArea = $$.main\r\n          .selectAll('.' + CLASS.areas)\r\n          .selectAll('.' + CLASS.area)\r\n          .data($$.lineData.bind($$));\r\n      var mainAreaEnter = mainArea\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', $$.classArea.bind($$))\r\n          .style('fill', $$.color)\r\n          .style('opacity', function () {\r\n          $$.orgAreaOpacity = +d3.select(this).style('opacity');\r\n          return 0;\r\n      });\r\n      $$.mainArea = mainAreaEnter\r\n          .merge(mainArea)\r\n          .style('opacity', $$.orgAreaOpacity);\r\n      mainArea\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0);\r\n  };\r\n  ChartInternal.prototype.redrawArea = function (drawArea, withTransition, transition) {\r\n      return [\r\n          (withTransition ? this.mainArea.transition(transition) : this.mainArea)\r\n              .attr('d', drawArea)\r\n              .style('fill', this.color)\r\n              .style('opacity', this.orgAreaOpacity)\r\n      ];\r\n  };\r\n  ChartInternal.prototype.generateDrawArea = function (areaIndices, isSub) {\r\n      var $$ = this, config = $$.config, area = $$.d3.area(), getPoints = $$.generateGetAreaPoints(areaIndices, isSub), yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, xValue = function (d) {\r\n          return (isSub ? $$.subxx : $$.xx).call($$, d);\r\n      }, value0 = function (d, i) {\r\n          return config.data_groups.length > 0\r\n              ? getPoints(d, i)[0][1]\r\n              : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id));\r\n      }, value1 = function (d, i) {\r\n          return config.data_groups.length > 0\r\n              ? getPoints(d, i)[1][1]\r\n              : yScaleGetter.call($$, d.id)(d.value);\r\n      };\r\n      area = config.axis_rotated\r\n          ? area\r\n              .x0(value0)\r\n              .x1(value1)\r\n              .y(xValue)\r\n          : area\r\n              .x(xValue)\r\n              .y0(config.area_above ? 0 : value0)\r\n              .y1(value1);\r\n      if (!config.line_connectNull) {\r\n          area = area.defined(function (d) {\r\n              return d.value !== null;\r\n          });\r\n      }\r\n      return function (d) {\r\n          var values = config.line_connectNull\r\n              ? $$.filterRemoveNull(d.values)\r\n              : d.values, x0 = 0, y0 = 0, path;\r\n          if ($$.isAreaType(d)) {\r\n              if ($$.isStepType(d)) {\r\n                  values = $$.convertValuesToStep(values);\r\n              }\r\n              path = area.curve($$.getInterpolate(d))(values);\r\n          }\r\n          else {\r\n              if (values[0]) {\r\n                  x0 = $$.x(values[0].x);\r\n                  y0 = $$.getYScale(d.id)(values[0].value);\r\n              }\r\n              path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0;\r\n          }\r\n          return path ? path : 'M 0 0';\r\n      };\r\n  };\r\n  ChartInternal.prototype.getAreaBaseValue = function () {\r\n      return 0;\r\n  };\r\n  ChartInternal.prototype.generateGetAreaPoints = function (areaIndices, isSub) {\r\n      // partial duplication of generateGetBarPoints\r\n      var $$ = this, config = $$.config, areaTargetsNum = areaIndices.__max__ + 1, x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub), y = $$.getShapeY(!!isSub), areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub), yScale = isSub ? $$.getSubYScale : $$.getYScale;\r\n      return function (d, i) {\r\n          var y0 = yScale.call($$, d.id)(0), offset = areaOffset(d, i) || y0, // offset is for stacked area chart\r\n          posX = x(d), posY = y(d);\r\n          // fix posY not to overflow opposite quadrant\r\n          if (config.axis_rotated) {\r\n              if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\r\n                  posY = y0;\r\n              }\r\n          }\r\n          // 1 point that marks the area position\r\n          return [\r\n              [posX, offset],\r\n              [posX, posY - (y0 - offset)],\r\n              [posX, posY - (y0 - offset)],\r\n              [posX, offset] // needed for compatibility\r\n          ];\r\n      };\r\n  };\r\n  ChartInternal.prototype.updateCircle = function (cx, cy) {\r\n      var $$ = this;\r\n      var mainCircle = $$.main\r\n          .selectAll('.' + CLASS.circles)\r\n          .selectAll('.' + CLASS.circle)\r\n          .data($$.lineOrScatterOrStanfordData.bind($$));\r\n      var mainCircleEnter = mainCircle\r\n          .enter()\r\n          .append('circle')\r\n          .attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '')\r\n          .attr('class', $$.classCircle.bind($$))\r\n          .attr('cx', cx)\r\n          .attr('cy', cy)\r\n          .attr('r', $$.pointR.bind($$))\r\n          .style('color', $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color);\r\n      $$.mainCircle = mainCircleEnter\r\n          .merge(mainCircle)\r\n          .style('opacity', $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$));\r\n      mainCircle.exit().style('opacity', 0);\r\n  };\r\n  ChartInternal.prototype.redrawCircle = function (cx, cy, withTransition, transition) {\r\n      var $$ = this, selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle);\r\n      return [\r\n          (withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle)\r\n              .style('opacity', this.opacityForCircle.bind($$))\r\n              .style('color', $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color)\r\n              .attr('cx', cx)\r\n              .attr('cy', cy),\r\n          (withTransition ? selectedCircles.transition(transition) : selectedCircles)\r\n              .attr('cx', cx)\r\n              .attr('cy', cy)\r\n      ];\r\n  };\r\n  ChartInternal.prototype.circleX = function (d) {\r\n      return d.x || d.x === 0 ? this.x(d.x) : null;\r\n  };\r\n  ChartInternal.prototype.updateCircleY = function () {\r\n      var $$ = this, lineIndices, getPoints;\r\n      if ($$.config.data_groups.length > 0) {\r\n          (lineIndices = $$.getShapeIndices($$.isLineType)),\r\n              (getPoints = $$.generateGetLinePoints(lineIndices));\r\n          $$.circleY = function (d, i) {\r\n              return getPoints(d, i)[0][1];\r\n          };\r\n      }\r\n      else {\r\n          $$.circleY = function (d) {\r\n              return $$.getYScale(d.id)(d.value);\r\n          };\r\n      }\r\n  };\r\n  ChartInternal.prototype.getCircles = function (i, id) {\r\n      var $$ = this;\r\n      return (id\r\n          ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id))\r\n          : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''));\r\n  };\r\n  ChartInternal.prototype.expandCircles = function (i, id, reset) {\r\n      var $$ = this, r = $$.pointExpandedR.bind($$);\r\n      if (reset) {\r\n          $$.unexpandCircles();\r\n      }\r\n      $$.getCircles(i, id)\r\n          .classed(CLASS.EXPANDED, true)\r\n          .attr('r', r);\r\n  };\r\n  ChartInternal.prototype.unexpandCircles = function (i) {\r\n      var $$ = this, r = $$.pointR.bind($$);\r\n      $$.getCircles(i)\r\n          .filter(function () {\r\n          return $$.d3.select(this).classed(CLASS.EXPANDED);\r\n      })\r\n          .classed(CLASS.EXPANDED, false)\r\n          .attr('r', r);\r\n  };\r\n  ChartInternal.prototype.pointR = function (d) {\r\n      var $$ = this, config = $$.config;\r\n      return $$.isStepType(d)\r\n          ? 0\r\n          : isFunction(config.point_r)\r\n              ? config.point_r(d)\r\n              : config.point_r;\r\n  };\r\n  ChartInternal.prototype.pointExpandedR = function (d) {\r\n      var $$ = this, config = $$.config;\r\n      if (config.point_focus_expand_enabled) {\r\n          return isFunction(config.point_focus_expand_r)\r\n              ? config.point_focus_expand_r(d)\r\n              : config.point_focus_expand_r\r\n                  ? config.point_focus_expand_r\r\n                  : $$.pointR(d) * 1.75;\r\n      }\r\n      else {\r\n          return $$.pointR(d);\r\n      }\r\n  };\r\n  ChartInternal.prototype.pointSelectR = function (d) {\r\n      var $$ = this, config = $$.config;\r\n      return isFunction(config.point_select_r)\r\n          ? config.point_select_r(d)\r\n          : config.point_select_r\r\n              ? config.point_select_r\r\n              : $$.pointR(d) * 4;\r\n  };\r\n  ChartInternal.prototype.isWithinCircle = function (that, r) {\r\n      var d3 = this.d3, mouse = d3.mouse(that), d3_this = d3.select(that), cx = +d3_this.attr('cx'), cy = +d3_this.attr('cy');\r\n      return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r;\r\n  };\r\n  ChartInternal.prototype.isWithinStep = function (that, y) {\r\n      return Math.abs(y - this.d3.mouse(that)[1]) < 30;\r\n  };\n\n  ChartInternal.prototype.getCurrentWidth = function () {\r\n      var $$ = this, config = $$.config;\r\n      return config.size_width ? config.size_width : $$.getParentWidth();\r\n  };\r\n  ChartInternal.prototype.getCurrentHeight = function () {\r\n      var $$ = this, config = $$.config, h = config.size_height ? config.size_height : $$.getParentHeight();\r\n      return h > 0\r\n          ? h\r\n          : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1);\r\n  };\r\n  ChartInternal.prototype.getCurrentPaddingTop = function () {\r\n      var $$ = this, config = $$.config, padding = isValue(config.padding_top) ? config.padding_top : 0;\r\n      if ($$.title && $$.title.node()) {\r\n          padding += $$.getTitlePadding();\r\n      }\r\n      return padding;\r\n  };\r\n  ChartInternal.prototype.getCurrentPaddingBottom = function () {\r\n      var config = this.config;\r\n      return isValue(config.padding_bottom) ? config.padding_bottom : 0;\r\n  };\r\n  ChartInternal.prototype.getCurrentPaddingLeft = function (withoutRecompute) {\r\n      var $$ = this, config = $$.config;\r\n      if (isValue(config.padding_left)) {\r\n          return config.padding_left;\r\n      }\r\n      else if (config.axis_rotated) {\r\n          return !config.axis_x_show || config.axis_x_inner\r\n              ? 1\r\n              : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40);\r\n      }\r\n      else if (!config.axis_y_show || config.axis_y_inner) {\r\n          // && !config.axis_rotated\r\n          return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1;\r\n      }\r\n      else {\r\n          return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute));\r\n      }\r\n  };\r\n  ChartInternal.prototype.getCurrentPaddingRight = function () {\r\n      var $$ = this, config = $$.config, padding = 0, defaultPadding = 10, legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0;\r\n      if (isValue(config.padding_right)) {\r\n          padding = config.padding_right + 1; // 1 is needed not to hide tick line\r\n      }\r\n      else if (config.axis_rotated) {\r\n          padding = defaultPadding + legendWidthOnRight;\r\n      }\r\n      else if (!config.axis_y2_show || config.axis_y2_inner) {\r\n          // && !config.axis_rotated\r\n          padding =\r\n              2 +\r\n                  legendWidthOnRight +\r\n                  ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0);\r\n      }\r\n      else {\r\n          padding = ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight;\r\n      }\r\n      if ($$.colorScale && $$.colorScale.node()) {\r\n          padding += $$.getColorScalePadding();\r\n      }\r\n      return padding;\r\n  };\r\n  ChartInternal.prototype.getParentRectValue = function (key) {\r\n      var parent = this.selectChart.node(), v;\r\n      while (parent && parent.tagName !== 'BODY') {\r\n          try {\r\n              v = parent.getBoundingClientRect()[key];\r\n          }\r\n          catch (e) {\r\n              if (key === 'width') {\r\n                  // In IE in certain cases getBoundingClientRect\r\n                  // will cause an \"unspecified error\"\r\n                  v = parent.offsetWidth;\r\n              }\r\n          }\r\n          if (v) {\r\n              break;\r\n          }\r\n          parent = parent.parentNode;\r\n      }\r\n      return v;\r\n  };\r\n  ChartInternal.prototype.getParentWidth = function () {\r\n      return this.getParentRectValue('width');\r\n  };\r\n  ChartInternal.prototype.getParentHeight = function () {\r\n      var h = this.selectChart.style('height');\r\n      return h.indexOf('px') > 0 ? +h.replace('px', '') : 0;\r\n  };\r\n  ChartInternal.prototype.getSvgLeft = function (withoutRecompute) {\r\n      var $$ = this, config = $$.config, hasLeftAxisRect = config.axis_rotated || (!config.axis_rotated && !config.axis_y_inner), leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY, leftAxis = $$.main.select('.' + leftAxisClass).node(), svgRect = leftAxis && hasLeftAxisRect\r\n          ? leftAxis.getBoundingClientRect()\r\n          : { right: 0 }, chartRect = $$.selectChart.node().getBoundingClientRect(), hasArc = $$.hasArcType(), svgLeft = svgRect.right -\r\n          chartRect.left -\r\n          (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute));\r\n      return svgLeft > 0 ? svgLeft : 0;\r\n  };\r\n  ChartInternal.prototype.getAxisWidthByAxisId = function (id, withoutRecompute) {\r\n      var $$ = this, position = $$.axis.getLabelPositionById(id);\r\n      return ($$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40));\r\n  };\r\n  ChartInternal.prototype.getHorizontalAxisHeight = function (axisId, isSubchart) {\r\n      var $$ = this, config = $$.config, h = 30;\r\n      if (axisId === 'x' && !(isDefined(isSubchart) && isSubchart ? config.subchart_axis_x_show : config.axis_x_show)) {\r\n          return 8;\r\n      }\r\n      if (axisId === 'x' && config.axis_x_height) {\r\n          return config.axis_x_height;\r\n      }\r\n      if (axisId === 'y' && !config.axis_y_show) {\r\n          return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1;\r\n      }\r\n      if (axisId === 'y2' && !config.axis_y2_show) {\r\n          return $$.rotated_padding_top;\r\n      }\r\n      // Calculate x axis height when tick rotated\r\n      if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {\r\n          h =\r\n              30 +\r\n                  $$.axis.getMaxTickWidth(axisId) *\r\n                      Math.cos((Math.PI * (90 - Math.abs(config.axis_x_tick_rotate))) / 180);\r\n      }\r\n      // Calculate y axis height when tick rotated\r\n      if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) {\r\n          h =\r\n              30 +\r\n                  $$.axis.getMaxTickWidth(axisId) *\r\n                      Math.cos((Math.PI * (90 - Math.abs(config.axis_y_tick_rotate))) / 180);\r\n      }\r\n      return (h +\r\n          ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) +\r\n          (axisId === 'y2' ? -10 : 0));\r\n  };\n\n  ChartInternal.prototype.initBrush = function (scale) {\r\n      var $$ = this, d3 = $$.d3;\r\n      // TODO: dynamically change brushY/brushX according to axis_rotated.\r\n      $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX())\r\n          .on('brush', function () {\r\n          var event = d3.event.sourceEvent;\r\n          if (event && event.type === 'zoom') {\r\n              return;\r\n          }\r\n          $$.redrawForBrush();\r\n      })\r\n          .on('end', function () {\r\n          var event = d3.event.sourceEvent;\r\n          if (event && event.type === 'zoom') {\r\n              return;\r\n          }\r\n          if ($$.brush.empty() && event && event.type !== 'end') {\r\n              $$.brush.clear();\r\n          }\r\n      });\r\n      $$.brush.updateExtent = function () {\r\n          var range = this.scale.range(), extent;\r\n          if ($$.config.axis_rotated) {\r\n              extent = [\r\n                  [0, range[0]],\r\n                  [$$.width2, range[1]]\r\n              ];\r\n          }\r\n          else {\r\n              extent = [\r\n                  [range[0], 0],\r\n                  [range[1], $$.height2]\r\n              ];\r\n          }\r\n          this.extent(extent);\r\n          return this;\r\n      };\r\n      $$.brush.updateScale = function (scale) {\r\n          this.scale = scale;\r\n          return this;\r\n      };\r\n      $$.brush.update = function (scale) {\r\n          this.updateScale(scale || $$.subX).updateExtent();\r\n          $$.context.select('.' + CLASS.brush).call(this);\r\n      };\r\n      $$.brush.clear = function () {\r\n          $$.context.select('.' + CLASS.brush).call($$.brush.move, null);\r\n      };\r\n      $$.brush.selection = function () {\r\n          return d3.brushSelection($$.context.select('.' + CLASS.brush).node());\r\n      };\r\n      $$.brush.selectionAsValue = function (selectionAsValue, withTransition) {\r\n          var selection, brush;\r\n          if (selectionAsValue) {\r\n              if ($$.context) {\r\n                  selection = [\r\n                      this.scale(selectionAsValue[0]),\r\n                      this.scale(selectionAsValue[1])\r\n                  ];\r\n                  brush = $$.context.select('.' + CLASS.brush);\r\n                  if (withTransition) {\r\n                      brush = brush.transition();\r\n                  }\r\n                  $$.brush.move(brush, selection);\r\n              }\r\n              return [];\r\n          }\r\n          selection = $$.brush.selection() || [0, 0];\r\n          return [this.scale.invert(selection[0]), this.scale.invert(selection[1])];\r\n      };\r\n      $$.brush.empty = function () {\r\n          var selection = $$.brush.selection();\r\n          return !selection || selection[0] === selection[1];\r\n      };\r\n      return $$.brush.updateScale(scale);\r\n  };\r\n  ChartInternal.prototype.initSubchart = function () {\r\n      var $$ = this, config = $$.config, context = ($$.context = $$.svg\r\n          .append('g')\r\n          .attr('transform', $$.getTranslate('context')));\r\n      // set style\r\n      context.style('visibility', 'visible');\r\n      // Define g for chart area\r\n      context\r\n          .append('g')\r\n          .attr('clip-path', $$.clipPathForSubchart)\r\n          .attr('class', CLASS.chart);\r\n      // Define g for bar chart area\r\n      context\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.chartBars);\r\n      // Define g for line chart area\r\n      context\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.chartLines);\r\n      // Add extent rect for Brush\r\n      context\r\n          .append('g')\r\n          .attr('clip-path', $$.clipPath)\r\n          .attr('class', CLASS.brush);\r\n      // ATTENTION: This must be called AFTER chart added\r\n      // Add Axis\r\n      $$.axes.subx = context\r\n          .append('g')\r\n          .attr('class', CLASS.axisX)\r\n          .attr('transform', $$.getTranslate('subx'))\r\n          .attr('clip-path', config.axis_rotated ? '' : $$.clipPathForXAxis)\r\n          .style('visibility', config.subchart_axis_x_show ? 'visible' : 'hidden');\r\n  };\r\n  ChartInternal.prototype.initSubchartBrush = function () {\r\n      var $$ = this;\r\n      // Add extent rect for Brush\r\n      $$.initBrush($$.subX).updateExtent();\r\n      $$.context.select('.' + CLASS.brush).call($$.brush);\r\n  };\r\n  ChartInternal.prototype.updateTargetsForSubchart = function (targets) {\r\n      var $$ = this, context = $$.context, config = $$.config, contextLineEnter, contextLine, contextBarEnter, contextBar, classChartBar = $$.classChartBar.bind($$), classBars = $$.classBars.bind($$), classChartLine = $$.classChartLine.bind($$), classLines = $$.classLines.bind($$), classAreas = $$.classAreas.bind($$);\r\n      //-- Bar --//\r\n      contextBar = context\r\n          .select('.' + CLASS.chartBars)\r\n          .selectAll('.' + CLASS.chartBar)\r\n          .data(targets);\r\n      contextBarEnter = contextBar\r\n          .enter()\r\n          .append('g')\r\n          .style('opacity', 0);\r\n      contextBarEnter.merge(contextBar).attr('class', classChartBar);\r\n      // Bars for each data\r\n      contextBarEnter.append('g').attr('class', classBars);\r\n      //-- Line --//\r\n      contextLine = context\r\n          .select('.' + CLASS.chartLines)\r\n          .selectAll('.' + CLASS.chartLine)\r\n          .data(targets);\r\n      contextLineEnter = contextLine\r\n          .enter()\r\n          .append('g')\r\n          .style('opacity', 0);\r\n      contextLineEnter.merge(contextLine).attr('class', classChartLine);\r\n      // Lines for each data\r\n      contextLineEnter.append('g').attr('class', classLines);\r\n      // Area\r\n      contextLineEnter.append('g').attr('class', classAreas);\r\n      //-- Brush --//\r\n      context\r\n          .selectAll('.' + CLASS.brush + ' rect')\r\n          .attr(config.axis_rotated ? 'width' : 'height', config.axis_rotated ? $$.width2 : $$.height2);\r\n  };\r\n  ChartInternal.prototype.updateBarForSubchart = function (durationForExit) {\r\n      var $$ = this;\r\n      var contextBar = $$.context\r\n          .selectAll('.' + CLASS.bars)\r\n          .selectAll('.' + CLASS.bar)\r\n          .data($$.barData.bind($$));\r\n      var contextBarEnter = contextBar\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', $$.classBar.bind($$))\r\n          .style('stroke', 'none')\r\n          .style('fill', $$.color);\r\n      contextBar\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      $$.contextBar = contextBarEnter\r\n          .merge(contextBar)\r\n          .style('opacity', $$.initialOpacity.bind($$));\r\n  };\r\n  ChartInternal.prototype.redrawBarForSubchart = function (drawBarOnSub, withTransition, duration) {\r\n      (withTransition\r\n          ? this.contextBar.transition(Math.random().toString()).duration(duration)\r\n          : this.contextBar)\r\n          .attr('d', drawBarOnSub)\r\n          .style('opacity', 1);\r\n  };\r\n  ChartInternal.prototype.updateLineForSubchart = function (durationForExit) {\r\n      var $$ = this;\r\n      var contextLine = $$.context\r\n          .selectAll('.' + CLASS.lines)\r\n          .selectAll('.' + CLASS.line)\r\n          .data($$.lineData.bind($$));\r\n      var contextLineEnter = contextLine\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', $$.classLine.bind($$))\r\n          .style('stroke', $$.color);\r\n      contextLine\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      $$.contextLine = contextLineEnter\r\n          .merge(contextLine)\r\n          .style('opacity', $$.initialOpacity.bind($$));\r\n  };\r\n  ChartInternal.prototype.redrawLineForSubchart = function (drawLineOnSub, withTransition, duration) {\r\n      (withTransition\r\n          ? this.contextLine.transition(Math.random().toString()).duration(duration)\r\n          : this.contextLine)\r\n          .attr('d', drawLineOnSub)\r\n          .style('opacity', 1);\r\n  };\r\n  ChartInternal.prototype.updateAreaForSubchart = function (durationForExit) {\r\n      var $$ = this, d3 = $$.d3;\r\n      var contextArea = $$.context\r\n          .selectAll('.' + CLASS.areas)\r\n          .selectAll('.' + CLASS.area)\r\n          .data($$.lineData.bind($$));\r\n      var contextAreaEnter = contextArea\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', $$.classArea.bind($$))\r\n          .style('fill', $$.color)\r\n          .style('opacity', function () {\r\n          $$.orgAreaOpacity = +d3.select(this).style('opacity');\r\n          return 0;\r\n      });\r\n      contextArea\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      $$.contextArea = contextAreaEnter.merge(contextArea).style('opacity', 0);\r\n  };\r\n  ChartInternal.prototype.redrawAreaForSubchart = function (drawAreaOnSub, withTransition, duration) {\r\n      (withTransition\r\n          ? this.contextArea.transition(Math.random().toString()).duration(duration)\r\n          : this.contextArea)\r\n          .attr('d', drawAreaOnSub)\r\n          .style('fill', this.color)\r\n          .style('opacity', this.orgAreaOpacity);\r\n  };\r\n  ChartInternal.prototype.redrawSubchart = function (withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices) {\r\n      var $$ = this, d3 = $$.d3, drawAreaOnSub, drawBarOnSub, drawLineOnSub;\r\n      // reflect main chart to extent on subchart if zoomed\r\n      if (d3.event && d3.event.type === 'zoom') {\r\n          $$.brush.selectionAsValue($$.x.orgDomain());\r\n      }\r\n      // update subchart elements if needed\r\n      if (withSubchart) {\r\n          // extent rect\r\n          if (!$$.brush.empty()) {\r\n              $$.brush.selectionAsValue($$.x.orgDomain());\r\n          }\r\n          // setup drawer - MEMO: this must be called after axis updated\r\n          drawAreaOnSub = $$.generateDrawArea(areaIndices, true);\r\n          drawBarOnSub = $$.generateDrawBar(barIndices, true);\r\n          drawLineOnSub = $$.generateDrawLine(lineIndices, true);\r\n          $$.updateBarForSubchart(duration);\r\n          $$.updateLineForSubchart(duration);\r\n          $$.updateAreaForSubchart(duration);\r\n          $$.redrawBarForSubchart(drawBarOnSub, duration, duration);\r\n          $$.redrawLineForSubchart(drawLineOnSub, duration, duration);\r\n          $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration);\r\n      }\r\n  };\r\n  ChartInternal.prototype.redrawForBrush = function () {\r\n      var $$ = this, x = $$.x, d3 = $$.d3, s;\r\n      $$.redraw({\r\n          withTransition: false,\r\n          withY: $$.config.zoom_rescale,\r\n          withSubchart: false,\r\n          withUpdateXDomain: true,\r\n          withEventRect: false,\r\n          withDimension: false\r\n      });\r\n      // update zoom transation binded to event rect\r\n      s = d3.event.selection || $$.brush.scale.range();\r\n      $$.main\r\n          .select('.' + CLASS.eventRect)\r\n          .call($$.zoom.transform, d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0));\r\n      $$.config.subchart_onbrush.call($$.api, x.orgDomain());\r\n  };\r\n  ChartInternal.prototype.transformContext = function (withTransition, transitions) {\r\n      var $$ = this, subXAxis;\r\n      if (transitions && transitions.axisSubX) {\r\n          subXAxis = transitions.axisSubX;\r\n      }\r\n      else {\r\n          subXAxis = $$.context.select('.' + CLASS.axisX);\r\n          if (withTransition) {\r\n              subXAxis = subXAxis.transition();\r\n          }\r\n      }\r\n      $$.context.attr('transform', $$.getTranslate('context'));\r\n      subXAxis.attr('transform', $$.getTranslate('subx'));\r\n  };\r\n  ChartInternal.prototype.getDefaultSelection = function () {\r\n      var $$ = this, config = $$.config, selection = isFunction(config.axis_x_selection)\r\n          ? config.axis_x_selection($$.getXDomain($$.data.targets))\r\n          : config.axis_x_selection;\r\n      if ($$.isTimeSeries()) {\r\n          selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])];\r\n      }\r\n      return selection;\r\n  };\r\n  ChartInternal.prototype.removeSubchart = function () {\r\n      var $$ = this;\r\n      $$.brush = null;\r\n      $$.context.remove();\r\n      $$.context = null;\r\n  };\n\n  ChartInternal.prototype.initText = function () {\r\n      var $$ = this;\r\n      $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.chartTexts);\r\n      $$.mainText = $$.d3.selectAll([]);\r\n  };\r\n  ChartInternal.prototype.updateTargetsForText = function (targets) {\r\n      var $$ = this, classChartText = $$.classChartText.bind($$), classTexts = $$.classTexts.bind($$), classFocus = $$.classFocus.bind($$);\r\n      var mainText = $$.main\r\n          .select('.' + CLASS.chartTexts)\r\n          .selectAll('.' + CLASS.chartText)\r\n          .data(targets);\r\n      var mainTextEnter = mainText\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', classChartText)\r\n          .style('opacity', 0)\r\n          .style('pointer-events', 'none');\r\n      mainTextEnter.append('g').attr('class', classTexts);\r\n      mainTextEnter.merge(mainText).attr('class', function (d) {\r\n          return classChartText(d) + classFocus(d);\r\n      });\r\n  };\r\n  ChartInternal.prototype.updateText = function (xForText, yForText, durationForExit) {\r\n      var $$ = this, config = $$.config, barOrLineData = $$.barOrLineData.bind($$), classText = $$.classText.bind($$);\r\n      var mainText = $$.main\r\n          .selectAll('.' + CLASS.texts)\r\n          .selectAll('.' + CLASS.text)\r\n          .data(barOrLineData);\r\n      var mainTextEnter = mainText\r\n          .enter()\r\n          .append('text')\r\n          .attr('class', classText)\r\n          .attr('text-anchor', function (d) {\r\n          return config.axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle';\r\n      })\r\n          .style('stroke', 'none')\r\n          .attr('x', xForText)\r\n          .attr('y', yForText)\r\n          .style('fill', function (d) {\r\n          return $$.color(d);\r\n      })\r\n          .style('fill-opacity', 0);\r\n      $$.mainText = mainTextEnter.merge(mainText).text(function (d, i, j) {\r\n          return $$.dataLabelFormat(d.id)(d.value, d.id, i, j);\r\n      });\r\n      mainText\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('fill-opacity', 0)\r\n          .remove();\r\n  };\r\n  ChartInternal.prototype.redrawText = function (xForText, yForText, forFlow, withTransition, transition) {\r\n      return [\r\n          (withTransition ? this.mainText.transition(transition) : this.mainText)\r\n              .attr('x', xForText)\r\n              .attr('y', yForText)\r\n              .style('fill', this.color)\r\n              .style('fill-opacity', forFlow ? 0 : this.opacityForText.bind(this))\r\n      ];\r\n  };\r\n  ChartInternal.prototype.getTextRect = function (text, cls, element) {\r\n      var dummy = this.d3\r\n          .select('body')\r\n          .append('div')\r\n          .classed('c3', true), svg = dummy\r\n          .append('svg')\r\n          .style('visibility', 'hidden')\r\n          .style('position', 'fixed')\r\n          .style('top', 0)\r\n          .style('left', 0), font = this.d3.select(element).style('font'), rect;\r\n      svg\r\n          .selectAll('.dummy')\r\n          .data([text])\r\n          .enter()\r\n          .append('text')\r\n          .classed(cls ? cls : '', true)\r\n          .style('font', font)\r\n          .text(text)\r\n          .each(function () {\r\n          rect = getBBox(this);\r\n      });\r\n      dummy.remove();\r\n      return rect;\r\n  };\r\n  ChartInternal.prototype.generateXYForText = function (areaIndices, barIndices, lineIndices, forX) {\r\n      var $$ = this, getAreaPoints = $$.generateGetAreaPoints(areaIndices, false), getBarPoints = $$.generateGetBarPoints(barIndices, false), getLinePoints = $$.generateGetLinePoints(lineIndices, false), getter = forX ? $$.getXForText : $$.getYForText;\r\n      return function (d, i) {\r\n          var getPoints = $$.isAreaType(d)\r\n              ? getAreaPoints\r\n              : $$.isBarType(d)\r\n                  ? getBarPoints\r\n                  : getLinePoints;\r\n          return getter.call($$, getPoints(d, i), d, this);\r\n      };\r\n  };\r\n  ChartInternal.prototype.getXForText = function (points, d, textElement) {\r\n      var $$ = this, box = getBBox(textElement), xPos, padding;\r\n      if ($$.config.axis_rotated) {\r\n          padding = $$.isBarType(d) ? 4 : 6;\r\n          xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1);\r\n      }\r\n      else {\r\n          xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0];\r\n      }\r\n      // show labels regardless of the domain if value is null\r\n      if (d.value === null) {\r\n          if (xPos > $$.width) {\r\n              xPos = $$.width - box.width;\r\n          }\r\n          else if (xPos < 0) {\r\n              xPos = 4;\r\n          }\r\n      }\r\n      return xPos;\r\n  };\r\n  ChartInternal.prototype.getYForText = function (points, d, textElement) {\r\n      var $$ = this, box = getBBox(textElement), yPos;\r\n      if ($$.config.axis_rotated) {\r\n          yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2;\r\n      }\r\n      else {\r\n          yPos = points[2][1];\r\n          if (d.value < 0 || (d.value === 0 && !$$.hasPositiveValue)) {\r\n              yPos += box.height;\r\n              if ($$.isBarType(d) && $$.isSafari()) {\r\n                  yPos -= 3;\r\n              }\r\n              else if (!$$.isBarType(d) && $$.isChrome()) {\r\n                  yPos += 3;\r\n              }\r\n          }\r\n          else {\r\n              yPos += $$.isBarType(d) ? -3 : -6;\r\n          }\r\n      }\r\n      // show labels regardless of the domain if value is null\r\n      if (d.value === null && !$$.config.axis_rotated) {\r\n          if (yPos < box.height) {\r\n              yPos = box.height;\r\n          }\r\n          else if (yPos > this.height) {\r\n              yPos = this.height - 4;\r\n          }\r\n      }\r\n      return yPos;\r\n  };\n\n  ChartInternal.prototype.initTitle = function () {\r\n      var $$ = this;\r\n      $$.title = $$.svg\r\n          .append('text')\r\n          .text($$.config.title_text)\r\n          .attr('class', $$.CLASS.title);\r\n  };\r\n  ChartInternal.prototype.redrawTitle = function () {\r\n      var $$ = this;\r\n      $$.title.attr('x', $$.xForTitle.bind($$)).attr('y', $$.yForTitle.bind($$));\r\n  };\r\n  ChartInternal.prototype.xForTitle = function () {\r\n      var $$ = this, config = $$.config, position = config.title_position || 'left', x;\r\n      if (position.indexOf('right') >= 0) {\r\n          x =\r\n              $$.currentWidth -\r\n                  $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width -\r\n                  config.title_padding.right;\r\n      }\r\n      else if (position.indexOf('center') >= 0) {\r\n          x = Math.max(($$.currentWidth -\r\n              $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width) /\r\n              2, 0);\r\n      }\r\n      else {\r\n          // left\r\n          x = config.title_padding.left;\r\n      }\r\n      return x;\r\n  };\r\n  ChartInternal.prototype.yForTitle = function () {\r\n      var $$ = this;\r\n      return ($$.config.title_padding.top +\r\n          $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node())\r\n              .height);\r\n  };\r\n  ChartInternal.prototype.getTitlePadding = function () {\r\n      var $$ = this;\r\n      return $$.yForTitle() + $$.config.title_padding.bottom;\r\n  };\n\n  function powerOfTen(d) {\r\n      return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1;\r\n  }\r\n  ChartInternal.prototype.drawColorScale = function () {\r\n      var $$ = this, d3 = $$.d3, config = $$.config, target = $$.data.targets[0], barWidth, barHeight, axis, points, legendAxis, axisScale, inverseScale, height;\r\n      barWidth = !isNaN(config.stanford_scaleWidth)\r\n          ? config.stanford_scaleWidth\r\n          : 20;\r\n      barHeight = 5;\r\n      if (barHeight < 0 || barWidth < 0) {\r\n          throw Error(\"Colorscale's barheight and barwidth must be greater than 0.\");\r\n      }\r\n      height =\r\n          $$.height - config.stanford_padding.bottom - config.stanford_padding.top;\r\n      points = d3.range(config.stanford_padding.bottom, height, barHeight);\r\n      inverseScale = d3\r\n          .scaleSequential(target.colors)\r\n          .domain([points[points.length - 1], points[0]]);\r\n      if ($$.colorScale) {\r\n          $$.colorScale.remove();\r\n      }\r\n      $$.colorScale = $$.svg\r\n          .append('g')\r\n          .attr('width', 50)\r\n          .attr('height', height)\r\n          .attr('class', CLASS.colorScale);\r\n      $$.colorScale\r\n          .append('g')\r\n          .attr('transform', \"translate(0, \" + config.stanford_padding.top + \")\")\r\n          .selectAll('bars')\r\n          .data(points)\r\n          .enter()\r\n          .append('rect')\r\n          .attr('y', function (d, i) { return i * barHeight; })\r\n          .attr('x', 0)\r\n          .attr('width', barWidth)\r\n          .attr('height', barHeight)\r\n          .attr('fill', function (d) {\r\n          return inverseScale(d);\r\n      });\r\n      // Legend Axis\r\n      axisScale = d3\r\n          .scaleLog()\r\n          .domain([target.minEpochs, target.maxEpochs])\r\n          .range([\r\n          points[0] +\r\n              config.stanford_padding.top +\r\n              points[points.length - 1] +\r\n              barHeight -\r\n              1,\r\n          points[0] + config.stanford_padding.top\r\n      ]);\r\n      legendAxis = d3.axisRight(axisScale);\r\n      if (config.stanford_scaleFormat === 'pow10') {\r\n          legendAxis.tickValues([1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]);\r\n      }\r\n      else if (isFunction(config.stanford_scaleFormat)) {\r\n          legendAxis.tickFormat(config.stanford_scaleFormat);\r\n      }\r\n      else {\r\n          legendAxis.tickFormat(d3.format('d'));\r\n      }\r\n      if (isFunction(config.stanford_scaleValues)) {\r\n          legendAxis.tickValues(config.stanford_scaleValues(target.minEpochs, target.maxEpochs));\r\n      }\r\n      // Draw Axis\r\n      axis = $$.colorScale\r\n          .append('g')\r\n          .attr('class', 'legend axis')\r\n          .attr('transform', \"translate(\" + barWidth + \",0)\")\r\n          .call(legendAxis);\r\n      if (config.stanford_scaleFormat === 'pow10') {\r\n          axis\r\n              .selectAll('.tick text')\r\n              .text(null)\r\n              .filter(powerOfTen)\r\n              .text(10)\r\n              .append('tspan')\r\n              .attr('dy', '-.7em') // https://bl.ocks.org/mbostock/6738229\r\n              .text(function (d) {\r\n              return Math.round(Math.log(d) / Math.LN10);\r\n          });\r\n      }\r\n      $$.colorScale.attr('transform', \"translate(\" + ($$.currentWidth - $$.xForColorScale()) + \", 0)\");\r\n  };\r\n  ChartInternal.prototype.xForColorScale = function () {\r\n      var $$ = this;\r\n      return $$.config.stanford_padding.right + getBBox($$.colorScale.node()).width;\r\n  };\r\n  ChartInternal.prototype.getColorScalePadding = function () {\r\n      var $$ = this;\r\n      return $$.xForColorScale() + $$.config.stanford_padding.left + 20;\r\n  };\n\n  ChartInternal.prototype.isStanfordGraphType = function () {\r\n      var $$ = this;\r\n      return $$.config.data_type === 'stanford';\r\n  };\r\n  ChartInternal.prototype.initStanfordData = function () {\r\n      var $$ = this, d3 = $$.d3, config = $$.config, target = $$.data.targets[0], epochs, maxEpochs, minEpochs;\r\n      // Make larger values appear on top\r\n      target.values.sort(compareEpochs);\r\n      // Get array of epochs\r\n      epochs = target.values.map(function (a) { return a.epochs; });\r\n      minEpochs = !isNaN(config.stanford_scaleMin)\r\n          ? config.stanford_scaleMin\r\n          : d3.min(epochs);\r\n      maxEpochs = !isNaN(config.stanford_scaleMax)\r\n          ? config.stanford_scaleMax\r\n          : d3.max(epochs);\r\n      if (minEpochs > maxEpochs) {\r\n          throw Error('Number of minEpochs has to be smaller than maxEpochs');\r\n      }\r\n      target.colors = isFunction(config.stanford_colors)\r\n          ? config.stanford_colors\r\n          : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5));\r\n      target.colorscale = d3\r\n          .scaleSequentialLog(target.colors)\r\n          .domain([minEpochs, maxEpochs]);\r\n      target.minEpochs = minEpochs;\r\n      target.maxEpochs = maxEpochs;\r\n  };\r\n  ChartInternal.prototype.getStanfordPointColor = function (d) {\r\n      var $$ = this, target = $$.data.targets[0];\r\n      return target.colorscale(d.epochs);\r\n  };\r\n  // http://jsfiddle.net/Xotic750/KtzLq/\r\n  ChartInternal.prototype.getCentroid = function (points) {\r\n      var area = getRegionArea(points);\r\n      var x = 0, y = 0, i, j, f, point1, point2;\r\n      for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {\r\n          point1 = points[i];\r\n          point2 = points[j];\r\n          f = point1.x * point2.y - point2.x * point1.y;\r\n          x += (point1.x + point2.x) * f;\r\n          y += (point1.y + point2.y) * f;\r\n      }\r\n      f = area * 6;\r\n      return {\r\n          x: x / f,\r\n          y: y / f\r\n      };\r\n  };\r\n  ChartInternal.prototype.getStanfordTooltipTitle = function (d) {\r\n      var $$ = this, labelX = $$.axis.getLabelText('x'), labelY = $$.axis.getLabelText('y');\r\n      return \"\\n      <tr><th>\" + (labelX ? sanitise(labelX) : 'x') + \"</th><th class='value'>\" + d.x + \"</th></tr>\\n      <tr><th>\" + (labelY ? sanitise(labelY) : 'y') + \"</th><th class='value'>\" + d.value + \"</th></tr>\\n    \";\r\n  };\r\n  ChartInternal.prototype.countEpochsInRegion = function (region) {\r\n      var $$ = this, target = $$.data.targets[0], total, count;\r\n      total = target.values.reduce(function (accumulator, currentValue) { return accumulator + Number(currentValue.epochs); }, 0);\r\n      count = target.values.reduce(function (accumulator, currentValue) {\r\n          if (pointInRegion(currentValue, region)) {\r\n              return accumulator + Number(currentValue.epochs);\r\n          }\r\n          return accumulator;\r\n      }, 0);\r\n      return {\r\n          value: count,\r\n          percentage: count !== 0 ? ((count / total) * 100).toFixed(1) : 0\r\n      };\r\n  };\r\n  var getRegionArea = function (points) {\r\n      // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript\r\n      var area = 0, i, j, point1, point2;\r\n      for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {\r\n          point1 = points[i];\r\n          point2 = points[j];\r\n          area += point1.x * point2.y;\r\n          area -= point1.y * point2.x;\r\n      }\r\n      area /= 2;\r\n      return area;\r\n  };\r\n  var pointInRegion = function (point, region) {\r\n      // thanks to: http://bl.ocks.org/bycoffe/5575904\r\n      // ray-casting algorithm based on\r\n      // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html\r\n      var xi, yi, yj, xj, intersect, x = point.x, y = point.value, inside = false;\r\n      for (var i = 0, j = region.length - 1; i < region.length; j = i++) {\r\n          xi = region[i].x;\r\n          yi = region[i].y;\r\n          xj = region[j].x;\r\n          yj = region[j].y;\r\n          intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;\r\n          if (intersect) {\r\n              inside = !inside;\r\n          }\r\n      }\r\n      return inside;\r\n  };\r\n  var compareEpochs = function (a, b) {\r\n      if (a.epochs < b.epochs) {\r\n          return -1;\r\n      }\r\n      if (a.epochs > b.epochs) {\r\n          return 1;\r\n      }\r\n      return 0;\r\n  };\n\n  ChartInternal.prototype.initStanfordElements = function () {\r\n      var $$ = this;\r\n      // Avoid blocking eventRect\r\n      $$.stanfordElements = $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.stanfordElements);\r\n      $$.stanfordElements.append('g').attr('class', CLASS.stanfordLines);\r\n      $$.stanfordElements.append('g').attr('class', CLASS.stanfordTexts);\r\n      $$.stanfordElements.append('g').attr('class', CLASS.stanfordRegions);\r\n  };\r\n  ChartInternal.prototype.updateStanfordElements = function (duration) {\r\n      var $$ = this, main = $$.main, config = $$.config, stanfordLine, stanfordLineEnter, stanfordRegion, stanfordRegionEnter, stanfordText, stanfordTextEnter, xvCustom = $$.xvCustom.bind($$), yvCustom = $$.yvCustom.bind($$), countPointsInRegion = $$.countEpochsInRegion.bind($$);\r\n      // Stanford-Lines\r\n      stanfordLine = main\r\n          .select('.' + CLASS.stanfordLines)\r\n          .style('shape-rendering', 'geometricprecision')\r\n          .selectAll('.' + CLASS.stanfordLine)\r\n          .data(config.stanford_lines);\r\n      // enter\r\n      stanfordLineEnter = stanfordLine\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', function (d) {\r\n          return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : '');\r\n      });\r\n      stanfordLineEnter\r\n          .append('line')\r\n          .attr('x1', function (d) {\r\n          return config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1');\r\n      })\r\n          .attr('x2', function (d) {\r\n          return config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2');\r\n      })\r\n          .attr('y1', function (d) {\r\n          return config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1');\r\n      })\r\n          .attr('y2', function (d) {\r\n          return config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2');\r\n      })\r\n          .style('opacity', 0);\r\n      // update\r\n      $$.stanfordLines = stanfordLineEnter.merge(stanfordLine);\r\n      $$.stanfordLines\r\n          .select('line')\r\n          .transition()\r\n          .duration(duration)\r\n          .attr('x1', function (d) {\r\n          return config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1');\r\n      })\r\n          .attr('x2', function (d) {\r\n          return config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2');\r\n      })\r\n          .attr('y1', function (d) {\r\n          return config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1');\r\n      })\r\n          .attr('y2', function (d) {\r\n          return config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2');\r\n      })\r\n          .style('opacity', 1);\r\n      // exit\r\n      stanfordLine\r\n          .exit()\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      // Stanford-Text\r\n      stanfordText = main\r\n          .select('.' + CLASS.stanfordTexts)\r\n          .selectAll('.' + CLASS.stanfordText)\r\n          .data(config.stanford_texts);\r\n      // enter\r\n      stanfordTextEnter = stanfordText\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', function (d) {\r\n          return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : '');\r\n      });\r\n      stanfordTextEnter\r\n          .append('text')\r\n          .attr('x', function (d) { return (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')); })\r\n          .attr('y', function (d) { return (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')); })\r\n          .style('opacity', 0);\r\n      // update\r\n      $$.stanfordTexts = stanfordTextEnter.merge(stanfordText);\r\n      $$.stanfordTexts\r\n          .select('text')\r\n          .transition()\r\n          .duration(duration)\r\n          .attr('x', function (d) { return (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')); })\r\n          .attr('y', function (d) { return (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')); })\r\n          .text(function (d) {\r\n          return d.content;\r\n      })\r\n          .style('opacity', 1);\r\n      // exit\r\n      stanfordText\r\n          .exit()\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      // Stanford-Regions\r\n      stanfordRegion = main\r\n          .select('.' + CLASS.stanfordRegions)\r\n          .selectAll('.' + CLASS.stanfordRegion)\r\n          .data(config.stanford_regions);\r\n      // enter\r\n      stanfordRegionEnter = stanfordRegion\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', function (d) {\r\n          return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : '');\r\n      });\r\n      stanfordRegionEnter\r\n          .append('polygon')\r\n          .attr('points', function (d) {\r\n          return d.points\r\n              .map(function (value) {\r\n              return [\r\n                  config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'),\r\n                  config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')\r\n              ].join(',');\r\n          })\r\n              .join(' ');\r\n      })\r\n          .style('opacity', 0);\r\n      stanfordRegionEnter\r\n          .append('text')\r\n          .attr('x', function (d) { return $$.getCentroid(d.points).x; })\r\n          .attr('y', function (d) { return $$.getCentroid(d.points).y; })\r\n          .style('opacity', 0);\r\n      // update\r\n      $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion);\r\n      $$.stanfordRegions\r\n          .select('polygon')\r\n          .transition()\r\n          .duration(duration)\r\n          .attr('points', function (d) {\r\n          return d.points\r\n              .map(function (value) {\r\n              return [\r\n                  config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'),\r\n                  config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')\r\n              ].join(',');\r\n          })\r\n              .join(' ');\r\n      })\r\n          .style('opacity', function (d) {\r\n          return d.opacity ? d.opacity : 0.2;\r\n      });\r\n      $$.stanfordRegions\r\n          .select('text')\r\n          .transition()\r\n          .duration(duration)\r\n          .attr('x', function (d) {\r\n          return config.axis_rotated\r\n              ? yvCustom($$.getCentroid(d.points), 'y')\r\n              : xvCustom($$.getCentroid(d.points), 'x');\r\n      })\r\n          .attr('y', function (d) {\r\n          return config.axis_rotated\r\n              ? xvCustom($$.getCentroid(d.points), 'x')\r\n              : yvCustom($$.getCentroid(d.points), 'y');\r\n      })\r\n          .text(function (d) {\r\n          if (d.text) {\r\n              var value, percentage, temp;\r\n              if ($$.isStanfordGraphType()) {\r\n                  temp = countPointsInRegion(d.points);\r\n                  value = temp.value;\r\n                  percentage = temp.percentage;\r\n              }\r\n              return d.text(value, percentage);\r\n          }\r\n          return '';\r\n      })\r\n          .attr('text-anchor', 'middle')\r\n          .attr('dominant-baseline', 'middle')\r\n          .style('opacity', 1);\r\n      // exit\r\n      stanfordRegion\r\n          .exit()\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n  };\n\n  ChartInternal.prototype.initTooltip = function () {\r\n      var $$ = this, config = $$.config, i;\r\n      $$.tooltip = $$.selectChart\r\n          .style('position', 'relative')\r\n          .append('div')\r\n          .attr('class', CLASS.tooltipContainer)\r\n          .style('position', 'absolute')\r\n          .style('pointer-events', 'none')\r\n          .style('display', 'none');\r\n      // Show tooltip if needed\r\n      if (config.tooltip_init_show) {\r\n          if ($$.isTimeSeries() && isString(config.tooltip_init_x)) {\r\n              config.tooltip_init_x = $$.parseDate(config.tooltip_init_x);\r\n              for (i = 0; i < $$.data.targets[0].values.length; i++) {\r\n                  if ($$.data.targets[0].values[i].x - config.tooltip_init_x === 0) {\r\n                      break;\r\n                  }\r\n              }\r\n              config.tooltip_init_x = i;\r\n          }\r\n          $$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) {\r\n              return $$.addName(d.values[config.tooltip_init_x]);\r\n          }), $$.axis.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color));\r\n          $$.tooltip\r\n              .style('top', config.tooltip_init_position.top)\r\n              .style('left', config.tooltip_init_position.left)\r\n              .style('display', 'block');\r\n      }\r\n  };\r\n  ChartInternal.prototype.getTooltipSortFunction = function () {\r\n      var $$ = this, config = $$.config;\r\n      if (config.data_groups.length === 0 || config.tooltip_order !== undefined) {\r\n          // if data are not grouped or if an order is specified\r\n          // for the tooltip values we sort them by their values\r\n          var order = config.tooltip_order;\r\n          if (order === undefined) {\r\n              order = config.data_order;\r\n          }\r\n          var valueOf = function (obj) {\r\n              return obj ? obj.value : null;\r\n          };\r\n          // if data are not grouped, we sort them by their value\r\n          if (isString(order) && order.toLowerCase() === 'asc') {\r\n              return function (a, b) {\r\n                  return valueOf(a) - valueOf(b);\r\n              };\r\n          }\r\n          else if (isString(order) && order.toLowerCase() === 'desc') {\r\n              return function (a, b) {\r\n                  return valueOf(b) - valueOf(a);\r\n              };\r\n          }\r\n          else if (isFunction(order)) {\r\n              // if the function is from data_order we need\r\n              // to wrap the returned function in order to format\r\n              // the sorted value to the expected format\r\n              var sortFunction = order;\r\n              if (config.tooltip_order === undefined) {\r\n                  sortFunction = function (a, b) {\r\n                      return order(a\r\n                          ? {\r\n                              id: a.id,\r\n                              values: [a]\r\n                          }\r\n                          : null, b\r\n                          ? {\r\n                              id: b.id,\r\n                              values: [b]\r\n                          }\r\n                          : null);\r\n                  };\r\n              }\r\n              return sortFunction;\r\n          }\r\n          else if (isArray(order)) {\r\n              return function (a, b) {\r\n                  return order.indexOf(a.id) - order.indexOf(b.id);\r\n              };\r\n          }\r\n      }\r\n      else {\r\n          // if data are grouped, we follow the order of grouped targets\r\n          var ids = $$.orderTargets($$.data.targets).map(function (i) {\r\n              return i.id;\r\n          });\r\n          // if it was either asc or desc we need to invert the order\r\n          // returned by orderTargets\r\n          if ($$.isOrderAsc() || $$.isOrderDesc()) {\r\n              ids = ids.reverse();\r\n          }\r\n          return function (a, b) {\r\n              return ids.indexOf(a.id) - ids.indexOf(b.id);\r\n          };\r\n      }\r\n  };\r\n  ChartInternal.prototype.getTooltipContent = function (d, defaultTitleFormat, defaultValueFormat, color) {\r\n      var $$ = this, config = $$.config, titleFormat = config.tooltip_format_title || defaultTitleFormat, nameFormat = config.tooltip_format_name ||\r\n          function (name) {\r\n              return name;\r\n          }, text, i, title, value, name, bgcolor;\r\n      var valueFormat = config.tooltip_format_value;\r\n      if (!valueFormat) {\r\n          valueFormat = $$.isTargetNormalized(d.id)\r\n              ? function (v, ratio) { return (ratio * 100).toFixed(2) + \"%\"; }\r\n              : defaultValueFormat;\r\n      }\r\n      var tooltipSortFunction = this.getTooltipSortFunction();\r\n      if (tooltipSortFunction) {\r\n          d.sort(tooltipSortFunction);\r\n      }\r\n      for (i = 0; i < d.length; i++) {\r\n          if (!(d[i] && (d[i].value || d[i].value === 0))) {\r\n              continue;\r\n          }\r\n          if ($$.isStanfordGraphType()) {\r\n              // Custom tooltip for stanford plots\r\n              if (!text) {\r\n                  title = $$.getStanfordTooltipTitle(d[i]);\r\n                  text = \"<table class='\" + $$.CLASS.tooltip + \"'>\" + title;\r\n              }\r\n              bgcolor = $$.getStanfordPointColor(d[i]);\r\n              name = sanitise(config.data_epochs); // Epochs key name\r\n              value = d[i].epochs;\r\n          }\r\n          else {\r\n              // Regular tooltip\r\n              if (!text) {\r\n                  title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x);\r\n                  text =\r\n                      \"<table class='\" +\r\n                          $$.CLASS.tooltip +\r\n                          \"'>\" +\r\n                          (title || title === 0\r\n                              ? \"<tr><th colspan='2'>\" + title + '</th></tr>'\r\n                              : '');\r\n              }\r\n              value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d));\r\n              if (value !== undefined) {\r\n                  // Skip elements when their name is set to null\r\n                  if (d[i].name === null) {\r\n                      continue;\r\n                  }\r\n                  name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index));\r\n                  bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);\r\n              }\r\n          }\r\n          if (value !== undefined) {\r\n              text +=\r\n                  \"<tr class='\" +\r\n                      $$.CLASS.tooltipName +\r\n                      '-' +\r\n                      $$.getTargetSelectorSuffix(d[i].id) +\r\n                      \"'>\";\r\n              text +=\r\n                  \"<td class='name'><span style='background-color:\" +\r\n                      bgcolor +\r\n                      \"'></span>\" +\r\n                      name +\r\n                      '</td>';\r\n              text += \"<td class='value'>\" + value + '</td>';\r\n              text += '</tr>';\r\n          }\r\n      }\r\n      return text + '</table>';\r\n  };\r\n  ChartInternal.prototype.tooltipPosition = function (dataToShow, tWidth, tHeight, element) {\r\n      var $$ = this, config = $$.config, d3 = $$.d3;\r\n      var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight;\r\n      var forArc = $$.hasArcType(), mouse = d3.mouse(element);\r\n      // Determin tooltip position\r\n      if (forArc) {\r\n          tooltipLeft =\r\n              ($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2 + mouse[0];\r\n          tooltipTop =\r\n              ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20;\r\n      }\r\n      else {\r\n          svgLeft = $$.getSvgLeft(true);\r\n          if (config.axis_rotated) {\r\n              tooltipLeft = svgLeft + mouse[0] + 100;\r\n              tooltipRight = tooltipLeft + tWidth;\r\n              chartRight = $$.currentWidth - $$.getCurrentPaddingRight();\r\n              tooltipTop = $$.x(dataToShow[0].x) + 20;\r\n          }\r\n          else {\r\n              tooltipLeft =\r\n                  svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20;\r\n              tooltipRight = tooltipLeft + tWidth;\r\n              chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight();\r\n              tooltipTop = mouse[1] + 15;\r\n          }\r\n          if (tooltipRight > chartRight) {\r\n              // 20 is needed for Firefox to keep tooltip width\r\n              tooltipLeft -= tooltipRight - chartRight + 20;\r\n          }\r\n          if (tooltipTop + tHeight > $$.currentHeight) {\r\n              tooltipTop -= tHeight + 30;\r\n          }\r\n      }\r\n      if (tooltipTop < 0) {\r\n          tooltipTop = 0;\r\n      }\r\n      return {\r\n          top: tooltipTop,\r\n          left: tooltipLeft\r\n      };\r\n  };\r\n  ChartInternal.prototype.showTooltip = function (selectedData, element) {\r\n      var $$ = this, config = $$.config;\r\n      var tWidth, tHeight, position;\r\n      var forArc = $$.hasArcType(), dataToShow = selectedData.filter(function (d) {\r\n          return d && isValue(d.value);\r\n      }), positionFunction = config.tooltip_position || ChartInternal.prototype.tooltipPosition;\r\n      if (dataToShow.length === 0 || !config.tooltip_show) {\r\n          $$.hideTooltip();\r\n          return;\r\n      }\r\n      $$.tooltip\r\n          .html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color))\r\n          .style('display', 'block');\r\n      // Get tooltip dimensions\r\n      tWidth = $$.tooltip.property('offsetWidth');\r\n      tHeight = $$.tooltip.property('offsetHeight');\r\n      position = positionFunction.call(this, dataToShow, tWidth, tHeight, element);\r\n      // Set tooltip\r\n      $$.tooltip\r\n          .style('top', position.top + 'px')\r\n          .style('left', position.left + 'px');\r\n  };\r\n  ChartInternal.prototype.hideTooltip = function () {\r\n      this.tooltip.style('display', 'none');\r\n  };\n\n  ChartInternal.prototype.setTargetType = function (targetIds, type) {\r\n      var $$ = this, config = $$.config;\r\n      $$.mapToTargetIds(targetIds).forEach(function (id) {\r\n          $$.withoutFadeIn[id] = type === config.data_types[id];\r\n          config.data_types[id] = type;\r\n      });\r\n      if (!targetIds) {\r\n          config.data_type = type;\r\n      }\r\n  };\r\n  ChartInternal.prototype.hasType = function (type, targets) {\r\n      var $$ = this, types = $$.config.data_types, has = false;\r\n      targets = targets || $$.data.targets;\r\n      if (targets && targets.length) {\r\n          targets.forEach(function (target) {\r\n              var t = types[target.id];\r\n              if ((t && t.indexOf(type) >= 0) || (!t && type === 'line')) {\r\n                  has = true;\r\n              }\r\n          });\r\n      }\r\n      else if (Object.keys(types).length) {\r\n          Object.keys(types).forEach(function (id) {\r\n              if (types[id] === type) {\r\n                  has = true;\r\n              }\r\n          });\r\n      }\r\n      else {\r\n          has = $$.config.data_type === type;\r\n      }\r\n      return has;\r\n  };\r\n  ChartInternal.prototype.hasArcType = function (targets) {\r\n      return (this.hasType('pie', targets) ||\r\n          this.hasType('donut', targets) ||\r\n          this.hasType('gauge', targets));\r\n  };\r\n  ChartInternal.prototype.isLineType = function (d) {\r\n      var config = this.config, id = isString(d) ? d : d.id;\r\n      return (!config.data_types[id] ||\r\n          ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(config.data_types[id]) >= 0);\r\n  };\r\n  ChartInternal.prototype.isStepType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0;\r\n  };\r\n  ChartInternal.prototype.isSplineType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0;\r\n  };\r\n  ChartInternal.prototype.isAreaType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return (['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >=\r\n          0);\r\n  };\r\n  ChartInternal.prototype.isBarType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return this.config.data_types[id] === 'bar';\r\n  };\r\n  ChartInternal.prototype.isScatterType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return this.config.data_types[id] === 'scatter';\r\n  };\r\n  ChartInternal.prototype.isStanfordType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return this.config.data_types[id] === 'stanford';\r\n  };\r\n  ChartInternal.prototype.isPieType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return this.config.data_types[id] === 'pie';\r\n  };\r\n  ChartInternal.prototype.isGaugeType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return this.config.data_types[id] === 'gauge';\r\n  };\r\n  ChartInternal.prototype.isDonutType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return this.config.data_types[id] === 'donut';\r\n  };\r\n  ChartInternal.prototype.isArcType = function (d) {\r\n      return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d);\r\n  };\r\n  ChartInternal.prototype.lineData = function (d) {\r\n      return this.isLineType(d) ? [d] : [];\r\n  };\r\n  ChartInternal.prototype.arcData = function (d) {\r\n      return this.isArcType(d.data) ? [d] : [];\r\n  };\r\n  /* not used\r\n   function scatterData(d) {\r\n   return isScatterType(d) ? d.values : [];\r\n   }\r\n   */\r\n  ChartInternal.prototype.barData = function (d) {\r\n      return this.isBarType(d) ? d.values : [];\r\n  };\r\n  ChartInternal.prototype.lineOrScatterOrStanfordData = function (d) {\r\n      return this.isLineType(d) || this.isScatterType(d) || this.isStanfordType(d)\r\n          ? d.values\r\n          : [];\r\n  };\r\n  ChartInternal.prototype.barOrLineData = function (d) {\r\n      return this.isBarType(d) || this.isLineType(d) ? d.values : [];\r\n  };\n\n  ChartInternal.prototype.isSafari = function () {\r\n      var ua = window.navigator.userAgent;\r\n      return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0;\r\n  };\r\n  ChartInternal.prototype.isChrome = function () {\r\n      var ua = window.navigator.userAgent;\r\n      return ua.indexOf('Chrome') >= 0;\r\n  };\n\n  ChartInternal.prototype.initZoom = function () {\r\n      var $$ = this, d3 = $$.d3, config = $$.config, startEvent;\r\n      $$.zoom = d3\r\n          .zoom()\r\n          .on('start', function () {\r\n          if (config.zoom_type !== 'scroll') {\r\n              return;\r\n          }\r\n          var e = d3.event.sourceEvent;\r\n          if (e && e.type === 'brush') {\r\n              return;\r\n          }\r\n          startEvent = e;\r\n          config.zoom_onzoomstart.call($$.api, e);\r\n      })\r\n          .on('zoom', function () {\r\n          if (config.zoom_type !== 'scroll') {\r\n              return;\r\n          }\r\n          var e = d3.event.sourceEvent;\r\n          if (e && e.type === 'brush') {\r\n              return;\r\n          }\r\n          $$.redrawForZoom();\r\n          config.zoom_onzoom.call($$.api, $$.x.orgDomain());\r\n      })\r\n          .on('end', function () {\r\n          if (config.zoom_type !== 'scroll') {\r\n              return;\r\n          }\r\n          var e = d3.event.sourceEvent;\r\n          if (e && e.type === 'brush') {\r\n              return;\r\n          }\r\n          // if click, do nothing. otherwise, click interaction will be canceled.\r\n          if (e &&\r\n              startEvent.clientX === e.clientX &&\r\n              startEvent.clientY === e.clientY) {\r\n              return;\r\n          }\r\n          config.zoom_onzoomend.call($$.api, $$.x.orgDomain());\r\n      });\r\n      $$.zoom.updateDomain = function () {\r\n          if (d3.event && d3.event.transform) {\r\n              if (config.axis_rotated && config.zoom_type === 'scroll' && d3.event.sourceEvent.type === 'mousemove') {\r\n                  // we're moving the mouse in a rotated chart with zoom = \"scroll\", so we need rescaleY (i.e. vertical)\r\n                  $$.x.domain(d3.event.transform.rescaleY($$.subX).domain());\r\n              }\r\n              else {\r\n                  $$.x.domain(d3.event.transform.rescaleX($$.subX).domain());\r\n              }\r\n          }\r\n          return this;\r\n      };\r\n      $$.zoom.updateExtent = function () {\r\n          this.scaleExtent([1, Infinity])\r\n              .translateExtent([\r\n              [0, 0],\r\n              [$$.width, $$.height]\r\n          ])\r\n              .extent([\r\n              [0, 0],\r\n              [$$.width, $$.height]\r\n          ]);\r\n          return this;\r\n      };\r\n      $$.zoom.update = function () {\r\n          return this.updateExtent().updateDomain();\r\n      };\r\n      return $$.zoom.updateExtent();\r\n  };\r\n  ChartInternal.prototype.zoomTransform = function (range) {\r\n      var $$ = this, s = [$$.x(range[0]), $$.x(range[1])];\r\n      return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0);\r\n  };\r\n  ChartInternal.prototype.initDragZoom = function () {\r\n      var $$ = this;\r\n      var d3 = $$.d3;\r\n      var config = $$.config;\r\n      var context = ($$.context = $$.svg);\r\n      var brushXPos = $$.margin.left + 20.5;\r\n      var brushYPos = $$.margin.top + 0.5;\r\n      if (!(config.zoom_type === 'drag' && config.zoom_enabled)) {\r\n          return;\r\n      }\r\n      var getZoomedDomain = function (selection) {\r\n          return selection && selection.map(function (x) { return $$.x.invert(x); });\r\n      };\r\n      var brush = ($$.dragZoomBrush = d3\r\n          .brushX()\r\n          .on('start', function () {\r\n          $$.api.unzoom();\r\n          $$.svg.select('.' + CLASS.dragZoom).classed('disabled', false);\r\n          config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent);\r\n      })\r\n          .on('brush', function () {\r\n          config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection));\r\n      })\r\n          .on('end', function () {\r\n          if (d3.event.selection == null) {\r\n              return;\r\n          }\r\n          var zoomedDomain = getZoomedDomain(d3.event.selection);\r\n          if (!config.zoom_disableDefaultBehavior) {\r\n              $$.api.zoom(zoomedDomain);\r\n          }\r\n          $$.svg.select('.' + CLASS.dragZoom).classed('disabled', true);\r\n          config.zoom_onzoomend.call($$.api, zoomedDomain);\r\n      }));\r\n      context\r\n          .append('g')\r\n          .classed(CLASS.dragZoom, true)\r\n          .attr('clip-path', $$.clipPath)\r\n          .attr('transform', 'translate(' + brushXPos + ',' + brushYPos + ')')\r\n          .call(brush);\r\n  };\r\n  ChartInternal.prototype.getZoomDomain = function () {\r\n      var $$ = this, config = $$.config, d3 = $$.d3, min = d3.min([$$.orgXDomain[0], config.zoom_x_min]), max = d3.max([$$.orgXDomain[1], config.zoom_x_max]);\r\n      return [min, max];\r\n  };\r\n  ChartInternal.prototype.redrawForZoom = function () {\r\n      var $$ = this, d3 = $$.d3, config = $$.config, zoom = $$.zoom, x = $$.x;\r\n      if (!config.zoom_enabled) {\r\n          return;\r\n      }\r\n      if ($$.filterTargetsToShow($$.data.targets).length === 0) {\r\n          return;\r\n      }\r\n      zoom.update();\r\n      if (config.zoom_disableDefaultBehavior) {\r\n          return;\r\n      }\r\n      if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) {\r\n          x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]);\r\n      }\r\n      $$.redraw({\r\n          withTransition: false,\r\n          withY: config.zoom_rescale,\r\n          withSubchart: false,\r\n          withEventRect: false,\r\n          withDimension: false\r\n      });\r\n      if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') {\r\n          $$.cancelClick = true;\r\n      }\r\n  };\n\n  return c3;\n\n})));\n"
  },
  {
    "path": "codecov.yml",
    "content": "coverage:\n  status: no\n"
  },
  {
    "path": "component.json",
    "content": "{\n  \"name\": \"c3\",\n  \"repo\": \"masayuki0812/c3\",\n  \"description\": \"A D3-based reusable chart library\",\n  \"version\": \"0.7.20\",\n  \"keywords\": [],\n  \"dependencies\": {\n    \"mbostock/d3\": \"v5.0.0\"\n  },\n  \"development\": {},\n  \"license\": \"MIT\",\n  \"main\": \"c3.js\",\n  \"scripts\": [\"c3.js\"],\n  \"styles\": [\"c3.css\"]\n}\n"
  },
  {
    "path": "config.rb",
    "content": "helpers do\n  def js_as_plain(id)\n    f = open(\"docs/js/samples/\" + id + \".js\")\n    js = f.read\n    f.close\n    js\n  end\n  def data_as_plain(name)\n    f = open(\"docs/data/\" + name)\n    data = f.read\n    f.close\n    data\n  end\n  def css_as_plain(name)\n    f = open(\"docs/css/samples/\" + name)\n    css = f.read\n    f.close\n    css\n  end\n  def get_css_name(path)\n    path.gsub('.html', '')\n  end\nend\n\nset :source, 'docs'\nset :haml, { :ugly => true, :format => :html5 }\nset :css_dir, 'css'\nset :js_dir, 'js'\nset :images_dir, 'img'\n\nconfigure :build do\n  activate :asset_hash, :ignore => %r{^js/ace/.*}\nend\n"
  },
  {
    "path": "data/samples.yml",
    "content": "simple_multiple:\n  title: 'Line Chart'\n  desc: 'Line chart with sequential data.'\n\ntimeseries:\n  title: Timeseries Chart\n  desc: Simple line chart with timeseries data.\n\nchart_spline:\n  title: Spline Chart\n  desc: Display as Spline Chart.\n\nsimple_xy:\n  title: Simple XY Line Chart\n  desc: Simple line chart with custom x.\n\nsimple_xy_multiple:\n  title: Multiple XY Line Chart\n  desc: Multiple line chart with multiple custom x.\n\nsimple_regions:\n  title: Line Chart with Regions\n  desc: Set regions for each data with style.\n\nchart_bar:\n  title: Bar Chart\n  desc: Display as Bar Chart.\n\nchart_bar_stacked:\n  title: Stacked Bar Chart\n  desc: Display as Stacked Bar Chart.\n\nchart_scatter:\n  title: Scatter Plot\n  desc: Display as Scatter Plot.\n\nchart_pie:\n  title: Pie Chart\n  desc: Display as Pie Chart.\n\nchart_donut:\n  title: Donut Chart\n  desc: Display as Donut Chart.\n\nchart_gauge:\n  title: Gauge Chart\n  desc: Display as Gauge Chart.\n\nchart_step:\n  title: Step Chart\n  desc: Display as Step Chart.\n\nchart_area:\n  title: Area Chart\n  desc: Display as Area Chart.\n\nchart_area_stacked:\n  title: Stacked Area Chart\n  desc: Display as Stacked Area Chart.\n\nchart_stanford:\n  title: Stanford Chart\n  desc: Display as Stanford Chart.\n\nchart_combination:\n  title: Combination Chart\n  desc: Display all kinda charts up in here.\n\ncategorized:\n  title: Category Axis\n  desc: Show ticks as categorized by each data.\n\naxes_y2:\n  title: Additional Y Axis\n  desc: Additional y axis can be added.\n\naxes_rotated:\n  title: Rotated Axis\n  desc: Switch x and y axis position.\n\naxes_x_localtime:\n  title: X Axis Timezone\n  desc: Convert time to UTC.\n\naxes_x_tick_rotate:\n  title: Rotate X Axis Tick Text\n  desc: Rotate x axis tick text.\n\naxes_x_tick_format:\n  title: X Axis Tick Format\n  desc: Format x axis tick text.\n\naxes_y_tick_format:\n  title: Y Axis Tick Format\n  desc: Format y axis tick text.\n\naxes_x_tick_culling:\n  title: X Axis Tick Culling\n  desc: Set cull ticks or not on X Axis.\n\naxes_x_tick_values:\n  title: X Axis Tick Values\n  desc: Set tick texts on X Axis.\n\naxes_x_tick_count:\n  title: X Axis Tick Count\n  desc: Set the number of ticks on X Axis.\n\naxes_x_tick_fit:\n  title: X Axis Tick Fitting\n  desc: Set ticks position to x of data.\n\naxes_label:\n  title: Axis Label\n  desc: Set label for axis.\n\naxes_label_position:\n  title: Axis Label Position\n  desc: Set axis label position.\n\naxes_y_padding:\n  title: Padding for Y Axis\n  desc: Set padding for y axis.\n\naxes_y_range:\n  title: Range for Y Axis\n  desc: Set range for y axis.\n\ndata_columned:\n  title: Column Oriented Data\n  desc: Column-oriented data can be used as input.\n\ndata_rowed:\n  title: Row Oriented Data\n  desc: Row-oriented data can be used as input.\n\ndata_json:\n  title: JSON Data\n  desc: JSON can be used as input.\n\ndata_url:\n  title: Data from URL\n  desc: Data from URL can be used as input.\n\ndata_load:\n  title: Load Data\n  desc: Load data dynamically.\n\ndata_name:\n  title: Data Name\n  desc: Set name for each data.\n\ndata_stringx:\n  title: Category Data\n  desc: Load data with x values on category axis.\n\ndata_order:\n  title: Data Order\n  desc: Define data order. This will be used for stacked bar chart.\n\ndata_label:\n  title: Data Label\n  desc: Show label of data.\n\ndata_label_format:\n  title: Data Label Format\n  desc: Format label of data.\n\ndata_number_format_l10n:\n  title: Number Format Localization\n  desc: Number format localization using D3 locale settings.\n\ndata_color:\n  title: Data Color\n  desc: Set color according to data.\n\noptions_legend:\n  title: Hide Legend\n  desc: Set visibility of legend.\n\nlegend_position:\n  title: Legend Position\n  desc: Show legend on bottom or right side.\n\nlegend_custom:\n  title: Custom Legend\n  desc: Build custom legend\n\ntooltip_show:\n  title: Hide Tooltip\n  desc: Set visibility of tooltip.\n\ntooltip_grouped:\n  title: Tooltip Grouping\n  desc: Show tooltips as grouped or not.\n\ntooltip_format:\n  title: Tooltip Format\n  desc: Set format for title and value on tooltip.\n\ntooltip_horizontal:\n  title: Horizontal Tooltip\n  desc: Show tooltips based on the horizontal position of the mouse.\n\noptions_gridline:\n  title: Grid Lines\n  desc: Show grid lines for x and y axis.\n\ngrid_x_lines:\n  title: Optional X Grid Lines\n  desc: Add optional grid lines on x grid.\n\ngrid_y_lines:\n  title: Optional Y Grid Lines\n  desc: Add optional grid lines on y grid.\n\noptions_subchart:\n  title: Sub Chart\n  desc: Show sub chart for zoom and selection range.\n\ninteraction_zoom:\n  title: Zoom\n  desc: Zoom by mouse wheel event and slide by drag.\n\ninteraction_zoom_by_drag:\n  title: Zoom by Drag\n  desc: Zoom by dragging area.\n\nregion:\n  title: Region\n  desc: Show rects on chart.\n\nregion_timeseries:\n  title: Region with Timeseries\n  desc: Show rects on timeseries chart.\n\noptions_size:\n  title: Chart Size\n  desc: Set chart size in px.\n\noptions_color:\n  title: Color Pattern\n  desc: Set custom color pattern.\n\noptions_padding:\n  title: Padding\n  desc: Change padding for the chart.\n\npoint_show:\n  title: Hide points\n  desc: Hide points on line chart\n\npie_label_format:\n  title: Pie Label Format\n  desc: Change label format on Pie chart\n\ntransition_duration:\n  title: Duration of Transition\n  desc: Set duration of transition for chart animation.\n\napi_flow:\n  title: Flow\n  desc: Load/Unload data as flowing\n\napi_resize:\n  title: Resize\n  desc: Resize chart.\n\napi_data_name:\n  title: Data Name\n  desc: Update data names.\n\napi_data_color:\n  title: Data Color\n  desc: Update data colors.\n\napi_axis_label:\n  title: Axis Label\n  desc: Update axis labels.\n\napi_axis_range:\n  title: Axis Range\n  desc: Update axis range.\n\napi_grid_x:\n  title: X Grid\n  desc: Update custom x grids.\n\ntransform_line:\n  title: To Line Chart\n  desc: Transform to line chart.\n\ntransform_spline:\n  title: To Spline Chart\n  desc: Transform to spline chart.\n\ntransform_bar:\n  title: To Bar Chart\n  desc: Transform to bar chart.\n\ntransform_area:\n  title: To Area Chart\n  desc: Transform to area chart.\n\ntransform_areaspline:\n  title: To Area Spline Chart\n  desc: Transform to area spline chart.\n\ntransform_scatter:\n  title: To Scatter Plot\n  desc: Transform to scatter plot.\n\ntransform_pie:\n  title: To Pie Chart\n  desc: Transform to pie chart.\n\ntransform_donut:\n  title: To Donut Chart\n  desc: Transform to donut chart.\n\nstyle_region:\n  title: Style for Region\n  desc: Set style for regions.\n\nstyle_grid:\n  title: Style for Grid\n  desc: Set style for grids.\n"
  },
  {
    "path": "docs/404.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"utf-8\">\n        <title>Page Not Found :(</title>\n        <style>\n            ::-moz-selection {\n                background: #b3d4fc;\n                text-shadow: none;\n            }\n\n            ::selection {\n                background: #b3d4fc;\n                text-shadow: none;\n            }\n\n            html {\n                padding: 30px 10px;\n                font-size: 20px;\n                line-height: 1.4;\n                color: #737373;\n                background: #f0f0f0;\n                -webkit-text-size-adjust: 100%;\n                -ms-text-size-adjust: 100%;\n            }\n\n            html,\n            input {\n                font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n            }\n\n            body {\n                max-width: 500px;\n                _width: 500px;\n                padding: 30px 20px 50px;\n                border: 1px solid #b3b3b3;\n                border-radius: 4px;\n                margin: 0 auto;\n                box-shadow: 0 1px 10px #a7a7a7, inset 0 1px 0 #fff;\n                background: #fcfcfc;\n            }\n\n            h1 {\n                margin: 0 10px;\n                font-size: 50px;\n                text-align: center;\n            }\n\n            h1 span {\n                color: #bbb;\n            }\n\n            h3 {\n                margin: 1.5em 0 0.5em;\n            }\n\n            p {\n                margin: 1em 0;\n            }\n\n            ul {\n                padding: 0 0 0 40px;\n                margin: 1em 0;\n            }\n\n            .container {\n                max-width: 380px;\n                _width: 380px;\n                margin: 0 auto;\n            }\n\n            /* google search */\n\n            #goog-fixurl ul {\n                list-style: none;\n                padding: 0;\n                margin: 0;\n            }\n\n            #goog-fixurl form {\n                margin: 0;\n            }\n\n            #goog-wm-qt,\n            #goog-wm-sb {\n                border: 1px solid #bbb;\n                font-size: 16px;\n                line-height: normal;\n                vertical-align: top;\n                color: #444;\n                border-radius: 2px;\n            }\n\n            #goog-wm-qt {\n                width: 220px;\n                height: 20px;\n                padding: 5px;\n                margin: 5px 10px 0 0;\n                box-shadow: inset 0 1px 1px #ccc;\n            }\n\n            #goog-wm-sb {\n                display: inline-block;\n                height: 32px;\n                padding: 0 10px;\n                margin: 5px 0 0;\n                white-space: nowrap;\n                cursor: pointer;\n                background-color: #f5f5f5;\n                background-image: -webkit-linear-gradient(rgba(255,255,255,0), #f1f1f1);\n                background-image: -moz-linear-gradient(rgba(255,255,255,0), #f1f1f1);\n                background-image: -ms-linear-gradient(rgba(255,255,255,0), #f1f1f1);\n                background-image: -o-linear-gradient(rgba(255,255,255,0), #f1f1f1);\n                -webkit-appearance: none;\n                -moz-appearance: none;\n                appearance: none;\n                *overflow: visible;\n                *display: inline;\n                *zoom: 1;\n            }\n\n            #goog-wm-sb:hover,\n            #goog-wm-sb:focus {\n                border-color: #aaa;\n                box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n                background-color: #f8f8f8;\n            }\n\n            #goog-wm-qt:hover,\n            #goog-wm-qt:focus {\n                border-color: #105cb6;\n                outline: 0;\n                color: #222;\n            }\n\n            input::-moz-focus-inner {\n                padding: 0;\n                border: 0;\n            }\n        </style>\n    </head>\n    <body>\n        <div class=\"container\">\n            <h1>Not found <span>:(</span></h1>\n            <p>Sorry, but the page you were trying to view does not exist.</p>\n            <p>It looks like this was the result of either:</p>\n            <ul>\n                <li>a mistyped address</li>\n                <li>an out-of-date link</li>\n            </ul>\n            <script>\n                var GOOG_FIXURL_LANG = (navigator.language || '').slice(0,2),GOOG_FIXURL_SITE = location.host;\n            </script>\n            <script src=\"http://linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js\"></script>\n        </div>\n    </body>\n</html>\n"
  },
  {
    "path": "docs/CNAME",
    "content": "c3js.org\n"
  },
  {
    "path": "docs/_footer.haml",
    "content": "%footer\n  %hr\n  %p &copy Masayuki Tanaka 2014\n"
  },
  {
    "path": "docs/_index_item.haml",
    "content": ".large-4.columns\n  %h3 #{data.samples[id].title}\n  %p.margin-small-bottom #{data.samples[id].desc}\n  %a.btn.btn-default( href=\"/samples/#{id}.html\" role=\"button\" ) View details &raquo;\n"
  },
  {
    "path": "docs/_index_item_title.haml",
    "content": "%a( href=\"/examples.html##{id}\" name=\"#{id}\" )\n  %h2<\n    \\#\n    %span #{name}\n"
  },
  {
    "path": "docs/_reference_item_link.haml",
    "content": "%a( href=\"##{ id.gsub(/\\./, '-') }\")< #{ id.gsub(/(api|class)\\./, '') }\n- if defined? experimental\n  <span class=\"secondary label\">Experimental</span>\n"
  },
  {
    "path": "docs/_reference_menu_item.haml",
    "content": "%li\n  - if defined? experimental\n    = partial :reference_item_link, locals: { id: id, experimental: experimental }\n  - else\n    = partial :reference_item_link, locals: { id: id }"
  },
  {
    "path": "docs/_sample.haml",
    "content": ".container\n\n  %h1.title #{data.samples[id].title}\n\n  .chart\n    #chart\n\n  #ace-error\n\n  .sourcecode.margin-medium-v.margin-small-h\n    %h3 # #{id}.js\n    #javascript-editor.c3-editor\n      = js_as_plain id\n\n  - if defined? other_css\n    .sourcecode\n      %h3 # #{other_css}\n      %pre\n        %code.css\n          = css_as_plain other_css\n\n  - if defined? other_files\n    - other_files.each do |f|\n      .sourcecode\n        %h3 # #{f}\n        %pre\n          %code.html\n            = data_as_plain f\n\n  = partial :footer\n\n= partial :script\n= partial :sample_editor, locals: { type: 'javascript' }\n= javascript_include_tag \"samples/#{id}.js\"\n"
  },
  {
    "path": "docs/_sample_editor.haml",
    "content": "= javascript_include_tag \"ace/ace.js\"\n= javascript_include_tag \"ace/mode-javascript.js\"\n= javascript_include_tag \"ace/theme-tomorrow.js\"\n:javascript\n  var editor = ace.edit('#{type}-editor'),\n      error  = document.getElementById('ace-error');\n\n  function debounce(func, wait) {\n    var timeout;\n    return function() {\n      var context = this, args = arguments;\n      var later = function() {\n        func.apply(context, args);\n      };\n      clearTimeout(timeout);\n      timeout = setTimeout(later, wait);\n    };\n  };\n\n  editor.on('change', debounce(function(e) {\n    try {\n      eval(editor.getValue());\n      error.innerHTML = '';\n    }\n    catch(e) {\n      error.innerHTML = e;\n    }\n  }, 300));\n\n  editor.setOption(\"maxLines\", 100);\n  editor.setOption(\"showLineNumbers\", false);\n  editor.setOption(\"showGutter\", false);\n\n  editor.setTheme(\"ace/theme/tomorrow\");\n  editor.getSession().setMode(\"ace/mode/#{type}\");\n  editor.commands.removeCommand('gotoline') // Disables the override of Command-L\n"
  },
  {
    "path": "docs/_samples_header.haml",
    "content": ".nav\n  %a( href=\"/\") Home\n\n.page-header.title\n  %h1 #{data.samples[id].title}\n\n.chart\n  #chart\n\n.sourcecode\n  %h3 # #{id}.js\n  %pre\n    %code.html.javascript\n      = js_as_plain id\n\n= partial :script\n= javascript_include_tag \"samples/#{id}.js\"\n"
  },
  {
    "path": "docs/_script.haml",
    "content": "= javascript_include_tag 'jquery-1.11.0.min.js'\n= javascript_include_tag 'foundation.min.js'\n= javascript_include_tag 'highlight.pack.js'\n= javascript_include_tag 'd3-5.8.2.min.js'\n= javascript_include_tag 'c3.min.js'\n:javascript\n  hljs.initHighlightingOnLoad();\n  $(document).foundation();\n"
  },
  {
    "path": "docs/_script_scroll.haml",
    "content": ":javascript\n  $(function(){\n    function scrollToHash() {\n      var hash = document.location.hash,\n          target = $('.column-content h3 a[href^=' + hash + ']'),\n          position;\n      if (target.length) {\n        position = target.offset().top - 60;\n        $(\"html, body\").animate({scrollTop:position}, 250, \"swing\");\n      }\n    }\n    $(window).on('hashchange', scrollToHash);\n\n    // When clicked\n    $('a[href^=#]').click(function(){\n      document.location.hash = $(this).attr(\"href\");\n      return false;\n    });\n\n    // When loaded\n    $(window).trigger('hashchange');\n  });\n"
  },
  {
    "path": "docs/_sidemenu_item.haml",
    "content": "%li\n  %a( href=\"##{ id }\") #{ name }"
  },
  {
    "path": "docs/crossdomain.xml",
    "content": "<?xml version=\"1.0\"?>\n<!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n<cross-domain-policy>\n    <!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->\n\n    <!-- Most restrictive policy: -->\n    <site-control permitted-cross-domain-policies=\"none\"/>\n\n    <!-- Least restrictive policy: -->\n    <!--\n    <site-control permitted-cross-domain-policies=\"all\"/>\n    <allow-access-from domain=\"*\" to-ports=\"*\" secure=\"false\"/>\n    <allow-http-request-headers-from domain=\"*\" headers=\"*\" secure=\"false\"/>\n    -->\n</cross-domain-policy>\n"
  },
  {
    "path": "docs/css/c3.css",
    "content": "/*-- Chart --*/\n.c3 svg {\n  font: 10px sans-serif;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\n.c3 path, .c3 line {\n  fill: none;\n  stroke: #000;\n}\n\n.c3 text {\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  user-select: none;\n}\n\n.c3-legend-item-tile,\n.c3-xgrid-focus,\n.c3-ygrid,\n.c3-event-rect,\n.c3-bars path {\n  shape-rendering: crispEdges;\n}\n\n.c3-chart-arc path {\n  stroke: #fff;\n}\n\n.c3-chart-arc rect {\n  stroke: white;\n  stroke-width: 1;\n}\n\n.c3-chart-arc text {\n  fill: #fff;\n  font-size: 13px;\n}\n\n/*-- Axis --*/\n/*-- Grid --*/\n.c3-grid line {\n  stroke: #aaa;\n}\n\n.c3-grid text {\n  fill: #aaa;\n}\n\n.c3-xgrid, .c3-ygrid {\n  stroke-dasharray: 3 3;\n}\n\n/*-- Text on Chart --*/\n.c3-text.c3-empty {\n  fill: #808080;\n  font-size: 2em;\n}\n\n/*-- Line --*/\n.c3-line {\n  stroke-width: 1px;\n}\n\n/*-- Point --*/\n.c3-circle {\n  fill: currentColor;\n}\n\n.c3-circle._expanded_ {\n  stroke-width: 1px;\n  stroke: white;\n}\n\n.c3-selected-circle {\n  fill: white;\n  stroke-width: 2px;\n}\n\n/*-- Bar --*/\n.c3-bar {\n  stroke-width: 0;\n}\n\n.c3-bar._expanded_ {\n  fill-opacity: 1;\n  fill-opacity: 0.75;\n}\n\n/*-- Focus --*/\n.c3-target.c3-focused {\n  opacity: 1;\n}\n\n.c3-target.c3-focused path.c3-line, .c3-target.c3-focused path.c3-step {\n  stroke-width: 2px;\n}\n\n.c3-target.c3-defocused {\n  opacity: 0.3 !important;\n}\n\n/*-- Region --*/\n.c3-region {\n  fill: steelblue;\n  fill-opacity: 0.1;\n}\n.c3-region text {\n  fill-opacity: 1;\n}\n\n/*-- Brush --*/\n.c3-brush .extent {\n  fill-opacity: 0.1;\n}\n\n/*-- Select - Drag --*/\n/*-- Legend --*/\n.c3-legend-item {\n  font-size: 12px;\n}\n\n.c3-legend-item-hidden {\n  opacity: 0.15;\n}\n\n.c3-legend-background {\n  opacity: 0.75;\n  fill: white;\n  stroke: lightgray;\n  stroke-width: 1;\n}\n\n/*-- Title --*/\n.c3-title {\n  font: 14px sans-serif;\n}\n\n/*-- Tooltip --*/\n.c3-tooltip-container {\n  z-index: 10;\n}\n\n.c3-tooltip {\n  border-collapse: collapse;\n  border-spacing: 0;\n  background-color: #fff;\n  empty-cells: show;\n  -webkit-box-shadow: 7px 7px 12px -9px #777777;\n  -moz-box-shadow: 7px 7px 12px -9px #777777;\n  box-shadow: 7px 7px 12px -9px #777777;\n  opacity: 0.9;\n}\n\n.c3-tooltip tr {\n  border: 1px solid #CCC;\n}\n\n.c3-tooltip th {\n  background-color: #aaa;\n  font-size: 14px;\n  padding: 2px 5px;\n  text-align: left;\n  color: #FFF;\n}\n\n.c3-tooltip td {\n  font-size: 13px;\n  padding: 3px 6px;\n  background-color: #fff;\n  border-left: 1px dotted #999;\n}\n\n.c3-tooltip td > span {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin-right: 6px;\n}\n\n.c3-tooltip .value {\n  text-align: right;\n}\n\n/*-- Area --*/\n.c3-area {\n  stroke-width: 0;\n  opacity: 0.2;\n}\n\n/*-- Arc --*/\n.c3-chart-arcs-title {\n  dominant-baseline: middle;\n  font-size: 1.3em;\n}\n\n.c3-chart-arcs .c3-chart-arcs-background {\n  fill: #e0e0e0;\n  stroke: #FFF;\n}\n\n.c3-chart-arcs .c3-chart-arcs-gauge-unit {\n  fill: #000;\n  font-size: 16px;\n}\n\n.c3-chart-arcs .c3-chart-arcs-gauge-max {\n  fill: #777;\n}\n\n.c3-chart-arcs .c3-chart-arcs-gauge-min {\n  fill: #777;\n}\n\n.c3-chart-arc .c3-gauge-value {\n  fill: #000;\n  /*  font-size: 28px !important;*/\n}\n\n.c3-chart-arc.c3-target g path {\n  opacity: 1;\n}\n\n.c3-chart-arc.c3-target.c3-focused g path {\n  opacity: 1;\n}\n\n/*-- Zoom --*/\n.c3-drag-zoom.enabled {\n  pointer-events: all !important;\n  visibility: visible;\n}\n\n.c3-drag-zoom.disabled {\n  pointer-events: none !important;\n  visibility: hidden;\n}\n\n.c3-drag-zoom .extent {\n  fill-opacity: 0.1;\n}\n"
  },
  {
    "path": "docs/css/examples.css",
    "content": ""
  },
  {
    "path": "docs/css/foundation.css",
    "content": "meta.foundation-version {\n  font-family: \"/5.2.2/\"; }\n\nmeta.foundation-mq-small {\n  font-family: \"/only screen/\";\n  width: 0em; }\n\nmeta.foundation-mq-medium {\n  font-family: \"/only screen and (min-width:40.063em)/\";\n  width: 40.063em; }\n\nmeta.foundation-mq-large {\n  font-family: \"/only screen and (min-width:64.063em)/\";\n  width: 64.063em; }\n\nmeta.foundation-mq-xlarge {\n  font-family: \"/only screen and (min-width:90.063em)/\";\n  width: 90.063em; }\n\nmeta.foundation-mq-xxlarge {\n  font-family: \"/only screen and (min-width:120.063em)/\";\n  width: 120.063em; }\n\nmeta.foundation-data-attribute-namespace {\n  font-family: false; }\n\nhtml, body {\n  height: 100%; }\n\n*,\n*:before,\n*:after {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box; }\n\nhtml,\nbody {\n  font-size: 100%; }\n\nbody {\n  background: white;\n  color: #222222;\n  padding: 0;\n  margin: 0;\n  font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;\n  font-weight: normal;\n  font-style: normal;\n  line-height: 1;\n  position: relative;\n  cursor: default; }\n\na:hover {\n  cursor: pointer; }\n\nimg {\n  max-width: 100%;\n  height: auto; }\n\nimg {\n  -ms-interpolation-mode: bicubic; }\n\n#map_canvas img,\n#map_canvas embed,\n#map_canvas object,\n.map_canvas img,\n.map_canvas embed,\n.map_canvas object {\n  max-width: none !important; }\n\n.left {\n  float: left !important; }\n\n.right {\n  float: right !important; }\n\n.clearfix {\n  *zoom: 1; }\n  .clearfix:before, .clearfix:after {\n    content: \" \";\n    display: table; }\n  .clearfix:after {\n    clear: both; }\n\n.hide {\n  display: none; }\n\n.antialiased {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale; }\n\nimg {\n  display: inline-block;\n  vertical-align: middle; }\n\ntextarea {\n  height: auto;\n  min-height: 50px; }\n\nselect {\n  width: 100%; }\n\n.row {\n  width: 100%;\n  margin-left: auto;\n  margin-right: auto;\n  margin-top: 0;\n  margin-bottom: 0;\n  max-width: 62.5rem;\n  *zoom: 1; }\n  .row:before, .row:after {\n    content: \" \";\n    display: table; }\n  .row:after {\n    clear: both; }\n  .row.collapse > .column,\n  .row.collapse > .columns {\n    padding-left: 0;\n    padding-right: 0; }\n  .row.collapse .row {\n    margin-left: 0;\n    margin-right: 0; }\n  .row .row {\n    width: auto;\n    margin-left: -0.9375rem;\n    margin-right: -0.9375rem;\n    margin-top: 0;\n    margin-bottom: 0;\n    max-width: none;\n    *zoom: 1; }\n    .row .row:before, .row .row:after {\n      content: \" \";\n      display: table; }\n    .row .row:after {\n      clear: both; }\n    .row .row.collapse {\n      width: auto;\n      margin: 0;\n      max-width: none;\n      *zoom: 1; }\n      .row .row.collapse:before, .row .row.collapse:after {\n        content: \" \";\n        display: table; }\n      .row .row.collapse:after {\n        clear: both; }\n\n.column,\n.columns {\n  padding-left: 0.9375rem;\n  padding-right: 0.9375rem;\n  width: 100%;\n  float: left; }\n\n@media only screen {\n  .small-push-0 {\n    position: relative;\n    left: 0%;\n    right: auto; }\n\n  .small-pull-0 {\n    position: relative;\n    right: 0%;\n    left: auto; }\n\n  .small-push-1 {\n    position: relative;\n    left: 8.33333%;\n    right: auto; }\n\n  .small-pull-1 {\n    position: relative;\n    right: 8.33333%;\n    left: auto; }\n\n  .small-push-2 {\n    position: relative;\n    left: 16.66667%;\n    right: auto; }\n\n  .small-pull-2 {\n    position: relative;\n    right: 16.66667%;\n    left: auto; }\n\n  .small-push-3 {\n    position: relative;\n    left: 25%;\n    right: auto; }\n\n  .small-pull-3 {\n    position: relative;\n    right: 25%;\n    left: auto; }\n\n  .small-push-4 {\n    position: relative;\n    left: 33.33333%;\n    right: auto; }\n\n  .small-pull-4 {\n    position: relative;\n    right: 33.33333%;\n    left: auto; }\n\n  .small-push-5 {\n    position: relative;\n    left: 41.66667%;\n    right: auto; }\n\n  .small-pull-5 {\n    position: relative;\n    right: 41.66667%;\n    left: auto; }\n\n  .small-push-6 {\n    position: relative;\n    left: 50%;\n    right: auto; }\n\n  .small-pull-6 {\n    position: relative;\n    right: 50%;\n    left: auto; }\n\n  .small-push-7 {\n    position: relative;\n    left: 58.33333%;\n    right: auto; }\n\n  .small-pull-7 {\n    position: relative;\n    right: 58.33333%;\n    left: auto; }\n\n  .small-push-8 {\n    position: relative;\n    left: 66.66667%;\n    right: auto; }\n\n  .small-pull-8 {\n    position: relative;\n    right: 66.66667%;\n    left: auto; }\n\n  .small-push-9 {\n    position: relative;\n    left: 75%;\n    right: auto; }\n\n  .small-pull-9 {\n    position: relative;\n    right: 75%;\n    left: auto; }\n\n  .small-push-10 {\n    position: relative;\n    left: 83.33333%;\n    right: auto; }\n\n  .small-pull-10 {\n    position: relative;\n    right: 83.33333%;\n    left: auto; }\n\n  .small-push-11 {\n    position: relative;\n    left: 91.66667%;\n    right: auto; }\n\n  .small-pull-11 {\n    position: relative;\n    right: 91.66667%;\n    left: auto; }\n\n  .column,\n  .columns {\n    position: relative;\n    padding-left: 0.9375rem;\n    padding-right: 0.9375rem;\n    float: left; }\n\n  .small-1 {\n    width: 8.33333%; }\n\n  .small-2 {\n    width: 16.66667%; }\n\n  .small-3 {\n    width: 25%; }\n\n  .small-4 {\n    width: 33.33333%; }\n\n  .small-5 {\n    width: 41.66667%; }\n\n  .small-6 {\n    width: 50%; }\n\n  .small-7 {\n    width: 58.33333%; }\n\n  .small-8 {\n    width: 66.66667%; }\n\n  .small-9 {\n    width: 75%; }\n\n  .small-10 {\n    width: 83.33333%; }\n\n  .small-11 {\n    width: 91.66667%; }\n\n  .small-12 {\n    width: 100%; }\n\n  [class*=\"column\"] + [class*=\"column\"]:last-child {\n    float: right; }\n\n  [class*=\"column\"] + [class*=\"column\"].end {\n    float: left; }\n\n  .small-offset-0 {\n    margin-left: 0% !important; }\n\n  .small-offset-1 {\n    margin-left: 8.33333% !important; }\n\n  .small-offset-2 {\n    margin-left: 16.66667% !important; }\n\n  .small-offset-3 {\n    margin-left: 25% !important; }\n\n  .small-offset-4 {\n    margin-left: 33.33333% !important; }\n\n  .small-offset-5 {\n    margin-left: 41.66667% !important; }\n\n  .small-offset-6 {\n    margin-left: 50% !important; }\n\n  .small-offset-7 {\n    margin-left: 58.33333% !important; }\n\n  .small-offset-8 {\n    margin-left: 66.66667% !important; }\n\n  .small-offset-9 {\n    margin-left: 75% !important; }\n\n  .small-offset-10 {\n    margin-left: 83.33333% !important; }\n\n  .small-offset-11 {\n    margin-left: 91.66667% !important; }\n\n  .small-reset-order,\n  .small-reset-order {\n    margin-left: 0;\n    margin-right: 0;\n    left: auto;\n    right: auto;\n    float: left; }\n\n  .column.small-centered,\n  .columns.small-centered {\n    margin-left: auto;\n    margin-right: auto;\n    float: none; }\n\n  .column.small-uncentered,\n  .columns.small-uncentered {\n    margin-left: 0;\n    margin-right: 0;\n    float: left !important; }\n\n  .column.small-uncentered.opposite,\n  .columns.small-uncentered.opposite {\n    float: right; } }\n@media only screen and (min-width: 40.063em) {\n  .medium-push-0 {\n    position: relative;\n    left: 0%;\n    right: auto; }\n\n  .medium-pull-0 {\n    position: relative;\n    right: 0%;\n    left: auto; }\n\n  .medium-push-1 {\n    position: relative;\n    left: 8.33333%;\n    right: auto; }\n\n  .medium-pull-1 {\n    position: relative;\n    right: 8.33333%;\n    left: auto; }\n\n  .medium-push-2 {\n    position: relative;\n    left: 16.66667%;\n    right: auto; }\n\n  .medium-pull-2 {\n    position: relative;\n    right: 16.66667%;\n    left: auto; }\n\n  .medium-push-3 {\n    position: relative;\n    left: 25%;\n    right: auto; }\n\n  .medium-pull-3 {\n    position: relative;\n    right: 25%;\n    left: auto; }\n\n  .medium-push-4 {\n    position: relative;\n    left: 33.33333%;\n    right: auto; }\n\n  .medium-pull-4 {\n    position: relative;\n    right: 33.33333%;\n    left: auto; }\n\n  .medium-push-5 {\n    position: relative;\n    left: 41.66667%;\n    right: auto; }\n\n  .medium-pull-5 {\n    position: relative;\n    right: 41.66667%;\n    left: auto; }\n\n  .medium-push-6 {\n    position: relative;\n    left: 50%;\n    right: auto; }\n\n  .medium-pull-6 {\n    position: relative;\n    right: 50%;\n    left: auto; }\n\n  .medium-push-7 {\n    position: relative;\n    left: 58.33333%;\n    right: auto; }\n\n  .medium-pull-7 {\n    position: relative;\n    right: 58.33333%;\n    left: auto; }\n\n  .medium-push-8 {\n    position: relative;\n    left: 66.66667%;\n    right: auto; }\n\n  .medium-pull-8 {\n    position: relative;\n    right: 66.66667%;\n    left: auto; }\n\n  .medium-push-9 {\n    position: relative;\n    left: 75%;\n    right: auto; }\n\n  .medium-pull-9 {\n    position: relative;\n    right: 75%;\n    left: auto; }\n\n  .medium-push-10 {\n    position: relative;\n    left: 83.33333%;\n    right: auto; }\n\n  .medium-pull-10 {\n    position: relative;\n    right: 83.33333%;\n    left: auto; }\n\n  .medium-push-11 {\n    position: relative;\n    left: 91.66667%;\n    right: auto; }\n\n  .medium-pull-11 {\n    position: relative;\n    right: 91.66667%;\n    left: auto; }\n\n  .column,\n  .columns {\n    position: relative;\n    padding-left: 0.9375rem;\n    padding-right: 0.9375rem;\n    float: left; }\n\n  .medium-1 {\n    width: 8.33333%; }\n\n  .medium-2 {\n    width: 16.66667%; }\n\n  .medium-3 {\n    width: 25%; }\n\n  .medium-4 {\n    width: 33.33333%; }\n\n  .medium-5 {\n    width: 41.66667%; }\n\n  .medium-6 {\n    width: 50%; }\n\n  .medium-7 {\n    width: 58.33333%; }\n\n  .medium-8 {\n    width: 66.66667%; }\n\n  .medium-9 {\n    width: 75%; }\n\n  .medium-10 {\n    width: 83.33333%; }\n\n  .medium-11 {\n    width: 91.66667%; }\n\n  .medium-12 {\n    width: 100%; }\n\n  [class*=\"column\"] + [class*=\"column\"]:last-child {\n    float: right; }\n\n  [class*=\"column\"] + [class*=\"column\"].end {\n    float: left; }\n\n  .medium-offset-0 {\n    margin-left: 0% !important; }\n\n  .medium-offset-1 {\n    margin-left: 8.33333% !important; }\n\n  .medium-offset-2 {\n    margin-left: 16.66667% !important; }\n\n  .medium-offset-3 {\n    margin-left: 25% !important; }\n\n  .medium-offset-4 {\n    margin-left: 33.33333% !important; }\n\n  .medium-offset-5 {\n    margin-left: 41.66667% !important; }\n\n  .medium-offset-6 {\n    margin-left: 50% !important; }\n\n  .medium-offset-7 {\n    margin-left: 58.33333% !important; }\n\n  .medium-offset-8 {\n    margin-left: 66.66667% !important; }\n\n  .medium-offset-9 {\n    margin-left: 75% !important; }\n\n  .medium-offset-10 {\n    margin-left: 83.33333% !important; }\n\n  .medium-offset-11 {\n    margin-left: 91.66667% !important; }\n\n  .medium-reset-order,\n  .medium-reset-order {\n    margin-left: 0;\n    margin-right: 0;\n    left: auto;\n    right: auto;\n    float: left; }\n\n  .column.medium-centered,\n  .columns.medium-centered {\n    margin-left: auto;\n    margin-right: auto;\n    float: none; }\n\n  .column.medium-uncentered,\n  .columns.medium-uncentered {\n    margin-left: 0;\n    margin-right: 0;\n    float: left !important; }\n\n  .column.medium-uncentered.opposite,\n  .columns.medium-uncentered.opposite {\n    float: right; }\n\n  .push-0 {\n    position: relative;\n    left: 0%;\n    right: auto; }\n\n  .pull-0 {\n    position: relative;\n    right: 0%;\n    left: auto; }\n\n  .push-1 {\n    position: relative;\n    left: 8.33333%;\n    right: auto; }\n\n  .pull-1 {\n    position: relative;\n    right: 8.33333%;\n    left: auto; }\n\n  .push-2 {\n    position: relative;\n    left: 16.66667%;\n    right: auto; }\n\n  .pull-2 {\n    position: relative;\n    right: 16.66667%;\n    left: auto; }\n\n  .push-3 {\n    position: relative;\n    left: 25%;\n    right: auto; }\n\n  .pull-3 {\n    position: relative;\n    right: 25%;\n    left: auto; }\n\n  .push-4 {\n    position: relative;\n    left: 33.33333%;\n    right: auto; }\n\n  .pull-4 {\n    position: relative;\n    right: 33.33333%;\n    left: auto; }\n\n  .push-5 {\n    position: relative;\n    left: 41.66667%;\n    right: auto; }\n\n  .pull-5 {\n    position: relative;\n    right: 41.66667%;\n    left: auto; }\n\n  .push-6 {\n    position: relative;\n    left: 50%;\n    right: auto; }\n\n  .pull-6 {\n    position: relative;\n    right: 50%;\n    left: auto; }\n\n  .push-7 {\n    position: relative;\n    left: 58.33333%;\n    right: auto; }\n\n  .pull-7 {\n    position: relative;\n    right: 58.33333%;\n    left: auto; }\n\n  .push-8 {\n    position: relative;\n    left: 66.66667%;\n    right: auto; }\n\n  .pull-8 {\n    position: relative;\n    right: 66.66667%;\n    left: auto; }\n\n  .push-9 {\n    position: relative;\n    left: 75%;\n    right: auto; }\n\n  .pull-9 {\n    position: relative;\n    right: 75%;\n    left: auto; }\n\n  .push-10 {\n    position: relative;\n    left: 83.33333%;\n    right: auto; }\n\n  .pull-10 {\n    position: relative;\n    right: 83.33333%;\n    left: auto; }\n\n  .push-11 {\n    position: relative;\n    left: 91.66667%;\n    right: auto; }\n\n  .pull-11 {\n    position: relative;\n    right: 91.66667%;\n    left: auto; } }\n@media only screen and (min-width: 64.063em) {\n  .large-push-0 {\n    position: relative;\n    left: 0%;\n    right: auto; }\n\n  .large-pull-0 {\n    position: relative;\n    right: 0%;\n    left: auto; }\n\n  .large-push-1 {\n    position: relative;\n    left: 8.33333%;\n    right: auto; }\n\n  .large-pull-1 {\n    position: relative;\n    right: 8.33333%;\n    left: auto; }\n\n  .large-push-2 {\n    position: relative;\n    left: 16.66667%;\n    right: auto; }\n\n  .large-pull-2 {\n    position: relative;\n    right: 16.66667%;\n    left: auto; }\n\n  .large-push-3 {\n    position: relative;\n    left: 25%;\n    right: auto; }\n\n  .large-pull-3 {\n    position: relative;\n    right: 25%;\n    left: auto; }\n\n  .large-push-4 {\n    position: relative;\n    left: 33.33333%;\n    right: auto; }\n\n  .large-pull-4 {\n    position: relative;\n    right: 33.33333%;\n    left: auto; }\n\n  .large-push-5 {\n    position: relative;\n    left: 41.66667%;\n    right: auto; }\n\n  .large-pull-5 {\n    position: relative;\n    right: 41.66667%;\n    left: auto; }\n\n  .large-push-6 {\n    position: relative;\n    left: 50%;\n    right: auto; }\n\n  .large-pull-6 {\n    position: relative;\n    right: 50%;\n    left: auto; }\n\n  .large-push-7 {\n    position: relative;\n    left: 58.33333%;\n    right: auto; }\n\n  .large-pull-7 {\n    position: relative;\n    right: 58.33333%;\n    left: auto; }\n\n  .large-push-8 {\n    position: relative;\n    left: 66.66667%;\n    right: auto; }\n\n  .large-pull-8 {\n    position: relative;\n    right: 66.66667%;\n    left: auto; }\n\n  .large-push-9 {\n    position: relative;\n    left: 75%;\n    right: auto; }\n\n  .large-pull-9 {\n    position: relative;\n    right: 75%;\n    left: auto; }\n\n  .large-push-10 {\n    position: relative;\n    left: 83.33333%;\n    right: auto; }\n\n  .large-pull-10 {\n    position: relative;\n    right: 83.33333%;\n    left: auto; }\n\n  .large-push-11 {\n    position: relative;\n    left: 91.66667%;\n    right: auto; }\n\n  .large-pull-11 {\n    position: relative;\n    right: 91.66667%;\n    left: auto; }\n\n  .column,\n  .columns {\n    position: relative;\n    padding-left: 0.9375rem;\n    padding-right: 0.9375rem;\n    float: left; }\n\n  .large-1 {\n    width: 8.33333%; }\n\n  .large-2 {\n    width: 16.66667%; }\n\n  .large-3 {\n    width: 25%; }\n\n  .large-4 {\n    width: 33.33333%; }\n\n  .large-5 {\n    width: 41.66667%; }\n\n  .large-6 {\n    width: 50%; }\n\n  .large-7 {\n    width: 58.33333%; }\n\n  .large-8 {\n    width: 66.66667%; }\n\n  .large-9 {\n    width: 75%; }\n\n  .large-10 {\n    width: 83.33333%; }\n\n  .large-11 {\n    width: 91.66667%; }\n\n  .large-12 {\n    width: 100%; }\n\n  [class*=\"column\"] + [class*=\"column\"]:last-child {\n    float: right; }\n\n  [class*=\"column\"] + [class*=\"column\"].end {\n    float: left; }\n\n  .large-offset-0 {\n    margin-left: 0% !important; }\n\n  .large-offset-1 {\n    margin-left: 8.33333% !important; }\n\n  .large-offset-2 {\n    margin-left: 16.66667% !important; }\n\n  .large-offset-3 {\n    margin-left: 25% !important; }\n\n  .large-offset-4 {\n    margin-left: 33.33333% !important; }\n\n  .large-offset-5 {\n    margin-left: 41.66667% !important; }\n\n  .large-offset-6 {\n    margin-left: 50% !important; }\n\n  .large-offset-7 {\n    margin-left: 58.33333% !important; }\n\n  .large-offset-8 {\n    margin-left: 66.66667% !important; }\n\n  .large-offset-9 {\n    margin-left: 75% !important; }\n\n  .large-offset-10 {\n    margin-left: 83.33333% !important; }\n\n  .large-offset-11 {\n    margin-left: 91.66667% !important; }\n\n  .large-reset-order,\n  .large-reset-order {\n    margin-left: 0;\n    margin-right: 0;\n    left: auto;\n    right: auto;\n    float: left; }\n\n  .column.large-centered,\n  .columns.large-centered {\n    margin-left: auto;\n    margin-right: auto;\n    float: none; }\n\n  .column.large-uncentered,\n  .columns.large-uncentered {\n    margin-left: 0;\n    margin-right: 0;\n    float: left !important; }\n\n  .column.large-uncentered.opposite,\n  .columns.large-uncentered.opposite {\n    float: right; }\n\n  .push-0 {\n    position: relative;\n    left: 0%;\n    right: auto; }\n\n  .pull-0 {\n    position: relative;\n    right: 0%;\n    left: auto; }\n\n  .push-1 {\n    position: relative;\n    left: 8.33333%;\n    right: auto; }\n\n  .pull-1 {\n    position: relative;\n    right: 8.33333%;\n    left: auto; }\n\n  .push-2 {\n    position: relative;\n    left: 16.66667%;\n    right: auto; }\n\n  .pull-2 {\n    position: relative;\n    right: 16.66667%;\n    left: auto; }\n\n  .push-3 {\n    position: relative;\n    left: 25%;\n    right: auto; }\n\n  .pull-3 {\n    position: relative;\n    right: 25%;\n    left: auto; }\n\n  .push-4 {\n    position: relative;\n    left: 33.33333%;\n    right: auto; }\n\n  .pull-4 {\n    position: relative;\n    right: 33.33333%;\n    left: auto; }\n\n  .push-5 {\n    position: relative;\n    left: 41.66667%;\n    right: auto; }\n\n  .pull-5 {\n    position: relative;\n    right: 41.66667%;\n    left: auto; }\n\n  .push-6 {\n    position: relative;\n    left: 50%;\n    right: auto; }\n\n  .pull-6 {\n    position: relative;\n    right: 50%;\n    left: auto; }\n\n  .push-7 {\n    position: relative;\n    left: 58.33333%;\n    right: auto; }\n\n  .pull-7 {\n    position: relative;\n    right: 58.33333%;\n    left: auto; }\n\n  .push-8 {\n    position: relative;\n    left: 66.66667%;\n    right: auto; }\n\n  .pull-8 {\n    position: relative;\n    right: 66.66667%;\n    left: auto; }\n\n  .push-9 {\n    position: relative;\n    left: 75%;\n    right: auto; }\n\n  .pull-9 {\n    position: relative;\n    right: 75%;\n    left: auto; }\n\n  .push-10 {\n    position: relative;\n    left: 83.33333%;\n    right: auto; }\n\n  .pull-10 {\n    position: relative;\n    right: 83.33333%;\n    left: auto; }\n\n  .push-11 {\n    position: relative;\n    left: 91.66667%;\n    right: auto; }\n\n  .pull-11 {\n    position: relative;\n    right: 91.66667%;\n    left: auto; } }\nbutton, .button {\n  border-style: solid;\n  border-width: 0px;\n  cursor: pointer;\n  font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;\n  font-weight: normal;\n  line-height: normal;\n  margin: 0 0 1.25rem;\n  position: relative;\n  text-decoration: none;\n  text-align: center;\n  -webkit-appearance: none;\n  -webkit-border-radius: 0;\n  display: inline-block;\n  padding-top: 1rem;\n  padding-right: 2rem;\n  padding-bottom: 1.0625rem;\n  padding-left: 2rem;\n  font-size: 1rem;\n  background-color: #008cba;\n  border-color: #007095;\n  color: white;\n  transition: background-color 300ms ease-out; }\n  button:hover, button:focus, .button:hover, .button:focus {\n    background-color: #007095; }\n  button:hover, button:focus, .button:hover, .button:focus {\n    color: white; }\n  button.secondary, .button.secondary {\n    background-color: #e7e7e7;\n    border-color: #b9b9b9;\n    color: #333333; }\n    button.secondary:hover, button.secondary:focus, .button.secondary:hover, .button.secondary:focus {\n      background-color: #b9b9b9; }\n    button.secondary:hover, button.secondary:focus, .button.secondary:hover, .button.secondary:focus {\n      color: #333333; }\n  button.success, .button.success {\n    background-color: #43ac6a;\n    border-color: #368a55;\n    color: white; }\n    button.success:hover, button.success:focus, .button.success:hover, .button.success:focus {\n      background-color: #368a55; }\n    button.success:hover, button.success:focus, .button.success:hover, .button.success:focus {\n      color: white; }\n  button.alert, .button.alert {\n    background-color: #f04124;\n    border-color: #cf2a0e;\n    color: white; }\n    button.alert:hover, button.alert:focus, .button.alert:hover, .button.alert:focus {\n      background-color: #cf2a0e; }\n    button.alert:hover, button.alert:focus, .button.alert:hover, .button.alert:focus {\n      color: white; }\n  button.large, .button.large {\n    padding-top: 1.125rem;\n    padding-right: 2.25rem;\n    padding-bottom: 1.1875rem;\n    padding-left: 2.25rem;\n    font-size: 1.25rem; }\n  button.small, .button.small {\n    padding-top: 0.875rem;\n    padding-right: 1.75rem;\n    padding-bottom: 0.9375rem;\n    padding-left: 1.75rem;\n    font-size: 0.8125rem; }\n  button.tiny, .button.tiny {\n    padding-top: 0.625rem;\n    padding-right: 1.25rem;\n    padding-bottom: 0.6875rem;\n    padding-left: 1.25rem;\n    font-size: 0.6875rem; }\n  button.expand, .button.expand {\n    padding-right: 0;\n    padding-left: 0;\n    width: 100%; }\n  button.left-align, .button.left-align {\n    text-align: left;\n    text-indent: 0.75rem; }\n  button.right-align, .button.right-align {\n    text-align: right;\n    padding-right: 0.75rem; }\n  button.radius, .button.radius {\n    border-radius: 3px; }\n  button.round, .button.round {\n    border-radius: 1000px; }\n  button.disabled, button[disabled], .button.disabled, .button[disabled] {\n    background-color: #008cba;\n    border-color: #007095;\n    color: white;\n    cursor: default;\n    opacity: 0.7;\n    box-shadow: none; }\n    button.disabled:hover, button.disabled:focus, button[disabled]:hover, button[disabled]:focus, .button.disabled:hover, .button.disabled:focus, .button[disabled]:hover, .button[disabled]:focus {\n      background-color: #007095; }\n    button.disabled:hover, button.disabled:focus, button[disabled]:hover, button[disabled]:focus, .button.disabled:hover, .button.disabled:focus, .button[disabled]:hover, .button[disabled]:focus {\n      color: white; }\n    button.disabled:hover, button.disabled:focus, button[disabled]:hover, button[disabled]:focus, .button.disabled:hover, .button.disabled:focus, .button[disabled]:hover, .button[disabled]:focus {\n      background-color: #008cba; }\n    button.disabled.secondary, button[disabled].secondary, .button.disabled.secondary, .button[disabled].secondary {\n      background-color: #e7e7e7;\n      border-color: #b9b9b9;\n      color: #333333;\n      cursor: default;\n      opacity: 0.7;\n      box-shadow: none; }\n      button.disabled.secondary:hover, button.disabled.secondary:focus, button[disabled].secondary:hover, button[disabled].secondary:focus, .button.disabled.secondary:hover, .button.disabled.secondary:focus, .button[disabled].secondary:hover, .button[disabled].secondary:focus {\n        background-color: #b9b9b9; }\n      button.disabled.secondary:hover, button.disabled.secondary:focus, button[disabled].secondary:hover, button[disabled].secondary:focus, .button.disabled.secondary:hover, .button.disabled.secondary:focus, .button[disabled].secondary:hover, .button[disabled].secondary:focus {\n        color: #333333; }\n      button.disabled.secondary:hover, button.disabled.secondary:focus, button[disabled].secondary:hover, button[disabled].secondary:focus, .button.disabled.secondary:hover, .button.disabled.secondary:focus, .button[disabled].secondary:hover, .button[disabled].secondary:focus {\n        background-color: #e7e7e7; }\n    button.disabled.success, button[disabled].success, .button.disabled.success, .button[disabled].success {\n      background-color: #43ac6a;\n      border-color: #368a55;\n      color: white;\n      cursor: default;\n      opacity: 0.7;\n      box-shadow: none; }\n      button.disabled.success:hover, button.disabled.success:focus, button[disabled].success:hover, button[disabled].success:focus, .button.disabled.success:hover, .button.disabled.success:focus, .button[disabled].success:hover, .button[disabled].success:focus {\n        background-color: #368a55; }\n      button.disabled.success:hover, button.disabled.success:focus, button[disabled].success:hover, button[disabled].success:focus, .button.disabled.success:hover, .button.disabled.success:focus, .button[disabled].success:hover, .button[disabled].success:focus {\n        color: white; }\n      button.disabled.success:hover, button.disabled.success:focus, button[disabled].success:hover, button[disabled].success:focus, .button.disabled.success:hover, .button.disabled.success:focus, .button[disabled].success:hover, .button[disabled].success:focus {\n        background-color: #43ac6a; }\n    button.disabled.alert, button[disabled].alert, .button.disabled.alert, .button[disabled].alert {\n      background-color: #f04124;\n      border-color: #cf2a0e;\n      color: white;\n      cursor: default;\n      opacity: 0.7;\n      box-shadow: none; }\n      button.disabled.alert:hover, button.disabled.alert:focus, button[disabled].alert:hover, button[disabled].alert:focus, .button.disabled.alert:hover, .button.disabled.alert:focus, .button[disabled].alert:hover, .button[disabled].alert:focus {\n        background-color: #cf2a0e; }\n      button.disabled.alert:hover, button.disabled.alert:focus, button[disabled].alert:hover, button[disabled].alert:focus, .button.disabled.alert:hover, .button.disabled.alert:focus, .button[disabled].alert:hover, .button[disabled].alert:focus {\n        color: white; }\n      button.disabled.alert:hover, button.disabled.alert:focus, button[disabled].alert:hover, button[disabled].alert:focus, .button.disabled.alert:hover, .button.disabled.alert:focus, .button[disabled].alert:hover, .button[disabled].alert:focus {\n        background-color: #f04124; }\n\n@media only screen and (min-width: 40.063em) {\n  button, .button {\n    display: inline-block; } }\nmeta.foundation-mq-topbar {\n  font-family: \"/only screen and (min-width:40.063em)/\";\n  width: 40.063em; }\n\n/* Wrapped around .top-bar to contain to grid width */\n.contain-to-grid {\n  width: 100%;\n  background: #333333; }\n  .contain-to-grid .top-bar {\n    margin-bottom: 0; }\n\n.fixed {\n  width: 100%;\n  left: 0;\n  position: fixed;\n  top: 0;\n  z-index: 99; }\n  .fixed.expanded:not(.top-bar) {\n    overflow-y: auto;\n    height: auto;\n    width: 100%;\n    max-height: 100%; }\n    .fixed.expanded:not(.top-bar) .title-area {\n      position: fixed;\n      width: 100%;\n      z-index: 99; }\n    .fixed.expanded:not(.top-bar) .top-bar-section {\n      z-index: 98;\n      margin-top: 45px; }\n\n.top-bar {\n  overflow: hidden;\n  height: 45px;\n  line-height: 45px;\n  position: relative;\n  background: #333333;\n  margin-bottom: 0; }\n  .top-bar ul {\n    margin-bottom: 0;\n    list-style: none; }\n  .top-bar .row {\n    max-width: none; }\n  .top-bar form,\n  .top-bar input {\n    margin-bottom: 0; }\n  .top-bar input {\n    height: auto;\n    padding-top: .35rem;\n    padding-bottom: .35rem;\n    font-size: 0.75rem; }\n  .top-bar .button, .top-bar button {\n    padding-top: .45rem;\n    padding-bottom: .35rem;\n    margin-bottom: 0;\n    font-size: 0.75rem; }\n  .top-bar .title-area {\n    position: relative;\n    margin: 0; }\n  .top-bar .name {\n    height: 45px;\n    margin: 0;\n    font-size: 16px; }\n    .top-bar .name h1 {\n      line-height: 45px;\n/*      font-size: 1.0625rem;*/\n      font-size: 0.94444rem;\n      margin: 0; }\n      .top-bar .name h1 a {\n        font-weight: normal;\n        color: white;\n        width: 75%;\n        display: block;\n        padding: 0 15px; }\n  .top-bar .toggle-topbar {\n    position: absolute;\n    right: 0;\n    top: 0; }\n    .top-bar .toggle-topbar a {\n      color: white;\n      text-transform: uppercase;\n      font-size: 0.8125rem;\n      font-weight: bold;\n      position: relative;\n      display: block;\n      padding: 0 15px;\n      height: 45px;\n      line-height: 45px; }\n    .top-bar .toggle-topbar.menu-icon {\n      right: 15px;\n      top: 50%;\n      margin-top: -16px;\n      padding-left: 40px; }\n      .top-bar .toggle-topbar.menu-icon a {\n        height: 34px;\n        line-height: 33px;\n        padding: 0;\n        padding-right: 25px;\n        color: white;\n        position: relative; }\n        .top-bar .toggle-topbar.menu-icon a::after {\n          content: \"\";\n          position: absolute;\n          right: 0;\n          display: block;\n          width: 16px;\n          top: 0;\n          height: 0;\n          box-shadow: 0 10px 0 1px white, 0 16px 0 1px white, 0 22px 0 1px white; }\n  .top-bar.expanded {\n    height: auto;\n    background: transparent; }\n    .top-bar.expanded .title-area {\n      background: #333333; }\n    .top-bar.expanded .toggle-topbar a {\n      color: #888888; }\n      .top-bar.expanded .toggle-topbar a::after {\n        box-shadow: 0 10px 0 1px #888888, 0 16px 0 1px #888888, 0 22px 0 1px #888888; }\n\n.top-bar-section {\n  left: 0;\n  position: relative;\n  width: auto;\n  transition: left 300ms ease-out; }\n  .top-bar-section ul {\n    width: 100%;\n    height: auto;\n    display: block;\n    background: #333333;\n    font-size: 16px;\n    margin: 0; }\n  .top-bar-section .divider,\n  .top-bar-section [role=\"separator\"] {\n    border-top: solid 1px #1a1a1a;\n    clear: both;\n    height: 1px;\n    width: 100%; }\n  .top-bar-section ul li > a {\n    display: block;\n    width: 100%;\n    color: white;\n    padding: 12px 0 12px 0;\n    padding-left: 15px;\n    font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;\n    font-size: 0.8125rem;\n    font-weight: normal;\n    text-transform: none;\n    background: #333333; }\n    .top-bar-section ul li > a.button {\n      font-size: 0.8125rem;\n      padding-right: 15px;\n      padding-left: 15px;\n      background-color: #008cba;\n      border-color: #007095;\n      color: white; }\n      .top-bar-section ul li > a.button:hover, .top-bar-section ul li > a.button:focus {\n        background-color: #007095; }\n      .top-bar-section ul li > a.button:hover, .top-bar-section ul li > a.button:focus {\n        color: white; }\n    .top-bar-section ul li > a.button.secondary {\n      background-color: #e7e7e7;\n      border-color: #b9b9b9;\n      color: #333333; }\n      .top-bar-section ul li > a.button.secondary:hover, .top-bar-section ul li > a.button.secondary:focus {\n        background-color: #b9b9b9; }\n      .top-bar-section ul li > a.button.secondary:hover, .top-bar-section ul li > a.button.secondary:focus {\n        color: #333333; }\n    .top-bar-section ul li > a.button.success {\n      background-color: #43ac6a;\n      border-color: #368a55;\n      color: white; }\n      .top-bar-section ul li > a.button.success:hover, .top-bar-section ul li > a.button.success:focus {\n        background-color: #368a55; }\n      .top-bar-section ul li > a.button.success:hover, .top-bar-section ul li > a.button.success:focus {\n        color: white; }\n    .top-bar-section ul li > a.button.alert {\n      background-color: #f04124;\n      border-color: #cf2a0e;\n      color: white; }\n      .top-bar-section ul li > a.button.alert:hover, .top-bar-section ul li > a.button.alert:focus {\n        background-color: #cf2a0e; }\n      .top-bar-section ul li > a.button.alert:hover, .top-bar-section ul li > a.button.alert:focus {\n        color: white; }\n  .top-bar-section ul li > button {\n    font-size: 0.8125rem;\n    padding-right: 15px;\n    padding-left: 15px;\n    background-color: #008cba;\n    border-color: #007095;\n    color: white; }\n    .top-bar-section ul li > button:hover, .top-bar-section ul li > button:focus {\n      background-color: #007095; }\n    .top-bar-section ul li > button:hover, .top-bar-section ul li > button:focus {\n      color: white; }\n    .top-bar-section ul li > button.secondary {\n      background-color: #e7e7e7;\n      border-color: #b9b9b9;\n      color: #333333; }\n      .top-bar-section ul li > button.secondary:hover, .top-bar-section ul li > button.secondary:focus {\n        background-color: #b9b9b9; }\n      .top-bar-section ul li > button.secondary:hover, .top-bar-section ul li > button.secondary:focus {\n        color: #333333; }\n    .top-bar-section ul li > button.success {\n      background-color: #43ac6a;\n      border-color: #368a55;\n      color: white; }\n      .top-bar-section ul li > button.success:hover, .top-bar-section ul li > button.success:focus {\n        background-color: #368a55; }\n      .top-bar-section ul li > button.success:hover, .top-bar-section ul li > button.success:focus {\n        color: white; }\n    .top-bar-section ul li > button.alert {\n      background-color: #f04124;\n      border-color: #cf2a0e;\n      color: white; }\n      .top-bar-section ul li > button.alert:hover, .top-bar-section ul li > button.alert:focus {\n        background-color: #cf2a0e; }\n      .top-bar-section ul li > button.alert:hover, .top-bar-section ul li > button.alert:focus {\n        color: white; }\n  .top-bar-section ul li:hover:not(.has-form) > a {\n    background: #272727;\n    color: white; }\n  .top-bar-section ul li.active > a {\n    background: #008cba;\n    color: white; }\n    .top-bar-section ul li.active > a:hover {\n      background: #0078a0;\n      color: white; }\n  .top-bar-section .has-form {\n    padding: 15px; }\n  .top-bar-section .has-dropdown {\n    position: relative; }\n    .top-bar-section .has-dropdown > a:after {\n      content: \"\";\n      display: block;\n      width: 0;\n      height: 0;\n      border: inset 5px;\n      border-color: transparent transparent transparent rgba(255, 255, 255, 0.4);\n      border-left-style: solid;\n      margin-right: 15px;\n      margin-top: -4.5px;\n      position: absolute;\n      top: 50%;\n      right: 0; }\n    .top-bar-section .has-dropdown.moved {\n      position: static; }\n      .top-bar-section .has-dropdown.moved > .dropdown {\n        display: block;\n        position: static !important;\n        height: auto;\n        width: auto;\n        overflow: visible;\n        clip: auto;\n        position: absolute !important;\n        width: 100%; }\n      .top-bar-section .has-dropdown.moved > a:after {\n        display: none; }\n  .top-bar-section .dropdown {\n    position: absolute;\n    left: 100%;\n    top: 0;\n    z-index: 99;\n    display: block;\n    position: absolute !important;\n    height: 1px;\n    width: 1px;\n    overflow: hidden;\n    clip: rect(1px, 1px, 1px, 1px); }\n    .top-bar-section .dropdown li {\n      width: 100%;\n      height: auto; }\n      .top-bar-section .dropdown li a {\n        font-weight: normal;\n        padding: 8px 15px; }\n        .top-bar-section .dropdown li a.parent-link {\n          font-weight: normal; }\n      .top-bar-section .dropdown li.title h5 {\n        margin-bottom: 0; }\n        .top-bar-section .dropdown li.title h5 a {\n          color: white;\n          line-height: 22.5px;\n          display: block; }\n      .top-bar-section .dropdown li.has-form {\n        padding: 8px 15px; }\n      .top-bar-section .dropdown li .button, .top-bar-section .dropdown li button {\n        top: auto; }\n    .top-bar-section .dropdown label {\n      padding: 8px 15px 2px;\n      margin-bottom: 0;\n      text-transform: uppercase;\n      color: #777777;\n      font-weight: bold;\n      font-size: 0.625rem; }\n\n.js-generated {\n  display: block; }\n\n@media only screen and (min-width: 40.063em) {\n  .top-bar {\n    background: #333333;\n    *zoom: 1;\n    overflow: visible; }\n    .top-bar:before, .top-bar:after {\n      content: \" \";\n      display: table; }\n    .top-bar:after {\n      clear: both; }\n    .top-bar .toggle-topbar {\n      display: none; }\n    .top-bar .title-area {\n      float: left; }\n    .top-bar .name h1 a {\n      width: auto; }\n    .top-bar input,\n    .top-bar .button,\n    .top-bar button {\n      font-size: 0.875rem;\n      position: relative;\n      top: 7px; }\n    .top-bar.expanded {\n      background: #333333; }\n\n  .contain-to-grid .top-bar {\n    max-width: 62.5rem;\n    margin: 0 auto;\n    margin-bottom: 0; }\n\n  .top-bar-section {\n    transition: none 0 0;\n    left: 0 !important; }\n    .top-bar-section ul {\n      width: auto;\n      height: auto !important;\n      display: inline; }\n      .top-bar-section ul li {\n        float: left; }\n        .top-bar-section ul li .js-generated {\n          display: none; }\n    .top-bar-section li.hover > a:not(.button) {\n      background: #272727;\n      color: white; }\n    .top-bar-section li:not(.has-form) a:not(.button) {\n      padding: 0 15px;\n      line-height: 45px;\n      background: #333333; }\n      .top-bar-section li:not(.has-form) a:not(.button):hover {\n        background: #272727; }\n    .top-bar-section li.active:not(.has-form) a:not(.button) {\n      padding: 0 15px;\n      line-height: 45px;\n      color: white;\n      background: #008cba; }\n      .top-bar-section li.active:not(.has-form) a:not(.button):hover {\n        background: #0078a0; }\n    .top-bar-section .has-dropdown > a {\n      padding-right: 35px !important; }\n      .top-bar-section .has-dropdown > a:after {\n        content: \"\";\n        display: block;\n        width: 0;\n        height: 0;\n        border: inset 5px;\n        border-color: rgba(255, 255, 255, 0.4) transparent transparent transparent;\n        border-top-style: solid;\n        margin-top: -2.5px;\n        top: 22.5px; }\n    .top-bar-section .has-dropdown.moved {\n      position: relative; }\n      .top-bar-section .has-dropdown.moved > .dropdown {\n        display: block;\n        position: absolute !important;\n        height: 1px;\n        width: 1px;\n        overflow: hidden;\n        clip: rect(1px, 1px, 1px, 1px); }\n    .top-bar-section .has-dropdown.hover > .dropdown, .top-bar-section .has-dropdown.not-click:hover > .dropdown {\n      display: block;\n      position: static !important;\n      height: auto;\n      width: auto;\n      overflow: visible;\n      clip: auto;\n      position: absolute !important; }\n    .top-bar-section .has-dropdown .dropdown li.has-dropdown > a:after {\n      border: none;\n      content: \"\\00bb\";\n      top: 1rem;\n      margin-top: -1px;\n      right: 5px;\n      line-height: 1.2; }\n    .top-bar-section .dropdown {\n      left: 0;\n      top: auto;\n      background: transparent;\n      min-width: 100%; }\n      .top-bar-section .dropdown li a {\n        color: white;\n        line-height: 1;\n        white-space: nowrap;\n        padding: 12px 15px;\n        background: #333333; }\n      .top-bar-section .dropdown li:not(.has-form) a:not(.button) {\n        color: white;\n        background: #333333; }\n      .top-bar-section .dropdown li:not(.has-form):hover > a:not(.button) {\n        color: white;\n        background: #272727; }\n      .top-bar-section .dropdown li label {\n        white-space: nowrap;\n        background: #333333; }\n      .top-bar-section .dropdown li .dropdown {\n        left: 100%;\n        top: 0; }\n    .top-bar-section > ul > .divider, .top-bar-section > ul > [role=\"separator\"] {\n      border-bottom: none;\n      border-top: none;\n      border-right: solid 1px #4e4e4e;\n      clear: none;\n      height: 45px;\n      width: 0; }\n    .top-bar-section .has-form {\n      background: #333333;\n      padding: 0 15px;\n      height: 45px; }\n    .top-bar-section .right li .dropdown {\n      left: auto;\n      right: 0; }\n      .top-bar-section .right li .dropdown li .dropdown {\n        right: 100%; }\n    .top-bar-section .left li .dropdown {\n      right: auto;\n      left: 0; }\n      .top-bar-section .left li .dropdown li .dropdown {\n        left: 100%; }\n\n  .no-js .top-bar-section ul li:hover > a {\n    background: #272727;\n    color: white; }\n  .no-js .top-bar-section ul li:active > a {\n    background: #008cba;\n    color: white; }\n  .no-js .top-bar-section .has-dropdown:hover > .dropdown {\n    display: block;\n    position: static !important;\n    height: auto;\n    width: auto;\n    overflow: visible;\n    clip: auto;\n    position: absolute !important; } }\n.breadcrumbs {\n  display: block;\n  padding: 0.5625rem 0.875rem 0.5625rem;\n  overflow: hidden;\n  margin-left: 0;\n  list-style: none;\n  border-style: solid;\n  border-width: 1px;\n  background-color: #f4f4f4;\n  border-color: gainsboro;\n  border-radius: 3px; }\n  .breadcrumbs > * {\n    margin: 0;\n    float: left;\n    font-size: 0.6875rem;\n    line-height: 0.6875rem;\n    text-transform: uppercase;\n    color: #008cba; }\n    .breadcrumbs > *:hover a, .breadcrumbs > *:focus a {\n      text-decoration: underline; }\n    .breadcrumbs > * a {\n      color: #008cba; }\n    .breadcrumbs > *.current {\n      cursor: default;\n      color: #333333; }\n      .breadcrumbs > *.current a {\n        cursor: default;\n        color: #333333; }\n      .breadcrumbs > *.current:hover, .breadcrumbs > *.current:hover a, .breadcrumbs > *.current:focus, .breadcrumbs > *.current:focus a {\n        text-decoration: none; }\n    .breadcrumbs > *.unavailable {\n      color: #999999; }\n      .breadcrumbs > *.unavailable a {\n        color: #999999; }\n      .breadcrumbs > *.unavailable:hover, .breadcrumbs > *.unavailable:hover a, .breadcrumbs > *.unavailable:focus,\n      .breadcrumbs > *.unavailable a:focus {\n        text-decoration: none;\n        color: #999999;\n        cursor: default; }\n    .breadcrumbs > *:before {\n      content: \"/\";\n      color: #aaaaaa;\n      margin: 0 0.75rem;\n      position: relative;\n      top: 1px; }\n    .breadcrumbs > *:first-child:before {\n      content: \" \";\n      margin: 0; }\n\n.alert-box {\n  border-style: solid;\n  border-width: 1px;\n  display: block;\n  font-weight: normal;\n  margin-bottom: 1.25rem;\n  position: relative;\n  padding: 0.875rem 1.5rem 0.875rem 0.875rem;\n  font-size: 0.8125rem;\n  transition: opacity 300ms ease-out;\n  background-color: #008cba;\n  border-color: #0078a0;\n  color: white; }\n  .alert-box .close {\n    font-size: 1.375rem;\n    padding: 9px 6px 4px;\n    line-height: 0;\n    position: absolute;\n    top: 50%;\n    margin-top: -0.6875rem;\n    right: 0.25rem;\n    color: #333333;\n    opacity: 0.3; }\n    .alert-box .close:hover, .alert-box .close:focus {\n      opacity: 0.5; }\n  .alert-box.radius {\n    border-radius: 3px; }\n  .alert-box.round {\n    border-radius: 1000px; }\n  .alert-box.success {\n    background-color: #43ac6a;\n    border-color: #3a945b;\n    color: white; }\n  .alert-box.alert {\n    background-color: #f04124;\n    border-color: #de2d0f;\n    color: white; }\n  .alert-box.secondary {\n    background-color: #e7e7e7;\n    border-color: #c7c7c7;\n    color: #4f4f4f; }\n  .alert-box.warning {\n    background-color: #f08a24;\n    border-color: #de770f;\n    color: white; }\n  .alert-box.info {\n    background-color: #a0d3e8;\n    border-color: #74bfdd;\n    color: #4f4f4f; }\n  .alert-box.alert-close {\n    opacity: 0; }\n\n.inline-list {\n  margin: 0 auto 1.0625rem auto;\n  margin-left: -1.375rem;\n  margin-right: 0;\n  padding: 0;\n  list-style: none;\n  overflow: hidden; }\n  .inline-list > li {\n    list-style: none;\n    float: left;\n    margin-left: 1.375rem;\n    display: block; }\n    .inline-list > li > * {\n      display: block; }\n\n.button-group {\n  list-style: none;\n  margin: 0;\n  left: 0;\n  *zoom: 1; }\n  .button-group:before, .button-group:after {\n    content: \" \";\n    display: table; }\n  .button-group:after {\n    clear: both; }\n  .button-group li {\n    margin: 0;\n    float: left; }\n    .button-group li > button, .button-group li .button {\n      border-left: 1px solid;\n      border-color: rgba(255, 255, 255, 0.5); }\n    .button-group li:first-child button, .button-group li:first-child .button {\n      border-left: 0; }\n    .button-group li:first-child {\n      margin-left: 0; }\n  .button-group.radius > * > button, .button-group.radius > * .button {\n    border-left: 1px solid;\n    border-color: rgba(255, 255, 255, 0.5); }\n  .button-group.radius > *:first-child button, .button-group.radius > *:first-child .button {\n    border-left: 0; }\n  .button-group.radius > *:first-child, .button-group.radius > *:first-child > a, .button-group.radius > *:first-child > button, .button-group.radius > *:first-child > .button {\n    border-bottom-left-radius: 3px;\n    border-top-left-radius: 3px; }\n  .button-group.radius > *:last-child, .button-group.radius > *:last-child > a, .button-group.radius > *:last-child > button, .button-group.radius > *:last-child > .button {\n    border-bottom-right-radius: 3px;\n    border-top-right-radius: 3px; }\n  .button-group.round > * > button, .button-group.round > * .button {\n    border-left: 1px solid;\n    border-color: rgba(255, 255, 255, 0.5); }\n  .button-group.round > *:first-child button, .button-group.round > *:first-child .button {\n    border-left: 0; }\n  .button-group.round > *:first-child, .button-group.round > *:first-child > a, .button-group.round > *:first-child > button, .button-group.round > *:first-child > .button {\n    border-bottom-left-radius: 1000px;\n    border-top-left-radius: 1000px; }\n  .button-group.round > *:last-child, .button-group.round > *:last-child > a, .button-group.round > *:last-child > button, .button-group.round > *:last-child > .button {\n    border-bottom-right-radius: 1000px;\n    border-top-right-radius: 1000px; }\n  .button-group.even-2 li {\n    width: 50%; }\n    .button-group.even-2 li > button, .button-group.even-2 li .button {\n      border-left: 1px solid;\n      border-color: rgba(255, 255, 255, 0.5); }\n    .button-group.even-2 li:first-child button, .button-group.even-2 li:first-child .button {\n      border-left: 0; }\n    .button-group.even-2 li button, .button-group.even-2 li .button {\n      width: 100%; }\n  .button-group.even-3 li {\n    width: 33.33333%; }\n    .button-group.even-3 li > button, .button-group.even-3 li .button {\n      border-left: 1px solid;\n      border-color: rgba(255, 255, 255, 0.5); }\n    .button-group.even-3 li:first-child button, .button-group.even-3 li:first-child .button {\n      border-left: 0; }\n    .button-group.even-3 li button, .button-group.even-3 li .button {\n      width: 100%; }\n  .button-group.even-4 li {\n    width: 25%; }\n    .button-group.even-4 li > button, .button-group.even-4 li .button {\n      border-left: 1px solid;\n      border-color: rgba(255, 255, 255, 0.5); }\n    .button-group.even-4 li:first-child button, .button-group.even-4 li:first-child .button {\n      border-left: 0; }\n    .button-group.even-4 li button, .button-group.even-4 li .button {\n      width: 100%; }\n  .button-group.even-5 li {\n    width: 20%; }\n    .button-group.even-5 li > button, .button-group.even-5 li .button {\n      border-left: 1px solid;\n      border-color: rgba(255, 255, 255, 0.5); }\n    .button-group.even-5 li:first-child button, .button-group.even-5 li:first-child .button {\n      border-left: 0; }\n    .button-group.even-5 li button, .button-group.even-5 li .button {\n      width: 100%; }\n  .button-group.even-6 li {\n    width: 16.66667%; }\n    .button-group.even-6 li > button, .button-group.even-6 li .button {\n      border-left: 1px solid;\n      border-color: rgba(255, 255, 255, 0.5); }\n    .button-group.even-6 li:first-child button, .button-group.even-6 li:first-child .button {\n      border-left: 0; }\n    .button-group.even-6 li button, .button-group.even-6 li .button {\n      width: 100%; }\n  .button-group.even-7 li {\n    width: 14.28571%; }\n    .button-group.even-7 li > button, .button-group.even-7 li .button {\n      border-left: 1px solid;\n      border-color: rgba(255, 255, 255, 0.5); }\n    .button-group.even-7 li:first-child button, .button-group.even-7 li:first-child .button {\n      border-left: 0; }\n    .button-group.even-7 li button, .button-group.even-7 li .button {\n      width: 100%; }\n  .button-group.even-8 li {\n    width: 12.5%; }\n    .button-group.even-8 li > button, .button-group.even-8 li .button {\n      border-left: 1px solid;\n      border-color: rgba(255, 255, 255, 0.5); }\n    .button-group.even-8 li:first-child button, .button-group.even-8 li:first-child .button {\n      border-left: 0; }\n    .button-group.even-8 li button, .button-group.even-8 li .button {\n      width: 100%; }\n\n.button-bar {\n  *zoom: 1; }\n  .button-bar:before, .button-bar:after {\n    content: \" \";\n    display: table; }\n  .button-bar:after {\n    clear: both; }\n  .button-bar .button-group {\n    float: left;\n    margin-right: 0.625rem; }\n    .button-bar .button-group div {\n      overflow: hidden; }\n\n/* Panels */\n.panel {\n  border-style: solid;\n  border-width: 1px;\n  border-color: #d8d8d8;\n  margin-bottom: 1.25rem;\n  padding: 1.25rem;\n  background: #f2f2f2; }\n  .panel > :first-child {\n    margin-top: 0; }\n  .panel > :last-child {\n    margin-bottom: 0; }\n  .panel h1, .panel h2, .panel h3, .panel h4, .panel h5, .panel h6, .panel p {\n    color: #333333; }\n  .panel h1, .panel h2, .panel h3, .panel h4, .panel h5, .panel h6 {\n    line-height: 1;\n    margin-bottom: 0.625rem; }\n    .panel h1.subheader, .panel h2.subheader, .panel h3.subheader, .panel h4.subheader, .panel h5.subheader, .panel h6.subheader {\n      line-height: 1.4; }\n  .panel.callout {\n    border-style: solid;\n    border-width: 1px;\n    border-color: #b6edff;\n    margin-bottom: 1.25rem;\n    padding: 1.25rem;\n    background: #ecfaff; }\n    .panel.callout > :first-child {\n      margin-top: 0; }\n    .panel.callout > :last-child {\n      margin-bottom: 0; }\n    .panel.callout h1, .panel.callout h2, .panel.callout h3, .panel.callout h4, .panel.callout h5, .panel.callout h6, .panel.callout p {\n      color: #333333; }\n    .panel.callout h1, .panel.callout h2, .panel.callout h3, .panel.callout h4, .panel.callout h5, .panel.callout h6 {\n      line-height: 1;\n      margin-bottom: 0.625rem; }\n      .panel.callout h1.subheader, .panel.callout h2.subheader, .panel.callout h3.subheader, .panel.callout h4.subheader, .panel.callout h5.subheader, .panel.callout h6.subheader {\n        line-height: 1.4; }\n    .panel.callout a:not(.button) {\n      color: #008cba; }\n  .panel.radius {\n    border-radius: 3px; }\n\n.dropdown.button, button.dropdown {\n  position: relative;\n  padding-right: 3.5625rem; }\n  .dropdown.button:before, button.dropdown:before {\n    position: absolute;\n    content: \"\";\n    width: 0;\n    height: 0;\n    display: block;\n    border-style: solid;\n    border-color: white transparent transparent transparent;\n    top: 50%; }\n  .dropdown.button:before, button.dropdown:before {\n    border-width: 0.375rem;\n    right: 1.40625rem;\n    margin-top: -0.15625rem; }\n  .dropdown.button:before, button.dropdown:before {\n    border-color: white transparent transparent transparent; }\n  .dropdown.button.tiny, button.dropdown.tiny {\n    padding-right: 2.625rem; }\n    .dropdown.button.tiny:before, button.dropdown.tiny:before {\n      border-width: 0.375rem;\n      right: 1.125rem;\n      margin-top: -0.125rem; }\n    .dropdown.button.tiny:before, button.dropdown.tiny:before {\n      border-color: white transparent transparent transparent; }\n  .dropdown.button.small, button.dropdown.small {\n    padding-right: 3.0625rem; }\n    .dropdown.button.small:before, button.dropdown.small:before {\n      border-width: 0.4375rem;\n      right: 1.3125rem;\n      margin-top: -0.15625rem; }\n    .dropdown.button.small:before, button.dropdown.small:before {\n      border-color: white transparent transparent transparent; }\n  .dropdown.button.large, button.dropdown.large {\n    padding-right: 3.625rem; }\n    .dropdown.button.large:before, button.dropdown.large:before {\n      border-width: 0.3125rem;\n      right: 1.71875rem;\n      margin-top: -0.15625rem; }\n    .dropdown.button.large:before, button.dropdown.large:before {\n      border-color: white transparent transparent transparent; }\n  .dropdown.button.secondary:before, button.dropdown.secondary:before {\n    border-color: #333333 transparent transparent transparent; }\n\ndiv.switch {\n  position: relative;\n  padding: 0;\n  display: block;\n  overflow: hidden;\n  border-style: solid;\n  border-width: 1px;\n  margin-bottom: 1.25rem;\n  height: 2.25rem;\n  background: white;\n  border-color: #cccccc; }\n  div.switch label {\n    position: relative;\n    left: 0;\n    z-index: 2;\n    float: left;\n    width: 50%;\n    height: 100%;\n    margin: 0;\n    font-weight: bold;\n    text-align: left;\n    transition: all 0.1s ease-out; }\n  div.switch input {\n    position: absolute;\n    z-index: 3;\n    opacity: 0;\n    width: 100%;\n    height: 100%;\n    -moz-appearance: none; }\n    div.switch input:hover, div.switch input:focus {\n      cursor: pointer; }\n  div.switch span:last-child {\n    position: absolute;\n    top: -1px;\n    left: -1px;\n    z-index: 1;\n    display: block;\n    padding: 0;\n    border-width: 1px;\n    border-style: solid;\n    transition: all 0.1s ease-out; }\n  div.switch input:not(:checked) + label {\n    opacity: 0; }\n  div.switch input:checked {\n    display: none !important; }\n  div.switch input {\n    left: 0;\n    display: block !important; }\n  div.switch input:first-of-type + label,\n  div.switch input:first-of-type + span + label {\n    left: -50%; }\n  div.switch input:first-of-type:checked + label,\n  div.switch input:first-of-type:checked + span + label {\n    left: 0%; }\n  div.switch input:last-of-type + label,\n  div.switch input:last-of-type + span + label {\n    right: -50%;\n    left: auto;\n    text-align: right; }\n  div.switch input:last-of-type:checked + label,\n  div.switch input:last-of-type:checked + span + label {\n    right: 0%;\n    left: auto; }\n  div.switch span.custom {\n    display: none !important; }\n  form.custom div.switch .hidden-field {\n    margin-left: auto;\n    position: absolute;\n    visibility: visible; }\n  div.switch label {\n    padding: 0;\n    line-height: 2.3rem;\n    font-size: 0.875rem; }\n  div.switch input:first-of-type:checked ~ span:last-child {\n    left: 100%;\n    margin-left: -2.1875rem; }\n  div.switch span:last-child {\n    width: 2.25rem;\n    height: 2.25rem; }\n  div.switch span:last-child {\n    border-color: #b3b3b3;\n    background: white;\n    background: linear-gradient(to bottom, white 0%, #f2f2f2 100%);\n    box-shadow: 2px 0 10px 0 rgba(0, 0, 0, 0.07), 1000px 0 0 980px #f3faf6, -2px 0 10px 0 rgba(0, 0, 0, 0.07), -1000px 0 0 1000px whitesmoke; }\n  div.switch:hover span:last-child, div.switch:focus span:last-child {\n    background: white;\n    background: linear-gradient(to bottom, white 0%, #e6e6e6 100%); }\n  div.switch:active {\n    background: transparent; }\n  div.switch.large {\n    height: 2.75rem; }\n    div.switch.large label {\n      padding: 0;\n      line-height: 2.3rem;\n      font-size: 1.0625rem; }\n    div.switch.large input:first-of-type:checked ~ span:last-child {\n      left: 100%;\n      margin-left: -2.6875rem; }\n    div.switch.large span:last-child {\n      width: 2.75rem;\n      height: 2.75rem; }\n  div.switch.small {\n    height: 1.75rem; }\n    div.switch.small label {\n      padding: 0;\n      line-height: 2.1rem;\n      font-size: 0.75rem; }\n    div.switch.small input:first-of-type:checked ~ span:last-child {\n      left: 100%;\n      margin-left: -1.6875rem; }\n    div.switch.small span:last-child {\n      width: 1.75rem;\n      height: 1.75rem; }\n  div.switch.tiny {\n    height: 1.375rem; }\n    div.switch.tiny label {\n      padding: 0;\n      line-height: 1.9rem;\n      font-size: 0.6875rem; }\n    div.switch.tiny input:first-of-type:checked ~ span:last-child {\n      left: 100%;\n      margin-left: -1.3125rem; }\n    div.switch.tiny span:last-child {\n      width: 1.375rem;\n      height: 1.375rem; }\n  div.switch.radius {\n    border-radius: 4px; }\n    div.switch.radius span:last-child {\n      border-radius: 3px; }\n  div.switch.round {\n    border-radius: 1000px; }\n    div.switch.round span:last-child {\n      border-radius: 999px; }\n    div.switch.round label {\n      padding: 0 0.5625rem; }\n\n/* Image Thumbnails */\n.th {\n  line-height: 0;\n  display: inline-block;\n  border: solid 4px white;\n  max-width: 100%;\n  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2);\n  transition: all 200ms ease-out; }\n  .th:hover, .th:focus {\n    box-shadow: 0 0 6px 1px rgba(0, 140, 186, 0.5); }\n  .th.radius {\n    border-radius: 3px; }\n\n/* Pricing Tables */\n.pricing-table {\n  border: solid 1px #dddddd;\n  margin-left: 0;\n  margin-bottom: 1.25rem; }\n  .pricing-table * {\n    list-style: none;\n    line-height: 1; }\n  .pricing-table .title {\n    background-color: #333333;\n    padding: 0.9375rem 1.25rem;\n    text-align: center;\n    color: #eeeeee;\n    font-weight: normal;\n    font-size: 1rem;\n    font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif; }\n  .pricing-table .price {\n    background-color: #f6f6f6;\n    padding: 0.9375rem 1.25rem;\n    text-align: center;\n    color: #333333;\n    font-weight: normal;\n    font-size: 2rem;\n    font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif; }\n  .pricing-table .description {\n    background-color: white;\n    padding: 0.9375rem;\n    text-align: center;\n    color: #777777;\n    font-size: 0.75rem;\n    font-weight: normal;\n    line-height: 1.4;\n    border-bottom: dotted 1px #dddddd; }\n  .pricing-table .bullet-item {\n    background-color: white;\n    padding: 0.9375rem;\n    text-align: center;\n    color: #333333;\n    font-size: 0.875rem;\n    font-weight: normal;\n    border-bottom: dotted 1px #dddddd; }\n  .pricing-table .cta-button {\n    background-color: white;\n    text-align: center;\n    padding: 1.25rem 1.25rem 0; }\n\n@keyframes rotate {\n  from {\n    -webkit-transform: rotate(0deg);\n    -moz-transform: rotate(0deg);\n    -ms-transform: rotate(0deg);\n    -o-transform: rotate(0deg);\n    transform: rotate(0deg); }\n\n  to {\n    -webkit-transform: rotate(360deg);\n    -moz-transform: rotate(360deg);\n    -ms-transform: rotate(360deg);\n    -o-transform: rotate(360deg);\n    transform: rotate(360deg); } }\n\n/* Orbit Graceful Loading */\n.slideshow-wrapper {\n  position: relative; }\n  .slideshow-wrapper ul {\n    list-style-type: none;\n    margin: 0; }\n    .slideshow-wrapper ul li,\n    .slideshow-wrapper ul li .orbit-caption {\n      display: none; }\n    .slideshow-wrapper ul li:first-child {\n      display: block; }\n  .slideshow-wrapper .orbit-container {\n    background-color: transparent; }\n    .slideshow-wrapper .orbit-container li {\n      display: block; }\n      .slideshow-wrapper .orbit-container li .orbit-caption {\n        display: block; }\n  .slideshow-wrapper .preloader {\n    display: block;\n    width: 40px;\n    height: 40px;\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    margin-top: -20px;\n    margin-left: -20px;\n    border: solid 3px;\n    border-color: #555555 white;\n    border-radius: 1000px;\n    animation-name: rotate;\n    animation-duration: 1.5s;\n    animation-iteration-count: infinite;\n    animation-timing-function: linear; }\n\n.orbit-container {\n  overflow: hidden;\n  width: 100%;\n  position: relative;\n  background: none; }\n  .orbit-container .orbit-slides-container {\n    list-style: none;\n    margin: 0;\n    padding: 0;\n    position: relative;\n    -webkit-transform: translateZ(0); }\n    .orbit-container .orbit-slides-container img {\n      display: block;\n      max-width: 100%; }\n    .orbit-container .orbit-slides-container.fade li {\n      opacity: 0;\n      transition: opacity 500ms ease-in-out;\n      -ms-transform: translate(0, 0);\n      -webkit-transform: translate3d(0, 0, 0);\n      -moz-transform: translate3d(0, 0, 0);\n      -o-transform: translate3d(0, 0, 0);\n      transform: translate3d(0, 0, 0); }\n      .orbit-container .orbit-slides-container.fade li.animate-in {\n        opacity: 1;\n        z-index: 20;\n        transition: opacity 500ms ease-in-out; }\n      .orbit-container .orbit-slides-container.fade li.animate-out {\n        z-index: 10;\n        transition: opacity 500ms ease-in-out; }\n    .orbit-container .orbit-slides-container.swipe-next li {\n      -ms-transform: translate(100%, 0);\n      -webkit-transform: translate3d(100%, 0, 0);\n      -moz-transform: translate3d(100%, 0, 0);\n      -o-transform: translate3d(100%, 0, 0);\n      transform: translate3d(100%, 0, 0); }\n      .orbit-container .orbit-slides-container.swipe-next li.animate-in {\n        -ms-transform: translate(0, 0);\n        -webkit-transform: translate3d(0, 0, 0);\n        -moz-transform: translate3d(0, 0, 0);\n        -o-transform: translate3d(0, 0, 0);\n        transform: translate3d(0, 0, 0);\n        transition-duration: 500ms; }\n      .orbit-container .orbit-slides-container.swipe-next li.animate-out {\n        -ms-transform: translate(-100%, 0);\n        -webkit-transform: translate3d(-100%, 0, 0);\n        -moz-transform: translate3d(-100%, 0, 0);\n        -o-transform: translate3d(-100%, 0, 0);\n        transform: translate3d(-100%, 0, 0);\n        transition-duration: 500ms; }\n    .orbit-container .orbit-slides-container.swipe-prev li {\n      -ms-transform: translate(-100%, 0);\n      -webkit-transform: translate3d(-100%, 0, 0);\n      -moz-transform: translate3d(-100%, 0, 0);\n      -o-transform: translate3d(-100%, 0, 0);\n      transform: translate3d(-100%, 0, 0); }\n      .orbit-container .orbit-slides-container.swipe-prev li.animate-in {\n        -ms-transform: translate(0, 0);\n        -webkit-transform: translate3d(0, 0, 0);\n        -moz-transform: translate3d(0, 0, 0);\n        -o-transform: translate3d(0, 0, 0);\n        transform: translate3d(0, 0, 0);\n        transition-duration: 500ms; }\n      .orbit-container .orbit-slides-container.swipe-prev li.animate-out {\n        -ms-transform: translate(100%, 0);\n        -webkit-transform: translate3d(100%, 0, 0);\n        -moz-transform: translate3d(100%, 0, 0);\n        -o-transform: translate3d(100%, 0, 0);\n        transform: translate3d(100%, 0, 0);\n        transition-duration: 500ms; }\n    .orbit-container .orbit-slides-container li {\n      position: absolute;\n      top: 0;\n      left: 0;\n      width: 100%;\n      -ms-transform: translate(100%, 0);\n      -webkit-transform: translate3d(100%, 0, 0);\n      -moz-transform: translate3d(100%, 0, 0);\n      -o-transform: translate3d(100%, 0, 0);\n      transform: translate3d(100%, 0, 0); }\n      .orbit-container .orbit-slides-container li.active {\n        opacity: 1;\n        top: 0;\n        left: 0;\n        -ms-transform: translate(0, 0);\n        -webkit-transform: translate3d(0, 0, 0);\n        -moz-transform: translate3d(0, 0, 0);\n        -o-transform: translate3d(0, 0, 0);\n        transform: translate3d(0, 0, 0); }\n      .orbit-container .orbit-slides-container li .orbit-caption {\n        position: absolute;\n        bottom: 0;\n        background-color: rgba(51, 51, 51, 0.8);\n        color: white;\n        width: 100%;\n        padding: 0.625rem 0.875rem;\n        font-size: 0.875rem; }\n  .orbit-container .orbit-slide-number {\n    position: absolute;\n    top: 10px;\n    left: 10px;\n    font-size: 12px;\n    color: white;\n    background: rgba(0, 0, 0, 0);\n    z-index: 10; }\n    .orbit-container .orbit-slide-number span {\n      font-weight: 700;\n      padding: 0.3125rem; }\n  .orbit-container .orbit-timer {\n    position: absolute;\n    top: 12px;\n    right: 10px;\n    height: 6px;\n    width: 100px;\n    z-index: 10; }\n    .orbit-container .orbit-timer .orbit-progress {\n      height: 3px;\n      background-color: rgba(255, 255, 255, 0.3);\n      display: block;\n      width: 0%;\n      position: relative;\n      right: 20px;\n      top: 5px; }\n    .orbit-container .orbit-timer > span {\n      display: none;\n      position: absolute;\n      top: 0px;\n      right: 0;\n      width: 11px;\n      height: 14px;\n      border: solid 4px white;\n      border-top: none;\n      border-bottom: none; }\n    .orbit-container .orbit-timer.paused > span {\n      right: -4px;\n      top: 0px;\n      width: 11px;\n      height: 14px;\n      border: inset 8px;\n      border-left-style: solid;\n      -webkit-transform: rotate(180deg);\n      -moz-transform: rotate(180deg);\n      -ms-transform: rotate(180deg);\n      -o-transform: rotate(180deg);\n      transform: rotate(180deg);\n      border-color: transparent white transparent transparent; }\n      .orbit-container .orbit-timer.paused > span.dark {\n        border-color: transparent #333333 transparent transparent; }\n  .orbit-container:hover .orbit-timer > span {\n    display: block; }\n  .orbit-container .orbit-prev,\n  .orbit-container .orbit-next {\n    position: absolute;\n    top: 45%;\n    margin-top: -25px;\n    width: 36px;\n    height: 60px;\n    line-height: 50px;\n    color: white;\n    background-color: transparent;\n    text-indent: -9999px !important;\n    z-index: 10; }\n    .orbit-container .orbit-prev:hover,\n    .orbit-container .orbit-next:hover {\n      background-color: rgba(0, 0, 0, 0.3); }\n    .orbit-container .orbit-prev > span,\n    .orbit-container .orbit-next > span {\n      position: absolute;\n      top: 50%;\n      margin-top: -10px;\n      display: block;\n      width: 0;\n      height: 0;\n      border: inset 10px; }\n  .orbit-container .orbit-prev {\n    left: 0; }\n    .orbit-container .orbit-prev > span {\n      border-right-style: solid;\n      border-color: transparent;\n      border-right-color: white; }\n    .orbit-container .orbit-prev:hover > span {\n      border-right-color: white; }\n  .orbit-container .orbit-next {\n    right: 0; }\n    .orbit-container .orbit-next > span {\n      border-color: transparent;\n      border-left-style: solid;\n      border-left-color: white;\n      left: 50%;\n      margin-left: -4px; }\n    .orbit-container .orbit-next:hover > span {\n      border-left-color: white; }\n  .orbit-container .orbit-bullets-container {\n    text-align: center; }\n  .orbit-container .orbit-bullets {\n    margin: 0 auto 30px auto;\n    overflow: hidden;\n    position: relative;\n    top: 10px;\n    float: none;\n    text-align: center;\n    display: block; }\n    .orbit-container .orbit-bullets li {\n      display: inline-block;\n      width: 0.5625rem;\n      height: 0.5625rem;\n      background: #cccccc;\n      float: none;\n      margin-right: 6px;\n      border-radius: 1000px; }\n      .orbit-container .orbit-bullets li.active {\n        background: #999999; }\n      .orbit-container .orbit-bullets li:last-child {\n        margin-right: 0; }\n\n.touch .orbit-container .orbit-prev,\n.touch .orbit-container .orbit-next {\n  display: none; }\n.touch .orbit-bullets {\n  display: none; }\n\n@media only screen and (min-width: 40.063em) {\n  .touch .orbit-container .orbit-prev,\n  .touch .orbit-container .orbit-next {\n    display: inherit; }\n  .touch .orbit-bullets {\n    display: block; } }\n@media only screen and (max-width: 40em) {\n  .orbit-stack-on-small .orbit-slides-container {\n    height: auto !important; }\n  .orbit-stack-on-small .orbit-slides-container > * {\n    position: relative;\n    margin-left: 0% !important;\n    opacity: 1 !important;\n    -webkit-transform: none !important;\n    -moz-transform: none !important;\n    -ms-transform: none !important;\n    -o-transform: none !important;\n    transform: none !important;\n    transition: none !important; }\n  .orbit-stack-on-small .orbit-timer {\n    display: none; }\n  .orbit-stack-on-small .orbit-next, .orbit-stack-on-small .orbit-prev {\n    display: none; }\n  .orbit-stack-on-small .orbit-bullets {\n    display: none; } }\n[data-magellan-expedition], [data-magellan-expedition-clone] {\n  background: white;\n  z-index: 50;\n  min-width: 100%;\n  padding: 10px; }\n  [data-magellan-expedition] .sub-nav, [data-magellan-expedition-clone] .sub-nav {\n    margin-bottom: 0; }\n    [data-magellan-expedition] .sub-nav dd, [data-magellan-expedition-clone] .sub-nav dd {\n      margin-bottom: 0; }\n    [data-magellan-expedition] .sub-nav a, [data-magellan-expedition-clone] .sub-nav a {\n      line-height: 1.8em; }\n\n.tabs {\n  *zoom: 1;\n  margin-bottom: 0 !important; }\n  .tabs:before, .tabs:after {\n    content: \" \";\n    display: table; }\n  .tabs:after {\n    clear: both; }\n  .tabs dd {\n    position: relative;\n    margin-bottom: 0 !important;\n    float: left; }\n    .tabs dd > a {\n      display: block;\n      background: #efefef;\n      color: #222222;\n      padding: 1rem 2rem;\n      font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;\n      font-size: 1rem; }\n      .tabs dd > a:hover {\n        background: #e1e1e1; }\n    .tabs dd.active a {\n      background: white; }\n  .tabs.radius dd:first-child a {\n    border-bottom-left-radius: 3px;\n    border-top-left-radius: 3px; }\n  .tabs.radius dd:last-child a {\n    border-bottom-right-radius: 3px;\n    border-top-right-radius: 3px; }\n  .tabs.vertical dd {\n    position: inherit;\n    float: none;\n    display: block;\n    top: auto; }\n\n.tabs-content {\n  *zoom: 1;\n  margin-bottom: 1.5rem;\n  width: 100%; }\n  .tabs-content:before, .tabs-content:after {\n    content: \" \";\n    display: table; }\n  .tabs-content:after {\n    clear: both; }\n  .tabs-content > .content {\n    display: none;\n    float: left;\n    padding: 0.9375rem 0;\n    width: 100%; }\n    .tabs-content > .content.active {\n      display: block;\n      float: none; }\n    .tabs-content > .content.contained {\n      padding: 0.9375rem; }\n  .tabs-content.vertical {\n    display: block; }\n    .tabs-content.vertical > .content {\n      padding: 0 0.9375rem; }\n\n@media only screen and (min-width: 40.063em) {\n  .tabs.vertical {\n    width: 20%;\n    float: left;\n    margin-bottom: 1.25rem; }\n\n  .tabs-content.vertical {\n    width: 80%;\n    float: left;\n    margin-left: -1px; } }\n.no-js .tabs-content > .content {\n  display: block;\n  float: none; }\n\nul.pagination {\n  display: block;\n  height: 1.5rem;\n  margin-left: -0.3125rem; }\n  ul.pagination li {\n    height: 1.5rem;\n    color: #222222;\n    font-size: 0.875rem;\n    margin-left: 0.3125rem; }\n    ul.pagination li a {\n      display: block;\n      padding: 0.0625rem 0.625rem 0.0625rem;\n      color: #999999;\n      border-radius: 3px; }\n    ul.pagination li:hover a,\n    ul.pagination li a:focus {\n      background: #e6e6e6; }\n    ul.pagination li.unavailable a {\n      cursor: default;\n      color: #999999; }\n    ul.pagination li.unavailable:hover a, ul.pagination li.unavailable a:focus {\n      background: transparent; }\n    ul.pagination li.current a {\n      background: #008cba;\n      color: white;\n      font-weight: bold;\n      cursor: default; }\n      ul.pagination li.current a:hover, ul.pagination li.current a:focus {\n        background: #008cba; }\n  ul.pagination li {\n    float: left;\n    display: block; }\n\n/* Pagination centred wrapper */\n.pagination-centered {\n  text-align: center; }\n  .pagination-centered ul.pagination li {\n    float: none;\n    display: inline-block; }\n\n.side-nav {\n  display: block;\n  margin: 0;\n  padding: 0.875rem 0;\n  list-style-type: none;\n  list-style-position: inside;\n  font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif; }\n  .side-nav li {\n    margin: 0 0 0.4375rem 0;\n    font-size: 0.875rem; }\n    .side-nav li a:not(.button) {\n      display: block;\n      color: #008cba; }\n      .side-nav li a:not(.button):hover, .side-nav li a:not(.button):focus {\n        color: #1cc7ff; }\n    .side-nav li.active > a:first-child:not(.button) {\n      color: #1cc7ff;\n      font-weight: normal;\n      font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif; }\n    .side-nav li.divider {\n      border-top: 1px solid;\n      height: 0;\n      padding: 0;\n      list-style: none;\n      border-top-color: white; }\n\n.accordion {\n  *zoom: 1;\n  margin-bottom: 0; }\n  .accordion:before, .accordion:after {\n    content: \" \";\n    display: table; }\n  .accordion:after {\n    clear: both; }\n  .accordion dd {\n    display: block;\n    margin-bottom: 0 !important; }\n    .accordion dd.active > a {\n      background: #e8e8e8; }\n    .accordion dd > a {\n      background: #efefef;\n      color: #222222;\n      padding: 1rem;\n      display: block;\n      font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;\n      font-size: 1rem; }\n      .accordion dd > a:hover {\n        background: #e3e3e3; }\n  .accordion .content {\n    display: none;\n    padding: 0.9375rem; }\n    .accordion .content.active {\n      display: block;\n      background: white; }\n\n.text-left {\n  text-align: left !important; }\n\n.text-right {\n  text-align: right !important; }\n\n.text-center {\n  text-align: center !important; }\n\n.text-justify {\n  text-align: justify !important; }\n\n@media only screen and (max-width: 40em) {\n  .small-only-text-left {\n    text-align: left !important; }\n\n  .small-only-text-right {\n    text-align: right !important; }\n\n  .small-only-text-center {\n    text-align: center !important; }\n\n  .small-only-text-justify {\n    text-align: justify !important; } }\n@media only screen {\n  .small-text-left {\n    text-align: left !important; }\n\n  .small-text-right {\n    text-align: right !important; }\n\n  .small-text-center {\n    text-align: center !important; }\n\n  .small-text-justify {\n    text-align: justify !important; } }\n@media only screen and (min-width: 40.063em) and (max-width: 64em) {\n  .medium-only-text-left {\n    text-align: left !important; }\n\n  .medium-only-text-right {\n    text-align: right !important; }\n\n  .medium-only-text-center {\n    text-align: center !important; }\n\n  .medium-only-text-justify {\n    text-align: justify !important; } }\n@media only screen and (min-width: 40.063em) {\n  .medium-text-left {\n    text-align: left !important; }\n\n  .medium-text-right {\n    text-align: right !important; }\n\n  .medium-text-center {\n    text-align: center !important; }\n\n  .medium-text-justify {\n    text-align: justify !important; } }\n@media only screen and (min-width: 64.063em) and (max-width: 90em) {\n  .large-only-text-left {\n    text-align: left !important; }\n\n  .large-only-text-right {\n    text-align: right !important; }\n\n  .large-only-text-center {\n    text-align: center !important; }\n\n  .large-only-text-justify {\n    text-align: justify !important; } }\n@media only screen and (min-width: 64.063em) {\n  .large-text-left {\n    text-align: left !important; }\n\n  .large-text-right {\n    text-align: right !important; }\n\n  .large-text-center {\n    text-align: center !important; }\n\n  .large-text-justify {\n    text-align: justify !important; } }\n@media only screen and (min-width: 90.063em) and (max-width: 120em) {\n  .xlarge-only-text-left {\n    text-align: left !important; }\n\n  .xlarge-only-text-right {\n    text-align: right !important; }\n\n  .xlarge-only-text-center {\n    text-align: center !important; }\n\n  .xlarge-only-text-justify {\n    text-align: justify !important; } }\n@media only screen and (min-width: 90.063em) {\n  .xlarge-text-left {\n    text-align: left !important; }\n\n  .xlarge-text-right {\n    text-align: right !important; }\n\n  .xlarge-text-center {\n    text-align: center !important; }\n\n  .xlarge-text-justify {\n    text-align: justify !important; } }\n@media only screen and (min-width: 120.063em) and (max-width: 99999999em) {\n  .xxlarge-only-text-left {\n    text-align: left !important; }\n\n  .xxlarge-only-text-right {\n    text-align: right !important; }\n\n  .xxlarge-only-text-center {\n    text-align: center !important; }\n\n  .xxlarge-only-text-justify {\n    text-align: justify !important; } }\n@media only screen and (min-width: 120.063em) {\n  .xxlarge-text-left {\n    text-align: left !important; }\n\n  .xxlarge-text-right {\n    text-align: right !important; }\n\n  .xxlarge-text-center {\n    text-align: center !important; }\n\n  .xxlarge-text-justify {\n    text-align: justify !important; } }\n/* Typography resets */\ndiv,\ndl,\ndt,\ndd,\nul,\nol,\nli,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\npre,\nform,\np,\nblockquote,\nth,\ntd {\n  margin: 0;\n  padding: 0; }\n\n/* Default Link Styles */\na {\n  color: #008cba;\n  text-decoration: none;\n  line-height: inherit; }\n  a:hover, a:focus {\n    color: #0078a0; }\n  a img {\n    border: none; }\n\n/* Default paragraph styles */\np {\n  font-family: inherit;\n  font-weight: normal;\n  font-size: 1rem;\n  line-height: 1.6;\n  margin-bottom: 1.25rem;\n  text-rendering: optimizeLegibility; }\n  p.lead {\n    font-size: 1.21875rem;\n    line-height: 1.6; }\n  p aside {\n    font-size: 0.875rem;\n    line-height: 1.35;\n    font-style: italic; }\n\n/* Default header styles */\nh1, h2, h3, h4, h5, h6 {\n  font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif !important;\n  font-weight: normal;\n  font-style: normal;\n  color: #222222;\n  text-rendering: optimizeLegibility;\n  margin-top: 0.2rem;\n  margin-bottom: 0.5rem;\n  line-height: 1.4; }\n  h1 small, h2 small, h3 small, h4 small, h5 small, h6 small {\n    font-size: 60%;\n    color: #6f6f6f;\n    line-height: 0; }\n\nh1 {\n  font-size: 2.125rem; }\n\nh2 {\n  font-size: 1.6875rem; }\n\nh3 {\n  font-size: 1.375rem; }\n\nh4 {\n  font-size: 1.125rem; }\n\nh5 {\n  font-size: 1.125rem; }\n\nh6 {\n  font-size: 1rem; }\n\n.subheader {\n  line-height: 1.4;\n  color: #6f6f6f;\n  font-weight: normal;\n  margin-top: 0.2rem;\n  margin-bottom: 0.5rem; }\n\nhr {\n  border: solid #dddddd;\n  border-width: 1px 0 0;\n  clear: both;\n  margin: 1.25rem 0 1.1875rem;\n  height: 0; }\n\n/* Helpful Typography Defaults */\nem,\ni {\n  font-style: italic;\n  line-height: inherit; }\n\nstrong,\nb {\n  font-weight: bold;\n  line-height: inherit; }\n\nsmall {\n  font-size: 60%;\n  line-height: inherit; }\n\ncode {\n  font-family: Consolas, \"Liberation Mono\", Courier, monospace;\n  font-weight: bold;\n  color: #bd260d; }\n\n/* Lists */\nul,\nol,\ndl {\n  font-size: 1rem;\n  line-height: 1.6;\n  margin-bottom: 1.25rem;\n  list-style-position: outside;\n  font-family: inherit; }\n\nul {\n  margin-left: 1.1rem; }\n  ul.no-bullet {\n    margin-left: 0; }\n    ul.no-bullet li ul,\n    ul.no-bullet li ol {\n      margin-left: 1.25rem;\n      margin-bottom: 0;\n      list-style: none; }\n\n/* Unordered Lists */\nul li ul,\nul li ol {\n  margin-left: 1.25rem;\n  margin-bottom: 0; }\nul.square li ul, ul.circle li ul, ul.disc li ul {\n  list-style: inherit; }\nul.square {\n  list-style-type: square;\n  margin-left: 1.1rem; }\nul.circle {\n  list-style-type: circle;\n  margin-left: 1.1rem; }\nul.disc {\n  list-style-type: disc;\n  margin-left: 1.1rem; }\nul.no-bullet {\n  list-style: none; }\n\n/* Ordered Lists */\nol {\n  margin-left: 1.4rem; }\n  ol li ul,\n  ol li ol {\n    margin-left: 1.25rem;\n    margin-bottom: 0; }\n\n/* Definition Lists */\ndl dt {\n  margin-bottom: 0.3rem;\n  font-weight: bold; }\ndl dd {\n  margin-bottom: 0.75rem; }\n\n/* Abbreviations */\nabbr,\nacronym {\n  text-transform: uppercase;\n  font-size: 90%;\n  color: #222222;\n  border-bottom: 1px dotted #dddddd;\n  cursor: help; }\n\nabbr {\n  text-transform: none; }\n\n/* Blockquotes */\nblockquote {\n  margin: 0 0 1.25rem;\n  padding: 0.5625rem 1.25rem 0 1.1875rem;\n  border-left: 1px solid #dddddd; }\n  blockquote cite {\n    display: block;\n    font-size: 0.8125rem;\n    color: #555555; }\n    blockquote cite:before {\n      content: \"\\2014 \\0020\"; }\n    blockquote cite a,\n    blockquote cite a:visited {\n      color: #555555; }\n\nblockquote,\nblockquote p {\n  line-height: 1.6;\n  color: #6f6f6f; }\n\n/* Microformats */\n.vcard {\n  display: inline-block;\n  margin: 0 0 1.25rem 0;\n  border: 1px solid #dddddd;\n  padding: 0.625rem 0.75rem; }\n  .vcard li {\n    margin: 0;\n    display: block; }\n  .vcard .fn {\n    font-weight: bold;\n    font-size: 0.9375rem; }\n\n.vevent .summary {\n  font-weight: bold; }\n.vevent abbr {\n  cursor: default;\n  text-decoration: none;\n  font-weight: bold;\n  border: none;\n  padding: 0 0.0625rem; }\n\n@media only screen and (min-width: 40.063em) {\n  h1, h2, h3, h4, h5, h6 {\n    line-height: 1.4; }\n\n  h1 {\n    font-size: 2.75rem; }\n\n  h2 {\n    font-size: 2.3125rem; }\n\n  h3 {\n    font-size: 1.6875rem; }\n\n  h4 {\n    font-size: 1.4375rem; } }\n/*\n * Print styles.\n *\n * Inlined to avoid required HTTP connection: www.phpied.com/delay-loading-your-print-css/\n * Credit to Paul Irish and HTML5 Boilerplate (html5boilerplate.com)\n*/\n.print-only {\n  display: none !important; }\n\n@media print {\n  * {\n    background: transparent !important;\n    color: black !important;\n    /* Black prints faster: h5bp.com/s */\n    box-shadow: none !important;\n    text-shadow: none !important; }\n\n  a,\n  a:visited {\n    text-decoration: underline; }\n\n  a[href]:after {\n    content: \" (\" attr(href) \")\"; }\n\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\"; }\n\n  .ir a:after,\n  a[href^=\"javascript:\"]:after,\n  a[href^=\"#\"]:after {\n    content: \"\"; }\n\n  pre,\n  blockquote {\n    border: 1px solid #999999;\n    page-break-inside: avoid; }\n\n  thead {\n    display: table-header-group;\n    /* h5bp.com/t */ }\n\n  tr,\n  img {\n    page-break-inside: avoid; }\n\n  img {\n    max-width: 100% !important; }\n\n  @page {\n    margin: 0.5cm; }\n\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3; }\n\n  h2,\n  h3 {\n    page-break-after: avoid; }\n\n  .hide-on-print {\n    display: none !important; }\n\n  .print-only {\n    display: block !important; }\n\n  .hide-for-print {\n    display: none !important; }\n\n  .show-for-print {\n    display: inherit !important; } }\n.split.button {\n  position: relative;\n  padding-right: 5.0625rem; }\n  .split.button span {\n    display: block;\n    height: 100%;\n    position: absolute;\n    right: 0;\n    top: 0;\n    border-left: solid 1px; }\n    .split.button span:before {\n      position: absolute;\n      content: \"\";\n      width: 0;\n      height: 0;\n      display: block;\n      border-style: inset;\n      top: 50%;\n      left: 50%; }\n    .split.button span:active {\n      background-color: rgba(0, 0, 0, 0.1); }\n  .split.button span {\n    border-left-color: rgba(255, 255, 255, 0.5); }\n  .split.button span {\n    width: 3.09375rem; }\n    .split.button span:before {\n      border-top-style: solid;\n      border-width: 0.375rem;\n      top: 48%;\n      margin-left: -0.375rem; }\n  .split.button span:before {\n    border-color: white transparent transparent transparent; }\n  .split.button.secondary span {\n    border-left-color: rgba(255, 255, 255, 0.5); }\n  .split.button.secondary span:before {\n    border-color: white transparent transparent transparent; }\n  .split.button.alert span {\n    border-left-color: rgba(255, 255, 255, 0.5); }\n  .split.button.success span {\n    border-left-color: rgba(255, 255, 255, 0.5); }\n  .split.button.tiny {\n    padding-right: 3.75rem; }\n    .split.button.tiny span {\n      width: 2.25rem; }\n      .split.button.tiny span:before {\n        border-top-style: solid;\n        border-width: 0.375rem;\n        top: 48%;\n        margin-left: -0.375rem; }\n  .split.button.small {\n    padding-right: 4.375rem; }\n    .split.button.small span {\n      width: 2.625rem; }\n      .split.button.small span:before {\n        border-top-style: solid;\n        border-width: 0.4375rem;\n        top: 48%;\n        margin-left: -0.375rem; }\n  .split.button.large {\n    padding-right: 5.5rem; }\n    .split.button.large span {\n      width: 3.4375rem; }\n      .split.button.large span:before {\n        border-top-style: solid;\n        border-width: 0.3125rem;\n        top: 48%;\n        margin-left: -0.375rem; }\n  .split.button.expand {\n    padding-left: 2rem; }\n  .split.button.secondary span:before {\n    border-color: #333333 transparent transparent transparent; }\n  .split.button.radius span {\n    border-bottom-right-radius: 3px;\n    border-top-right-radius: 3px; }\n  .split.button.round span {\n    border-bottom-right-radius: 1000px;\n    border-top-right-radius: 1000px; }\n\n.reveal-modal-bg {\n  position: fixed;\n  height: 100%;\n  width: 100%;\n  background: black;\n  background: rgba(0, 0, 0, 0.45);\n  z-index: 99;\n  display: none;\n  top: 0;\n  left: 0; }\n\ndialog, .reveal-modal {\n  visibility: hidden;\n  display: none;\n  position: absolute;\n  z-index: 100;\n  width: 100vw;\n  top: 0;\n  left: 0;\n  background-color: white;\n  padding: 1.25rem;\n  border: solid 1px #666666;\n  box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); }\n  @media only screen and (max-width: 40em) {\n    dialog, .reveal-modal {\n      min-height: 100vh; } }\n  @media only screen and (min-width: 40.063em) {\n    dialog, .reveal-modal {\n      left: 50%; } }\n  dialog .column,\n  dialog .columns, .reveal-modal .column,\n  .reveal-modal .columns {\n    min-width: 0; }\n  dialog > :first-child, .reveal-modal > :first-child {\n    margin-top: 0; }\n  dialog > :last-child, .reveal-modal > :last-child {\n    margin-bottom: 0; }\n  @media only screen and (min-width: 40.063em) {\n    dialog, .reveal-modal {\n      margin-left: -40%;\n      width: 80%; } }\n  @media only screen and (min-width: 40.063em) {\n    dialog, .reveal-modal {\n      top: 6.25rem; } }\n  dialog .close-reveal-modal, .reveal-modal .close-reveal-modal {\n    font-size: 2.5rem;\n    line-height: 1;\n    position: absolute;\n    top: 0.5rem;\n    right: 0.6875rem;\n    color: #aaaaaa;\n    font-weight: bold;\n    cursor: pointer; }\n\ndialog[open] {\n  display: block;\n  visibility: visible; }\n\n@media only screen and (min-width: 40.063em) {\n  dialog, .reveal-modal {\n    padding: 1.875rem; }\n    dialog.radius, .reveal-modal.radius {\n      border-radius: 3px; }\n    dialog.round, .reveal-modal.round {\n      border-radius: 1000px; }\n    dialog.collapse, .reveal-modal.collapse {\n      padding: 0; }\n  dialog.full, .reveal-modal.full {\n    top: 0;\n    left: 0;\n    height: 100vh;\n    min-height: 100vh;\n    margin-left: 0 !important; } }\n  @media only screen and (min-width: 40.063em) and (min-width: 40.063em) {\n    dialog.tiny, .reveal-modal.tiny {\n      margin-left: -15%;\n      width: 30%; } }\n  @media only screen and (min-width: 40.063em) and (min-width: 40.063em) {\n    dialog.small, .reveal-modal.small {\n      margin-left: -20%;\n      width: 40%; } }\n  @media only screen and (min-width: 40.063em) and (min-width: 40.063em) {\n    dialog.medium, .reveal-modal.medium {\n      margin-left: -30%;\n      width: 60%; } }\n  @media only screen and (min-width: 40.063em) and (min-width: 40.063em) {\n    dialog.large, .reveal-modal.large {\n      margin-left: -35%;\n      width: 70%; } }\n  @media only screen and (min-width: 40.063em) and (min-width: 40.063em) {\n    dialog.xlarge, .reveal-modal.xlarge {\n      margin-left: -47.5%;\n      width: 95%; } }\n\n  @media only screen and (min-width: 40.063em) and (min-width: 40.063em) {\n    dialog.full, .reveal-modal.full {\n      margin-left: -50vw;\n      width: 100vw; } }\n\n@media print {\n  dialog, .reveal-modal {\n    background: white !important; } }\n/* Tooltips */\n.has-tip {\n  border-bottom: dotted 1px #cccccc;\n  cursor: help;\n  font-weight: bold;\n  color: #333333; }\n  .has-tip:hover, .has-tip:focus {\n    border-bottom: dotted 1px #003f54;\n    color: #008cba; }\n  .has-tip.tip-left, .has-tip.tip-right {\n    float: none !important; }\n\n.tooltip {\n  display: none;\n  position: absolute;\n  z-index: 999;\n  font-weight: normal;\n  font-size: 0.875rem;\n  line-height: 1.3;\n  padding: 0.75rem;\n  max-width: 85%;\n  left: 50%;\n  width: 100%;\n  color: white;\n  background: #333333; }\n  .tooltip > .nub {\n    display: block;\n    left: 5px;\n    position: absolute;\n    width: 0;\n    height: 0;\n    border: solid 5px;\n    border-color: transparent transparent #333333 transparent;\n    top: -10px; }\n    .tooltip > .nub.rtl {\n      left: auto;\n      right: 5px; }\n  .tooltip.radius {\n    border-radius: 3px; }\n  .tooltip.round {\n    border-radius: 1000px; }\n    .tooltip.round > .nub {\n      left: 2rem; }\n  .tooltip.opened {\n    color: #008cba !important;\n    border-bottom: dotted 1px #003f54 !important; }\n\n.tap-to-close {\n  display: block;\n  font-size: 0.625rem;\n  color: #777777;\n  font-weight: normal; }\n\n@media only screen and (min-width: 40.063em) {\n  .tooltip > .nub {\n    border-color: transparent transparent #333333 transparent;\n    top: -10px; }\n  .tooltip.tip-top > .nub {\n    border-color: #333333 transparent transparent transparent;\n    top: auto;\n    bottom: -10px; }\n  .tooltip.tip-left, .tooltip.tip-right {\n    float: none !important; }\n  .tooltip.tip-left > .nub {\n    border-color: transparent transparent transparent #333333;\n    right: -10px;\n    left: auto;\n    top: 50%;\n    margin-top: -5px; }\n  .tooltip.tip-right > .nub {\n    border-color: transparent #333333 transparent transparent;\n    right: auto;\n    left: -10px;\n    top: 50%;\n    margin-top: -5px; } }\n/* Clearing Styles */\n.clearing-thumbs, [data-clearing] {\n  *zoom: 1;\n  margin-bottom: 0;\n  margin-left: 0;\n  list-style: none; }\n  .clearing-thumbs:before, .clearing-thumbs:after, [data-clearing]:before, [data-clearing]:after {\n    content: \" \";\n    display: table; }\n  .clearing-thumbs:after, [data-clearing]:after {\n    clear: both; }\n  .clearing-thumbs li, [data-clearing] li {\n    float: left;\n    margin-right: 10px; }\n  .clearing-thumbs[class*=\"block-grid-\"] li, [data-clearing][class*=\"block-grid-\"] li {\n    margin-right: 0; }\n\n.clearing-blackout {\n  background: #333333;\n  position: fixed;\n  width: 100%;\n  height: 100%;\n  top: 0;\n  left: 0;\n  z-index: 998; }\n  .clearing-blackout .clearing-close {\n    display: block; }\n\n.clearing-container {\n  position: relative;\n  z-index: 998;\n  height: 100%;\n  overflow: hidden;\n  margin: 0; }\n\n.clearing-touch-label {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  color: #aaa;\n  font-size: 0.6em; }\n\n.visible-img {\n  height: 95%;\n  position: relative; }\n  .visible-img img {\n    position: absolute;\n    left: 50%;\n    top: 50%;\n    margin-left: -50%;\n    max-height: 100%;\n    max-width: 100%; }\n\n.clearing-caption {\n  color: #cccccc;\n  font-size: 0.875em;\n  line-height: 1.3;\n  margin-bottom: 0;\n  text-align: center;\n  bottom: 0;\n  background: #333333;\n  width: 100%;\n  padding: 10px 30px 20px;\n  position: absolute;\n  left: 0; }\n\n.clearing-close {\n  z-index: 999;\n  padding-left: 20px;\n  padding-top: 10px;\n  font-size: 30px;\n  line-height: 1;\n  color: #cccccc;\n  display: none; }\n  .clearing-close:hover, .clearing-close:focus {\n    color: #ccc; }\n\n.clearing-assembled .clearing-container {\n  height: 100%; }\n  .clearing-assembled .clearing-container .carousel > ul {\n    display: none; }\n\n.clearing-feature li {\n  display: none; }\n  .clearing-feature li.clearing-featured-img {\n    display: block; }\n\n@media only screen and (min-width: 40.063em) {\n  .clearing-main-prev,\n  .clearing-main-next {\n    position: absolute;\n    height: 100%;\n    width: 40px;\n    top: 0; }\n    .clearing-main-prev > span,\n    .clearing-main-next > span {\n      position: absolute;\n      top: 50%;\n      display: block;\n      width: 0;\n      height: 0;\n      border: solid 12px; }\n      .clearing-main-prev > span:hover,\n      .clearing-main-next > span:hover {\n        opacity: 0.8; }\n\n  .clearing-main-prev {\n    left: 0; }\n    .clearing-main-prev > span {\n      left: 5px;\n      border-color: transparent;\n      border-right-color: #cccccc; }\n\n  .clearing-main-next {\n    right: 0; }\n    .clearing-main-next > span {\n      border-color: transparent;\n      border-left-color: #cccccc; }\n\n  .clearing-main-prev.disabled,\n  .clearing-main-next.disabled {\n    opacity: 0.3; }\n\n  .clearing-assembled .clearing-container .carousel {\n    background: rgba(51, 51, 51, 0.8);\n    height: 120px;\n    margin-top: 10px;\n    text-align: center; }\n    .clearing-assembled .clearing-container .carousel > ul {\n      display: inline-block;\n      z-index: 999;\n      height: 100%;\n      position: relative;\n      float: none; }\n      .clearing-assembled .clearing-container .carousel > ul li {\n        display: block;\n        width: 120px;\n        min-height: inherit;\n        float: left;\n        overflow: hidden;\n        margin-right: 0;\n        padding: 0;\n        position: relative;\n        cursor: pointer;\n        opacity: 0.4;\n        clear: none; }\n        .clearing-assembled .clearing-container .carousel > ul li.fix-height img {\n          height: 100%;\n          max-width: none; }\n        .clearing-assembled .clearing-container .carousel > ul li a.th {\n          border: none;\n          box-shadow: none;\n          display: block; }\n        .clearing-assembled .clearing-container .carousel > ul li img {\n          cursor: pointer !important;\n          width: 100% !important; }\n        .clearing-assembled .clearing-container .carousel > ul li.visible {\n          opacity: 1; }\n        .clearing-assembled .clearing-container .carousel > ul li:hover {\n          opacity: 0.8; }\n  .clearing-assembled .clearing-container .visible-img {\n    background: #333333;\n    overflow: hidden;\n    height: 85%; }\n\n  .clearing-close {\n    position: absolute;\n    top: 10px;\n    right: 20px;\n    padding-left: 0;\n    padding-top: 0; } }\n/* Progress Bar */\n.progress {\n  background-color: #f6f6f6;\n  height: 1.5625rem;\n  border: 1px solid white;\n  padding: 0.125rem;\n  margin-bottom: 0.625rem; }\n  .progress .meter {\n    background: #008cba;\n    height: 100%;\n    display: block; }\n  .progress.secondary .meter {\n    background: #e7e7e7;\n    height: 100%;\n    display: block; }\n  .progress.success .meter {\n    background: #43ac6a;\n    height: 100%;\n    display: block; }\n  .progress.alert .meter {\n    background: #f04124;\n    height: 100%;\n    display: block; }\n  .progress.radius {\n    border-radius: 3px; }\n    .progress.radius .meter {\n      border-radius: 2px; }\n  .progress.round {\n    border-radius: 1000px; }\n    .progress.round .meter {\n      border-radius: 999px; }\n\n.sub-nav {\n  display: block;\n  width: auto;\n  overflow: hidden;\n  margin: -0.25rem 0 1.125rem;\n  padding-top: 0.25rem;\n  margin-right: 0;\n  margin-left: -0.75rem; }\n  .sub-nav dt {\n    text-transform: uppercase; }\n  .sub-nav dt,\n  .sub-nav dd,\n  .sub-nav li {\n    float: left;\n    display: inline;\n    margin-left: 1rem;\n    margin-bottom: 0.625rem;\n    font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;\n    font-weight: normal;\n    font-size: 0.875rem;\n    color: #999999; }\n    .sub-nav dt a,\n    .sub-nav dd a,\n    .sub-nav li a {\n      text-decoration: none;\n      color: #999999;\n      padding: 0.1875rem 1rem; }\n      .sub-nav dt a:hover,\n      .sub-nav dd a:hover,\n      .sub-nav li a:hover {\n        color: #737373; }\n    .sub-nav dt.active a,\n    .sub-nav dd.active a,\n    .sub-nav li.active a {\n      border-radius: 3px;\n      font-weight: normal;\n      background: #008cba;\n      padding: 0.1875rem 1rem;\n      cursor: default;\n      color: white; }\n      .sub-nav dt.active a:hover,\n      .sub-nav dd.active a:hover,\n      .sub-nav li.active a:hover {\n        background: #0078a0; }\n\n/* Foundation Joyride */\n.joyride-list {\n  display: none; }\n\n/* Default styles for the container */\n.joyride-tip-guide {\n  display: none;\n  position: absolute;\n  background: #333333;\n  color: white;\n  z-index: 101;\n  top: 0;\n  left: 2.5%;\n  font-family: inherit;\n  font-weight: normal;\n  width: 95%; }\n\n.lt-ie9 .joyride-tip-guide {\n  max-width: 800px;\n  left: 50%;\n  margin-left: -400px; }\n\n.joyride-content-wrapper {\n  width: 100%;\n  padding: 1.125rem 1.25rem 1.5rem; }\n  .joyride-content-wrapper .button {\n    margin-bottom: 0 !important; }\n\n/* Add a little css triangle pip, older browser just miss out on the fanciness of it */\n.joyride-tip-guide .joyride-nub {\n  display: block;\n  position: absolute;\n  left: 22px;\n  width: 0;\n  height: 0;\n  border: 10px solid #333333; }\n  .joyride-tip-guide .joyride-nub.top {\n    border-top-style: solid;\n    border-color: #333333;\n    border-top-color: transparent !important;\n    border-left-color: transparent !important;\n    border-right-color: transparent !important;\n    top: -20px; }\n  .joyride-tip-guide .joyride-nub.bottom {\n    border-bottom-style: solid;\n    border-color: #333333 !important;\n    border-bottom-color: transparent !important;\n    border-left-color: transparent !important;\n    border-right-color: transparent !important;\n    bottom: -20px; }\n  .joyride-tip-guide .joyride-nub.right {\n    right: -20px; }\n  .joyride-tip-guide .joyride-nub.left {\n    left: -20px; }\n\n/* Typography */\n.joyride-tip-guide h1,\n.joyride-tip-guide h2,\n.joyride-tip-guide h3,\n.joyride-tip-guide h4,\n.joyride-tip-guide h5,\n.joyride-tip-guide h6 {\n  line-height: 1.25;\n  margin: 0;\n  font-weight: bold;\n  color: white; }\n\n.joyride-tip-guide p {\n  margin: 0 0 1.125rem 0;\n  font-size: 0.875rem;\n  line-height: 1.3; }\n\n.joyride-timer-indicator-wrap {\n  width: 50px;\n  height: 3px;\n  border: solid 1px #555555;\n  position: absolute;\n  right: 1.0625rem;\n  bottom: 1rem; }\n\n.joyride-timer-indicator {\n  display: block;\n  width: 0;\n  height: inherit;\n  background: #666666; }\n\n.joyride-close-tip {\n  position: absolute;\n  right: 12px;\n  top: 10px;\n  color: #777777 !important;\n  text-decoration: none;\n  font-size: 24px;\n  font-weight: normal;\n  line-height: 0.5 !important; }\n  .joyride-close-tip:hover, .joyride-close-tip:focus {\n    color: #eeeeee !important; }\n\n.joyride-modal-bg {\n  position: fixed;\n  height: 100%;\n  width: 100%;\n  background: transparent;\n  background: rgba(0, 0, 0, 0.5);\n  z-index: 100;\n  display: none;\n  top: 0;\n  left: 0;\n  cursor: pointer; }\n\n.joyride-expose-wrapper {\n  background-color: #ffffff;\n  position: absolute;\n  border-radius: 3px;\n  z-index: 102;\n  box-shadow: 0 0 15px white; }\n\n.joyride-expose-cover {\n  background: transparent;\n  border-radius: 3px;\n  position: absolute;\n  z-index: 9999;\n  top: 0;\n  left: 0; }\n\n/* Styles for screens that are at least 768px; */\n@media only screen and (min-width: 40.063em) {\n  .joyride-tip-guide {\n    width: 300px;\n    left: inherit; }\n    .joyride-tip-guide .joyride-nub.bottom {\n      border-color: #333333 !important;\n      border-bottom-color: transparent !important;\n      border-left-color: transparent !important;\n      border-right-color: transparent !important;\n      bottom: -20px; }\n    .joyride-tip-guide .joyride-nub.right {\n      border-color: #333333 !important;\n      border-top-color: transparent !important;\n      border-right-color: transparent !important;\n      border-bottom-color: transparent !important;\n      top: 22px;\n      left: auto;\n      right: -20px; }\n    .joyride-tip-guide .joyride-nub.left {\n      border-color: #333333 !important;\n      border-top-color: transparent !important;\n      border-left-color: transparent !important;\n      border-bottom-color: transparent !important;\n      top: 22px;\n      left: -20px;\n      right: auto; } }\n.label {\n  font-weight: normal;\n  font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif;\n  text-align: center;\n  text-decoration: none;\n  line-height: 1;\n  white-space: nowrap;\n  display: inline-block;\n  position: relative;\n  margin-bottom: inherit;\n  padding: 0.25rem 0.5rem 0.375rem;\n  font-size: 0.6875rem;\n  background-color: #008cba;\n  color: white; }\n  .label.radius {\n    border-radius: 3px; }\n  .label.round {\n    border-radius: 1000px; }\n  .label.alert {\n    background-color: #f04124;\n    color: white; }\n  .label.success {\n    background-color: #43ac6a;\n    color: white; }\n  .label.secondary {\n    background-color: #e7e7e7;\n    color: #333333; }\n\n.off-canvas-wrap {\n  -webkit-backface-visibility: hidden;\n  position: relative;\n  width: 100%;\n  overflow: hidden; }\n  .off-canvas-wrap.move-right, .off-canvas-wrap.move-left {\n    min-height: 100%;\n    -webkit-overflow-scrolling: touch; }\n\n.inner-wrap {\n  -webkit-backface-visibility: hidden;\n  position: relative;\n  width: 100%;\n  *zoom: 1;\n  -webkit-transition: -webkit-transform 500ms ease;\n  -moz-transition: -moz-transform 500ms ease;\n  -ms-transition: -ms-transform 500ms ease;\n  -o-transition: -o-transform 500ms ease;\n  transition: transform 500ms ease; }\n  .inner-wrap:before, .inner-wrap:after {\n    content: \" \";\n    display: table; }\n  .inner-wrap:after {\n    clear: both; }\n\n.tab-bar {\n  -webkit-backface-visibility: hidden;\n  background: #333333;\n  color: white;\n  height: 2.8125rem;\n  line-height: 2.8125rem;\n  position: relative; }\n  .tab-bar h1, .tab-bar h2, .tab-bar h3, .tab-bar h4, .tab-bar h5, .tab-bar h6 {\n    color: white;\n    font-weight: bold;\n    line-height: 2.8125rem;\n    margin: 0; }\n  .tab-bar h1, .tab-bar h2, .tab-bar h3, .tab-bar h4 {\n    font-size: 1.125rem; }\n\n.left-small {\n  width: 2.8125rem;\n  height: 2.8125rem;\n  position: absolute;\n  top: 0;\n  border-right: solid 1px #1a1a1a;\n  left: 0; }\n\n.right-small {\n  width: 2.8125rem;\n  height: 2.8125rem;\n  position: absolute;\n  top: 0;\n  border-left: solid 1px #1a1a1a;\n  right: 0; }\n\n.tab-bar-section {\n  padding: 0 0.625rem;\n  position: absolute;\n  text-align: center;\n  height: 2.8125rem;\n  top: 0; }\n  @media only screen and (min-width: 40.063em) {\n    .tab-bar-section {\n      text-align: left; } }\n  .tab-bar-section.left {\n    left: 0;\n    right: 2.8125rem; }\n  .tab-bar-section.right {\n    left: 2.8125rem;\n    right: 0; }\n  .tab-bar-section.middle {\n    left: 2.8125rem;\n    right: 2.8125rem; }\n\n.tab-bar .menu-icon {\n  text-indent: 2.1875rem;\n  width: 2.8125rem;\n  height: 2.8125rem;\n  display: block;\n  line-height: 2.0625rem;\n  padding: 0;\n  color: white;\n  position: relative;\n  -ms-transform: translate(0, 0);\n  -webkit-transform: translate3d(0, 0, 0);\n  -moz-transform: translate3d(0, 0, 0);\n  -ms-transform: translate3d(0, 0, 0);\n  -o-transform: translate3d(0, 0, 0);\n  transform: translate3d(0, 0, 0); }\n  .tab-bar .menu-icon span {\n    position: absolute;\n    display: block;\n    height: 0;\n    width: 1rem;\n    line-height: 1;\n    top: 0.9375rem;\n    left: 0.90625rem;\n    box-shadow: 0 0px 0 1px white, 0 7px 0 1px white, 0 14px 0 1px white; }\n  .tab-bar .menu-icon:hover span {\n    box-shadow: 0 0px 0 1px #b3b3b3, 0 7px 0 1px #b3b3b3, 0 14px 0 1px #b3b3b3; }\n\n.left-off-canvas-menu {\n  -webkit-backface-visibility: hidden;\n  width: 15.625rem;\n  top: 0;\n  bottom: 0;\n  position: absolute;\n  overflow-y: auto;\n  background: #333333;\n  z-index: 1001;\n  box-sizing: content-box;\n  -webkit-overflow-scrolling: touch;\n  -ms-transform: translate(-100%, 0);\n  -webkit-transform: translate3d(-100%, 0, 0);\n  -moz-transform: translate3d(-100%, 0, 0);\n  -ms-transform: translate3d(-100%, 0, 0);\n  -o-transform: translate3d(-100%, 0, 0);\n  transform: translate3d(-100%, 0, 0);\n  left: 0; }\n  .left-off-canvas-menu * {\n    -webkit-backface-visibility: hidden; }\n\n.right-off-canvas-menu {\n  -webkit-backface-visibility: hidden;\n  width: 15.625rem;\n  top: 0;\n  bottom: 0;\n  position: absolute;\n  overflow-y: auto;\n  background: #333333;\n  z-index: 1001;\n  box-sizing: content-box;\n  -webkit-overflow-scrolling: touch;\n  -ms-transform: translate(100%, 0);\n  -webkit-transform: translate3d(100%, 0, 0);\n  -moz-transform: translate3d(100%, 0, 0);\n  -ms-transform: translate3d(100%, 0, 0);\n  -o-transform: translate3d(100%, 0, 0);\n  transform: translate3d(100%, 0, 0);\n  right: 0; }\n  .right-off-canvas-menu * {\n    -webkit-backface-visibility: hidden; }\n\nul.off-canvas-list {\n  list-style-type: none;\n  padding: 0;\n  margin: 0; }\n  ul.off-canvas-list li label {\n    padding: 0.3rem 0.9375rem;\n    color: #999999;\n    text-transform: uppercase;\n    font-weight: bold;\n    background: #444444;\n    border-top: 1px solid #5e5e5e;\n    border-bottom: none;\n    margin: 0; }\n  ul.off-canvas-list li a {\n    display: block;\n    padding: 0.66667rem;\n    color: rgba(255, 255, 255, 0.7);\n    border-bottom: 1px solid #262626;\n    transition: background 300ms ease; }\n    ul.off-canvas-list li a:hover {\n      background: #242424; }\n\n.move-right > .inner-wrap {\n  -ms-transform: translate(15.625rem, 0);\n  -webkit-transform: translate3d(15.625rem, 0, 0);\n  -moz-transform: translate3d(15.625rem, 0, 0);\n  -ms-transform: translate3d(15.625rem, 0, 0);\n  -o-transform: translate3d(15.625rem, 0, 0);\n  transform: translate3d(15.625rem, 0, 0); }\n.move-right .exit-off-canvas {\n  -webkit-backface-visibility: hidden;\n  transition: background 300ms ease;\n  cursor: pointer;\n  box-shadow: -4px 0 4px rgba(0, 0, 0, 0.5), 4px 0 4px rgba(0, 0, 0, 0.5);\n  display: block;\n  position: absolute;\n  background: rgba(255, 255, 255, 0.2);\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  z-index: 1002;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }\n  @media only screen and (min-width: 40.063em) {\n    .move-right .exit-off-canvas:hover {\n      background: rgba(255, 255, 255, 0.05); } }\n\n.move-left > .inner-wrap {\n  -ms-transform: translate(-15.625rem, 0);\n  -webkit-transform: translate3d(-15.625rem, 0, 0);\n  -moz-transform: translate3d(-15.625rem, 0, 0);\n  -ms-transform: translate3d(-15.625rem, 0, 0);\n  -o-transform: translate3d(-15.625rem, 0, 0);\n  transform: translate3d(-15.625rem, 0, 0); }\n.move-left .exit-off-canvas {\n  -webkit-backface-visibility: hidden;\n  transition: background 300ms ease;\n  cursor: pointer;\n  box-shadow: -4px 0 4px rgba(0, 0, 0, 0.5), 4px 0 4px rgba(0, 0, 0, 0.5);\n  display: block;\n  position: absolute;\n  background: rgba(255, 255, 255, 0.2);\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  z-index: 1002;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }\n  @media only screen and (min-width: 40.063em) {\n    .move-left .exit-off-canvas:hover {\n      background: rgba(255, 255, 255, 0.05); } }\n\n.no-csstransforms .left-off-canvas-menu {\n  left: -15.625rem; }\n.no-csstransforms .right-off-canvas-menu {\n  right: -15.625rem; }\n.no-csstransforms .move-left > .inner-wrap {\n  right: 15.625rem; }\n.no-csstransforms .move-right > .inner-wrap {\n  left: 15.625rem; }\n\n/* Foundation Dropdowns */\n.f-dropdown {\n  position: absolute;\n  left: -9999px;\n  list-style: none;\n  margin-left: 0;\n  width: 100%;\n  max-height: none;\n  height: auto;\n  background: white;\n  border: solid 1px #cccccc;\n  font-size: 0.875rem;\n  z-index: 99;\n  margin-top: 2px;\n  max-width: 200px; }\n  .f-dropdown > *:first-child {\n    margin-top: 0; }\n  .f-dropdown > *:last-child {\n    margin-bottom: 0; }\n  .f-dropdown:before {\n    content: \"\";\n    display: block;\n    width: 0;\n    height: 0;\n    border: inset 6px;\n    border-color: transparent transparent white transparent;\n    border-bottom-style: solid;\n    position: absolute;\n    top: -12px;\n    left: 10px;\n    z-index: 99; }\n  .f-dropdown:after {\n    content: \"\";\n    display: block;\n    width: 0;\n    height: 0;\n    border: inset 7px;\n    border-color: transparent transparent #cccccc transparent;\n    border-bottom-style: solid;\n    position: absolute;\n    top: -14px;\n    left: 9px;\n    z-index: 98; }\n  .f-dropdown.right:before {\n    left: auto;\n    right: 10px; }\n  .f-dropdown.right:after {\n    left: auto;\n    right: 9px; }\n  .f-dropdown.drop-right {\n    position: absolute;\n    left: -9999px;\n    list-style: none;\n    margin-left: 0;\n    width: 100%;\n    max-height: none;\n    height: auto;\n    background: white;\n    border: solid 1px #cccccc;\n    font-size: 0.875rem;\n    z-index: 99;\n    margin-top: 0;\n    margin-left: 2px;\n    max-width: 200px; }\n    .f-dropdown.drop-right > *:first-child {\n      margin-top: 0; }\n    .f-dropdown.drop-right > *:last-child {\n      margin-bottom: 0; }\n    .f-dropdown.drop-right:before {\n      content: \"\";\n      display: block;\n      width: 0;\n      height: 0;\n      border: inset 6px;\n      border-color: transparent white transparent transparent;\n      border-right-style: solid;\n      position: absolute;\n      top: 10px;\n      left: -12px;\n      z-index: 99; }\n    .f-dropdown.drop-right:after {\n      content: \"\";\n      display: block;\n      width: 0;\n      height: 0;\n      border: inset 7px;\n      border-color: transparent #cccccc transparent transparent;\n      border-right-style: solid;\n      position: absolute;\n      top: 9px;\n      left: -14px;\n      z-index: 98; }\n  .f-dropdown.drop-left {\n    position: absolute;\n    left: -9999px;\n    list-style: none;\n    margin-left: 0;\n    width: 100%;\n    max-height: none;\n    height: auto;\n    background: white;\n    border: solid 1px #cccccc;\n    font-size: 0.875rem;\n    z-index: 99;\n    margin-top: 0;\n    margin-left: -2px;\n    max-width: 200px; }\n    .f-dropdown.drop-left > *:first-child {\n      margin-top: 0; }\n    .f-dropdown.drop-left > *:last-child {\n      margin-bottom: 0; }\n    .f-dropdown.drop-left:before {\n      content: \"\";\n      display: block;\n      width: 0;\n      height: 0;\n      border: inset 6px;\n      border-color: transparent transparent transparent white;\n      border-left-style: solid;\n      position: absolute;\n      top: 10px;\n      right: -12px;\n      left: auto;\n      z-index: 99; }\n    .f-dropdown.drop-left:after {\n      content: \"\";\n      display: block;\n      width: 0;\n      height: 0;\n      border: inset 7px;\n      border-color: transparent transparent transparent #cccccc;\n      border-left-style: solid;\n      position: absolute;\n      top: 9px;\n      right: -14px;\n      left: auto;\n      z-index: 98; }\n  .f-dropdown.drop-top {\n    position: absolute;\n    left: -9999px;\n    list-style: none;\n    margin-left: 0;\n    width: 100%;\n    max-height: none;\n    height: auto;\n    background: white;\n    border: solid 1px #cccccc;\n    font-size: 0.875rem;\n    z-index: 99;\n    margin-top: -2px;\n    margin-left: 0;\n    max-width: 200px; }\n    .f-dropdown.drop-top > *:first-child {\n      margin-top: 0; }\n    .f-dropdown.drop-top > *:last-child {\n      margin-bottom: 0; }\n    .f-dropdown.drop-top:before {\n      content: \"\";\n      display: block;\n      width: 0;\n      height: 0;\n      border: inset 6px;\n      border-color: white transparent transparent transparent;\n      border-top-style: solid;\n      position: absolute;\n      top: auto;\n      bottom: -12px;\n      left: 10px;\n      right: auto;\n      z-index: 99; }\n    .f-dropdown.drop-top:after {\n      content: \"\";\n      display: block;\n      width: 0;\n      height: 0;\n      border: inset 7px;\n      border-color: #cccccc transparent transparent transparent;\n      border-top-style: solid;\n      position: absolute;\n      top: auto;\n      bottom: -14px;\n      left: 9px;\n      right: auto;\n      z-index: 98; }\n  .f-dropdown li {\n    font-size: 0.875rem;\n    cursor: pointer;\n    line-height: 1.125rem;\n    margin: 0; }\n    .f-dropdown li:hover, .f-dropdown li:focus {\n      background: #eeeeee; }\n    .f-dropdown li a {\n      display: block;\n      padding: 0.5rem;\n      color: #555555; }\n  .f-dropdown.content {\n    position: absolute;\n    left: -9999px;\n    list-style: none;\n    margin-left: 0;\n    padding: 1.25rem;\n    width: 100%;\n    height: auto;\n    max-height: none;\n    background: white;\n    border: solid 1px #cccccc;\n    font-size: 0.875rem;\n    z-index: 99;\n    max-width: 200px; }\n    .f-dropdown.content > *:first-child {\n      margin-top: 0; }\n    .f-dropdown.content > *:last-child {\n      margin-bottom: 0; }\n  .f-dropdown.tiny {\n    max-width: 200px; }\n  .f-dropdown.small {\n    max-width: 300px; }\n  .f-dropdown.medium {\n    max-width: 500px; }\n  .f-dropdown.large {\n    max-width: 800px; }\n\ntable {\n  background: white;\n  margin-bottom: 1.25rem;\n  border: solid 1px #dddddd; }\n  table thead,\n  table tfoot {\n    background: whitesmoke; }\n    table thead tr th,\n    table thead tr td,\n    table tfoot tr th,\n    table tfoot tr td {\n      padding: 0.5rem 0.625rem 0.625rem;\n      font-size: 0.875rem;\n      font-weight: bold;\n      color: #222222;\n      text-align: left; }\n  table tr th,\n  table tr td {\n    padding: 0.5625rem 0.625rem;\n    font-size: 0.875rem;\n    color: #222222; }\n  table tr.even, table tr.alt, table tr:nth-of-type(even) {\n    background: #f9f9f9; }\n  table thead tr th,\n  table tfoot tr th,\n  table tbody tr td,\n  table tr td,\n  table tfoot tr td {\n    display: table-cell;\n    line-height: 1.125rem; }\n\n/* Standard Forms */\nform {\n  margin: 0 0 1rem; }\n\n/* Using forms within rows, we need to set some defaults */\nform .row .row {\n  margin: 0 -0.5rem; }\n  form .row .row .column,\n  form .row .row .columns {\n    padding: 0 0.5rem; }\n  form .row .row.collapse {\n    margin: 0; }\n    form .row .row.collapse .column,\n    form .row .row.collapse .columns {\n      padding: 0; }\n    form .row .row.collapse input {\n      border-bottom-right-radius: 0;\n      border-top-right-radius: 0; }\nform .row input.column,\nform .row input.columns,\nform .row textarea.column,\nform .row textarea.columns {\n  padding-left: 0.5rem; }\n\n/* Label Styles */\nlabel {\n  font-size: 0.875rem;\n  color: #4d4d4d;\n  cursor: pointer;\n  display: block;\n  font-weight: normal;\n  line-height: 1.5;\n  margin-bottom: 0;\n  /* Styles for required inputs */ }\n  label.right {\n    float: none;\n    text-align: right; }\n  label.inline {\n    margin: 0 0 1rem 0;\n    padding: 0.5625rem 0; }\n  label small {\n    text-transform: capitalize;\n    color: #676767; }\n\nselect::-ms-expand {\n  display: none; }\n\n@-moz-document url-prefix() {\n  select {\n    background: #fafafa; }\n\n  select:hover {\n    background: #f3f3f3; } }\n\n/* Attach elements to the beginning or end of an input */\n.prefix,\n.postfix {\n  display: block;\n  position: relative;\n  z-index: 2;\n  text-align: center;\n  width: 100%;\n  padding-top: 0;\n  padding-bottom: 0;\n  border-style: solid;\n  border-width: 1px;\n  overflow: hidden;\n  font-size: 0.875rem;\n  height: 2.3125rem;\n  line-height: 2.3125rem; }\n\n/* Adjust padding, alignment and radius if pre/post element is a button */\n.postfix.button {\n  padding-left: 0;\n  padding-right: 0;\n  padding-top: 0;\n  padding-bottom: 0;\n  text-align: center;\n  line-height: 2.125rem;\n  border: none; }\n\n.prefix.button {\n  padding-left: 0;\n  padding-right: 0;\n  padding-top: 0;\n  padding-bottom: 0;\n  text-align: center;\n  line-height: 2.125rem;\n  border: none; }\n\n.prefix.button.radius {\n  border-radius: 0;\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px; }\n\n.postfix.button.radius {\n  border-radius: 0;\n  border-bottom-right-radius: 3px;\n  border-top-right-radius: 3px; }\n\n.prefix.button.round {\n  border-radius: 0;\n  border-bottom-left-radius: 1000px;\n  border-top-left-radius: 1000px; }\n\n.postfix.button.round {\n  border-radius: 0;\n  border-bottom-right-radius: 1000px;\n  border-top-right-radius: 1000px; }\n\n/* Separate prefix and postfix styles when on span or label so buttons keep their own */\nspan.prefix, label.prefix {\n  background: #f2f2f2;\n  border-right: none;\n  color: #333333;\n  border-color: #cccccc; }\n  span.prefix.radius, label.prefix.radius {\n    border-radius: 0;\n    border-bottom-left-radius: 3px;\n    border-top-left-radius: 3px; }\n\nspan.postfix, label.postfix {\n  background: #f2f2f2;\n  border-left: none;\n  color: #333333;\n  border-color: #cccccc; }\n  span.postfix.radius, label.postfix.radius {\n    border-radius: 0;\n    border-bottom-right-radius: 3px;\n    border-top-right-radius: 3px; }\n\n/* We use this to get basic styling on all basic form elements */\ninput[type=\"text\"],\ninput[type=\"password\"],\ninput[type=\"date\"],\ninput[type=\"datetime\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"],\ninput[type=\"week\"],\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ninput[type=\"tel\"],\ninput[type=\"time\"],\ninput[type=\"url\"],\ntextarea {\n  -webkit-appearance: none;\n  background-color: white;\n  font-family: inherit;\n  border: 1px solid #cccccc;\n  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n  color: rgba(0, 0, 0, 0.75);\n  display: block;\n  font-size: 0.875rem;\n  margin: 0 0 1rem 0;\n  padding: 0.5rem;\n  height: 2.3125rem;\n  width: 100%;\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  transition: box-shadow 0.45s, border-color 0.45s ease-in-out; }\n  input[type=\"text\"]:focus,\n  input[type=\"password\"]:focus,\n  input[type=\"date\"]:focus,\n  input[type=\"datetime\"]:focus,\n  input[type=\"datetime-local\"]:focus,\n  input[type=\"month\"]:focus,\n  input[type=\"week\"]:focus,\n  input[type=\"email\"]:focus,\n  input[type=\"number\"]:focus,\n  input[type=\"search\"]:focus,\n  input[type=\"tel\"]:focus,\n  input[type=\"time\"]:focus,\n  input[type=\"url\"]:focus,\n  textarea:focus {\n    box-shadow: 0 0 5px #999999;\n    border-color: #999999; }\n  input[type=\"text\"]:focus,\n  input[type=\"password\"]:focus,\n  input[type=\"date\"]:focus,\n  input[type=\"datetime\"]:focus,\n  input[type=\"datetime-local\"]:focus,\n  input[type=\"month\"]:focus,\n  input[type=\"week\"]:focus,\n  input[type=\"email\"]:focus,\n  input[type=\"number\"]:focus,\n  input[type=\"search\"]:focus,\n  input[type=\"tel\"]:focus,\n  input[type=\"time\"]:focus,\n  input[type=\"url\"]:focus,\n  textarea:focus {\n    background: #fafafa;\n    border-color: #999999;\n    outline: none; }\n  input[type=\"text\"][disabled], fieldset[disabled] input[type=\"text\"],\n  input[type=\"password\"][disabled], fieldset[disabled]\n  input[type=\"password\"],\n  input[type=\"date\"][disabled], fieldset[disabled]\n  input[type=\"date\"],\n  input[type=\"datetime\"][disabled], fieldset[disabled]\n  input[type=\"datetime\"],\n  input[type=\"datetime-local\"][disabled], fieldset[disabled]\n  input[type=\"datetime-local\"],\n  input[type=\"month\"][disabled], fieldset[disabled]\n  input[type=\"month\"],\n  input[type=\"week\"][disabled], fieldset[disabled]\n  input[type=\"week\"],\n  input[type=\"email\"][disabled], fieldset[disabled]\n  input[type=\"email\"],\n  input[type=\"number\"][disabled], fieldset[disabled]\n  input[type=\"number\"],\n  input[type=\"search\"][disabled], fieldset[disabled]\n  input[type=\"search\"],\n  input[type=\"tel\"][disabled], fieldset[disabled]\n  input[type=\"tel\"],\n  input[type=\"time\"][disabled], fieldset[disabled]\n  input[type=\"time\"],\n  input[type=\"url\"][disabled], fieldset[disabled]\n  input[type=\"url\"],\n  textarea[disabled], fieldset[disabled]\n  textarea {\n    background-color: #dddddd; }\n  input[type=\"text\"].radius,\n  input[type=\"password\"].radius,\n  input[type=\"date\"].radius,\n  input[type=\"datetime\"].radius,\n  input[type=\"datetime-local\"].radius,\n  input[type=\"month\"].radius,\n  input[type=\"week\"].radius,\n  input[type=\"email\"].radius,\n  input[type=\"number\"].radius,\n  input[type=\"search\"].radius,\n  input[type=\"tel\"].radius,\n  input[type=\"time\"].radius,\n  input[type=\"url\"].radius,\n  textarea.radius {\n    border-radius: 3px; }\n\ninput[type=\"submit\"] {\n  -webkit-appearance: none; }\n\n/* Respect enforced amount of rows for textarea */\ntextarea[rows] {\n  height: auto; }\n\n/* Add height value for select elements to match text input height */\nselect {\n  -webkit-appearance: none !important;\n  background-color: #fafafa;\n  background-image: url(\"data:image/svg+xml;base64, PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI2cHgiIGhlaWdodD0iM3B4IiB2aWV3Qm94PSIwIDAgNiAzIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA2IDMiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwb2x5Z29uIHBvaW50cz0iNS45OTIsMCAyLjk5MiwzIC0wLjAwOCwwICIvPjwvc3ZnPg==\");\n  background-repeat: no-repeat;\n  background-position: 97% center;\n  border: 1px solid #cccccc;\n  padding: 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0;\n  height: 2.3125rem; }\n  select.radius {\n    border-radius: 3px; }\n  select:hover {\n    background-color: #f3f3f3;\n    border-color: #999999; }\n\n/* Adjust margin for form elements below */\ninput[type=\"file\"],\ninput[type=\"checkbox\"],\ninput[type=\"radio\"],\nselect {\n  margin: 0 0 1rem 0; }\n\ninput[type=\"checkbox\"] + label,\ninput[type=\"radio\"] + label {\n  display: inline-block;\n  margin-left: 0.5rem;\n  margin-right: 1rem;\n  margin-bottom: 0;\n  vertical-align: baseline; }\n\n/* Normalize file input width */\ninput[type=\"file\"] {\n  width: 100%; }\n\n/* We add basic fieldset styling */\nfieldset {\n  border: 1px solid #dddddd;\n  padding: 1.25rem;\n  margin: 1.125rem 0; }\n  fieldset legend {\n    font-weight: bold;\n    background: white;\n    padding: 0 0.1875rem;\n    margin: 0;\n    margin-left: -0.1875rem; }\n\n/* Error Handling */\n[data-abide] .error small.error, [data-abide] span.error, [data-abide] small.error {\n  display: block;\n  padding: 0.375rem 0.5625rem 0.5625rem;\n  margin-top: -1px;\n  margin-bottom: 1rem;\n  font-size: 0.75rem;\n  font-weight: normal;\n  font-style: italic;\n  background: #f04124;\n  color: white; }\n[data-abide] span.error, [data-abide] small.error {\n  display: none; }\n\nspan.error, small.error {\n  display: block;\n  padding: 0.375rem 0.5625rem 0.5625rem;\n  margin-top: -1px;\n  margin-bottom: 1rem;\n  font-size: 0.75rem;\n  font-weight: normal;\n  font-style: italic;\n  background: #f04124;\n  color: white; }\n\n.error input,\n.error textarea,\n.error select {\n  margin-bottom: 0; }\n.error input[type=\"checkbox\"],\n.error input[type=\"radio\"] {\n  margin-bottom: 1rem; }\n.error label,\n.error label.error {\n  color: #f04124; }\n.error small.error {\n  display: block;\n  padding: 0.375rem 0.5625rem 0.5625rem;\n  margin-top: -1px;\n  margin-bottom: 1rem;\n  font-size: 0.75rem;\n  font-weight: normal;\n  font-style: italic;\n  background: #f04124;\n  color: white; }\n.error > label > small {\n  color: #676767;\n  background: transparent;\n  padding: 0;\n  text-transform: capitalize;\n  font-style: normal;\n  font-size: 60%;\n  margin: 0;\n  display: inline; }\n.error span.error-message {\n  display: block; }\n\ninput.error,\ntextarea.error {\n  margin-bottom: 0; }\n\nlabel.error {\n  color: #f04124; }\n\n.range-slider {\n  display: block;\n  position: relative;\n  width: 100%;\n  height: 1rem;\n  border: 1px solid #dddddd;\n  margin: 1.25rem 0;\n  -ms-touch-action: none;\n  touch-action: none;\n  background: #fafafa; }\n  .range-slider.vertical-range {\n    display: block;\n    position: relative;\n    width: 100%;\n    height: 1rem;\n    border: 1px solid #dddddd;\n    margin: 1.25rem 0;\n    -ms-touch-action: none;\n    touch-action: none;\n    display: inline-block;\n    width: 1rem;\n    height: 12.5rem; }\n    .range-slider.vertical-range .range-slider-handle {\n      margin-top: 0;\n      margin-left: -0.5rem;\n      position: absolute;\n      bottom: -10.5rem; }\n    .range-slider.vertical-range .range-slider-active-segment {\n      width: 0.875rem;\n      height: auto;\n      bottom: 0; }\n  .range-slider.radius {\n    background: #fafafa;\n    border-radius: 3px; }\n    .range-slider.radius .range-slider-handle {\n      background: #008cba;\n      border-radius: 3px; }\n      .range-slider.radius .range-slider-handle:hover {\n        background: #007ba4; }\n  .range-slider.round {\n    background: #fafafa;\n    border-radius: 1000px; }\n    .range-slider.round .range-slider-handle {\n      background: #008cba;\n      border-radius: 1000px; }\n      .range-slider.round .range-slider-handle:hover {\n        background: #007ba4; }\n\n.range-slider-active-segment {\n  display: inline-block;\n  position: absolute;\n  height: 0.875rem;\n  background: #e5e5e5; }\n\n.range-slider-handle {\n  display: inline-block;\n  position: absolute;\n  z-index: 1;\n  top: -0.3125rem;\n  width: 2rem;\n  height: 1.375rem;\n  border: 1px solid none;\n  cursor: pointer;\n  background: #008cba; }\n  .range-slider-handle:hover {\n    background: #007ba4; }\n\n[class*=\"block-grid-\"] {\n  display: block;\n  padding: 0;\n  margin: 0 -0.625rem;\n  *zoom: 1; }\n  [class*=\"block-grid-\"]:before, [class*=\"block-grid-\"]:after {\n    content: \" \";\n    display: table; }\n  [class*=\"block-grid-\"]:after {\n    clear: both; }\n  [class*=\"block-grid-\"] > li {\n    display: block;\n    height: auto;\n    float: left;\n    padding: 0 0.625rem 1.25rem; }\n\n@media only screen {\n  .small-block-grid-1 > li {\n    width: 100%;\n    list-style: none; }\n    .small-block-grid-1 > li:nth-of-type(n) {\n      clear: none; }\n    .small-block-grid-1 > li:nth-of-type(1n+1) {\n      clear: both; }\n\n  .small-block-grid-2 > li {\n    width: 50%;\n    list-style: none; }\n    .small-block-grid-2 > li:nth-of-type(n) {\n      clear: none; }\n    .small-block-grid-2 > li:nth-of-type(2n+1) {\n      clear: both; }\n\n  .small-block-grid-3 > li {\n    width: 33.33333%;\n    list-style: none; }\n    .small-block-grid-3 > li:nth-of-type(n) {\n      clear: none; }\n    .small-block-grid-3 > li:nth-of-type(3n+1) {\n      clear: both; }\n\n  .small-block-grid-4 > li {\n    width: 25%;\n    list-style: none; }\n    .small-block-grid-4 > li:nth-of-type(n) {\n      clear: none; }\n    .small-block-grid-4 > li:nth-of-type(4n+1) {\n      clear: both; }\n\n  .small-block-grid-5 > li {\n    width: 20%;\n    list-style: none; }\n    .small-block-grid-5 > li:nth-of-type(n) {\n      clear: none; }\n    .small-block-grid-5 > li:nth-of-type(5n+1) {\n      clear: both; }\n\n  .small-block-grid-6 > li {\n    width: 16.66667%;\n    list-style: none; }\n    .small-block-grid-6 > li:nth-of-type(n) {\n      clear: none; }\n    .small-block-grid-6 > li:nth-of-type(6n+1) {\n      clear: both; }\n\n  .small-block-grid-7 > li {\n    width: 14.28571%;\n    list-style: none; }\n    .small-block-grid-7 > li:nth-of-type(n) {\n      clear: none; }\n    .small-block-grid-7 > li:nth-of-type(7n+1) {\n      clear: both; }\n\n  .small-block-grid-8 > li {\n    width: 12.5%;\n    list-style: none; }\n    .small-block-grid-8 > li:nth-of-type(n) {\n      clear: none; }\n    .small-block-grid-8 > li:nth-of-type(8n+1) {\n      clear: both; }\n\n  .small-block-grid-9 > li {\n    width: 11.11111%;\n    list-style: none; }\n    .small-block-grid-9 > li:nth-of-type(n) {\n      clear: none; }\n    .small-block-grid-9 > li:nth-of-type(9n+1) {\n      clear: both; }\n\n  .small-block-grid-10 > li {\n    width: 10%;\n    list-style: none; }\n    .small-block-grid-10 > li:nth-of-type(n) {\n      clear: none; }\n    .small-block-grid-10 > li:nth-of-type(10n+1) {\n      clear: both; }\n\n  .small-block-grid-11 > li {\n    width: 9.09091%;\n    list-style: none; }\n    .small-block-grid-11 > li:nth-of-type(n) {\n      clear: none; }\n    .small-block-grid-11 > li:nth-of-type(11n+1) {\n      clear: both; }\n\n  .small-block-grid-12 > li {\n    width: 8.33333%;\n    list-style: none; }\n    .small-block-grid-12 > li:nth-of-type(n) {\n      clear: none; }\n    .small-block-grid-12 > li:nth-of-type(12n+1) {\n      clear: both; } }\n@media only screen and (min-width: 40.063em) {\n  .medium-block-grid-1 > li {\n    width: 100%;\n    list-style: none; }\n    .medium-block-grid-1 > li:nth-of-type(n) {\n      clear: none; }\n    .medium-block-grid-1 > li:nth-of-type(1n+1) {\n      clear: both; }\n\n  .medium-block-grid-2 > li {\n    width: 50%;\n    list-style: none; }\n    .medium-block-grid-2 > li:nth-of-type(n) {\n      clear: none; }\n    .medium-block-grid-2 > li:nth-of-type(2n+1) {\n      clear: both; }\n\n  .medium-block-grid-3 > li {\n    width: 33.33333%;\n    list-style: none; }\n    .medium-block-grid-3 > li:nth-of-type(n) {\n      clear: none; }\n    .medium-block-grid-3 > li:nth-of-type(3n+1) {\n      clear: both; }\n\n  .medium-block-grid-4 > li {\n    width: 25%;\n    list-style: none; }\n    .medium-block-grid-4 > li:nth-of-type(n) {\n      clear: none; }\n    .medium-block-grid-4 > li:nth-of-type(4n+1) {\n      clear: both; }\n\n  .medium-block-grid-5 > li {\n    width: 20%;\n    list-style: none; }\n    .medium-block-grid-5 > li:nth-of-type(n) {\n      clear: none; }\n    .medium-block-grid-5 > li:nth-of-type(5n+1) {\n      clear: both; }\n\n  .medium-block-grid-6 > li {\n    width: 16.66667%;\n    list-style: none; }\n    .medium-block-grid-6 > li:nth-of-type(n) {\n      clear: none; }\n    .medium-block-grid-6 > li:nth-of-type(6n+1) {\n      clear: both; }\n\n  .medium-block-grid-7 > li {\n    width: 14.28571%;\n    list-style: none; }\n    .medium-block-grid-7 > li:nth-of-type(n) {\n      clear: none; }\n    .medium-block-grid-7 > li:nth-of-type(7n+1) {\n      clear: both; }\n\n  .medium-block-grid-8 > li {\n    width: 12.5%;\n    list-style: none; }\n    .medium-block-grid-8 > li:nth-of-type(n) {\n      clear: none; }\n    .medium-block-grid-8 > li:nth-of-type(8n+1) {\n      clear: both; }\n\n  .medium-block-grid-9 > li {\n    width: 11.11111%;\n    list-style: none; }\n    .medium-block-grid-9 > li:nth-of-type(n) {\n      clear: none; }\n    .medium-block-grid-9 > li:nth-of-type(9n+1) {\n      clear: both; }\n\n  .medium-block-grid-10 > li {\n    width: 10%;\n    list-style: none; }\n    .medium-block-grid-10 > li:nth-of-type(n) {\n      clear: none; }\n    .medium-block-grid-10 > li:nth-of-type(10n+1) {\n      clear: both; }\n\n  .medium-block-grid-11 > li {\n    width: 9.09091%;\n    list-style: none; }\n    .medium-block-grid-11 > li:nth-of-type(n) {\n      clear: none; }\n    .medium-block-grid-11 > li:nth-of-type(11n+1) {\n      clear: both; }\n\n  .medium-block-grid-12 > li {\n    width: 8.33333%;\n    list-style: none; }\n    .medium-block-grid-12 > li:nth-of-type(n) {\n      clear: none; }\n    .medium-block-grid-12 > li:nth-of-type(12n+1) {\n      clear: both; } }\n@media only screen and (min-width: 64.063em) {\n  .large-block-grid-1 > li {\n    width: 100%;\n    list-style: none; }\n    .large-block-grid-1 > li:nth-of-type(n) {\n      clear: none; }\n    .large-block-grid-1 > li:nth-of-type(1n+1) {\n      clear: both; }\n\n  .large-block-grid-2 > li {\n    width: 50%;\n    list-style: none; }\n    .large-block-grid-2 > li:nth-of-type(n) {\n      clear: none; }\n    .large-block-grid-2 > li:nth-of-type(2n+1) {\n      clear: both; }\n\n  .large-block-grid-3 > li {\n    width: 33.33333%;\n    list-style: none; }\n    .large-block-grid-3 > li:nth-of-type(n) {\n      clear: none; }\n    .large-block-grid-3 > li:nth-of-type(3n+1) {\n      clear: both; }\n\n  .large-block-grid-4 > li {\n    width: 25%;\n    list-style: none; }\n    .large-block-grid-4 > li:nth-of-type(n) {\n      clear: none; }\n    .large-block-grid-4 > li:nth-of-type(4n+1) {\n      clear: both; }\n\n  .large-block-grid-5 > li {\n    width: 20%;\n    list-style: none; }\n    .large-block-grid-5 > li:nth-of-type(n) {\n      clear: none; }\n    .large-block-grid-5 > li:nth-of-type(5n+1) {\n      clear: both; }\n\n  .large-block-grid-6 > li {\n    width: 16.66667%;\n    list-style: none; }\n    .large-block-grid-6 > li:nth-of-type(n) {\n      clear: none; }\n    .large-block-grid-6 > li:nth-of-type(6n+1) {\n      clear: both; }\n\n  .large-block-grid-7 > li {\n    width: 14.28571%;\n    list-style: none; }\n    .large-block-grid-7 > li:nth-of-type(n) {\n      clear: none; }\n    .large-block-grid-7 > li:nth-of-type(7n+1) {\n      clear: both; }\n\n  .large-block-grid-8 > li {\n    width: 12.5%;\n    list-style: none; }\n    .large-block-grid-8 > li:nth-of-type(n) {\n      clear: none; }\n    .large-block-grid-8 > li:nth-of-type(8n+1) {\n      clear: both; }\n\n  .large-block-grid-9 > li {\n    width: 11.11111%;\n    list-style: none; }\n    .large-block-grid-9 > li:nth-of-type(n) {\n      clear: none; }\n    .large-block-grid-9 > li:nth-of-type(9n+1) {\n      clear: both; }\n\n  .large-block-grid-10 > li {\n    width: 10%;\n    list-style: none; }\n    .large-block-grid-10 > li:nth-of-type(n) {\n      clear: none; }\n    .large-block-grid-10 > li:nth-of-type(10n+1) {\n      clear: both; }\n\n  .large-block-grid-11 > li {\n    width: 9.09091%;\n    list-style: none; }\n    .large-block-grid-11 > li:nth-of-type(n) {\n      clear: none; }\n    .large-block-grid-11 > li:nth-of-type(11n+1) {\n      clear: both; }\n\n  .large-block-grid-12 > li {\n    width: 8.33333%;\n    list-style: none; }\n    .large-block-grid-12 > li:nth-of-type(n) {\n      clear: none; }\n    .large-block-grid-12 > li:nth-of-type(12n+1) {\n      clear: both; } }\n.flex-video {\n  position: relative;\n  padding-top: 1.5625rem;\n  padding-bottom: 67.5%;\n  height: 0;\n  margin-bottom: 1rem;\n  overflow: hidden; }\n  .flex-video.widescreen {\n    padding-bottom: 56.34%; }\n  .flex-video.vimeo {\n    padding-top: 0; }\n  .flex-video iframe,\n  .flex-video object,\n  .flex-video embed,\n  .flex-video video {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%; }\n\n.keystroke,\nkbd {\n  background-color: #ededed;\n  border-color: #dddddd;\n  color: #222222;\n  border-style: solid;\n  border-width: 1px;\n  margin: 0;\n  font-family: \"Consolas\", \"Menlo\", \"Courier\", monospace;\n  font-size: inherit;\n  padding: 0.125rem 0.25rem 0;\n  border-radius: 3px; }\n\n/* small displays */\n@media only screen {\n  .show-for-small-only, .show-for-small-up, .show-for-small, .show-for-small-down, .hide-for-medium-only, .hide-for-medium-up, .hide-for-medium, .show-for-medium-down, .hide-for-large-only, .hide-for-large-up, .hide-for-large, .show-for-large-down, .hide-for-xlarge-only, .hide-for-xlarge-up, .hide-for-xxlarge-only, .hide-for-xxlarge-up {\n    display: inherit !important; }\n\n  .hide-for-small-only, .hide-for-small-up, .hide-for-small, .hide-for-small-down, .show-for-medium-only, .show-for-medium-up, .show-for-medium, .hide-for-medium-down, .show-for-large-only, .show-for-large-up, .show-for-large, .hide-for-large-down, .show-for-xlarge-only, .show-for-xlarge-up, .show-for-xxlarge-only, .show-for-xxlarge-up {\n    display: none !important; }\n\n  table.show-for-small-only, table.show-for-small-up, table.show-for-small, table.show-for-small-down, table.hide-for-medium-only, table.hide-for-medium-up, table.hide-for-medium, table.show-for-medium-down, table.hide-for-large-only, table.hide-for-large-up, table.hide-for-large, table.show-for-large-down, table.hide-for-xlarge-only, table.hide-for-xlarge-up, table.hide-for-xxlarge-only, table.hide-for-xxlarge-up {\n    display: table; }\n\n  thead.show-for-small-only, thead.show-for-small-up, thead.show-for-small, thead.show-for-small-down, thead.hide-for-medium-only, thead.hide-for-medium-up, thead.hide-for-medium, thead.show-for-medium-down, thead.hide-for-large-only, thead.hide-for-large-up, thead.hide-for-large, thead.show-for-large-down, thead.hide-for-xlarge-only, thead.hide-for-xlarge-up, thead.hide-for-xxlarge-only, thead.hide-for-xxlarge-up {\n    display: table-header-group !important; }\n\n  tbody.show-for-small-only, tbody.show-for-small-up, tbody.show-for-small, tbody.show-for-small-down, tbody.hide-for-medium-only, tbody.hide-for-medium-up, tbody.hide-for-medium, tbody.show-for-medium-down, tbody.hide-for-large-only, tbody.hide-for-large-up, tbody.hide-for-large, tbody.show-for-large-down, tbody.hide-for-xlarge-only, tbody.hide-for-xlarge-up, tbody.hide-for-xxlarge-only, tbody.hide-for-xxlarge-up {\n    display: table-row-group !important; }\n\n  tr.show-for-small-only, tr.show-for-small-up, tr.show-for-small, tr.show-for-small-down, tr.hide-for-medium-only, tr.hide-for-medium-up, tr.hide-for-medium, tr.show-for-medium-down, tr.hide-for-large-only, tr.hide-for-large-up, tr.hide-for-large, tr.show-for-large-down, tr.hide-for-xlarge-only, tr.hide-for-xlarge-up, tr.hide-for-xxlarge-only, tr.hide-for-xxlarge-up {\n    display: table-row !important; }\n\n  th.show-for-small-only, td.show-for-small-only, th.show-for-small-up, td.show-for-small-up, th.show-for-small, td.show-for-small, th.show-for-small-down, td.show-for-small-down, th.hide-for-medium-only, td.hide-for-medium-only, th.hide-for-medium-up, td.hide-for-medium-up, th.hide-for-medium, td.hide-for-medium, th.show-for-medium-down, td.show-for-medium-down, th.hide-for-large-only, td.hide-for-large-only, th.hide-for-large-up, td.hide-for-large-up, th.hide-for-large, td.hide-for-large, th.show-for-large-down, td.show-for-large-down, th.hide-for-xlarge-only, td.hide-for-xlarge-only, th.hide-for-xlarge-up, td.hide-for-xlarge-up, th.hide-for-xxlarge-only, td.hide-for-xxlarge-only, th.hide-for-xxlarge-up, td.hide-for-xxlarge-up {\n    display: table-cell !important; } }\n/* medium displays */\n@media only screen and (min-width: 40.063em) {\n  .hide-for-small-only, .show-for-small-up, .hide-for-small, .hide-for-small-down, .show-for-medium-only, .show-for-medium-up, .show-for-medium, .show-for-medium-down, .hide-for-large-only, .hide-for-large-up, .hide-for-large, .show-for-large-down, .hide-for-xlarge-only, .hide-for-xlarge-up, .hide-for-xxlarge-only, .hide-for-xxlarge-up {\n    display: inherit !important; }\n\n  .show-for-small-only, .hide-for-small-up, .show-for-small, .show-for-small-down, .hide-for-medium-only, .hide-for-medium-up, .hide-for-medium, .hide-for-medium-down, .show-for-large-only, .show-for-large-up, .show-for-large, .hide-for-large-down, .show-for-xlarge-only, .show-for-xlarge-up, .show-for-xxlarge-only, .show-for-xxlarge-up {\n    display: none !important; }\n\n  table.hide-for-small-only, table.show-for-small-up, table.hide-for-small, table.hide-for-small-down, table.show-for-medium-only, table.show-for-medium-up, table.show-for-medium, table.show-for-medium-down, table.hide-for-large-only, table.hide-for-large-up, table.hide-for-large, table.show-for-large-down, table.hide-for-xlarge-only, table.hide-for-xlarge-up, table.hide-for-xxlarge-only, table.hide-for-xxlarge-up {\n    display: table; }\n\n  thead.hide-for-small-only, thead.show-for-small-up, thead.hide-for-small, thead.hide-for-small-down, thead.show-for-medium-only, thead.show-for-medium-up, thead.show-for-medium, thead.show-for-medium-down, thead.hide-for-large-only, thead.hide-for-large-up, thead.hide-for-large, thead.show-for-large-down, thead.hide-for-xlarge-only, thead.hide-for-xlarge-up, thead.hide-for-xxlarge-only, thead.hide-for-xxlarge-up {\n    display: table-header-group !important; }\n\n  tbody.hide-for-small-only, tbody.show-for-small-up, tbody.hide-for-small, tbody.hide-for-small-down, tbody.show-for-medium-only, tbody.show-for-medium-up, tbody.show-for-medium, tbody.show-for-medium-down, tbody.hide-for-large-only, tbody.hide-for-large-up, tbody.hide-for-large, tbody.show-for-large-down, tbody.hide-for-xlarge-only, tbody.hide-for-xlarge-up, tbody.hide-for-xxlarge-only, tbody.hide-for-xxlarge-up {\n    display: table-row-group !important; }\n\n  tr.hide-for-small-only, tr.show-for-small-up, tr.hide-for-small, tr.hide-for-small-down, tr.show-for-medium-only, tr.show-for-medium-up, tr.show-for-medium, tr.show-for-medium-down, tr.hide-for-large-only, tr.hide-for-large-up, tr.hide-for-large, tr.show-for-large-down, tr.hide-for-xlarge-only, tr.hide-for-xlarge-up, tr.hide-for-xxlarge-only, tr.hide-for-xxlarge-up {\n    display: table-row !important; }\n\n  th.hide-for-small-only, td.hide-for-small-only, th.show-for-small-up, td.show-for-small-up, th.hide-for-small, td.hide-for-small, th.hide-for-small-down, td.hide-for-small-down, th.show-for-medium-only, td.show-for-medium-only, th.show-for-medium-up, td.show-for-medium-up, th.show-for-medium, td.show-for-medium, th.show-for-medium-down, td.show-for-medium-down, th.hide-for-large-only, td.hide-for-large-only, th.hide-for-large-up, td.hide-for-large-up, th.hide-for-large, td.hide-for-large, th.show-for-large-down, td.show-for-large-down, th.hide-for-xlarge-only, td.hide-for-xlarge-only, th.hide-for-xlarge-up, td.hide-for-xlarge-up, th.hide-for-xxlarge-only, td.hide-for-xxlarge-only, th.hide-for-xxlarge-up, td.hide-for-xxlarge-up {\n    display: table-cell !important; } }\n/* large displays */\n@media only screen and (min-width: 64.063em) {\n  .hide-for-small-only, .show-for-small-up, .hide-for-small, .hide-for-small-down, .hide-for-medium-only, .show-for-medium-up, .hide-for-medium, .hide-for-medium-down, .show-for-large-only, .show-for-large-up, .show-for-large, .show-for-large-down, .hide-for-xlarge-only, .hide-for-xlarge-up, .hide-for-xxlarge-only, .hide-for-xxlarge-up {\n    display: inherit !important; }\n\n  .show-for-small-only, .hide-for-small-up, .show-for-small, .show-for-small-down, .show-for-medium-only, .hide-for-medium-up, .show-for-medium, .show-for-medium-down, .hide-for-large-only, .hide-for-large-up, .hide-for-large, .hide-for-large-down, .show-for-xlarge-only, .show-for-xlarge-up, .show-for-xxlarge-only, .show-for-xxlarge-up {\n    display: none !important; }\n\n  table.hide-for-small-only, table.show-for-small-up, table.hide-for-small, table.hide-for-small-down, table.hide-for-medium-only, table.show-for-medium-up, table.hide-for-medium, table.hide-for-medium-down, table.show-for-large-only, table.show-for-large-up, table.show-for-large, table.show-for-large-down, table.hide-for-xlarge-only, table.hide-for-xlarge-up, table.hide-for-xxlarge-only, table.hide-for-xxlarge-up {\n    display: table; }\n\n  thead.hide-for-small-only, thead.show-for-small-up, thead.hide-for-small, thead.hide-for-small-down, thead.hide-for-medium-only, thead.show-for-medium-up, thead.hide-for-medium, thead.hide-for-medium-down, thead.show-for-large-only, thead.show-for-large-up, thead.show-for-large, thead.show-for-large-down, thead.hide-for-xlarge-only, thead.hide-for-xlarge-up, thead.hide-for-xxlarge-only, thead.hide-for-xxlarge-up {\n    display: table-header-group !important; }\n\n  tbody.hide-for-small-only, tbody.show-for-small-up, tbody.hide-for-small, tbody.hide-for-small-down, tbody.hide-for-medium-only, tbody.show-for-medium-up, tbody.hide-for-medium, tbody.hide-for-medium-down, tbody.show-for-large-only, tbody.show-for-large-up, tbody.show-for-large, tbody.show-for-large-down, tbody.hide-for-xlarge-only, tbody.hide-for-xlarge-up, tbody.hide-for-xxlarge-only, tbody.hide-for-xxlarge-up {\n    display: table-row-group !important; }\n\n  tr.hide-for-small-only, tr.show-for-small-up, tr.hide-for-small, tr.hide-for-small-down, tr.hide-for-medium-only, tr.show-for-medium-up, tr.hide-for-medium, tr.hide-for-medium-down, tr.show-for-large-only, tr.show-for-large-up, tr.show-for-large, tr.show-for-large-down, tr.hide-for-xlarge-only, tr.hide-for-xlarge-up, tr.hide-for-xxlarge-only, tr.hide-for-xxlarge-up {\n    display: table-row !important; }\n\n  th.hide-for-small-only, td.hide-for-small-only, th.show-for-small-up, td.show-for-small-up, th.hide-for-small, td.hide-for-small, th.hide-for-small-down, td.hide-for-small-down, th.hide-for-medium-only, td.hide-for-medium-only, th.show-for-medium-up, td.show-for-medium-up, th.hide-for-medium, td.hide-for-medium, th.hide-for-medium-down, td.hide-for-medium-down, th.show-for-large-only, td.show-for-large-only, th.show-for-large-up, td.show-for-large-up, th.show-for-large, td.show-for-large, th.show-for-large-down, td.show-for-large-down, th.hide-for-xlarge-only, td.hide-for-xlarge-only, th.hide-for-xlarge-up, td.hide-for-xlarge-up, th.hide-for-xxlarge-only, td.hide-for-xxlarge-only, th.hide-for-xxlarge-up, td.hide-for-xxlarge-up {\n    display: table-cell !important; } }\n/* xlarge displays */\n@media only screen and (min-width: 90.063em) {\n  .hide-for-small-only, .show-for-small-up, .hide-for-small, .hide-for-small-down, .hide-for-medium-only, .show-for-medium-up, .hide-for-medium, .hide-for-medium-down, .hide-for-large-only, .show-for-large-up, .hide-for-large, .hide-for-large-down, .show-for-xlarge-only, .show-for-xlarge-up, .hide-for-xxlarge-only, .hide-for-xxlarge-up {\n    display: inherit !important; }\n\n  .show-for-small-only, .hide-for-small-up, .show-for-small, .show-for-small-down, .show-for-medium-only, .hide-for-medium-up, .show-for-medium, .show-for-medium-down, .show-for-large-only, .hide-for-large-up, .show-for-large, .show-for-large-down, .hide-for-xlarge-only, .hide-for-xlarge-up, .show-for-xxlarge-only, .show-for-xxlarge-up {\n    display: none !important; }\n\n  table.hide-for-small-only, table.show-for-small-up, table.hide-for-small, table.hide-for-small-down, table.hide-for-medium-only, table.show-for-medium-up, table.hide-for-medium, table.hide-for-medium-down, table.hide-for-large-only, table.show-for-large-up, table.hide-for-large, table.hide-for-large-down, table.show-for-xlarge-only, table.show-for-xlarge-up, table.hide-for-xxlarge-only, table.hide-for-xxlarge-up {\n    display: table; }\n\n  thead.hide-for-small-only, thead.show-for-small-up, thead.hide-for-small, thead.hide-for-small-down, thead.hide-for-medium-only, thead.show-for-medium-up, thead.hide-for-medium, thead.hide-for-medium-down, thead.hide-for-large-only, thead.show-for-large-up, thead.hide-for-large, thead.hide-for-large-down, thead.show-for-xlarge-only, thead.show-for-xlarge-up, thead.hide-for-xxlarge-only, thead.hide-for-xxlarge-up {\n    display: table-header-group !important; }\n\n  tbody.hide-for-small-only, tbody.show-for-small-up, tbody.hide-for-small, tbody.hide-for-small-down, tbody.hide-for-medium-only, tbody.show-for-medium-up, tbody.hide-for-medium, tbody.hide-for-medium-down, tbody.hide-for-large-only, tbody.show-for-large-up, tbody.hide-for-large, tbody.hide-for-large-down, tbody.show-for-xlarge-only, tbody.show-for-xlarge-up, tbody.hide-for-xxlarge-only, tbody.hide-for-xxlarge-up {\n    display: table-row-group !important; }\n\n  tr.hide-for-small-only, tr.show-for-small-up, tr.hide-for-small, tr.hide-for-small-down, tr.hide-for-medium-only, tr.show-for-medium-up, tr.hide-for-medium, tr.hide-for-medium-down, tr.hide-for-large-only, tr.show-for-large-up, tr.hide-for-large, tr.hide-for-large-down, tr.show-for-xlarge-only, tr.show-for-xlarge-up, tr.hide-for-xxlarge-only, tr.hide-for-xxlarge-up {\n    display: table-row !important; }\n\n  th.hide-for-small-only, td.hide-for-small-only, th.show-for-small-up, td.show-for-small-up, th.hide-for-small, td.hide-for-small, th.hide-for-small-down, td.hide-for-small-down, th.hide-for-medium-only, td.hide-for-medium-only, th.show-for-medium-up, td.show-for-medium-up, th.hide-for-medium, td.hide-for-medium, th.hide-for-medium-down, td.hide-for-medium-down, th.hide-for-large-only, td.hide-for-large-only, th.show-for-large-up, td.show-for-large-up, th.hide-for-large, td.hide-for-large, th.hide-for-large-down, td.hide-for-large-down, th.show-for-xlarge-only, td.show-for-xlarge-only, th.show-for-xlarge-up, td.show-for-xlarge-up, th.hide-for-xxlarge-only, td.hide-for-xxlarge-only, th.hide-for-xxlarge-up, td.hide-for-xxlarge-up {\n    display: table-cell !important; } }\n/* xxlarge displays */\n@media only screen and (min-width: 120.063em) {\n  .hide-for-small-only, .show-for-small-up, .hide-for-small, .hide-for-small-down, .hide-for-medium-only, .show-for-medium-up, .hide-for-medium, .hide-for-medium-down, .hide-for-large-only, .show-for-large-up, .hide-for-large, .hide-for-large-down, .hide-for-xlarge-only, .show-for-xlarge-up, .show-for-xxlarge-only, .show-for-xxlarge-up {\n    display: inherit !important; }\n\n  .show-for-small-only, .hide-for-small-up, .show-for-small, .show-for-small-down, .show-for-medium-only, .hide-for-medium-up, .show-for-medium, .show-for-medium-down, .show-for-large-only, .hide-for-large-up, .show-for-large, .show-for-large-down, .show-for-xlarge-only, .hide-for-xlarge-up, .hide-for-xxlarge-only, .hide-for-xxlarge-up {\n    display: none !important; }\n\n  table.hide-for-small-only, table.show-for-small-up, table.hide-for-small, table.hide-for-small-down, table.hide-for-medium-only, table.show-for-medium-up, table.hide-for-medium, table.hide-for-medium-down, table.hide-for-large-only, table.show-for-large-up, table.hide-for-large, table.hide-for-large-down, table.hide-for-xlarge-only, table.show-for-xlarge-up, table.show-for-xxlarge-only, table.show-for-xxlarge-up {\n    display: table; }\n\n  thead.hide-for-small-only, thead.show-for-small-up, thead.hide-for-small, thead.hide-for-small-down, thead.hide-for-medium-only, thead.show-for-medium-up, thead.hide-for-medium, thead.hide-for-medium-down, thead.hide-for-large-only, thead.show-for-large-up, thead.hide-for-large, thead.hide-for-large-down, thead.hide-for-xlarge-only, thead.show-for-xlarge-up, thead.show-for-xxlarge-only, thead.show-for-xxlarge-up {\n    display: table-header-group !important; }\n\n  tbody.hide-for-small-only, tbody.show-for-small-up, tbody.hide-for-small, tbody.hide-for-small-down, tbody.hide-for-medium-only, tbody.show-for-medium-up, tbody.hide-for-medium, tbody.hide-for-medium-down, tbody.hide-for-large-only, tbody.show-for-large-up, tbody.hide-for-large, tbody.hide-for-large-down, tbody.hide-for-xlarge-only, tbody.show-for-xlarge-up, tbody.show-for-xxlarge-only, tbody.show-for-xxlarge-up {\n    display: table-row-group !important; }\n\n  tr.hide-for-small-only, tr.show-for-small-up, tr.hide-for-small, tr.hide-for-small-down, tr.hide-for-medium-only, tr.show-for-medium-up, tr.hide-for-medium, tr.hide-for-medium-down, tr.hide-for-large-only, tr.show-for-large-up, tr.hide-for-large, tr.hide-for-large-down, tr.hide-for-xlarge-only, tr.show-for-xlarge-up, tr.show-for-xxlarge-only, tr.show-for-xxlarge-up {\n    display: table-row !important; }\n\n  th.hide-for-small-only, td.hide-for-small-only, th.show-for-small-up, td.show-for-small-up, th.hide-for-small, td.hide-for-small, th.hide-for-small-down, td.hide-for-small-down, th.hide-for-medium-only, td.hide-for-medium-only, th.show-for-medium-up, td.show-for-medium-up, th.hide-for-medium, td.hide-for-medium, th.hide-for-medium-down, td.hide-for-medium-down, th.hide-for-large-only, td.hide-for-large-only, th.show-for-large-up, td.show-for-large-up, th.hide-for-large, td.hide-for-large, th.hide-for-large-down, td.hide-for-large-down, th.hide-for-xlarge-only, td.hide-for-xlarge-only, th.show-for-xlarge-up, td.show-for-xlarge-up, th.show-for-xxlarge-only, td.show-for-xxlarge-only, th.show-for-xxlarge-up, td.show-for-xxlarge-up {\n    display: table-cell !important; } }\n/* Orientation targeting */\n.show-for-landscape,\n.hide-for-portrait {\n  display: inherit !important; }\n\n.hide-for-landscape,\n.show-for-portrait {\n  display: none !important; }\n\n/* Specific visibility for tables */\ntable.hide-for-landscape, table.show-for-portrait {\n  display: table; }\n\nthead.hide-for-landscape, thead.show-for-portrait {\n  display: table-header-group !important; }\n\ntbody.hide-for-landscape, tbody.show-for-portrait {\n  display: table-row-group !important; }\n\ntr.hide-for-landscape, tr.show-for-portrait {\n  display: table-row !important; }\n\ntd.hide-for-landscape, td.show-for-portrait,\nth.hide-for-landscape,\nth.show-for-portrait {\n  display: table-cell !important; }\n\n@media only screen and (orientation: landscape) {\n  .show-for-landscape,\n  .hide-for-portrait {\n    display: inherit !important; }\n\n  .hide-for-landscape,\n  .show-for-portrait {\n    display: none !important; }\n\n  /* Specific visibility for tables */\n  table.show-for-landscape, table.hide-for-portrait {\n    display: table; }\n\n  thead.show-for-landscape, thead.hide-for-portrait {\n    display: table-header-group !important; }\n\n  tbody.show-for-landscape, tbody.hide-for-portrait {\n    display: table-row-group !important; }\n\n  tr.show-for-landscape, tr.hide-for-portrait {\n    display: table-row !important; }\n\n  td.show-for-landscape, td.hide-for-portrait,\n  th.show-for-landscape,\n  th.hide-for-portrait {\n    display: table-cell !important; } }\n@media only screen and (orientation: portrait) {\n  .show-for-portrait,\n  .hide-for-landscape {\n    display: inherit !important; }\n\n  .hide-for-portrait,\n  .show-for-landscape {\n    display: none !important; }\n\n  /* Specific visibility for tables */\n  table.show-for-portrait, table.hide-for-landscape {\n    display: table; }\n\n  thead.show-for-portrait, thead.hide-for-landscape {\n    display: table-header-group !important; }\n\n  tbody.show-for-portrait, tbody.hide-for-landscape {\n    display: table-row-group !important; }\n\n  tr.show-for-portrait, tr.hide-for-landscape {\n    display: table-row !important; }\n\n  td.show-for-portrait, td.hide-for-landscape,\n  th.show-for-portrait,\n  th.hide-for-landscape {\n    display: table-cell !important; } }\n/* Touch-enabled device targeting */\n.show-for-touch {\n  display: none !important; }\n\n.hide-for-touch {\n  display: inherit !important; }\n\n.touch .show-for-touch {\n  display: inherit !important; }\n\n.touch .hide-for-touch {\n  display: none !important; }\n\n/* Specific visibility for tables */\ntable.hide-for-touch {\n  display: table; }\n\n.touch table.show-for-touch {\n  display: table; }\n\nthead.hide-for-touch {\n  display: table-header-group !important; }\n\n.touch thead.show-for-touch {\n  display: table-header-group !important; }\n\ntbody.hide-for-touch {\n  display: table-row-group !important; }\n\n.touch tbody.show-for-touch {\n  display: table-row-group !important; }\n\ntr.hide-for-touch {\n  display: table-row !important; }\n\n.touch tr.show-for-touch {\n  display: table-row !important; }\n\ntd.hide-for-touch {\n  display: table-cell !important; }\n\n.touch td.show-for-touch {\n  display: table-cell !important; }\n\nth.hide-for-touch {\n  display: table-cell !important; }\n\n.touch th.show-for-touch {\n  display: table-cell !important; }\n"
  },
  {
    "path": "docs/css/gettingstarted.css",
    "content": "#chart5_1 .c3-line-data2 {\n  stroke-width: 5px;\n}"
  },
  {
    "path": "docs/css/index.css",
    "content": ""
  },
  {
    "path": "docs/css/normalize.css",
    "content": "/*! normalize.css v3.0.0 | MIT License | git.io/normalize */\n\n/**\n * 1. Set default font family to sans-serif.\n * 2. Prevent iOS text size adjust after orientation change, without disabling\n *    user zoom.\n */\n\nhtml {\n  font-family: sans-serif; /* 1 */\n  -ms-text-size-adjust: 100%; /* 2 */\n  -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/**\n * Remove default margin.\n */\n\nbody {\n  margin: 0;\n}\n\n/* HTML5 display definitions\n   ========================================================================== */\n\n/**\n * Correct `block` display not defined in IE 8/9.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n/**\n * 1. Correct `inline-block` display not defined in IE 8/9.\n * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n */\n\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block; /* 1 */\n  vertical-align: baseline; /* 2 */\n}\n\n/**\n * Prevent modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n/**\n * Address `[hidden]` styling not present in IE 8/9.\n * Hide the `template` element in IE, Safari, and Firefox < 22.\n */\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n/* Links\n   ========================================================================== */\n\n/**\n * Remove the gray background color from active links in IE 10.\n */\n\na {\n  background: transparent;\n}\n\n/**\n * Improve readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n  outline: 0;\n}\n\n/* Text-level semantics\n   ========================================================================== */\n\n/**\n * Address styling not present in IE 8/9, Safari 5, and Chrome.\n */\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n/**\n * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.\n */\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n/**\n * Address styling not present in Safari 5 and Chrome.\n */\n\ndfn {\n  font-style: italic;\n}\n\n/**\n * Address variable `h1` font-size and margin within `section` and `article`\n * contexts in Firefox 4+, Safari 5, and Chrome.\n */\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n/**\n * Address styling not present in IE 8/9.\n */\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n/**\n * Address inconsistent and variable font size in all browsers.\n */\n\nsmall {\n  font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n/* Embedded content\n   ========================================================================== */\n\n/**\n * Remove border when inside `a` element in IE 8/9.\n */\n\nimg {\n  border: 0;\n}\n\n/**\n * Correct overflow displayed oddly in IE 9.\n */\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n/* Grouping content\n   ========================================================================== */\n\n/**\n * Address margin not present in IE 8/9 and Safari 5.\n */\n\nfigure {\n  margin: 1em 40px;\n}\n\n/**\n * Address differences between Firefox and other browsers.\n */\n\nhr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\n\n/**\n * Contain overflow in all browsers.\n */\n\npre {\n  overflow: auto;\n}\n\n/**\n * Address odd `em`-unit font size rendering in all browsers.\n */\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n/* Forms\n   ========================================================================== */\n\n/**\n * Known limitation: by default, Chrome and Safari on OS X allow very limited\n * styling of `select`, unless a `border` property is set.\n */\n\n/**\n * 1. Correct color not being inherited.\n *    Known issue: affects color of disabled elements.\n * 2. Correct font properties not being inherited.\n * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit; /* 1 */\n  font: inherit; /* 2 */\n  margin: 0; /* 3 */\n}\n\n/**\n * Address `overflow` set to `hidden` in IE 8/9/10.\n */\n\nbutton {\n  overflow: visible;\n}\n\n/**\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\n * All other form control elements do not inherit `text-transform` values.\n * Correct `button` style inheritance in Firefox, IE 8+, and Opera\n * Correct `select` style inheritance in Firefox.\n */\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n/**\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *    and `video` controls.\n * 2. Correct inability to style clickable `input` types in iOS.\n * 3. Improve usability and consistency of cursor style between image-type\n *    `input` and others.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; /* 2 */\n  cursor: pointer; /* 3 */\n}\n\n/**\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n/**\n * Remove inner padding and border in Firefox 4+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n/**\n * Address Firefox 4+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\ninput {\n  line-height: normal;\n}\n\n/**\n * It's recommended that you don't attempt to style these elements.\n * Firefox's implementation doesn't respect box-sizing, padding, or width.\n *\n * 1. Address box sizing set to `content-box` in IE 8/9/10.\n * 2. Remove excess padding in IE 8/9/10.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Fix the cursor style for Chrome's increment/decrement buttons. For certain\n * `font-size` values of the `input`, it causes the cursor style of the\n * decrement button to change from `default` to `text`.\n */\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n/**\n * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.\n * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome\n *    (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; /* 1 */\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box; /* 2 */\n  box-sizing: content-box;\n}\n\n/**\n * Remove inner padding and search cancel button in Safari and Chrome on OS X.\n * Safari (but not Chrome) clips the cancel button when the search input has\n * padding (and `textfield` appearance).\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n/**\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n/**\n * 1. Correct `color` not being inherited in IE 8/9.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\n\nlegend {\n  border: 0; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Remove default vertical scrollbar in IE 8/9.\n */\n\ntextarea {\n  overflow: auto;\n}\n\n/**\n * Don't inherit the `font-weight` (applied by a rule above).\n * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n */\n\noptgroup {\n  font-weight: bold;\n}\n\n/* Tables\n   ========================================================================== */\n\n/**\n * Remove most spacing between table cells.\n */\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n"
  },
  {
    "path": "docs/css/reference.css",
    "content": "section p {\n    margin-bottom: 0;\n}\nsection h5 {\n    margin-top: 1rem;\n}\nsection code {\n    padding-left: 0;\n}\n.sourcecode {\n    margin-bottom: 1.25rem;\n    padding: 6px 10px;\n    background-color: #f4f4f4;\n}\n.sourcecode pre {\n    padding: 0;\n    font-size: 1em;\n}\n.sourcecode pre code {\n    background-color: #f4f4f4;\n}\n"
  },
  {
    "path": "docs/css/samples/api_axis_label.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/api_axis_range.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/api_data_color.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/api_data_name.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/api_flow.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/api_grid_x.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/api_resize.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_label.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_label_position.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_rotated.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_x_localtime.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_x_tick_count.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_x_tick_culling.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_x_tick_fit.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_x_tick_format.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_x_tick_rotate.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_x_tick_values.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_y2.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_y_padding.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_y_range.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/axes_y_tick_format.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/categorized.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_area.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_area_stacked.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_bar.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_bar_negative.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_bar_stacked.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_combination.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_donut.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_gauge.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_pie.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_scatter.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_spline.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_stanford.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/chart_step.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/data_color.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/data_columned.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/data_json.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/data_label.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/data_label_format.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/data_load.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/data_name.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/data_order.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/data_rowed.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/data_stringx.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/data_url.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/data_xformat.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/grid_x_lines.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/grid_y_lines.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/interaction_zoom.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/legend_custom.css",
    "content": ".legend span {\n    width: 33.333333%;\n    display: inline-block;\n    text-align: center;\n    cursor: pointer;\n    color: white;\n}"
  },
  {
    "path": "docs/css/samples/legend_position.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/options_color.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/options_gridline.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/options_legend.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/options_padding.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/options_size.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/options_subchart.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/pie_label_format.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/point_show.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/region.css",
    "content": ".c3-region.regionY {\n  fill: red;\n}\n.c3-region.regionY2 {\n  fill: green;\n}\n"
  },
  {
    "path": "docs/css/samples/region_timeseries.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/simple_multiple.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/simple_regions.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/simple_xy.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/simple_xy_multiple.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/style_grid.css",
    "content": ".c3-xgrid-line line {\n    stroke: blue;\n}\n.c3-xgrid-line.grid4 line {\n    stroke: pink;\n}\n.c3-xgrid-line.grid4 text {\n    fill: pink;\n}\n.c3-ygrid-line line {\n    stroke: red;\n}\n.c3-ygrid-line.grid800 line {\n    stroke: green;\n}\n.c3-ygrid-line.grid800 text {\n    fill: green;\n}"
  },
  {
    "path": "docs/css/samples/style_region.css",
    "content": ".c3-region-0 {\n  fill: red;\n}\n.c3-region.foo {\n  fill: green;\n}\n"
  },
  {
    "path": "docs/css/samples/timeseries.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/tooltip_format.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/tooltip_grouped.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/tooltip_show.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/transform_area.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/transform_areaspline.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/transform_bar.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/transform_donut.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/transform_line.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/transform_pie.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/transform_scatter.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/transform_spline.css",
    "content": ""
  },
  {
    "path": "docs/css/samples/transition_duration.css",
    "content": ""
  },
  {
    "path": "docs/css/style.css",
    "content": "body {\n  background-color: #fdfdfd;\n}\nfooter {\n  text-align: right;\n}\nfooter hr {\n  margin-bottom: 10px;\n}\nfooter p {\n  margin-bottom: 10px;\n}\n\n#chart {\n  height: 280px;\n  margin: 0px auto;\n  text-align: center;\n}\n\n#message {\n  font-size: 16px;\n  text-align: center;\n}\n\n#link {\n  margin-top: 18px;\n  float: right;\n}\n#link .git-icon {\n  height: 32px;\n}\n\n.antialiased {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.container {\n  width: 90%;\n  margin: 0 auto;\n}\n.container.sidemenu {\n  position: relative;\n}\n.container.sidemenu footer {\n  position: absolute;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  z-index: 100;\n  background-color: #fdfdfd;\n}\n@media only screen and (min-width: 40.063em) {\n.container.sidemenu .column-menu {\n  position: fixed;\n  overflow: auto;\n  top: 60px;\n  bottom: 0;\n  padding-bottom: 60px;\n  width: 280px;\n}\n.container.sidemenu .column-content {\n  padding-left: 10px;\n  padding-top: 20px;\n  padding-bottom: 60px;\n  margin-left: 280px;\n  float: none;\n}\n}\n.container.sidemenu .column-menu .side-bar {\n  position: relative;\n}\n.container.sidemenu .column-menu .side-bar li > a {\n  display: inline;\n  padding-left: 12px;\n}\n.container.sidemenu .column-menu .side-bar .label {\n  top: -2px;\n  padding: 0.22222rem 0.44444rem 0.33333rem;\n  font-size: 0.5rem;\n  margin-bottom: 0;\n}\n.container.sidemenu .column-content section .label {\n  top: -4px;\n  padding: 0.22222rem 0.44444rem 0.33333rem;\n  font-size: 0.61rem;\n}\n.container hr.large {\n  margin: 48px 0;\n}\n.container hr.medium {\n  margin: 24px 0;\n}\n.container hr.small {\n  margin: 12px 0;\n}\n.container h3.sub {\n  color: #999;\n  margin-bottom: 32px;\n}\n\nh1.title {\n  margin: 16px 0;\n}\n\n.top-bar .name h1 {\n  font-size: 0.94444rem;\n}\n\n.button {\n  transition: none;\n}\nh1, h2, h3, h4, h5 {\n  font-weight: 300;\n}\n.row {\n  max-width: 80rem;\n}\n\n.chart {\n  margin-top: 42px;\n}\n.overview {\n  margin-bottom: 42px;\n  padding: 0 18px;\n}\n.features {\n  margin: 42px auto 30px;\n}\n\n\n.side-bar {\n}\n.side-bar h5 {\n  font-weight: bold;\n}\n\n\n.margin-medium-v {\n  margin-top: 24px;\n  margin-bottom: 24px;\n}\n.margin-medium-top {\n  margin-top: 24px !important;\n}\n.margin-small-h {\n  margin-left: 12px;\n  margin-right: 12px;\n}\n.margin-small-bottom {\n  margin-bottom: 12px !important;\n}\n\n.c3-editor {\n  font-size: 1.1em !important;\n}\n.sourcecode {\n  margin-bottom: 1.25rem;\n}\n.sourcecode h3 {\n  border-bottom: 1px solid #ddd;\n  padding-bottom: 4px;\n}\n.sourcecode pre {\n  border: none;\n  border-radius: 0;\n  padding: 12px 0px;\n  font-size: 1.2em;\n  line-height: 1.428571429;\n  word-break: break-all;\n  word-wrap: break-word;\n}\n.sourcecode pre code {\n  background-color: #fdfdfd;\n  padding: 0;\n  font-family: Monaco,Menlo,Consolas,\"Courier New\",monospace;\n  font-weight: normal;\n  font-size: 0.9em;\n}\n\n.highlight {\n  border-left: 4px solid #ccc;\n  padding: 0 8px;\n}\n.highlight pre {\n  padding: 0 8px;\n  line-height: 1.2em;\n}\n\n.section .row {\n  margin-bottom: 32px;\n}\n.section > a > h2 {\n  line-height: 1.2em;\n  margin-top: 18px;\n  margin-bottom: 18px;\n}\n\nspan.code {\n  display: inline-block;\n  background-color: #eee;\n  padding-left: 4px;\n  padding-right: 4px;\n  font-family: Monaco,Menlo,Consolas,\"Courier New\",monospace;\n  font-size: 0.9em;\n}\n\nh3 + ul, p + ul {\n  margin-left: 32px;\n}\n\n.gray {\n  color: #999;\n}\n\nli .label {\n  top: -3px;\n  padding: 0.22222rem 0.44444rem 0.33333rem;\n  font-size: 0.61rem;\n  margin: 0 8px;\n}\n\ndiv.sub-section {\n  padding-top: 4px;\n  padding-left: 10px;\n}\n"
  },
  {
    "path": "docs/css/tomorrow.css",
    "content": "/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */\n.tomorrow-comment, pre .comment, pre .title {\n  color: #8e908c;\n}\n\n.tomorrow-red, pre .variable, pre .attribute, pre .tag, pre .regexp, pre .ruby .constant, pre .xml .tag .title, pre .xml .pi, pre .xml .doctype, pre .html .doctype, pre .css .id, pre .css .class, pre .css .pseudo {\n/*  color: #c82829;*/\n}\n\n.tomorrow-orange, pre .number, pre .preprocessor, pre .built_in, pre .literal, pre .params, pre .constant {\n  color: #f5871f;\n}\n\n.tomorrow-yellow, pre .class, pre .ruby .class .title, pre .css .rules .attribute {\n  color: #eab700;\n}\n\n.tomorrow-green, pre .string, pre .value, pre .inheritance, pre .header, pre .ruby .symbol, pre .xml .cdata {\n  color: #718c00;\n}\n\n.tomorrow-aqua, pre .css .hexcolor {\n  color: #3e999f;\n}\n\n.tomorrow-blue, pre .function, pre .python .decorator, pre .python .title, pre .ruby .function .title, pre .ruby .title .keyword, pre .perl .sub, pre .javascript .title, pre .coffeescript .title {\n  color: #4271ae;\n}\n\n.tomorrow-purple, pre .keyword, pre .javascript .function {\n  color: #8959a8;\n}\n\npre code {\n  display: block;\n  background: white;\n  color: #4d4d4c;\n  padding: 0.5em;\n}\n\npre .coffeescript .javascript,\npre .javascript .xml,\npre .tex .formula,\npre .xml .javascript,\npre .xml .vbscript,\npre .xml .css,\npre .xml .cdata {\n  opacity: 0.5;\n}\n"
  },
  {
    "path": "docs/data/c3_string_x.csv",
    "content": "x,download,loading\nwww.siteX.com,100,400\nwww.siteY.com,200,100\nwww.siteZ.com,300,200\n"
  },
  {
    "path": "docs/data/c3_test.csv",
    "content": "data1,data2,data3\n120,80,200\n140,50,210\n170,100,250\n150,70,300\n180,120,280"
  },
  {
    "path": "docs/data/c3_test.json",
    "content": "{\n  \"data1\": [220, 240, 270, 250, 280],\n  \"data2\": [180, 150, 300, 70, 120],\n  \"data3\": [200, 310, 150, 100, 180]\n}\n"
  },
  {
    "path": "docs/data/c3_test2.csv",
    "content": "data1,data2,data3\n20,180,400\n40,150,310\n70,120,470\n50,170,400\n80,200,380"
  },
  {
    "path": "docs/examples.html.haml",
    "content": ".container\n  .section\n    = partial :index_item_title, locals: { id: 'chart', name: 'Chart' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'simple_multiple' }\n        = partial :index_item, locals: { id: 'timeseries' }\n        = partial :index_item, locals: { id: 'chart_spline' }\n      .row\n        = partial :index_item, locals: { id: 'simple_xy' }\n        = partial :index_item, locals: { id: 'simple_xy_multiple' }\n        = partial :index_item, locals: { id: 'simple_regions' }\n      .row\n        = partial :index_item, locals: { id: 'chart_step' }\n        = partial :index_item, locals: { id: 'chart_area' }\n        = partial :index_item, locals: { id: 'chart_area_stacked' }\n      .row\n        = partial :index_item, locals: { id: 'chart_bar' }\n        = partial :index_item, locals: { id: 'chart_bar_stacked' }\n        = partial :index_item, locals: { id: 'chart_scatter' }\n      .row\n        = partial :index_item, locals: { id: 'chart_pie' }\n        = partial :index_item, locals: { id: 'chart_donut' }\n        = partial :index_item, locals: { id: 'chart_gauge' }\n      .row\n        = partial :index_item, locals: { id: 'chart_stanford' }\n        = partial :index_item, locals: { id: 'chart_combination' }\n        .large-4.columns\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'axis', name: 'Axis' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'categorized' }\n        = partial :index_item, locals: { id: 'axes_rotated' }\n        = partial :index_item, locals: { id: 'axes_y2' }\n      .row\n        = partial :index_item, locals: { id: 'axes_x_tick_format' }\n        = partial :index_item, locals: { id: 'axes_x_tick_count' }\n        = partial :index_item, locals: { id: 'axes_x_tick_values' }\n      .row\n        = partial :index_item, locals: { id: 'axes_x_tick_culling' }\n        = partial :index_item, locals: { id: 'axes_x_tick_fit' }\n        = partial :index_item, locals: { id: 'axes_x_localtime' }\n      .row\n        = partial :index_item, locals: { id: 'axes_x_tick_rotate' }\n        = partial :index_item, locals: { id: 'axes_y_tick_format' }\n        = partial :index_item, locals: { id: 'axes_y_padding' }\n      .row\n        = partial :index_item, locals: { id: 'axes_y_range' }\n        = partial :index_item, locals: { id: 'axes_label' }\n        = partial :index_item, locals: { id: 'axes_label_position' }\n        .large-4.columns\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'data', name: 'Data' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'data_columned' }\n        = partial :index_item, locals: { id: 'data_rowed' }\n        = partial :index_item, locals: { id: 'data_json' }\n      .row\n        = partial :index_item, locals: { id: 'data_url' }\n        = partial :index_item, locals: { id: 'data_stringx' }\n        = partial :index_item, locals: { id: 'data_load' }\n      .row\n        = partial :index_item, locals: { id: 'data_name' }\n        = partial :index_item, locals: { id: 'data_color' }\n        = partial :index_item, locals: { id: 'data_order' }\n      .row\n        = partial :index_item, locals: { id: 'data_label' }\n        = partial :index_item, locals: { id: 'data_label_format' }\n        = partial :index_item, locals: { id: 'data_number_format_l10n' }\n        .large-4.columns\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'grid', name: 'Grid' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'options_gridline' }\n        = partial :index_item, locals: { id: 'grid_x_lines' }\n        = partial :index_item, locals: { id: 'grid_y_lines' }\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'region', name: 'Region' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'region' }\n        = partial :index_item, locals: { id: 'region_timeseries' }\n        .large-4.columns\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'interaction', name: 'Interaction' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'options_subchart' }\n        = partial :index_item, locals: { id: 'interaction_zoom' }\n        .large-4.columns\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'legend', name: 'Legend' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'options_legend' }\n        = partial :index_item, locals: { id: 'legend_position' }\n        = partial :index_item, locals: { id: 'legend_custom' }\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'tooltip', name: 'Tooltip' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'tooltip_show' }\n        = partial :index_item, locals: { id: 'tooltip_grouped' }\n        = partial :index_item, locals: { id: 'tooltip_format' }\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'chart_options', name: 'Chart Options' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'options_size' }\n        = partial :index_item, locals: { id: 'options_padding' }\n        = partial :index_item, locals: { id: 'options_color' }\n      .row\n        = partial :index_item, locals: { id: 'transition_duration' }\n        .large-4.columns\n        .large-4.columns\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'line_chart_options', name: 'Line Chart Options' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'point_show' }\n        .large-4.columns\n        .large-4.columns\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'pie_chart_options', name: 'Pie Chart Options' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'pie_label_format' }\n        .large-4.columns\n        .large-4.columns\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'api', name: 'API' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'api_flow' }\n        = partial :index_item, locals: { id: 'api_data_name' }\n        = partial :index_item, locals: { id: 'api_data_color' }\n      .row\n        = partial :index_item, locals: { id: 'api_axis_label' }\n        = partial :index_item, locals: { id: 'api_axis_range' }\n        = partial :index_item, locals: { id: 'api_resize' }\n      .row\n        = partial :index_item, locals: { id: 'api_grid_x' }\n        .large-4.columns\n        .large-4.columns\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'transform', name: 'Transform' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'transform_line' }\n        = partial :index_item, locals: { id: 'transform_spline' }\n        = partial :index_item, locals: { id: 'transform_bar' }\n      .row\n        = partial :index_item, locals: { id: 'transform_area' }\n        = partial :index_item, locals: { id: 'transform_areaspline' }\n        = partial :index_item, locals: { id: 'transform_scatter' }\n      .row\n        = partial :index_item, locals: { id: 'transform_pie' }\n        = partial :index_item, locals: { id: 'transform_donut' }\n        .large-4.columns\n\n  %hr.medium\n\n  .section\n    = partial :index_item_title, locals: { id: 'style', name: 'Style' }\n    %div\n      .row\n        = partial :index_item, locals: { id: 'style_region' }\n        = partial :index_item, locals: { id: 'style_grid' }\n        .large-4.columns\n\n  = partial :footer\n\n= partial :script\n"
  },
  {
    "path": "docs/gettingstarted.html.haml",
    "content": ".container.sidemenu\n  .row\n    .large-3.medium-4.columns.column-menu\n      .side-bar\n        %ul.side-nav\n          %li GETTING STARTED\n          %li\n            %a( href=\"#setup\" ) 1. Setup\n          %li\n            %a( href=\"#generate\" ) 2. Generate chart\n          %li\n            %a( href=\"#customize\" ) 3. Customize chart\n          %li\n            %a( href=\"#api\" ) 4. Use APIs\n          %li\n            %a( href=\"#style\" ) 5. Customize style\n          %li\n            %a( href=\"#more\" ) 6. And more..\n\n    .large-9.medium-8.columns.column-content\n      %section\n        %h2 Getting Started\n        %p In this guide, we are going to show you how to get started with C3.\n\n      %hr\n\n      %section\n        %h3\n          %a( href=\"#setup\" ) 1. Setup\n        %p Download the latest version here:\n        %ul\n          %li <a href=\"https://github.com/c3js/c3/releases/latest\" target=\"_blank\">https://github.com/c3js/c3/releases/latest</a>\n        %p Installing by Bower/Component is also available with the name <span class=\"code\">c3</span>.\n\n        %p Then, load the scripts and css:\n\n        .sourcecode.highlight\n          %pre\n            %code.html.xml\n              :preserve\n                <span class=\"comment\">&lt;!-- Load c3.css --&gt;</span>\n                <span class=\"tag\">&lt;<span class=\"title\">link</span> <span class=\"attribute\">href</span>=<span class=\"value\">\"/path/to/c3.css\"</span> <span class=\"attribute\">rel</span>=<span class=\"value\">\"stylesheet\"</span>&gt;</span>\n\n                <span class=\"comment\">&lt;!-- Load d3.js and c3.js --&gt;</span>\n                <span class=\"tag\">&lt;<span class=\"title\">script</span> <span class=\"attribute\">src</span>=<span class=\"value\">\"/path/to/d3.v5.min.js\"</span> <span class=\"attribute\">charset</span>=<span class=\"value\">\"utf-8\"</span>&gt;</span><span class=\"tag\">&lt;/<span class=\"title\">script</span>&gt;</span>\n                <span class=\"tag\">&lt;<span class=\"title\">script</span> <span class=\"attribute\">src</span>=<span class=\"value\">\"/path/to/c3.min.js\"</span>&gt;</span><span class=\"tag\">&lt;/<span class=\"title\">script</span>&gt;</span>\n\n        %p C3 depends on D3, so please load D3 too.\n\n      %hr\n\n      %section\n        %h3\n          %a( href=\"#generate\" ) 2. Generate Chart\n        %p C3 generates a chart by calling <span class=\"code\">generate()</span> with the argument object, and an element including the chart will insert into the element specified as a selector in that argument as <span class=\"code\">bindto</span>.\n\n        %p Prepare the element to bind the chart:\n        .sourcecode.highlight\n          %pre\n            %code.html.xml\n              :preserve\n                <span class=\"tag\">&lt;<span class=\"title\">div</span> <span class=\"attribute\">id</span>=<span class=\"value\">\"chart\"</span>&gt;&lt;/<span class=\"title\">div</span>&gt;</span>\n\n        %p And, call <span class=\"code\">generate()</span> with arguments:\n\n        .sourcecode.highlight\n          %pre\n            %code.javascript\n              :preserve\n                var chart = c3.generate({\n                    bindto: '#chart',\n                    data: {\n                      columns: [\n                        ['data1', 30, 200, 100, 400, 150, 250],\n                        ['data2', 50, 20, 10, 40, 15, 25]\n                      ]\n                    }\n                });\n\n        %p C3 supports the asynchronous module definition (AMD) API. If you use <a href=\"http://requirejs.org/\" target=\"_blank\">RequireJS</a>, you can load like this:\n\n        .sourcecode.highlight\n          %pre\n            %code.javascript\n              :preserve\n                require.config({\n                  baseUrl: '/js',\n                  paths: {\n                    d3: \"http://d3js.org/d3.v5.min\"\n                  }\n                });\n\n                require([\"d3\", \"c3\"], function(d3, c3) {\n                  c3.generate({\n                    ...\n                  });\n                });\n\n        %p Then, you will see the chart:\n\n        #chart2_1\n        %br\n\n        %p Data can be loaded as <a href=\"/samples/data_columned.html\">columned data</a> / <a href=\"/samples/data_rowed.html\">rowed data</a> / <a href=\"/samples/data_url.html\">csv in URL</a>.\n        %p There are serveral options to customize the chart and you can see those here:\n        %ul\n          %li <a href=\"/examples.html\">Examples</a>\n\n      %hr\n\n      %section\n        %h3\n          %a( href=\"#customize\" ) 3. Customize Chart\n        %p The chart can be customize by giving some options when generating. We will introduce some of them here.\n\n        %h4 1. Additional Axis\n        %p Introduce additional axis for <span class=\"code\">data2</span>. Add <span class=\"code\">data.axes</span> and <span class=\"code\">axis.y2.show</span> as follows:\n\n        .sourcecode.highlight\n          %pre\n            %code.javascript\n              :preserve\n                var chart = c3.generate({\n                    bindto: '#chart',\n                    data: {\n                      columns: [\n                        ['data1', 30, 200, 100, 400, 150, 250],\n                        ['data2', 50, 20, 10, 40, 15, 25]\n                      ],\n                      axes: {\n                        data2: 'y2' // ADD\n                      }\n                    },\n                    axis: {\n                      y2: {\n                        show: true // ADD\n                      }\n                    }\n                });\n\n        %p Then, the chart will be like this:\n\n        #chart3_1\n        %br\n\n        %h4 2. Show Axis Label\n        %p Show labels for each axis. Add <span class=\"code\">axis.y.label</span> and <span class=\"code\">axis.y2.label</span> as follows:\n\n        .sourcecode.highlight\n          %pre\n            %code.javascript\n              :preserve\n                var chart = c3.generate({\n                    bindto: '#chart',\n                    data: {\n                      columns: [\n                        ['data1', 30, 200, 100, 400, 150, 250],\n                        ['data2', 50, 20, 10, 40, 15, 25]\n                      ],\n                      axes: {\n                        data2: 'y2'\n                      }\n                    },\n                    axis: {\n                      y: {\n                        label: { // ADD\n                          text: 'Y Label',\n                          position: 'outer-middle'\n                        }\n                      },\n                      y2: {\n                        show: true,\n                        label: { // ADD\n                          text: 'Y2 Label',\n                          position: 'outer-middle'\n                        }\n                      }\n                    }\n                });\n\n        %p Then, the chart will be like this:\n\n        #chart3_2\n        %br\n\n        %h4 3. Change Chart Type\n        %p Show <span class=\"code\">data2</span> as Bar chart. Add <span class=\"code\">data.types</span> as follows:\n\n        .sourcecode.highlight\n          %pre\n            %code.javascript\n              :preserve\n                var chart = c3.generate({\n                    bindto: '#chart',\n                    data: {\n                      columns: [\n                        ['data1', 30, 200, 100, 400, 150, 250],\n                        ['data2', 50, 20, 10, 40, 15, 25]\n                      ],\n                      axes: {\n                        data2: 'y2'\n                      },\n                      types: {\n                        data2: 'bar' // ADD\n                      }\n                    },\n                    axis: {\n                      y: {\n                        label: {\n                          text: 'Y Label',\n                          position: 'outer-middle'\n                        }\n                      },\n                      y2: {\n                        show: true,\n                        label: {\n                          text: 'Y2 Label',\n                          position: 'outer-middle'\n                        }\n                      }\n                    }\n                });\n\n        %p Then, the chart will be like this:\n\n        #chart3_3\n        %br\n\n        %h4 4. Format values\n        %p Format the values of each data. Add <span class=\"code\">axis.y.tick.format</span> as follows:\n\n        .sourcecode.highlight\n          %pre\n            %code.javascript\n              :preserve\n                var chart = c3.generate({\n                    bindto: '#chart',\n                    data: {\n                      columns: [\n                        ['data1', 30, 200, 100, 400, 150, 250],\n                        ['data2', 50, 20, 10, 40, 15, 25]\n                      ],\n                      axes: {\n                        data2: 'y2'\n                      },\n                      types: {\n                        data2: 'bar'\n                      }\n                    },\n                    axis: {\n                      y: {\n                        label: {\n                          text: 'Y Label',\n                          position: 'outer-middle'\n                        },\n                        tick: {\n                          format: d3.format(\"$,\") // ADD\n                        }\n                      },\n                      y2: {\n                        show: true,\n                        label: {\n                          text: 'Y2 Label',\n                          position: 'outer-middle'\n                        }\n                      }\n                    }\n                });\n\n        %p Then, the chart will be like this:\n\n        #chart3_4\n        %br\n\n        %p More information about the options, please see <a href=\"/examples.html\">Examples</a>. (We'll add the reference soon)\n\n      %hr\n\n      %section\n        %h3\n          %a( href=\"#api\" ) 4. Use APIs\n        %p By using APIs, you can update the chart after it's been rendered. We will introduce some of APIs here. APIs can be called through the object returned from <span class=\"code\">generate()</span>.\n\n        %h4 1. Load Data\n        %p By using <span class=\"code\">load()</span> API, you can load data and update the chart dynamically as follows:\n\n        .sourcecode.highlight\n          %pre\n            %code.javascript\n              :preserve\n                // var chart = c3.generate({ ... });\n\n                chart.load({\n                  columns: [\n                    ['data1', 300, 100, 250, 150, 300, 150, 500],\n                    ['data2', 100, 200, 150, 50, 100, 250]\n                  ]\n                });\n\n        %p If you push the button \"Load\" below, this code will run and the chart will be updated.\n\n        %button.small( onclick=\"example4_1();\" ) Load\n\n        #chart4_1\n        %br\n\n        %h4 2. Unload Data\n        %p By using <span class=\"code\">unload()</span> API, you can unload the data dynamically as follows:\n\n        .sourcecode.highlight\n          %pre\n            %code.javascript\n              :preserve\n                // var chart = c3.generate({ ... });\n\n                chart.unload({\n                    ids: ['data2', 'data3']\n                });\n\n        %p If you push the button \"Unload\" below, this code will run and the chart will be updated.\n\n        %button.small( onclick=\"example4_2();\" ) Unload\n\n        #chart4_2\n        %br\n\n        %p Please use <span class=\"code\">unload</span> param in <span class=\"code\">load()</span> API if load and unload need to run simultaneously. Please see <a href=\"/samples/data_load.html\">this example</a>.\n\n        %h4 3. Show/Hide Data\n        %p By using <span class=\"code\">show()</span> and <span class=\"code\">hide()</span> API, you can show/hide the data dynamically as follows:\n\n        .sourcecode.highlight\n          %pre\n            %code.javascript\n              :preserve\n                // var chart = c3.generate({ ... });\n\n                chart.hide(['data2', 'data3']);\n                chart.show(['data2', 'data3']);\n\n        %p If you push the button \"Show\" and \"Hide\" below, this code will run and the chart will be updated.\n\n        %button.small( onclick=\"example4_3_2();\" ) Hide\n        %button.small( onclick=\"example4_3_1();\" ) Show\n\n        #chart4_3\n        %br\n\n        %p The documentation about APIs is poor now, so please check the <a href=\"https://github.com/c3js/c3/issues?state=open\">issues on github</a>. There might be some hints about what you want to do. (We will add the document soon)\n\n      %hr\n\n      %section\n        %h3\n          %a( href=\"#style\" ) 5. Customize Style\n        %p C3 give some classes for each element when generating. So, you can change the style of the elements by using those classes.\n        %h4 1. Line style\n        %p The lines have <span class=\"code\">c3-line-[id]</span> class, so this class can be used to define the style in css as follows:\n\n        .sourcecode.highlight\n          %pre\n            %code.css\n              :preserve\n                #chart .c3-line-data2 {\n                  stroke-width: 5px;\n                }\n\n        #chart5_1\n        %br\n\n        %p Please check the class for each element if you want to change the style. Web Inspector would be useful. (We will add the document for class definition soon)\n\n      %hr\n\n      %section\n        %h3\n          %a( href=\"#more\" ) 6. And More..\n        %p Please check the <a href=\"/examples.html\">examples</a> and the <a href=\"https://github.com/c3js/c3/issues?state=open\">issues</a> on github for more information. Sorry for the poor documentation. We're working on now and please give me some time. Thank you.\n\n  = partial :footer\n\n= partial :script\n= partial :script_scroll\n= javascript_include_tag 'gettingstarted.js'\n"
  },
  {
    "path": "docs/img/.gitignore",
    "content": ""
  },
  {
    "path": "docs/index.html.haml",
    "content": ".container\n\n  %h1.title\n    C3.js\n    %small D3-based reusable chart library\n\n  .chart\n    #message\n      %a.button.small( onclick=\"startDemo();\") Start Demo\n    #chart\n\n  %hr.large\n\n  %h2.text-center Why C3?\n  .row.text-center.features\n    .medium-4.large-4.columns.supporticons\n      %h3 Comfortable\n      %p\n        C3 makes it easy to generate D3-based charts by wrapping the code required to construct the entire chart. We don't need to write D3 code any more.\n    .medium-4.large-4.columns.supporticons\n      %h3 Customizable\n      %p\n        C3 gives some classes to each element when generating, so you can define a custom style by the class and it's possible to extend the structure directly by D3.\n\n    .medium-4.large-4.columns.supporticons\n      %h3 Controllable\n      %p\n        C3 provides a variety of APIs and callbacks to access the state of the chart. By using them, you can update the chart even after it's rendered.\n\n  %h3.text-center.sub\n    C3 enables deeper integration of charts into your application.\n  %br\n\n  .text-center\n    %a.button( href=\"/gettingstarted.html\" ) Getting Started\n\n  %hr\n\n  %h3 Change Log\n  %ul\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.20\">v0.7.20</a><span class=\"gray\">&nbsp;-&nbsp;2020-08-08</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.18\">v0.7.18</a><span class=\"gray\">&nbsp;-&nbsp;2020-06-17</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.17\">v0.7.17</a><span class=\"gray\">&nbsp;-&nbsp;2020-06-15</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.16\">v0.7.16</a><span class=\"gray\">&nbsp;-&nbsp;2020-06-15</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.15\">v0.7.15</a><span class=\"gray\">&nbsp;-&nbsp;2020-02-28</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.14\">v0.7.14</a><span class=\"gray\">&nbsp;-&nbsp;2020-02-24</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.12\">v0.7.12</a><span class=\"gray\">&nbsp;-&nbsp;2019-10-04</span>\n      %ul\n        %li Add rollup support.\n        %li Improved subchart handling.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.11\">v0.7.11</a><span class=\"gray\">&nbsp;-&nbsp;2019-10-04</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.10\">v0.7.10</a><span class=\"gray\">&nbsp;-&nbsp;2019-10-02</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.9\">v0.7.9</a><span class=\"gray\">&nbsp;-&nbsp;2019-09-23</span>\n      %ul\n        %li Experimental support for y/y2 log scale.\n        %li Restore tooltip behavior when grouped.\n        %li Add Region Labels.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.8\">v0.7.8</a><span class=\"gray\">&nbsp;-&nbsp;2019-08-25</span>\n      %ul\n        %li Fix scatter appearance.\n        %li Points in charts can be styled by css.\n        %li A fix for Firefox.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.7\">v0.7.7</a><span class=\"gray\">&nbsp;-&nbsp;2019-08-25</span>\n      %ul\n        %li Fix a bug.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.6\">v0.7.6</a><span class=\"gray\">&nbsp;-&nbsp;2019-08-20</span>\n      %ul\n        %li A bug fix.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.5\">v0.7.5</a><span class=\"gray\">&nbsp;-&nbsp;2019-08-19</span>\n      %ul\n        %li Add normalized stack chart.\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.4\">v0.7.4</a><span class=\"gray\">&nbsp;-&nbsp;2019-08-09</span>\n      %ul\n        %li Add padAngle option.\n        %li A bug fix.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.3\">v0.7.3</a><span class=\"gray\">&nbsp;-&nbsp;2019-07-29</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.2\">v0.7.2</a><span class=\"gray\">&nbsp;-&nbsp;2019-07-06</span>\n      %ul\n        %li Add stanford.scaleValues option.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.1\">v0.7.1</a><span class=\"gray\">&nbsp;-&nbsp;2019-05-29</span>\n      %ul\n        %li Add an option for tooltip behavior.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.7.0\">v0.7.0</a><span class=\"gray\">&nbsp;-&nbsp;2019-04-10</span>\n      %ul\n        %li Add stanford diagram.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.14\">v0.6.14</a><span class=\"gray\">&nbsp;-&nbsp;2019-03-27</span>\n      %ul\n        %li Fixed a memory leak.\n        %li Fixed .selected() API.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.13\">v0.6.13</a><span class=\"gray\">&nbsp;-&nbsp;2019-03-04</span>\n      %ul\n        %li Reverted resizing change in 0.6.11.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.12\">v0.6.12</a><span class=\"gray\">&nbsp;-&nbsp;2018-12-28</span>\n      %ul\n        %li Added index to tooltip’s title format callback.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.11\">v0.6.11</a><span class=\"gray\">&nbsp;-&nbsp;2018-12-08</span>\n      %ul\n        %li Fix a bug of resizing.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.10\">v0.6.10</a><span class=\"gray\">&nbsp;-&nbsp;2018-12-04</span>\n      %ul\n        %li Fix a bug of arc chart.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.9\">v0.6.9</a><span class=\"gray\">&nbsp;-&nbsp;2018-11-22</span>\n      %ul\n        %li Fix a bug.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.8\">v0.6.8</a><span class=\"gray\">&nbsp;-&nbsp;2018-10-01</span>\n      %ul\n        %li Add src/* npm package.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.7\">v0.6.7</a><span class=\"gray\">&nbsp;-&nbsp;2018-08-08</span>\n      %ul\n        %li Add the zoom type 'drag'.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.6\">v0.6.6</a><span class=\"gray\">&nbsp;-&nbsp;2018-07-24</span>\n      %ul\n        %li Fix bug of gauge chart.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.5\">v0.6.5</a><span class=\"gray\">&nbsp;-&nbsp;2018-07-14</span>\n      %ul\n        %li Fix bug of hidden legend option.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.4\">v0.6.4</a><span class=\"gray\">&nbsp;-&nbsp;2018-07-12</span>\n      %ul\n        %li Fix a bug of mouse events.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.3\">v0.6.3</a><span class=\"gray\">&nbsp;-&nbsp;2018-07-06</span>\n      %ul\n        %li Fix a bug of gauge.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.2\">v0.6.2</a><span class=\"gray\">&nbsp;-&nbsp;2018-06-08</span>\n      %ul\n        %li Add step-before and step-after for line.step.type option.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.4.23\">v0.4.23</a><span class=\"gray\">&nbsp;-&nbsp;2018-05-18</span>\n      %ul\n        %li Add axis.x.tick.multilineMax option (0.4 branch).\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.1\">v0.6.1</a><span class=\"gray\">&nbsp;-&nbsp;2018-05-17</span>\n      %ul\n        %li Add axis.x.tick.multilineMax option.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.6.0\">v0.6.0</a><span class=\"gray\">&nbsp;-&nbsp;2018-05-14</span>\n      %ul\n        %li Update D3 dependency to v5.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.5.4\">v0.5.4</a><span class=\"gray\">&nbsp;-&nbsp;2018-04-23</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.5.3\">v0.5.3</a><span class=\"gray\">&nbsp;-&nbsp;2018-04-12</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.5.2\">v0.5.2</a><span class=\"gray\">&nbsp;-&nbsp;2018-03-31</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.5.1\">v0.5.1</a><span class=\"gray\">&nbsp;-&nbsp;2018-03-25</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.5.0\">v0.5.0</a><span class=\"gray\">&nbsp;-&nbsp;2018-03-24</span>\n      %ul\n        %li Update D3 dependency to version 4.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.4.22\">v0.4.22</a><span class=\"gray\">&nbsp;-&nbsp;2018-03-21</span>\n      %ul\n        %li Add axis.x.inner option.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.4.21\">v0.4.21</a><span class=\"gray\">&nbsp;-&nbsp;2018-02-15</span>\n      %ul\n        %li Multi arc gauge chart.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.4.20\">v0.4.20</a><span class=\"gray\">&nbsp;-&nbsp;2018-02-11</span>\n      %ul\n        %li Fix gauge chart with fullCircle option.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.4.19\">v0.4.19</a><span class=\"gray\">&nbsp;-&nbsp;2018-02-10</span>\n      %ul\n        %li Do not call resize functions when chart is hidden.\n        %li Switched CI environment.\n        %li Have license in minified bundle.\n        %li Fixed a memory leak.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.4.18\">v0.4.18</a><span class=\"gray\">&nbsp;-&nbsp;2017-09-14</span>\n      %ul\n        %li point.focus.expand.r takes a function.\n        %li Pie and donuts really handle data.order correctly.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.4.17\">v0.4.17</a><span class=\"gray\">&nbsp;-&nbsp;2017-08-19</span>\n      %ul\n        %li Added bar.space option.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.4.16\">v0.4.16</a><span class=\"gray\">&nbsp;-&nbsp;2017-08-16</span>\n      %ul\n        %li Bug fix of bar chart.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.4.15\">v0.4.15</a><span class=\"gray\">&nbsp;-&nbsp;2017-07-20</span>\n      %ul\n        %li Move some style handling to css.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.4.14\">v0.4.14</a><span class=\"gray\">&nbsp;-&nbsp;2017-06-24</span>\n      %ul\n        %li Bug fix.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.4.13\">v0.4.13</a><span class=\"gray\">&nbsp;-&nbsp;2017-06-11</span>\n      %ul\n        %li New option and bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/v0.4.12\">v0.4.12</a><span class=\"gray\">&nbsp;-&nbsp;2017-05-28</span>\n      %ul\n        %li Performance improvement and bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.4.11\">v0.4.11</a><span class=\"gray\">&nbsp;-&nbsp;2016-05-01</span>\n      %ul\n        %li New features, performance improvement and bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.4.10\">v0.4.10</a><span class=\"gray\">&nbsp;-&nbsp;2015-03-17</span>\n      %ul\n        %li New features, performance improvement and bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.4.9\">v0.4.9</a><span class=\"gray\">&nbsp;-&nbsp;2015-01-18</span>\n      %ul\n        %li New features, performance improvement and bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.4.8\">v0.4.8</a><span class=\"gray\">&nbsp;-&nbsp;2014-12-14</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.4.7\">v0.4.7</a><span class=\"gray\">&nbsp;-&nbsp;2014-12-02</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.4.6\">v0.4.6</a><span class=\"gray\">&nbsp;-&nbsp;2014-12-01</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.4.5\">v0.4.5</a><span class=\"gray\">&nbsp;-&nbsp;2014-11-30</span>\n      %ul\n        %li Bug fixes.\n        %li Performance improvement.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.4.4\">v0.4.4</a><span class=\"gray\">&nbsp;-&nbsp;2014-11-21</span>\n      %ul\n        %li New features (e.g. <span class=\"code\">axis.y/y2.inner</span>, <span class=\"code\">legend.hide</span> options)\n        %li Bug fixes.\n        %li Performance improvement.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.4.3\">v0.4.3</a><span class=\"gray\">&nbsp;-&nbsp;2014-11-18</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.4.2\">v0.4.2</a><span class=\"gray\">&nbsp;-&nbsp;2014-11-17</span>\n      %ul\n        %li Bug fixes.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.4.1\">v0.4.1</a><span class=\"gray\">&nbsp;-&nbsp;2014-11-16</span>\n      %ul\n        %li Fixed class suffix.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.4.0\">v0.4.0</a><span class=\"gray\">&nbsp;-&nbsp;2014-11-15</span>\n      %ul\n        %li A lot of bug fixes and new features\n        %li Introduce unit test (it's not enough though)\n        %li <a href=\"https://github.com/c3js/c3/releases/tag/0.4.0\">and more...</a>\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.3.0\">v0.3.0</a><span class=\"gray\">&nbsp;-&nbsp;2014-08-22</span>\n      %ul\n        %li Introduced new architecture so that we can extend this library more easily.\n        %li Modified some options such as <span class=\"code\">data.xFormat</span> and <span class=\"code\">data.xLocaltime</span>.\n        %li Splitted source file into small ones.\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.2.5\">v0.2.5</a><span class=\"gray\">&nbsp;-&nbsp;2014-08-09</span>\n      %ul\n        %li Modified to use <span class=\"code\">data.onclick</span>, <span class=\"code\">data.onmouseover</span> and <span class=\"code\">data.onmouseout</span> on pie/donut/gauge instead of its callbacks\n        %li Modified <span class=\"code\">unload</span> interface\n        %li Bug fixes\n        %li <a href=\"https://github.com/c3js/c3/releases/tag/0.2.5\">and more...</a>\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.2.4\">v0.2.4</a><span class=\"gray\">&nbsp;-&nbsp;2014-06-16</span>\n      %ul\n        %li Added new options such as <span class=\"code\">pie.sort</span>, <span class=\"code\">donut.sort</span>, <span class=\"code\">bar.zerobased</span>, <span class=\"code\">area.zerobased</span>\n        %li Added new API such as <span class=\"code\">category</span>, <span class=\"code\">categories</span>\n        %li Bug fixes\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.2.3\">v0.2.3</a><span class=\"gray\">&nbsp;-&nbsp;2014-06-04</span>\n      %ul\n        %li Renamed callbacks (onend/onenter/onleave)\n        %li Added extension for zoom with reduction (by <a href=\"https://github.com/danelkhen\">@danelkhen</a> Thank you!)\n        %li Bug fixes\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.2.2\">v0.2.2</a><span class=\"gray\">&nbsp;-&nbsp;2014-06-03</span>\n      %ul\n        %li Supported ungrouped tooltip\n        %li Added zoom.enable API\n        %li Bug fixes\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.2.1\">v0.2.1</a><span class=\"gray\">&nbsp;-&nbsp;2014-06-02</span>\n      %ul\n        %li Bug fixes\n    %li\n      <a href=\"https://github.com/c3js/c3/releases/tag/0.2.0\">v0.2.0</a><span class=\"gray\">&nbsp;-&nbsp;2014-05-30</span>\n      %ul\n        %li Supported step line/area, stacked line/area, stacked line/area, gauge chart\n        %li Supported JSON as input\n        %li Added flow API\n        %li etc\n    %li <a href=\"https://github.com/c3js/c3/releases/tag/0.1.42\">v0.1.42</a><span class=\"gray\">&nbsp;-&nbsp;2014-05-18</span>\n\n  %h3 Browser Support\n  %p Because of the dependence on D3, C3 supports only modern browsers D3 supports. Please see <a href=\"https://github.com/mbostock/d3/wiki#browser--platform-support\">the description in D3</a>.\n  %p Note: For IE9 and IE10, polyfill is required because c3 uses <span class=\"code\">MutationObserver</span>, which is not supported in those versions. However, it's not required if charts always will be binded to the DOM specified by <span class=\"code\">bindto</span> because <span class=\"code\">MutationObserver</span> is not called in that case.\n\n  %h3 Dependency\n  %ul\n    %li <a href=\"https://github.com/mbostock/d3\" target=\"_blank\">D3.js</a> <span class=\"code\">^4.12.0</span>\n  %p Note: If you need to use D3 v3.x, please use C3 <a href=\"https://unpkg.com/c3@0.4.22/c3.js\">v0.4.22</a>, which is compatible with D3 v3.x.\n\n  %h3 License\n  %p MIT\n\n  = partial :footer\n\n= partial :script\n= javascript_include_tag 'index'\n"
  },
  {
    "path": "docs/js/ace/ace.js",
    "content": "(function(){function s(r){var i=function(e,t){return n(\"\",e,t)},s=e;r&&(e[r]||(e[r]={}),s=e[r]);if(!s.define||!s.define.packaged)t.original=s.define,s.define=t,s.define.packaged=!0;if(!s.require||!s.require.packaged)n.original=s.require,s.require=i,s.require.packaged=!0}var ACE_NAMESPACE = \"ace\",e=function(){return this}();if(!ACE_NAMESPACE&&typeof requirejs!=\"undefined\")return;var t=function(e,n,r){if(typeof e!=\"string\"){t.original?t.original.apply(window,arguments):(console.error(\"dropping module because define wasn't a string.\"),console.trace());return}arguments.length==2&&(r=n),t.modules||(t.modules={},t.payloads={}),t.payloads[e]=r,t.modules[e]=null},n=function(e,t,r){if(Object.prototype.toString.call(t)===\"[object Array]\"){var s=[];for(var o=0,u=t.length;o<u;++o){var a=i(e,t[o]);if(!a&&n.original)return n.original.apply(window,arguments);s.push(a)}r&&r.apply(null,s)}else{if(typeof t==\"string\"){var f=i(e,t);return!f&&n.original?n.original.apply(window,arguments):(r&&r(),f)}if(n.original)return n.original.apply(window,arguments)}},r=function(e,t){if(t.indexOf(\"!\")!==-1){var n=t.split(\"!\");return r(e,n[0])+\"!\"+r(e,n[1])}if(t.charAt(0)==\".\"){var i=e.split(\"/\").slice(0,-1).join(\"/\");t=i+\"/\"+t;while(t.indexOf(\".\")!==-1&&s!=t){var s=t;t=t.replace(/\\/\\.\\//,\"/\").replace(/[^\\/]+\\/\\.\\.\\//,\"\")}}return t},i=function(e,i){i=r(e,i);var s=t.modules[i];if(!s){s=t.payloads[i];if(typeof s==\"function\"){var o={},u={id:i,uri:\"\",exports:o,packaged:!0},a=function(e,t){return n(i,e,t)},f=s(a,o,u);o=f||u.exports,t.modules[i]=o,delete t.payloads[i]}s=t.modules[i]=o||s}return s};s(ACE_NAMESPACE)})(),ace.define(\"ace/lib/regexp\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";function o(e){return(e.global?\"g\":\"\")+(e.ignoreCase?\"i\":\"\")+(e.multiline?\"m\":\"\")+(e.extended?\"x\":\"\")+(e.sticky?\"y\":\"\")}function u(e,t,n){if(Array.prototype.indexOf)return e.indexOf(t,n);for(var r=n||0;r<e.length;r++)if(e[r]===t)return r;return-1}var r={exec:RegExp.prototype.exec,test:RegExp.prototype.test,match:String.prototype.match,replace:String.prototype.replace,split:String.prototype.split},i=r.exec.call(/()??/,\"\")[1]===undefined,s=function(){var e=/^/g;return r.test.call(e,\"\"),!e.lastIndex}();if(s&&i)return;RegExp.prototype.exec=function(e){var t=r.exec.apply(this,arguments),n,a;if(typeof e==\"string\"&&t){!i&&t.length>1&&u(t,\"\")>-1&&(a=RegExp(this.source,r.replace.call(o(this),\"g\",\"\")),r.replace.call(e.slice(t.index),a,function(){for(var e=1;e<arguments.length-2;e++)arguments[e]===undefined&&(t[e]=undefined)}));if(this._xregexp&&this._xregexp.captureNames)for(var f=1;f<t.length;f++)n=this._xregexp.captureNames[f-1],n&&(t[n]=t[f]);!s&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--}return t},s||(RegExp.prototype.test=function(e){var t=r.exec.call(this,e);return t&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,!!t})}),ace.define(\"ace/lib/es5-shim\",[\"require\",\"exports\",\"module\"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,\"sentinel\",{}),\"sentinel\"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t===\"undefined\"||t===\"boolean\"||t===\"number\"||t===\"string\"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n==\"function\"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r==\"function\"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!=\"function\")throw new TypeError(\"Function.prototype.bind called on incompatible \"+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,\"__defineGetter__\"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,\"XXX\"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)==\"[object Array]\"});var m=Object(\"a\"),g=m[0]!=\"a\"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!=\"[object Function]\")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0;if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");if(!i&&arguments.length==1)throw new TypeError(\"reduce of empty array with no initial value\");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError(\"reduce of empty array with no initial value\")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0;if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");if(!i&&arguments.length==1)throw new TypeError(\"reduceRight of empty array with no initial value\");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError(\"reduceRight of empty array with no initial value\")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)==\"[object String]\"?this.split(\"\"):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)==\"[object String]\"?this.split(\"\"):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y=\"Object.getOwnPropertyDescriptor called on a non-object: \";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!=\"object\"&&typeof t!=\"function\"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!=\"object\")throw new TypeError(\"typeof prototype[\"+typeof t+\"] != 'object'\");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document==\"undefined\"||w(document.createElement(\"div\"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T=\"Property description must be an object: \",N=\"Object.defineProperty called on non-object: \",C=\"getters & setters can not be defined on this javascript engine\";Object.defineProperty=function(t,n,r){if(typeof t!=\"object\"&&typeof t!=\"function\"||t===null)throw new TypeError(N+t);if(typeof r!=\"object\"&&typeof r!=\"function\"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,\"value\"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,\"get\")&&l(t,n,r.get),f(r,\"set\")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n==\"function\"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n=\"\";while(f(t,n))n+=\"?\";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=[\"toString\",\"toLocaleString\",\"valueOf\",\"hasOwnProperty\",\"isPrototypeOf\",\"propertyIsEnumerable\",\"constructor\"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!=\"object\"&&typeof e!=\"function\"||e===null)throw new TypeError(\"Object.keys called on a non-object\");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _=\"  \\n\u000b\\f\\r \\u00a0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029\\ufeff\";if(!String.prototype.trim||_.trim()){_=\"[\"+_+\"]\";var D=new RegExp(\"^\"+_+_+\"*\"),P=new RegExp(_+_+\"*$\");String.prototype.trim=function(){return String(this).replace(D,\"\").replace(P,\"\")}}var F=function(e){if(e==null)throw new TypeError(\"can't convert \"+e+\" to object\");return Object(e)}}),ace.define(\"ace/lib/fixoldbrowsers\",[\"require\",\"exports\",\"module\",\"ace/lib/regexp\",\"ace/lib/es5-shim\"],function(e,t,n){\"use strict\";e(\"./regexp\"),e(\"./es5-shim\")}),ace.define(\"ace/lib/dom\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";if(typeof document==\"undefined\")return;var r=\"http://www.w3.org/1999/xhtml\";t.getDocumentHead=function(e){return e||(e=document),e.head||e.getElementsByTagName(\"head\")[0]||e.documentElement},t.createElement=function(e,t){return document.createElementNS?document.createElementNS(t||r,e):document.createElement(e)},t.hasCssClass=function(e,t){var n=(e.className||\"\").split(/\\s+/g);return n.indexOf(t)!==-1},t.addCssClass=function(e,n){t.hasCssClass(e,n)||(e.className+=\" \"+n)},t.removeCssClass=function(e,t){var n=e.className.split(/\\s+/g);for(;;){var r=n.indexOf(t);if(r==-1)break;n.splice(r,1)}e.className=n.join(\" \")},t.toggleCssClass=function(e,t){var n=e.className.split(/\\s+/g),r=!0;for(;;){var i=n.indexOf(t);if(i==-1)break;r=!1,n.splice(i,1)}return r&&n.push(t),e.className=n.join(\" \"),r},t.setCssClass=function(e,n,r){r?t.addCssClass(e,n):t.removeCssClass(e,n)},t.hasCssString=function(e,t){var n=0,r;t=t||document;if(t.createStyleSheet&&(r=t.styleSheets)){while(n<r.length)if(r[n++].owningElement.id===e)return!0}else if(r=t.getElementsByTagName(\"style\"))while(n<r.length)if(r[n++].id===e)return!0;return!1},t.importCssString=function(n,i,s){s=s||document;if(i&&t.hasCssString(i,s))return null;var o;s.createStyleSheet?(o=s.createStyleSheet(),o.cssText=n,i&&(o.owningElement.id=i)):(o=s.createElementNS?s.createElementNS(r,\"style\"):s.createElement(\"style\"),o.appendChild(s.createTextNode(n)),i&&(o.id=i),t.getDocumentHead(s).appendChild(o))},t.importCssStylsheet=function(e,n){if(n.createStyleSheet)n.createStyleSheet(e);else{var r=t.createElement(\"link\");r.rel=\"stylesheet\",r.href=e,t.getDocumentHead(n).appendChild(r)}},t.getInnerWidth=function(e){return parseInt(t.computedStyle(e,\"paddingLeft\"),10)+parseInt(t.computedStyle(e,\"paddingRight\"),10)+e.clientWidth},t.getInnerHeight=function(e){return parseInt(t.computedStyle(e,\"paddingTop\"),10)+parseInt(t.computedStyle(e,\"paddingBottom\"),10)+e.clientHeight},window.pageYOffset!==undefined?(t.getPageScrollTop=function(){return window.pageYOffset},t.getPageScrollLeft=function(){return window.pageXOffset}):(t.getPageScrollTop=function(){return document.body.scrollTop},t.getPageScrollLeft=function(){return document.body.scrollLeft}),window.getComputedStyle?t.computedStyle=function(e,t){return t?(window.getComputedStyle(e,\"\")||{})[t]||\"\":window.getComputedStyle(e,\"\")||{}}:t.computedStyle=function(e,t){return t?e.currentStyle[t]:e.currentStyle},t.scrollbarWidth=function(e){var n=t.createElement(\"ace_inner\");n.style.width=\"100%\",n.style.minWidth=\"0px\",n.style.height=\"200px\",n.style.display=\"block\";var r=t.createElement(\"ace_outer\"),i=r.style;i.position=\"absolute\",i.left=\"-10000px\",i.overflow=\"hidden\",i.width=\"200px\",i.minWidth=\"0px\",i.height=\"150px\",i.display=\"block\",r.appendChild(n);var s=e.documentElement;s.appendChild(r);var o=n.offsetWidth;i.overflow=\"scroll\";var u=n.offsetWidth;return o==u&&(u=r.clientWidth),s.removeChild(r),o-u},t.setInnerHtml=function(e,t){var n=e.cloneNode(!1);return n.innerHTML=t,e.parentNode.replaceChild(n,e),n},\"textContent\"in document.documentElement?(t.setInnerText=function(e,t){e.textContent=t},t.getInnerText=function(e){return e.textContent}):(t.setInnerText=function(e,t){e.innerText=t},t.getInnerText=function(e){return e.innerText}),t.getParentWindow=function(e){return e.defaultView||e.parentWindow}}),ace.define(\"ace/lib/oop\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define(\"ace/lib/keys\",[\"require\",\"exports\",\"module\",\"ace/lib/fixoldbrowsers\",\"ace/lib/oop\"],function(e,t,n){\"use strict\";e(\"./fixoldbrowsers\");var r=e(\"./oop\"),i=function(){var e={MODIFIER_KEYS:{16:\"Shift\",17:\"Ctrl\",18:\"Alt\",224:\"Meta\"},KEY_MODS:{ctrl:1,alt:2,option:2,shift:4,\"super\":8,meta:8,command:8,cmd:8},FUNCTION_KEYS:{8:\"Backspace\",9:\"Tab\",13:\"Return\",19:\"Pause\",27:\"Esc\",32:\"Space\",33:\"PageUp\",34:\"PageDown\",35:\"End\",36:\"Home\",37:\"Left\",38:\"Up\",39:\"Right\",40:\"Down\",44:\"Print\",45:\"Insert\",46:\"Delete\",96:\"Numpad0\",97:\"Numpad1\",98:\"Numpad2\",99:\"Numpad3\",100:\"Numpad4\",101:\"Numpad5\",102:\"Numpad6\",103:\"Numpad7\",104:\"Numpad8\",105:\"Numpad9\",\"-13\":\"NumpadEnter\",112:\"F1\",113:\"F2\",114:\"F3\",115:\"F4\",116:\"F5\",117:\"F6\",118:\"F7\",119:\"F8\",120:\"F9\",121:\"F10\",122:\"F11\",123:\"F12\",144:\"Numlock\",145:\"Scrolllock\"},PRINTABLE_KEYS:{32:\" \",48:\"0\",49:\"1\",50:\"2\",51:\"3\",52:\"4\",53:\"5\",54:\"6\",55:\"7\",56:\"8\",57:\"9\",59:\";\",61:\"=\",65:\"a\",66:\"b\",67:\"c\",68:\"d\",69:\"e\",70:\"f\",71:\"g\",72:\"h\",73:\"i\",74:\"j\",75:\"k\",76:\"l\",77:\"m\",78:\"n\",79:\"o\",80:\"p\",81:\"q\",82:\"r\",83:\"s\",84:\"t\",85:\"u\",86:\"v\",87:\"w\",88:\"x\",89:\"y\",90:\"z\",107:\"+\",109:\"-\",110:\".\",187:\"=\",188:\",\",189:\"-\",190:\".\",191:\"/\",192:\"`\",219:\"[\",220:\"\\\\\",221:\"]\",222:\"'\"}},t,n;for(n in e.FUNCTION_KEYS)t=e.FUNCTION_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);for(n in e.PRINTABLE_KEYS)t=e.PRINTABLE_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);return r.mixin(e,e.MODIFIER_KEYS),r.mixin(e,e.PRINTABLE_KEYS),r.mixin(e,e.FUNCTION_KEYS),e.enter=e[\"return\"],e.escape=e.esc,e.del=e[\"delete\"],e[173]=\"-\",function(){var t=[\"cmd\",\"ctrl\",\"alt\",\"shift\"];for(var n=Math.pow(2,t.length);n--;)e.KEY_MODS[n]=t.filter(function(t){return n&e.KEY_MODS[t]}).join(\"-\")+\"-\"}(),e.KEY_MODS[0]=\"\",e.KEY_MODS[-1]=\"input\",e}();r.mixin(t,i),t.keyCodeToString=function(e){var t=i[e];return typeof t!=\"string\"&&(t=String.fromCharCode(e)),t.toLowerCase()}}),ace.define(\"ace/lib/useragent\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";t.OS={LINUX:\"LINUX\",MAC:\"MAC\",WINDOWS:\"WINDOWS\"},t.getOS=function(){return t.isMac?t.OS.MAC:t.isLinux?t.OS.LINUX:t.OS.WINDOWS};if(typeof navigator!=\"object\")return;var r=(navigator.platform.match(/mac|win|linux/i)||[\"other\"])[0].toLowerCase(),i=navigator.userAgent;t.isWin=r==\"win\",t.isMac=r==\"mac\",t.isLinux=r==\"linux\",t.isIE=navigator.appName==\"Microsoft Internet Explorer\"||navigator.appName.indexOf(\"MSAppHost\")>=0?parseFloat((i.match(/(?:MSIE |Trident\\/[0-9]+[\\.0-9]+;.*rv:)([0-9]+[\\.0-9]+)/)||[])[1]):parseFloat((i.match(/(?:Trident\\/[0-9]+[\\.0-9]+;.*rv:)([0-9]+[\\.0-9]+)/)||[])[1]),t.isOldIE=t.isIE&&t.isIE<9,t.isGecko=t.isMozilla=(window.Controllers||window.controllers)&&window.navigator.product===\"Gecko\",t.isOldGecko=t.isGecko&&parseInt((i.match(/rv\\:(\\d+)/)||[])[1],10)<4,t.isOpera=window.opera&&Object.prototype.toString.call(window.opera)==\"[object Opera]\",t.isWebKit=parseFloat(i.split(\"WebKit/\")[1])||undefined,t.isChrome=parseFloat(i.split(\" Chrome/\")[1])||undefined,t.isAIR=i.indexOf(\"AdobeAIR\")>=0,t.isIPad=i.indexOf(\"iPad\")>=0,t.isTouchPad=i.indexOf(\"TouchPad\")>=0,t.isChromeOS=i.indexOf(\" CrOS \")>=0}),ace.define(\"ace/lib/event\",[\"require\",\"exports\",\"module\",\"ace/lib/keys\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";function o(e,t,n){var o=s(t);if(!i.isMac&&u){if(u[91]||u[92])o|=8;if(u.altGr){if((3&o)==3)return;u.altGr=0}if(n===18||n===17){var f=\"location\"in t?t.location:t.keyLocation;if(n===17&&f===1)a=t.timeStamp;else if(n===18&&o===3&&f===2){var l=-a;a=t.timeStamp,l+=a,l<3&&(u.altGr=!0)}}}if(n in r.MODIFIER_KEYS){switch(r.MODIFIER_KEYS[n]){case\"Alt\":o=2;break;case\"Shift\":o=4;break;case\"Ctrl\":o=1;break;default:o=8}n=-1}o&8&&(n===91||n===93)&&(n=-1);if(!o&&n===13){var f=\"location\"in t?t.location:t.keyLocation;if(f===3){e(t,o,-n);if(t.defaultPrevented)return}}if(i.isChromeOS&&o&8){e(t,o,n);if(t.defaultPrevented)return;o&=-9}return!!o||n in r.FUNCTION_KEYS||n in r.PRINTABLE_KEYS?e(t,o,n):!1}var r=e(\"./keys\"),i=e(\"./useragent\");t.addListener=function(e,t,n){if(e.addEventListener)return e.addEventListener(t,n,!1);if(e.attachEvent){var r=function(){n.call(e,window.event)};n._wrapper=r,e.attachEvent(\"on\"+t,r)}},t.removeListener=function(e,t,n){if(e.removeEventListener)return e.removeEventListener(t,n,!1);e.detachEvent&&e.detachEvent(\"on\"+t,n._wrapper||n)},t.stopEvent=function(e){return t.stopPropagation(e),t.preventDefault(e),!1},t.stopPropagation=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},t.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},t.getButton=function(e){return e.type==\"dblclick\"?0:e.type==\"contextmenu\"||i.isMac&&e.ctrlKey&&!e.altKey&&!e.shiftKey?2:e.preventDefault?e.button:{1:0,2:2,4:1}[e.button]},t.capture=function(e,n,r){function i(e){n&&n(e),r&&r(e),t.removeListener(document,\"mousemove\",n,!0),t.removeListener(document,\"mouseup\",i,!0),t.removeListener(document,\"dragstart\",i,!0)}return t.addListener(document,\"mousemove\",n,!0),t.addListener(document,\"mouseup\",i,!0),t.addListener(document,\"dragstart\",i,!0),i},t.addMouseWheelListener=function(e,n){\"onmousewheel\"in e?t.addListener(e,\"mousewheel\",function(e){var t=8;e.wheelDeltaX!==undefined?(e.wheelX=-e.wheelDeltaX/t,e.wheelY=-e.wheelDeltaY/t):(e.wheelX=0,e.wheelY=-e.wheelDelta/t),n(e)}):\"onwheel\"in e?t.addListener(e,\"wheel\",function(e){var t=.35;switch(e.deltaMode){case e.DOM_DELTA_PIXEL:e.wheelX=e.deltaX*t||0,e.wheelY=e.deltaY*t||0;break;case e.DOM_DELTA_LINE:case e.DOM_DELTA_PAGE:e.wheelX=(e.deltaX||0)*5,e.wheelY=(e.deltaY||0)*5}n(e)}):t.addListener(e,\"DOMMouseScroll\",function(e){e.axis&&e.axis==e.HORIZONTAL_AXIS?(e.wheelX=(e.detail||0)*5,e.wheelY=0):(e.wheelX=0,e.wheelY=(e.detail||0)*5),n(e)})},t.addMultiMouseDownListener=function(e,n,r,s){var o=0,u,a,f,l={2:\"dblclick\",3:\"tripleclick\",4:\"quadclick\"};t.addListener(e,\"mousedown\",function(e){t.getButton(e)!==0?o=0:e.detail>1?(o++,o>4&&(o=1)):o=1;if(i.isIE){var c=Math.abs(e.clientX-u)>5||Math.abs(e.clientY-a)>5;if(!f||c)o=1;f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),o==1&&(u=e.clientX,a=e.clientY)}e._clicks=o,r[s](\"mousedown\",e);if(o>4)o=0;else if(o>1)return r[s](l[o],e)}),i.isOldIE&&t.addListener(e,\"dblclick\",function(e){o=2,f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),r[s](\"mousedown\",e),r[s](l[o],e)})};var s=!i.isMac||!i.isOpera||\"KeyboardEvent\"in window?function(e){return 0|(e.ctrlKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.metaKey?8:0)}:function(e){return 0|(e.metaKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.ctrlKey?8:0)};t.getModifierString=function(e){return r.KEY_MODS[s(e)]};var u=null,a=0;t.addCommandKeyListener=function(e,n){var r=t.addListener;if(i.isOldGecko||i.isOpera&&!(\"KeyboardEvent\"in window)){var s=null;r(e,\"keydown\",function(e){s=e.keyCode}),r(e,\"keypress\",function(e){return o(n,e,s)})}else{var a=null;r(e,\"keydown\",function(e){u[e.keyCode]=!0;var t=o(n,e,e.keyCode);return a=e.defaultPrevented,t}),r(e,\"keypress\",function(e){a&&(e.ctrlKey||e.altKey||e.shiftKey||e.metaKey)&&(t.stopEvent(e),a=null)}),r(e,\"keyup\",function(e){u[e.keyCode]=null}),u||(u=Object.create(null),r(window,\"focus\",function(e){u=Object.create(null)}))}};if(window.postMessage&&!i.isOldIE){var f=1;t.nextTick=function(e,n){n=n||window;var r=\"zero-timeout-message-\"+f;t.addListener(n,\"message\",function i(s){s.data==r&&(t.stopPropagation(s),t.removeListener(n,\"message\",i),e())}),n.postMessage(r,\"*\")}}t.nextFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame,t.nextFrame?t.nextFrame=t.nextFrame.bind(window):t.nextFrame=function(e){setTimeout(e,17)}}),ace.define(\"ace/lib/lang\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split(\"\").reverse().join(\"\")},t.stringRepeat=function(e,t){var n=\"\";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\\s\\s*/,i=/\\s\\s*$/;t.stringTrimLeft=function(e){return e.replace(r,\"\")},t.stringTrimRight=function(e){return e.replace(i,\"\")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]==\"object\"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function(e){if(typeof e!=\"object\"||!e)return e;var n=e.constructor;if(n===RegExp)return e;var r=n();for(var i in e)typeof e[i]==\"object\"?r[i]=t.deepCopy(e[i]):r[i]=e[i];return r},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\\]\\/\\\\])/g,\"\\\\$1\")},t.escapeHTML=function(e){return e.replace(/&/g,\"&#38;\").replace(/\"/g,\"&#34;\").replace(/'/g,\"&#39;\").replace(/</g,\"&#60;\")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define(\"ace/keyboard/textinput\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\",\"ace/lib/dom\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../lib/event\"),i=e(\"../lib/useragent\"),s=e(\"../lib/dom\"),o=e(\"../lib/lang\"),u=i.isChrome<18,a=i.isIE,f=function(e,t){function b(e){if(h)return;if(k)t=0,r=e?0:n.value.length-1;else var t=e?2:1,r=2;try{n.setSelectionRange(t,r)}catch(i){}}function w(){if(h)return;n.value=f,i.isWebKit&&y.schedule()}function R(){clearTimeout(q),q=setTimeout(function(){p&&(n.style.cssText=p,p=\"\"),t.renderer.$keepTextAreaAtCursor==null&&(t.renderer.$keepTextAreaAtCursor=!0,t.renderer.$moveTextAreaToCursor())},i.isOldIE?200:0)}var n=s.createElement(\"textarea\");n.className=\"ace_text-input\",i.isTouchPad&&n.setAttribute(\"x-palm-disable-auto-cap\",!0),n.wrap=\"off\",n.autocorrect=\"off\",n.autocapitalize=\"off\",n.spellcheck=!1,n.style.opacity=\"0\",i.isOldIE&&(n.style.top=\"-100px\"),e.insertBefore(n,e.firstChild);var f=\"\u0001\u0001\",l=!1,c=!1,h=!1,p=\"\",d=!0;try{var v=document.activeElement===n}catch(m){}r.addListener(n,\"blur\",function(e){t.onBlur(e),v=!1}),r.addListener(n,\"focus\",function(e){v=!0,t.onFocus(e),b()}),this.focus=function(){n.focus()},this.blur=function(){n.blur()},this.isFocused=function(){return v};var g=o.delayedCall(function(){v&&b(d)}),y=o.delayedCall(function(){h||(n.value=f,v&&b())});i.isWebKit||t.addEventListener(\"changeSelection\",function(){t.selection.isEmpty()!=d&&(d=!d,g.schedule())}),w(),v&&t.onFocus();var E=function(e){return e.selectionStart===0&&e.selectionEnd===e.value.length};!n.setSelectionRange&&n.createTextRange&&(n.setSelectionRange=function(e,t){var n=this.createTextRange();n.collapse(!0),n.moveStart(\"character\",e),n.moveEnd(\"character\",t),n.select()},E=function(e){try{var t=e.ownerDocument.selection.createRange()}catch(n){}return!t||t.parentElement()!=e?!1:t.text==e.value});if(i.isOldIE){var S=!1,x=function(e){if(S)return;var t=n.value;if(h||!t||t==f)return;if(e&&t==f[0])return T.schedule();A(t),S=!0,w(),S=!1},T=o.delayedCall(x);r.addListener(n,\"propertychange\",x);var N={13:1,27:1};r.addListener(n,\"keyup\",function(e){h&&(!n.value||N[e.keyCode])&&setTimeout(F,0);if((n.value.charCodeAt(0)||0)<129)return T.call();h?j():B()}),r.addListener(n,\"keydown\",function(e){T.schedule(50)})}var C=function(e){l?l=!1:E(n)?(t.selectAll(),b()):k&&b(t.selection.isEmpty())},k=null;this.setInputHandler=function(e){k=e},this.getInputHandler=function(){return k};var L=!1,A=function(e){k&&(e=k(e),k=null),c?(b(),e&&t.onPaste(e),c=!1):e==f.charAt(0)?L?t.execCommand(\"del\",{source:\"ace\"}):t.execCommand(\"backspace\",{source:\"ace\"}):(e.substring(0,2)==f?e=e.substr(2):e.charAt(0)==f.charAt(0)?e=e.substr(1):e.charAt(e.length-1)==f.charAt(0)&&(e=e.slice(0,-1)),e.charAt(e.length-1)==f.charAt(0)&&(e=e.slice(0,-1)),e&&t.onTextInput(e)),L&&(L=!1)},O=function(e){if(h)return;var t=n.value;A(t),w()},M=function(e,t){var n=e.clipboardData||window.clipboardData;if(!n||u)return;var r=a?\"Text\":\"text/plain\";return t?n.setData(r,t)!==!1:n.getData(r)},_=function(e,i){var s=t.getCopyText();if(!s)return r.preventDefault(e);M(e,s)?(i?t.onCut():t.onCopy(),r.preventDefault(e)):(l=!0,n.value=s,n.select(),setTimeout(function(){l=!1,w(),b(),i?t.onCut():t.onCopy()}))},D=function(e){_(e,!0)},P=function(e){_(e,!1)},H=function(e){var s=M(e);typeof s==\"string\"?(s&&t.onPaste(s),i.isIE&&setTimeout(b),r.preventDefault(e)):(n.value=\"\",c=!0)};r.addCommandKeyListener(n,t.onCommandKey.bind(t)),r.addListener(n,\"select\",C),r.addListener(n,\"input\",O),r.addListener(n,\"cut\",D),r.addListener(n,\"copy\",P),r.addListener(n,\"paste\",H),(!(\"oncut\"in n)||!(\"oncopy\"in n)||!(\"onpaste\"in n))&&r.addListener(e,\"keydown\",function(e){if(i.isMac&&!e.metaKey||!e.ctrlKey)return;switch(e.keyCode){case 67:P(e);break;case 86:H(e);break;case 88:D(e)}});var B=function(e){if(h||!t.onCompositionStart||t.$readOnly)return;h={},t.onCompositionStart(),setTimeout(j,0),t.on(\"mousedown\",F),t.selection.isEmpty()||(t.insert(\"\"),t.session.markUndoGroup(),t.selection.clearSelection()),t.session.markUndoGroup()},j=function(){if(!h||!t.onCompositionUpdate||t.$readOnly)return;var e=n.value.replace(/\\x01/g,\"\");if(h.lastValue===e)return;t.onCompositionUpdate(e),h.lastValue&&t.undo(),h.lastValue=e;if(h.lastValue){var r=t.selection.getRange();t.insert(h.lastValue),t.session.markUndoGroup(),h.range=t.selection.getRange(),t.selection.setRange(r),t.selection.clearSelection()}},F=function(e){if(!t.onCompositionEnd||t.$readOnly)return;var r=h;h=!1;var i=setTimeout(function(){i=null;var e=n.value.replace(/\\x01/g,\"\");if(h)return;e==r.lastValue?w():!r.lastValue&&e&&(w(),A(e))});k=function(n){return i&&clearTimeout(i),n=n.replace(/\\x01/g,\"\"),n==r.lastValue?\"\":(r.lastValue&&i&&t.undo(),n)},t.onCompositionEnd(),t.removeListener(\"mousedown\",F),e.type==\"compositionend\"&&r.range&&t.selection.setRange(r.range)},I=o.delayedCall(j,50);r.addListener(n,\"compositionstart\",B),i.isGecko?r.addListener(n,\"text\",function(){I.schedule()}):(r.addListener(n,\"keyup\",function(){I.schedule()}),r.addListener(n,\"keydown\",function(){I.schedule()})),r.addListener(n,\"compositionend\",F),this.getElement=function(){return n},this.setReadOnly=function(e){n.readOnly=e},this.onContextMenu=function(e){L=!0,b(t.selection.isEmpty()),t._emit(\"nativecontextmenu\",{target:t,domEvent:e}),this.moveToMouse(e,!0)},this.moveToMouse=function(e,o){if(!o&&i.isOldIE)return;p||(p=n.style.cssText),n.style.cssText=(o?\"z-index:100000;\":\"\")+\"height:\"+n.style.height+\";\"+(i.isIE?\"opacity:0.1;\":\"\");var u=t.container.getBoundingClientRect(),a=s.computedStyle(t.container),f=u.top+(parseInt(a.borderTopWidth)||0),l=u.left+(parseInt(u.borderLeftWidth)||0),c=u.bottom-f-n.clientHeight-2,h=function(e){n.style.left=e.clientX-l-2+\"px\",n.style.top=Math.min(e.clientY-f-2,c)+\"px\"};h(e);if(e.type!=\"mousedown\")return;t.renderer.$keepTextAreaAtCursor&&(t.renderer.$keepTextAreaAtCursor=null),i.isWin&&!i.isOldIE&&r.capture(t.container,h,R)},this.onContextMenuClose=R;var q,U=function(e){t.textInput.onContextMenu(e),R()};r.addListener(t.renderer.scroller,\"contextmenu\",U),r.addListener(n,\"contextmenu\",U)};t.TextInput=f}),ace.define(\"ace/mouse/default_handlers\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";function u(e){e.$clickSelection=null;var t=e.editor;t.setDefaultHandler(\"mousedown\",this.onMouseDown.bind(e)),t.setDefaultHandler(\"dblclick\",this.onDoubleClick.bind(e)),t.setDefaultHandler(\"tripleclick\",this.onTripleClick.bind(e)),t.setDefaultHandler(\"quadclick\",this.onQuadClick.bind(e)),t.setDefaultHandler(\"mousewheel\",this.onMouseWheel.bind(e));var n=[\"select\",\"startSelect\",\"selectEnd\",\"selectAllEnd\",\"selectByWordsEnd\",\"selectByLinesEnd\",\"dragWait\",\"dragWaitEnd\",\"focusWait\"];n.forEach(function(t){e[t]=this[t]},this),e.selectByLines=this.extendSelectionBy.bind(e,\"getLineRange\"),e.selectByWords=this.extendSelectionBy.bind(e,\"getWordRange\")}function a(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}function f(e,t){if(e.start.row==e.end.row)var n=2*t.column-e.start.column-e.end.column;else if(e.start.row==e.end.row-1&&!e.start.column&&!e.end.column)var n=t.column-4;else var n=2*t.row-e.start.row-e.end.row;return n<0?{cursor:e.start,anchor:e.end}:{cursor:e.end,anchor:e.start}}var r=e(\"../lib/dom\"),i=e(\"../lib/event\"),s=e(\"../lib/useragent\"),o=0;(function(){this.onMouseDown=function(e){var t=e.inSelection(),n=e.getDocumentPosition();this.mousedownEvent=e;var r=this.editor,i=e.getButton();if(i!==0){var s=r.getSelectionRange(),o=s.isEmpty();o&&r.selection.moveToPosition(n),r.textInput.onContextMenu(e.domEvent);return}this.mousedownEvent.time=Date.now();if(t&&!r.isFocused()){r.focus();if(this.$focusTimout&&!this.$clickSelection&&!r.inMultiSelectMode){this.setState(\"focusWait\"),this.captureMouse(e);return}}return this.captureMouse(e),this.startSelect(n,e.domEvent._clicks>1),e.preventDefault()},this.startSelect=function(e,t){e=e||this.editor.renderer.screenToTextCoordinates(this.x,this.y);var n=this.editor;this.mousedownEvent.getShiftKey()?n.selection.selectToPosition(e):t||n.selection.moveToPosition(e),t||this.select(),n.renderer.scroller.setCapture&&n.renderer.scroller.setCapture(),n.setStyle(\"ace_selecting\"),this.setState(\"select\")},this.select=function(){var e,t=this.editor,n=t.renderer.screenToTextCoordinates(this.x,this.y);if(this.$clickSelection){var r=this.$clickSelection.comparePoint(n);if(r==-1)e=this.$clickSelection.end;else if(r==1)e=this.$clickSelection.start;else{var i=f(this.$clickSelection,n);n=i.cursor,e=i.anchor}t.selection.setSelectionAnchor(e.row,e.column)}t.selection.selectToPosition(n),t.renderer.scrollCursorIntoView()},this.extendSelectionBy=function(e){var t,n=this.editor,r=n.renderer.screenToTextCoordinates(this.x,this.y),i=n.selection[e](r.row,r.column);if(this.$clickSelection){var s=this.$clickSelection.comparePoint(i.start),o=this.$clickSelection.comparePoint(i.end);if(s==-1&&o<=0){t=this.$clickSelection.end;if(i.end.row!=r.row||i.end.column!=r.column)r=i.start}else if(o==1&&s>=0){t=this.$clickSelection.start;if(i.start.row!=r.row||i.start.column!=r.column)r=i.end}else if(s==-1&&o==1)r=i.end,t=i.start;else{var u=f(this.$clickSelection,r);r=u.cursor,t=u.anchor}n.selection.setSelectionAnchor(t.row,t.column)}n.selection.selectToPosition(r),n.renderer.scrollCursorIntoView()},this.selectEnd=this.selectAllEnd=this.selectByWordsEnd=this.selectByLinesEnd=function(){this.$clickSelection=null,this.editor.unsetStyle(\"ace_selecting\"),this.editor.renderer.scroller.releaseCapture&&this.editor.renderer.scroller.releaseCapture()},this.focusWait=function(){var e=a(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y),t=Date.now();(e>o||t-this.mousedownEvent.time>this.$focusTimout)&&this.startSelect(this.mousedownEvent.getDocumentPosition())},this.onDoubleClick=function(e){var t=e.getDocumentPosition(),n=this.editor,r=n.session,i=r.getBracketRange(t);i?(i.isEmpty()&&(i.start.column--,i.end.column++),this.setState(\"select\")):(i=n.selection.getWordRange(t.row,t.column),this.setState(\"selectByWords\")),this.$clickSelection=i,this.select()},this.onTripleClick=function(e){var t=e.getDocumentPosition(),n=this.editor;this.setState(\"selectByLines\");var r=n.getSelectionRange();r.isMultiLine()&&r.contains(t.row,t.column)?(this.$clickSelection=n.selection.getLineRange(r.start.row),this.$clickSelection.end=n.selection.getLineRange(r.end.row).end):this.$clickSelection=n.selection.getLineRange(t.row),this.select()},this.onQuadClick=function(e){var t=this.editor;t.selectAll(),this.$clickSelection=t.getSelectionRange(),this.setState(\"selectAll\")},this.onMouseWheel=function(e){if(e.getAccelKey())return;e.getShiftKey()&&e.wheelY&&!e.wheelX&&(e.wheelX=e.wheelY,e.wheelY=0);var t=e.domEvent.timeStamp,n=t-(this.$lastScrollTime||0),r=this.editor,i=r.renderer.isScrollableBy(e.wheelX*e.speed,e.wheelY*e.speed);if(i||n<200)return this.$lastScrollTime=t,r.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()}}).call(u.prototype),t.DefaultHandlers=u}),ace.define(\"ace/tooltip\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";function s(e){this.isOpen=!1,this.$element=null,this.$parentNode=e}var r=e(\"./lib/oop\"),i=e(\"./lib/dom\");(function(){this.$init=function(){return this.$element=i.createElement(\"div\"),this.$element.className=\"ace_tooltip\",this.$element.style.display=\"none\",this.$parentNode.appendChild(this.$element),this.$element},this.getElement=function(){return this.$element||this.$init()},this.setText=function(e){i.setInnerText(this.getElement(),e)},this.setHtml=function(e){this.getElement().innerHTML=e},this.setPosition=function(e,t){this.getElement().style.left=e+\"px\",this.getElement().style.top=t+\"px\"},this.setClassName=function(e){i.addCssClass(this.getElement(),e)},this.show=function(e,t,n){e!=null&&this.setText(e),t!=null&&n!=null&&this.setPosition(t,n),this.isOpen||(this.getElement().style.display=\"block\",this.isOpen=!0)},this.hide=function(){this.isOpen&&(this.getElement().style.display=\"none\",this.isOpen=!1)},this.getHeight=function(){return this.getElement().offsetHeight},this.getWidth=function(){return this.getElement().offsetWidth}}).call(s.prototype),t.Tooltip=s}),ace.define(\"ace/mouse/default_gutter_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/oop\",\"ace/lib/event\",\"ace/tooltip\"],function(e,t,n){\"use strict\";function u(e){function l(){var r=u.getDocumentPosition().row,s=n.$annotations[r];if(!s)return c();var o=t.session.getLength();if(r==o){var a=t.renderer.pixelToScreenCoordinates(0,u.y).row,l=u.$pos;if(a>t.session.documentToScreenRow(l.row,l.column))return c()}if(f==s)return;f=s.text.join(\"<br/>\"),i.setHtml(f),i.show(),t.on(\"mousewheel\",c);if(e.$tooltipFollowsMouse)h(u);else{var p=n.$cells[t.session.documentToScreenRow(r,0)].element,d=p.getBoundingClientRect(),v=i.getElement().style;v.left=d.right+\"px\",v.top=d.bottom+\"px\"}}function c(){o&&(o=clearTimeout(o)),f&&(i.hide(),f=null,t.removeEventListener(\"mousewheel\",c))}function h(e){i.setPosition(e.x,e.y)}var t=e.editor,n=t.renderer.$gutterLayer,i=new a(t.container);e.editor.setDefaultHandler(\"guttermousedown\",function(r){if(!t.isFocused()||r.getButton()!=0)return;var i=n.getRegion(r);if(i==\"foldWidgets\")return;var s=r.getDocumentPosition().row,o=t.session.selection;if(r.getShiftKey())o.selectTo(s,0);else{if(r.domEvent.detail==2)return t.selectAll(),r.preventDefault();e.$clickSelection=t.selection.getLineRange(s)}return e.setState(\"selectByLines\"),e.captureMouse(r),r.preventDefault()});var o,u,f;e.editor.setDefaultHandler(\"guttermousemove\",function(t){var n=t.domEvent.target||t.domEvent.srcElement;if(r.hasCssClass(n,\"ace_fold-widget\"))return c();f&&e.$tooltipFollowsMouse&&h(t),u=t;if(o)return;o=setTimeout(function(){o=null,u&&!e.isMousePressed?l():c()},50)}),s.addListener(t.renderer.$gutter,\"mouseout\",function(e){u=null;if(!f||o)return;o=setTimeout(function(){o=null,c()},50)}),t.on(\"changeSession\",c)}function a(e){o.call(this,e)}var r=e(\"../lib/dom\"),i=e(\"../lib/oop\"),s=e(\"../lib/event\"),o=e(\"../tooltip\").Tooltip;i.inherits(a,o),function(){this.setPosition=function(e,t){var n=window.innerWidth||document.documentElement.clientWidth,r=window.innerHeight||document.documentElement.clientHeight,i=this.getWidth(),s=this.getHeight();e+=15,t+=15,e+i>n&&(e-=e+i-n),t+s>r&&(t-=20+s),o.prototype.setPosition.call(this,e,t)}}.call(a.prototype),t.GutterHandler=u}),ace.define(\"ace/mouse/mouse_event\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";var r=e(\"../lib/event\"),i=e(\"../lib/useragent\"),s=t.MouseEvent=function(e,t){this.domEvent=e,this.editor=t,this.x=this.clientX=e.clientX,this.y=this.clientY=e.clientY,this.$pos=null,this.$inSelection=null,this.propagationStopped=!1,this.defaultPrevented=!1};(function(){this.stopPropagation=function(){r.stopPropagation(this.domEvent),this.propagationStopped=!0},this.preventDefault=function(){r.preventDefault(this.domEvent),this.defaultPrevented=!0},this.stop=function(){this.stopPropagation(),this.preventDefault()},this.getDocumentPosition=function(){return this.$pos?this.$pos:(this.$pos=this.editor.renderer.screenToTextCoordinates(this.clientX,this.clientY),this.$pos)},this.inSelection=function(){if(this.$inSelection!==null)return this.$inSelection;var e=this.editor,t=e.getSelectionRange();if(t.isEmpty())this.$inSelection=!1;else{var n=this.getDocumentPosition();this.$inSelection=t.contains(n.row,n.column)}return this.$inSelection},this.getButton=function(){return r.getButton(this.domEvent)},this.getShiftKey=function(){return this.domEvent.shiftKey},this.getAccelKey=i.isMac?function(){return this.domEvent.metaKey}:function(){return this.domEvent.ctrlKey}}).call(s.prototype)}),ace.define(\"ace/mouse/dragdrop_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";function f(e){function T(e,n){var r=Date.now(),i=!n||e.row!=n.row,s=!n||e.column!=n.column;if(!S||i||s)t.$blockScrolling+=1,t.moveCursorToPosition(e),t.$blockScrolling-=1,S=r,x={x:p,y:d};else{var o=l(x.x,x.y,p,d);o>a?S=null:r-S>=u&&(t.renderer.scrollCursorIntoView(),S=null)}}function N(e,n){var r=Date.now(),i=t.renderer.layerConfig.lineHeight,s=t.renderer.layerConfig.characterWidth,u=t.renderer.scroller.getBoundingClientRect(),a={x:{left:p-u.left,right:u.right-p},y:{top:d-u.top,bottom:u.bottom-d}},f=Math.min(a.x.left,a.x.right),l=Math.min(a.y.top,a.y.bottom),c={row:e.row,column:e.column};f/s<=2&&(c.column+=a.x.left<a.x.right?-3:2),l/i<=1&&(c.row+=a.y.top<a.y.bottom?-1:1);var h=e.row!=c.row,v=e.column!=c.column,m=!n||e.row!=n.row;h||v&&!m?E?r-E>=o&&t.renderer.scrollCursorIntoView(c):E=r:E=null}function C(){var e=g;g=t.renderer.screenToTextCoordinates(p,d),T(g,e),N(g,e)}function k(){m=t.selection.toOrientedRange(),h=t.session.addMarker(m,\"ace_selection\",t.getSelectionStyle()),t.clearSelection(),t.isFocused()&&t.renderer.$cursorLayer.setBlinking(!1),clearInterval(v),C(),v=setInterval(C,20),y=0,i.addListener(document,\"mousemove\",O)}function L(){clearInterval(v),t.session.removeMarker(h),h=null,t.$blockScrolling+=1,t.selection.fromOrientedRange(m),t.$blockScrolling-=1,t.isFocused()&&!w&&t.renderer.$cursorLayer.setBlinking(!t.getReadOnly()),m=null,g=null,y=0,E=null,S=null,i.removeListener(document,\"mousemove\",O)}function O(){A==null&&(A=setTimeout(function(){A!=null&&h&&L()},20))}function M(e){var t=e.types;return!t||Array.prototype.some.call(t,function(e){return e==\"text/plain\"||e==\"Text\"})}function _(e){var t=[\"copy\",\"copymove\",\"all\",\"uninitialized\"],n=[\"move\",\"copymove\",\"linkmove\",\"all\",\"uninitialized\"],r=s.isMac?e.altKey:e.ctrlKey,i=\"uninitialized\";try{i=e.dataTransfer.effectAllowed.toLowerCase()}catch(e){}var o=\"none\";return r&&t.indexOf(i)>=0?o=\"copy\":n.indexOf(i)>=0?o=\"move\":t.indexOf(i)>=0&&(o=\"copy\"),o}var t=e.editor,n=r.createElement(\"img\");n.src=\"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\",s.isOpera&&(n.style.cssText=\"width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;\");var f=[\"dragWait\",\"dragWaitEnd\",\"startDrag\",\"dragReadyEnd\",\"onMouseDrag\"];f.forEach(function(t){e[t]=this[t]},this),t.addEventListener(\"mousedown\",this.onMouseDown.bind(e));var c=t.container,h,p,d,v,m,g,y=0,b,w,E,S,x;this.onDragStart=function(e){if(this.cancelDrag||!c.draggable){var r=this;return setTimeout(function(){r.startSelect(),r.captureMouse(e)},0),e.preventDefault()}m=t.getSelectionRange();var i=e.dataTransfer;i.effectAllowed=t.getReadOnly()?\"copy\":\"copyMove\",s.isOpera&&(t.container.appendChild(n),n.scrollTop=0),i.setDragImage&&i.setDragImage(n,0,0),s.isOpera&&t.container.removeChild(n),i.clearData(),i.setData(\"Text\",t.session.getTextRange()),w=!0,this.setState(\"drag\")},this.onDragEnd=function(e){c.draggable=!1,w=!1,this.setState(null);if(!t.getReadOnly()){var n=e.dataTransfer.dropEffect;!b&&n==\"move\"&&t.session.remove(t.getSelectionRange()),t.renderer.$cursorLayer.setBlinking(!0)}this.editor.unsetStyle(\"ace_dragging\"),this.editor.renderer.setCursorStyle(\"\")},this.onDragEnter=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||k(),y++,e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragOver=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||(k(),y++),A!==null&&(A=null),e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragLeave=function(e){y--;if(y<=0&&h)return L(),b=null,i.preventDefault(e)},this.onDrop=function(e){if(!g)return;var n=e.dataTransfer;if(w)switch(b){case\"move\":m.contains(g.row,g.column)?m={start:g,end:g}:m=t.moveText(m,g);break;case\"copy\":m=t.moveText(m,g,!0)}else{var r=n.getData(\"Text\");m={start:g,end:t.session.insert(g,r)},t.focus(),b=null}return L(),i.preventDefault(e)},i.addListener(c,\"dragstart\",this.onDragStart.bind(e)),i.addListener(c,\"dragend\",this.onDragEnd.bind(e)),i.addListener(c,\"dragenter\",this.onDragEnter.bind(e)),i.addListener(c,\"dragover\",this.onDragOver.bind(e)),i.addListener(c,\"dragleave\",this.onDragLeave.bind(e)),i.addListener(c,\"drop\",this.onDrop.bind(e));var A=null}function l(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}var r=e(\"../lib/dom\"),i=e(\"../lib/event\"),s=e(\"../lib/useragent\"),o=200,u=200,a=5;(function(){this.dragWait=function(){var e=Date.now()-this.mousedownEvent.time;e>this.editor.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(){var e=this.editor.container;e.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()),this.selectEnd()},this.dragReadyEnd=function(e){this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly()),this.editor.unsetStyle(\"ace_dragging\"),this.editor.renderer.setCursorStyle(\"\"),this.dragWaitEnd()},this.startDrag=function(){this.cancelDrag=!1;var e=this.editor,t=e.container;t.draggable=!0,e.renderer.$cursorLayer.setBlinking(!1),e.setStyle(\"ace_dragging\");var n=s.isWin?\"default\":\"move\";e.renderer.setCursorStyle(n),this.setState(\"dragReady\")},this.onMouseDrag=function(e){var t=this.editor.container;if(s.isIE&&this.state==\"dragReady\"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>3&&t.dragDrop()}if(this.state===\"dragWait\"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>0&&(t.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()))}},this.onMouseDown=function(e){if(!this.$dragEnabled)return;this.mousedownEvent=e;var t=this.editor,n=e.inSelection(),r=e.getButton(),i=e.domEvent.detail||1;if(i===1&&r===0&&n){if(e.editor.inMultiSelectMode&&(e.getAccelKey()||e.getShiftKey()))return;this.mousedownEvent.time=Date.now();var o=e.domEvent.target||e.domEvent.srcElement;\"unselectable\"in o&&(o.unselectable=\"on\");if(t.getDragDelay()){if(s.isWebKit){this.cancelDrag=!0;var u=t.container;u.draggable=!0}this.setState(\"dragWait\")}else this.startDrag();this.captureMouse(e,this.onMouseDrag.bind(this)),e.defaultPrevented=!0}}}).call(f.prototype),t.DragdropHandler=f}),ace.define(\"ace/lib/net\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";var r=e(\"./dom\");t.get=function(e,t){var n=new XMLHttpRequest;n.open(\"GET\",e,!0),n.onreadystatechange=function(){n.readyState===4&&t(n.responseText)},n.send(null)},t.loadScript=function(e,t){var n=r.getDocumentHead(),i=document.createElement(\"script\");i.src=e,n.appendChild(i),i.onload=i.onreadystatechange=function(e,n){if(n||!i.readyState||i.readyState==\"loaded\"||i.readyState==\"complete\")i=i.onload=i.onreadystatechange=null,n||t()}},t.qualifyURL=function(e){var t=document.createElement(\"a\");return t.href=e,t.href}}),ace.define(\"ace/lib/event_emitter\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!=\"object\"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;t&&this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t){var i=n[e];r&&this.setDefaultHandler(e,r.pop())}else if(r){var s=r.indexOf(t);s!=-1&&r.splice(s,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?\"unshift\":\"push\"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define(\"ace/config\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/lib/oop\",\"ace/lib/net\",\"ace/lib/event_emitter\"],function(e,t,n){\"no use strict\";function f(r){a.packaged=r||e.packaged||n.packaged||u.define&&define.packaged;if(!u.document)return\"\";var i={},s=\"\",o=document.currentScript||document._currentScript,f=o&&o.ownerDocument||document,c=f.getElementsByTagName(\"script\");for(var h=0;h<c.length;h++){var p=c[h],d=p.src||p.getAttribute(\"src\");if(!d)continue;var v=p.attributes;for(var m=0,g=v.length;m<g;m++){var y=v[m];y.name.indexOf(\"data-ace-\")===0&&(i[l(y.name.replace(/^data-ace-/,\"\"))]=y.value)}var b=d.match(/^(.*)\\/ace(\\-\\w+)?\\.js(\\?|$)/);b&&(s=b[1])}s&&(i.base=i.base||s,i.packaged=!0),i.basePath=i.base,i.workerPath=i.workerPath||i.base,i.modePath=i.modePath||i.base,i.themePath=i.themePath||i.base,delete i.base;for(var w in i)typeof i[w]!=\"undefined\"&&t.set(w,i[w])}function l(e){return e.replace(/-(.)/g,function(e,t){return t.toUpperCase()})}var r=e(\"./lib/lang\"),i=e(\"./lib/oop\"),s=e(\"./lib/net\"),o=e(\"./lib/event_emitter\").EventEmitter,u=function(){return this}(),a={packaged:!1,workerPath:null,modePath:null,themePath:null,basePath:\"\",suffix:\".js\",$moduleUrls:{}};t.get=function(e){if(!a.hasOwnProperty(e))throw new Error(\"Unknown config key: \"+e);return a[e]},t.set=function(e,t){if(!a.hasOwnProperty(e))throw new Error(\"Unknown config key: \"+e);a[e]=t},t.all=function(){return r.copyObject(a)},i.implement(t,o),t.moduleUrl=function(e,t){if(a.$moduleUrls[e])return a.$moduleUrls[e];var n=e.split(\"/\");t=t||n[n.length-2]||\"\";var r=t==\"snippets\"?\"/\":\"-\",i=n[n.length-1];if(t==\"worker\"&&r==\"-\"){var s=new RegExp(\"^\"+t+\"[\\\\-_]|[\\\\-_]\"+t+\"$\",\"g\");i=i.replace(s,\"\")}(!i||i==t)&&n.length>1&&(i=n[n.length-2]);var o=a[t+\"Path\"];return o==null?o=a.basePath:r==\"/\"&&(t=r=\"\"),o&&o.slice(-1)!=\"/\"&&(o+=\"/\"),o+t+r+i+this.get(\"suffix\")},t.setModuleUrl=function(e,t){return a.$moduleUrls[e]=t},t.$loading={},t.loadModule=function(n,r){var i,o;Array.isArray(n)&&(o=n[0],n=n[1]);try{i=e(n)}catch(u){}if(i&&!t.$loading[n])return r&&r(i);t.$loading[n]||(t.$loading[n]=[]),t.$loading[n].push(r);if(t.$loading[n].length>1)return;var a=function(){e([n],function(e){t._emit(\"load.module\",{name:n,module:e});var r=t.$loading[n];t.$loading[n]=null,r.forEach(function(t){t&&t(e)})})};if(!t.get(\"packaged\"))return a();s.loadScript(t.moduleUrl(n,o),a)},t.init=f;var c={setOptions:function(e){Object.keys(e).forEach(function(t){this.setOption(t,e[t])},this)},getOptions:function(e){var t={};return e?Array.isArray(e)||(t=e,e=Object.keys(t)):e=Object.keys(this.$options),e.forEach(function(e){t[e]=this.getOption(e)},this),t},setOption:function(e,t){if(this[\"$\"+e]===t)return;var n=this.$options[e];if(!n)return typeof console!=\"undefined\"&&console.warn&&console.warn('misspelled option \"'+e+'\"'),undefined;if(n.forwardTo)return this[n.forwardTo]&&this[n.forwardTo].setOption(e,t);n.handlesSet||(this[\"$\"+e]=t),n&&n.set&&n.set.call(this,t)},getOption:function(e){var t=this.$options[e];return t?t.forwardTo?this[t.forwardTo]&&this[t.forwardTo].getOption(e):t&&t.get?t.get.call(this):this[\"$\"+e]:(typeof console!=\"undefined\"&&console.warn&&console.warn('misspelled option \"'+e+'\"'),undefined)}},h={};t.defineOptions=function(e,t,n){return e.$options||(h[t]=e.$options={}),Object.keys(n).forEach(function(t){var r=n[t];typeof r==\"string\"&&(r={forwardTo:r}),r.name||(r.name=t),e.$options[r.name]=r,\"initialValue\"in r&&(e[\"$\"+r.name]=r.initialValue)}),i.implement(e,c),this},t.resetOptions=function(e){Object.keys(e.$options).forEach(function(t){var n=e.$options[t];\"value\"in n&&e.setOption(t,n.value)})},t.setDefaultValue=function(e,n,r){var i=h[e]||(h[e]={});i[n]&&(i.forwardTo?t.setDefaultValue(i.forwardTo,n,r):i[n].value=r)},t.setDefaultValues=function(e,n){Object.keys(n).forEach(function(r){t.setDefaultValue(e,r,n[r])})}}),ace.define(\"ace/mouse/mouse_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\",\"ace/mouse/default_handlers\",\"ace/mouse/default_gutter_handler\",\"ace/mouse/mouse_event\",\"ace/mouse/dragdrop_handler\",\"ace/config\"],function(e,t,n){\"use strict\";var r=e(\"../lib/event\"),i=e(\"../lib/useragent\"),s=e(\"./default_handlers\").DefaultHandlers,o=e(\"./default_gutter_handler\").GutterHandler,u=e(\"./mouse_event\").MouseEvent,a=e(\"./dragdrop_handler\").DragdropHandler,f=e(\"../config\"),l=function(e){var t=this;this.editor=e,new s(this),new o(this),new a(this);var n=function(t){!e.isFocused()&&e.textInput&&e.textInput.moveToMouse(t),e.focus()},u=e.renderer.getMouseEventTarget();r.addListener(u,\"click\",this.onMouseEvent.bind(this,\"click\")),r.addListener(u,\"mousemove\",this.onMouseMove.bind(this,\"mousemove\")),r.addMultiMouseDownListener(u,[400,300,250],this,\"onMouseEvent\"),e.renderer.scrollBarV&&(r.addMultiMouseDownListener(e.renderer.scrollBarV.inner,[400,300,250],this,\"onMouseEvent\"),r.addMultiMouseDownListener(e.renderer.scrollBarH.inner,[400,300,250],this,\"onMouseEvent\"),i.isIE&&(r.addListener(e.renderer.scrollBarV.element,\"mousedown\",n),r.addListener(e.renderer.scrollBarH.element,\"mousemove\",n))),r.addMouseWheelListener(e.container,this.onMouseWheel.bind(this,\"mousewheel\"));var f=e.renderer.$gutter;r.addListener(f,\"mousedown\",this.onMouseEvent.bind(this,\"guttermousedown\")),r.addListener(f,\"click\",this.onMouseEvent.bind(this,\"gutterclick\")),r.addListener(f,\"dblclick\",this.onMouseEvent.bind(this,\"gutterdblclick\")),r.addListener(f,\"mousemove\",this.onMouseEvent.bind(this,\"guttermousemove\")),r.addListener(u,\"mousedown\",n),r.addListener(f,\"mousedown\",function(t){return e.focus(),r.preventDefault(t)}),e.on(\"mousemove\",function(n){if(t.state||t.$dragDelay||!t.$dragEnabled)return;var r=e.renderer.screenToTextCoordinates(n.x,n.y),i=e.session.selection.getRange(),s=e.renderer;!i.isEmpty()&&i.insideStart(r.row,r.column)?s.setCursorStyle(\"default\"):s.setCursorStyle(\"\")})};(function(){this.onMouseEvent=function(e,t){this.editor._emit(e,new u(t,this.editor))},this.onMouseMove=function(e,t){var n=this.editor._eventRegistry&&this.editor._eventRegistry.mousemove;if(!n||!n.length)return;this.editor._emit(e,new u(t,this.editor))},this.onMouseWheel=function(e,t){var n=new u(t,this.editor);n.speed=this.$scrollSpeed*2,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.setState=function(e){this.state=e},this.captureMouse=function(e,t){this.x=e.x,this.y=e.y,this.isMousePressed=!0;var n=this.editor.renderer;n.$keepTextAreaAtCursor&&(n.$keepTextAreaAtCursor=null);var s=this,o=function(e){if(!e)return;if(i.isWebKit&&!e.which&&s.releaseMouse)return s.releaseMouse();s.x=e.clientX,s.y=e.clientY,t&&t(e),s.mouseEvent=new u(e,s.editor),s.$mouseMoved=!0},a=function(e){clearInterval(l),f(),s[s.state+\"End\"]&&s[s.state+\"End\"](e),s.state=\"\",n.$keepTextAreaAtCursor==null&&(n.$keepTextAreaAtCursor=!0,n.$moveTextAreaToCursor()),s.isMousePressed=!1,s.$onCaptureMouseMove=s.releaseMouse=null,e&&s.onMouseEvent(\"mouseup\",e)},f=function(){s[s.state]&&s[s.state](),s.$mouseMoved=!1};if(i.isOldIE&&e.domEvent.type==\"dblclick\")return setTimeout(function(){a(e)});s.$onCaptureMouseMove=o,s.releaseMouse=r.capture(this.editor.container,o,a);var l=setInterval(f,20)},this.releaseMouse=null,this.cancelContextMenu=function(){var e=function(t){if(t&&t.domEvent&&t.domEvent.type!=\"contextmenu\")return;this.editor.off(\"nativecontextmenu\",e),t&&t.domEvent&&r.stopEvent(t.domEvent)}.bind(this);setTimeout(e,10),this.editor.on(\"nativecontextmenu\",e)}}).call(l.prototype),f.defineOptions(l.prototype,\"mouseHandler\",{scrollSpeed:{initialValue:2},dragDelay:{initialValue:i.isMac?150:0},dragEnabled:{initialValue:!0},focusTimout:{initialValue:0},tooltipFollowsMouse:{initialValue:!0}}),t.MouseHandler=l}),ace.define(\"ace/mouse/fold_handler\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";function r(e){e.on(\"click\",function(t){var n=t.getDocumentPosition(),r=e.session,i=r.getFoldAt(n.row,n.column,1);i&&(t.getAccelKey()?r.removeFold(i):r.expandFold(i),t.stop())}),e.on(\"gutterclick\",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n==\"foldWidgets\"){var r=t.getDocumentPosition().row,i=e.session;i.foldWidgets&&i.foldWidgets[r]&&e.session.onFoldWidgetClick(r,t),e.isFocused()||e.focus(),t.stop()}}),e.on(\"gutterdblclick\",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n==\"foldWidgets\"){var r=t.getDocumentPosition().row,i=e.session,s=i.getParentFoldRangeData(r,!0),o=s.range||s.firstRange;if(o){r=o.start.row;var u=i.getFoldAt(r,i.getLine(r).length,1);u?i.removeFold(u):(i.addFold(\"...\",o),e.renderer.scrollCursorIntoView({row:o.start.row,column:0}))}t.stop()}})}t.FoldHandler=r}),ace.define(\"ace/keyboard/keybinding\",[\"require\",\"exports\",\"module\",\"ace/lib/keys\",\"ace/lib/event\"],function(e,t,n){\"use strict\";var r=e(\"../lib/keys\"),i=e(\"../lib/event\"),s=function(e){this.$editor=e,this.$data={editor:e},this.$handlers=[],this.setDefaultHandler(e.commands)};(function(){this.setDefaultHandler=function(e){this.removeKeyboardHandler(this.$defaultHandler),this.$defaultHandler=e,this.addKeyboardHandler(e,0)},this.setKeyboardHandler=function(e){var t=this.$handlers;if(t[t.length-1]==e)return;while(t[t.length-1]&&t[t.length-1]!=this.$defaultHandler)this.removeKeyboardHandler(t[t.length-1]);this.addKeyboardHandler(e,1)},this.addKeyboardHandler=function(e,t){if(!e)return;typeof e==\"function\"&&!e.handleKeyboard&&(e.handleKeyboard=e);var n=this.$handlers.indexOf(e);n!=-1&&this.$handlers.splice(n,1),t==undefined?this.$handlers.push(e):this.$handlers.splice(t,0,e),n==-1&&e.attach&&e.attach(this.$editor)},this.removeKeyboardHandler=function(e){var t=this.$handlers.indexOf(e);return t==-1?!1:(this.$handlers.splice(t,1),e.detach&&e.detach(this.$editor),!0)},this.getKeyboardHandler=function(){return this.$handlers[this.$handlers.length-1]},this.getStatusText=function(){var e=this.$data,t=e.editor;return this.$handlers.map(function(n){return n.getStatusText&&n.getStatusText(t,e)||\"\"}).filter(Boolean).join(\" \")},this.$callKeyboardHandlers=function(e,t,n,r){var s,o=!1,u=this.$editor.commands;for(var a=this.$handlers.length;a--;){s=this.$handlers[a].handleKeyboard(this.$data,e,t,n,r);if(!s||!s.command)continue;s.command==\"null\"?o=!0:o=u.exec(s.command,this.$editor,s.args,r),o&&r&&e!=-1&&s.passEvent!=1&&s.command.passEvent!=1&&i.stopEvent(r);if(o)break}return o},this.onCommandKey=function(e,t,n){var i=r.keyCodeToString(n);this.$callKeyboardHandlers(t,i,n,e)},this.onTextInput=function(e){var t=this.$callKeyboardHandlers(-1,e);t||this.$editor.commands.exec(\"insertstring\",this.$editor,e)}}).call(s.prototype),t.KeyBinding=s}),ace.define(\"ace/range\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return\"Range: [\"+this.start.row+\"/\"+this.start.column+\"] -> [\"+this.end.row+\"/\"+this.end.column+\"]\"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e==\"object\"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e==\"object\"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define(\"ace/selection\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/lib/event_emitter\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/lang\"),s=e(\"./lib/event_emitter\").EventEmitter,o=e(\"./range\").Range,u=function(e){this.session=e,this.doc=e.getDocument(),this.clearSelection(),this.lead=this.selectionLead=this.doc.createAnchor(0,0),this.anchor=this.selectionAnchor=this.doc.createAnchor(0,0);var t=this;this.lead.on(\"change\",function(e){t._emit(\"changeCursor\"),t.$isEmpty||t._emit(\"changeSelection\"),!t.$keepDesiredColumnOnChange&&e.old.column!=e.value.column&&(t.$desiredColumn=null)}),this.selectionAnchor.on(\"change\",function(){t.$isEmpty||t._emit(\"changeSelection\")})};(function(){r.implement(this,s),this.isEmpty=function(){return this.$isEmpty||this.anchor.row==this.lead.row&&this.anchor.column==this.lead.column},this.isMultiLine=function(){return this.isEmpty()?!1:this.getRange().isMultiLine()},this.getCursor=function(){return this.lead.getPosition()},this.setSelectionAnchor=function(e,t){this.anchor.setPosition(e,t),this.$isEmpty&&(this.$isEmpty=!1,this._emit(\"changeSelection\"))},this.getSelectionAnchor=function(){return this.$isEmpty?this.getSelectionLead():this.anchor.getPosition()},this.getSelectionLead=function(){return this.lead.getPosition()},this.shiftSelection=function(e){if(this.$isEmpty){this.moveCursorTo(this.lead.row,this.lead.column+e);return}var t=this.getSelectionAnchor(),n=this.getSelectionLead(),r=this.isBackwards();(!r||t.column!==0)&&this.setSelectionAnchor(t.row,t.column+e),(r||n.column!==0)&&this.$moveSelection(function(){this.moveCursorTo(n.row,n.column+e)})},this.isBackwards=function(){var e=this.anchor,t=this.lead;return e.row>t.row||e.row==t.row&&e.column>t.column},this.getRange=function(){var e=this.anchor,t=this.lead;return this.isEmpty()?o.fromPoints(t,t):this.isBackwards()?o.fromPoints(t,e):o.fromPoints(e,t)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._emit(\"changeSelection\"))},this.selectAll=function(){var e=this.doc.getLength()-1;this.setSelectionAnchor(0,0),this.moveCursorTo(e,this.doc.getLine(e).length)},this.setRange=this.setSelectionRange=function(e,t){t?(this.setSelectionAnchor(e.end.row,e.end.column),this.selectTo(e.start.row,e.start.column)):(this.setSelectionAnchor(e.start.row,e.start.column),this.selectTo(e.end.row,e.end.column)),this.getRange().isEmpty()&&(this.$isEmpty=!0),this.$desiredColumn=null},this.$moveSelection=function(e){var t=this.lead;this.$isEmpty&&this.setSelectionAnchor(t.row,t.column),e.call(this)},this.selectTo=function(e,t){this.$moveSelection(function(){this.moveCursorTo(e,t)})},this.selectToPosition=function(e){this.$moveSelection(function(){this.moveCursorToPosition(e)})},this.moveTo=function(e,t){this.clearSelection(),this.moveCursorTo(e,t)},this.moveToPosition=function(e){this.clearSelection(),this.moveCursorToPosition(e)},this.selectUp=function(){this.$moveSelection(this.moveCursorUp)},this.selectDown=function(){this.$moveSelection(this.moveCursorDown)},this.selectRight=function(){this.$moveSelection(this.moveCursorRight)},this.selectLeft=function(){this.$moveSelection(this.moveCursorLeft)},this.selectLineStart=function(){this.$moveSelection(this.moveCursorLineStart)},this.selectLineEnd=function(){this.$moveSelection(this.moveCursorLineEnd)},this.selectFileEnd=function(){this.$moveSelection(this.moveCursorFileEnd)},this.selectFileStart=function(){this.$moveSelection(this.moveCursorFileStart)},this.selectWordRight=function(){this.$moveSelection(this.moveCursorWordRight)},this.selectWordLeft=function(){this.$moveSelection(this.moveCursorWordLeft)},this.getWordRange=function(e,t){if(typeof t==\"undefined\"){var n=e||this.lead;e=n.row,t=n.column}return this.session.getWordRange(e,t)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var e=this.getCursor(),t=this.session.getAWordRange(e.row,e.column);this.setSelectionRange(t)},this.getLineRange=function(e,t){var n=typeof e==\"number\"?e:this.lead.row,r,i=this.session.getFoldLine(n);return i?(n=i.start.row,r=i.end.row):r=n,t===!0?new o(n,0,r,this.session.getLine(r).length):new o(n,0,r+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.moveCursorLeft=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,-1))this.moveCursorTo(t.start.row,t.start.column);else if(e.column===0)e.row>0&&this.moveCursorTo(e.row-1,this.doc.getLine(e.row-1).length);else{var n=this.session.getTabSize();this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(e.column-n,e.column).split(\" \").length-1==n?this.moveCursorBy(0,-n):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,1))this.moveCursorTo(t.end.row,t.end.column);else if(this.lead.column==this.doc.getLine(this.lead.row).length)this.lead.row<this.doc.getLength()-1&&this.moveCursorTo(this.lead.row+1,0);else{var n=this.session.getTabSize(),e=this.lead;this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(e.column,e.column+n).split(\" \").length-1==n?this.moveCursorBy(0,n):this.moveCursorBy(0,1)}},this.moveCursorLineStart=function(){var e=this.lead.row,t=this.lead.column,n=this.session.documentToScreenRow(e,t),r=this.session.screenToDocumentPosition(n,0),i=this.session.getDisplayLine(e,null,r.row,r.column),s=i.match(/^\\s*/);s[0].length!=t&&!this.session.$useEmacsStyleLineStart&&(r.column+=s[0].length),this.moveCursorToPosition(r)},this.moveCursorLineEnd=function(){var e=this.lead,t=this.session.getDocumentLastRowColumnPosition(e.row,e.column);if(this.lead.column==t.column){var n=this.session.getLine(t.row);if(t.column==n.length){var r=n.search(/\\s+$/);r>0&&(t.column=r)}}this.moveCursorTo(t.row,t.column)},this.moveCursorFileEnd=function(){var e=this.doc.getLength()-1,t=this.doc.getLine(e).length;this.moveCursorTo(e,t)},this.moveCursorFileStart=function(){this.moveCursorTo(0,0)},this.moveCursorLongWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i;this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;var s=this.session.getFoldAt(e,t,1);if(s){this.moveCursorTo(s.end.row,s.end.column);return}if(i=this.session.nonTokenRe.exec(r))t+=this.session.nonTokenRe.lastIndex,this.session.nonTokenRe.lastIndex=0,r=n.substring(t);if(t>=n.length){this.moveCursorTo(e,n.length),this.moveCursorRight(),e<this.doc.getLength()-1&&this.moveCursorWordRight();return}if(i=this.session.tokenRe.exec(r))t+=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0;this.moveCursorTo(e,t)},this.moveCursorLongWordLeft=function(){var e=this.lead.row,t=this.lead.column,n;if(n=this.session.getFoldAt(e,t,-1)){this.moveCursorTo(n.start.row,n.start.column);return}var r=this.session.getFoldStringAt(e,t,-1);r==null&&(r=this.doc.getLine(e).substring(0,t));var s=i.stringReverse(r),o;this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;if(o=this.session.nonTokenRe.exec(s))t-=this.session.nonTokenRe.lastIndex,s=s.slice(this.session.nonTokenRe.lastIndex),this.session.nonTokenRe.lastIndex=0;if(t<=0){this.moveCursorTo(e,0),this.moveCursorLeft(),e>0&&this.moveCursorWordLeft();return}if(o=this.session.tokenRe.exec(s))t-=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0;this.moveCursorTo(e,t)},this.$shortWordEndIndex=function(e){var t,n=0,r,i=/\\s/,s=this.session.tokenRe;s.lastIndex=0;if(t=this.session.tokenRe.exec(e))n=this.session.tokenRe.lastIndex;else{while((r=e[n])&&i.test(r))n++;if(n<1){s.lastIndex=0;while((r=e[n])&&!s.test(r)){s.lastIndex=0,n++;if(i.test(r)){if(n>2){n--;break}while((r=e[n])&&i.test(r))n++;if(n>2)break}}}}return s.lastIndex=0,n},this.moveCursorShortWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i=this.session.getFoldAt(e,t,1);if(i)return this.moveCursorTo(i.end.row,i.end.column);if(t==n.length){var s=this.doc.getLength();do e++,r=this.doc.getLine(e);while(e<s&&/^\\s*$/.test(r));/^\\s+/.test(r)||(r=\"\"),t=0}var o=this.$shortWordEndIndex(r);this.moveCursorTo(e,t+o)},this.moveCursorShortWordLeft=function(){var e=this.lead.row,t=this.lead.column,n;if(n=this.session.getFoldAt(e,t,-1))return this.moveCursorTo(n.start.row,n.start.column);var r=this.session.getLine(e).substring(0,t);if(t===0){do e--,r=this.doc.getLine(e);while(e>0&&/^\\s*$/.test(r));t=r.length,/\\s+$/.test(r)||(r=\"\")}var s=i.stringReverse(r),o=this.$shortWordEndIndex(s);return this.moveCursorTo(e,t-o)},this.moveCursorWordRight=function(){this.session.$selectLongWords?this.moveCursorLongWordRight():this.moveCursorShortWordRight()},this.moveCursorWordLeft=function(){this.session.$selectLongWords?this.moveCursorLongWordLeft():this.moveCursorShortWordLeft()},this.moveCursorBy=function(e,t){var n=this.session.documentToScreenPosition(this.lead.row,this.lead.column);t===0&&(this.$desiredColumn?n.column=this.$desiredColumn:this.$desiredColumn=n.column);var r=this.session.screenToDocumentPosition(n.row+e,n.column);e!==0&&t===0&&r.row===this.lead.row&&r.column===this.lead.column&&this.session.lineWidgets&&this.session.lineWidgets[r.row]&&r.row++,this.moveCursorTo(r.row,r.column+t,t===0)},this.moveCursorToPosition=function(e){this.moveCursorTo(e.row,e.column)},this.moveCursorTo=function(e,t,n){var r=this.session.getFoldAt(e,t,1);r&&(e=r.start.row,t=r.start.column),this.$keepDesiredColumnOnChange=!0,this.lead.setPosition(e,t),this.$keepDesiredColumnOnChange=!1,n||(this.$desiredColumn=null)},this.moveCursorToScreen=function(e,t,n){var r=this.session.screenToDocumentPosition(e,t);this.moveCursorTo(r.row,r.column,n)},this.detach=function(){this.lead.detach(),this.anchor.detach(),this.session=this.doc=null},this.fromOrientedRange=function(e){this.setSelectionRange(e,e.cursor==e.start),this.$desiredColumn=e.desiredColumn||this.$desiredColumn},this.toOrientedRange=function(e){var t=this.getRange();return e?(e.start.column=t.start.column,e.start.row=t.start.row,e.end.column=t.end.column,e.end.row=t.end.row):e=t,e.cursor=this.isBackwards()?e.start:e.end,e.desiredColumn=this.$desiredColumn,e},this.getRangeOfMovements=function(e){var t=this.getCursor();try{e.call(null,this);var n=this.getCursor();return o.fromPoints(t,n)}catch(r){return o.fromPoints(t,t)}finally{this.moveCursorToPosition(t)}},this.toJSON=function(){if(this.rangeCount)var e=this.ranges.map(function(e){var t=e.clone();return t.isBackwards=e.cursor==e.start,t});else{var e=this.getRange();e.isBackwards=this.isBackwards()}return e},this.fromJSON=function(e){if(e.start==undefined){if(this.rangeList){this.toSingleRange(e[0]);for(var t=e.length;t--;){var n=o.fromPoints(e[t].start,e[t].end);e.isBackwards&&(n.cursor=n.start),this.addRange(n,!0)}return}e=e[0]}this.rangeList&&this.toSingleRange(e),this.setSelectionRange(e,e.isBackwards)},this.isEqual=function(e){if((e.length||this.rangeCount)&&e.length!=this.rangeCount)return!1;if(!e.length||!this.ranges)return this.getRange().isEqual(e);for(var t=this.ranges.length;t--;)if(!this.ranges[t].isEqual(e[t]))return!1;return!0}}).call(u.prototype),t.Selection=u}),ace.define(\"ace/tokenizer\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=2e3,i=function(e){this.states=e,this.regExps={},this.matchMappings={};for(var t in this.states){var n=this.states[t],r=[],i=0,s=this.matchMappings[t]={defaultToken:\"text\"},o=\"g\",u=[];for(var a=0;a<n.length;a++){var f=n[a];f.defaultToken&&(s.defaultToken=f.defaultToken),f.caseInsensitive&&(o=\"gi\");if(f.regex==null)continue;f.regex instanceof RegExp&&(f.regex=f.regex.toString().slice(1,-1));var l=f.regex,c=(new RegExp(\"(?:(\"+l+\")|(.))\")).exec(\"a\").length-2;Array.isArray(f.token)?f.token.length==1||c==1?f.token=f.token[0]:c-1!=f.token.length?(this.reportError(\"number of classes and regexp groups doesn't match\",{rule:f,groupCount:c-1}),f.token=f.token[0]):(f.tokenArray=f.token,f.token=null,f.onMatch=this.$arrayTokens):typeof f.token==\"function\"&&!f.onMatch&&(c>1?f.onMatch=this.$applyToken:f.onMatch=f.token),c>1&&(/\\\\\\d/.test(f.regex)?l=f.regex.replace(/\\\\([0-9]+)/g,function(e,t){return\"\\\\\"+(parseInt(t,10)+i+1)}):(c=1,l=this.removeCapturingGroups(f.regex)),!f.splitRegex&&typeof f.token!=\"string\"&&u.push(f)),s[i]=a,i+=c,r.push(l),f.onMatch||(f.onMatch=null)}r.length||(s[0]=0,r.push(\"$\")),u.forEach(function(e){e.splitRegex=this.createSplitterRegexp(e.regex,o)},this),this.regExps[t]=new RegExp(\"(\"+r.join(\")|(\")+\")|($)\",o)}};(function(){this.$setMaxTokenCount=function(e){r=e|0},this.$applyToken=function(e){var t=this.splitRegex.exec(e).slice(1),n=this.token.apply(this,t);if(typeof n==\"string\")return[{type:n,value:e}];var r=[];for(var i=0,s=n.length;i<s;i++)t[i]&&(r[r.length]={type:n[i],value:t[i]});return r},this.$arrayTokens=function(e){if(!e)return[];var t=this.splitRegex.exec(e);if(!t)return\"text\";var n=[],r=this.tokenArray;for(var i=0,s=r.length;i<s;i++)t[i+1]&&(n[n.length]={type:r[i],value:t[i+1]});return n},this.removeCapturingGroups=function(e){var t=e.replace(/\\[(?:\\\\.|[^\\]])*?\\]|\\\\.|\\(\\?[:=!]|(\\()/g,function(e,t){return t?\"(?:\":e});return t},this.createSplitterRegexp=function(e,t){if(e.indexOf(\"(?=\")!=-1){var n=0,r=!1,i={};e.replace(/(\\\\.)|(\\((?:\\?[=!])?)|(\\))|([\\[\\]])/g,function(e,t,s,o,u,a){return r?r=u!=\"]\":u?r=!0:o?(n==i.stack&&(i.end=a+1,i.stack=-1),n--):s&&(n++,s.length!=1&&(i.stack=n,i.start=a)),e}),i.end!=null&&/^\\)*$/.test(e.substr(i.end))&&(e=e.substring(0,i.start)+e.substr(i.end))}return new RegExp(e,(t||\"\").replace(\"g\",\"\"))},this.getLineTokens=function(e,t){if(t&&typeof t!=\"string\"){var n=t.slice(0);t=n[0],t===\"#tmp\"&&(n.shift(),t=n.shift())}else var n=[];var i=t||\"start\",s=this.states[i];s||(i=\"start\",s=this.states[i]);var o=this.matchMappings[i],u=this.regExps[i];u.lastIndex=0;var a,f=[],l=0,c=0,h={type:null,value:\"\"};while(a=u.exec(e)){var p=o.defaultToken,d=null,v=a[0],m=u.lastIndex;if(m-v.length>l){var g=e.substring(l,m-v.length);h.type==p?h.value+=g:(h.type&&f.push(h),h={type:p,value:g})}for(var y=0;y<a.length-2;y++){if(a[y+1]===undefined)continue;d=s[o[y]],d.onMatch?p=d.onMatch(v,i,n):p=d.token,d.next&&(typeof d.next==\"string\"?i=d.next:i=d.next(i,n),s=this.states[i],s||(this.reportError(\"state doesn't exist\",i),i=\"start\",s=this.states[i]),o=this.matchMappings[i],l=m,u=this.regExps[i],u.lastIndex=m);break}if(v)if(typeof p==\"string\")!!d&&d.merge===!1||h.type!==p?(h.type&&f.push(h),h={type:p,value:v}):h.value+=v;else if(p){h.type&&f.push(h),h={type:null,value:\"\"};for(var y=0;y<p.length;y++)f.push(p[y])}if(l==e.length)break;l=m;if(c++>r){c>2*e.length&&this.reportError(\"infinite loop with in ace tokenizer\",{startState:t,line:e});while(l<e.length)h.type&&f.push(h),h={value:e.substring(l,l+=2e3),type:\"overflow\"};i=\"start\",n=[];break}}return h.type&&f.push(h),n.length>1&&n[0]!==i&&n.unshift(\"#tmp\",i),{tokens:f,state:n.length?n:i}},this.reportError=function(e,t){var n=new Error(e);n.data=t,typeof console==\"object\"&&console.error&&console.error(n),setTimeout(function(){throw n})}}).call(i.prototype),t.Tokenizer=i}),ace.define(\"ace/mode/text_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../lib/lang\"),i=function(){this.$rules={start:[{token:\"empty_line\",regex:\"^$\"},{defaultToken:\"text\"}]}};(function(){this.addRules=function(e,t){if(!t){for(var n in e)this.$rules[n]=e[n];return}for(var n in e){var r=e[n];for(var i=0;i<r.length;i++){var s=r[i];if(s.next||s.onMatch)typeof s.next!=\"string\"?s.nextState&&s.nextState.indexOf(t)!==0&&(s.nextState=t+s.nextState):s.next.indexOf(t)!==0&&(s.next=t+s.next)}this.$rules[t+n]=r}},this.getRules=function(){return this.$rules},this.embedRules=function(e,t,n,i,s){var o=typeof e==\"function\"?(new e).getRules():e;if(i)for(var u=0;u<i.length;u++)i[u]=t+i[u];else{i=[];for(var a in o)i.push(t+a)}this.addRules(o,t);if(n){var f=Array.prototype[s?\"push\":\"unshift\"];for(var u=0;u<i.length;u++)f.apply(this.$rules[i[u]],r.deepCopy(n))}this.$embeds||(this.$embeds=[]),this.$embeds.push(t)},this.getEmbeds=function(){return this.$embeds};var e=function(e,t){return(e!=\"start\"||t.length)&&t.unshift(this.nextState,e),this.nextState},t=function(e,t){return t.shift(),t.shift()||\"start\"};this.normalizeRules=function(){function i(s){var o=r[s];o.processed=!0;for(var u=0;u<o.length;u++){var a=o[u];!a.regex&&a.start&&(a.regex=a.start,a.next||(a.next=[]),a.next.push({defaultToken:a.token},{token:a.token+\".end\",regex:a.end||a.start,next:\"pop\"}),a.token=a.token+\".start\",a.push=!0);var f=a.next||a.push;if(f&&Array.isArray(f)){var l=a.stateName;l||(l=a.token,typeof l!=\"string\"&&(l=l[0]||\"\"),r[l]&&(l+=n++)),r[l]=f,a.next=l,i(l)}else f==\"pop\"&&(a.next=t);a.push&&(a.nextState=a.next||a.push,a.next=e,delete a.push);if(a.rules)for(var c in a.rules)r[c]?r[c].push&&r[c].push.apply(r[c],a.rules[c]):r[c]=a.rules[c];if(a.include||typeof a==\"string\")var h=a.include||a,p=r[h];else Array.isArray(a)&&(p=a);if(p){var d=[u,1].concat(p);a.noEscape&&(d=d.filter(function(e){return!e.next})),o.splice.apply(o,d),u--,p=null}a.keywordMap&&(a.token=this.createKeywordMapper(a.keywordMap,a.defaultToken||\"text\",a.caseInsensitive),delete a.defaultToken)}}var n=0,r=this.$rules;Object.keys(r).forEach(i,this)},this.createKeywordMapper=function(e,t,n,r){var i=Object.create(null);return Object.keys(e).forEach(function(t){var s=e[t];n&&(s=s.toLowerCase());var o=s.split(r||\"|\");for(var u=o.length;u--;)i[o[u]]=t}),Object.getPrototypeOf(i)&&(i.__proto__=null),this.$keywordList=Object.keys(i),e=null,n?function(e){return i[e.toLowerCase()]||t}:function(e){return i[e]||t}},this.getKeywords=function(){return this.$keywords}}).call(i.prototype),t.TextHighlightRules=i}),ace.define(\"ace/mode/behaviour\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=function(){this.$behaviours={}};(function(){this.add=function(e,t,n){switch(undefined){case this.$behaviours:this.$behaviours={};case this.$behaviours[e]:this.$behaviours[e]={}}this.$behaviours[e][t]=n},this.addBehaviours=function(e){for(var t in e)for(var n in e[t])this.add(t,n,e[t][n])},this.remove=function(e){this.$behaviours&&this.$behaviours[e]&&delete this.$behaviours[e]},this.inherit=function(e,t){if(typeof e==\"function\")var n=(new e).getBehaviours(t);else var n=e.getBehaviours(t);this.addBehaviours(n)},this.getBehaviours=function(e){if(!e)return this.$behaviours;var t={};for(var n=0;n<e.length;n++)this.$behaviours[e[n]]&&(t[e[n]]=this.$behaviours[e[n]]);return t}}).call(r.prototype),t.Behaviour=r}),ace.define(\"ace/unicode\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";function r(e){var n=/\\w{4}/g;for(var r in e)t.packages[r]=e[r].replace(n,\"\\\\u$&\")}t.packages={},r({L:\"0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC\",Ll:\"0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A\",Lu:\"0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A\",Lt:\"01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC\",Lm:\"02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F\",Lo:\"01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC\",M:\"0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26\",Mn:\"0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26\",Mc:\"0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC\",Me:\"0488048906DE20DD-20E020E2-20E4A670-A672\",N:\"0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19\",Nd:\"0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19\",Nl:\"16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF\",No:\"00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835\",P:\"0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65\",Pd:\"002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D\",Ps:\"0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62\",Pe:\"0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63\",Pi:\"00AB2018201B201C201F20392E022E042E092E0C2E1C2E20\",Pf:\"00BB2019201D203A2E032E052E0A2E0D2E1D2E21\",Pc:\"005F203F20402054FE33FE34FE4D-FE4FFF3F\",Po:\"0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65\",S:\"0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD\",Sm:\"002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC\",Sc:\"002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6\",Sk:\"005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3\",So:\"00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD\",Z:\"002000A01680180E2000-200A20282029202F205F3000\",Zs:\"002000A01680180E2000-200A202F205F3000\",Zl:\"2028\",Zp:\"2029\",C:\"0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF\",Cc:\"0000-001F007F-009F\",Cf:\"00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB\",Co:\"E000-F8FF\",Cs:\"D800-DFFF\",Cn:\"03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF\"})}),ace.define(\"ace/token_iterator\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=function(e,t,n){this.$session=e,this.$row=t,this.$rowTokens=e.getTokens(t);var r=e.getTokenAt(t,n);this.$tokenIndex=r?r.index:-1};(function(){this.stepBackward=function(){this.$tokenIndex-=1;while(this.$tokenIndex<0){this.$row-=1;if(this.$row<0)return this.$row=0,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=this.$rowTokens.length-1}return this.$rowTokens[this.$tokenIndex]},this.stepForward=function(){this.$tokenIndex+=1;var e;while(this.$tokenIndex>=this.$rowTokens.length){this.$row+=1,e||(e=this.$session.getLength());if(this.$row>=e)return this.$row=e-1,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=0}return this.$rowTokens[this.$tokenIndex]},this.getCurrentToken=function(){return this.$rowTokens[this.$tokenIndex]},this.getCurrentTokenRow=function(){return this.$row},this.getCurrentTokenColumn=function(){var e=this.$rowTokens,t=this.$tokenIndex,n=e[t].start;if(n!==undefined)return n;n=0;while(t>0)t-=1,n+=e[t].value.length;return n}}).call(r.prototype),t.TokenIterator=r}),ace.define(\"ace/mode/text\",[\"require\",\"exports\",\"module\",\"ace/tokenizer\",\"ace/mode/text_highlight_rules\",\"ace/mode/behaviour\",\"ace/unicode\",\"ace/lib/lang\",\"ace/token_iterator\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../tokenizer\").Tokenizer,i=e(\"./text_highlight_rules\").TextHighlightRules,s=e(\"./behaviour\").Behaviour,o=e(\"../unicode\"),u=e(\"../lib/lang\"),a=e(\"../token_iterator\").TokenIterator,f=e(\"../range\").Range,l=function(){this.HighlightRules=i,this.$behaviour=new s};(function(){this.tokenRe=new RegExp(\"^[\"+o.packages.L+o.packages.Mn+o.packages.Mc+o.packages.Nd+o.packages.Pc+\"\\\\$_]+\",\"g\"),this.nonTokenRe=new RegExp(\"^(?:[^\"+o.packages.L+o.packages.Mn+o.packages.Mc+o.packages.Nd+o.packages.Pc+\"\\\\$_]|\\\\s])+\",\"g\"),this.getTokenizer=function(){return this.$tokenizer||(this.$highlightRules=this.$highlightRules||new this.HighlightRules,this.$tokenizer=new r(this.$highlightRules.getRules())),this.$tokenizer},this.lineCommentStart=\"\",this.blockComment=\"\",this.toggleCommentLines=function(e,t,n,r){function w(e){for(var t=n;t<=r;t++)e(i.getLine(t),t)}var i=t.doc,s=!0,o=!0,a=Infinity,f=t.getTabSize(),l=!1;if(!this.lineCommentStart){if(!this.blockComment)return!1;var c=this.blockComment.start,h=this.blockComment.end,p=new RegExp(\"^(\\\\s*)(?:\"+u.escapeRegExp(c)+\")\"),d=new RegExp(\"(?:\"+u.escapeRegExp(h)+\")\\\\s*$\"),v=function(e,t){if(g(e,t))return;if(!s||/\\S/.test(e))i.insertInLine({row:t,column:e.length},h),i.insertInLine({row:t,column:a},c)},m=function(e,t){var n;(n=e.match(d))&&i.removeInLine(t,e.length-n[0].length,e.length),(n=e.match(p))&&i.removeInLine(t,n[1].length,n[0].length)},g=function(e,n){if(p.test(e))return!0;var r=t.getTokens(n);for(var i=0;i<r.length;i++)if(r[i].type===\"comment\")return!0}}else{if(Array.isArray(this.lineCommentStart))var p=this.lineCommentStart.map(u.escapeRegExp).join(\"|\"),c=this.lineCommentStart[0];else var p=u.escapeRegExp(this.lineCommentStart),c=this.lineCommentStart;p=new RegExp(\"^(\\\\s*)(?:\"+p+\") ?\"),l=t.getUseSoftTabs();var m=function(e,t){var n=e.match(p);if(!n)return;var r=n[1].length,s=n[0].length;!b(e,r,s)&&n[0][s-1]==\" \"&&s--,i.removeInLine(t,r,s)},y=c+\" \",v=function(e,t){if(!s||/\\S/.test(e))b(e,a,a)?i.insertInLine({row:t,column:a},y):i.insertInLine({row:t,column:a},c)},g=function(e,t){return p.test(e)},b=function(e,t,n){var r=0;while(t--&&e.charAt(t)==\" \")r++;if(r%f!=0)return!1;var r=0;while(e.charAt(n++)==\" \")r++;return f>2?r%f!=f-1:r%f==0}}var E=Infinity;w(function(e,t){var n=e.search(/\\S/);n!==-1?(n<a&&(a=n),o&&!g(e,t)&&(o=!1)):E>e.length&&(E=e.length)}),a==Infinity&&(a=E,s=!1,o=!1),l&&a%f!=0&&(a=Math.floor(a/f)*f),w(o?m:v)},this.toggleBlockComment=function(e,t,n,r){var i=this.blockComment;if(!i)return;!i.start&&i[0]&&(i=i[0]);var s=new a(t,r.row,r.column),o=s.getCurrentToken(),u=t.selection,l=t.selection.toOrientedRange(),c,h;if(o&&/comment/.test(o.type)){var p,d;while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.start);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;p=new f(m,g,m,g+i.start.length);break}o=s.stepBackward()}var s=new a(t,r.row,r.column),o=s.getCurrentToken();while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.end);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;d=new f(m,g,m,g+i.end.length);break}o=s.stepForward()}d&&t.remove(d),p&&(t.remove(p),c=p.start.row,h=-i.start.length)}else h=i.start.length,c=n.start.row,t.insert(n.end,i.end),t.insert(n.start,i.start);l.start.row==c&&(l.start.column+=h),l.end.row==c&&(l.end.column+=h),t.selection.fromOrientedRange(l)},this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.autoOutdent=function(e,t,n){},this.$getIndent=function(e){return e.match(/^\\s*/)[0]},this.createWorker=function(e){return null},this.createModeDelegates=function(e){this.$embeds=[],this.$modes={};for(var t in e)e[t]&&(this.$embeds.push(t),this.$modes[t]=new e[t]);var n=[\"toggleBlockComment\",\"toggleCommentLines\",\"getNextLineIndent\",\"checkOutdent\",\"autoOutdent\",\"transformAction\",\"getCompletions\"];for(var t=0;t<n.length;t++)(function(e){var r=n[t],i=e[r];e[n[t]]=function(){return this.$delegator(r,arguments,i)}})(this)},this.$delegator=function(e,t,n){var r=t[0];typeof r!=\"string\"&&(r=r[0]);for(var i=0;i<this.$embeds.length;i++){if(!this.$modes[this.$embeds[i]])continue;var s=r.split(this.$embeds[i]);if(!s[0]&&s[1]){t[0]=s[1];var o=this.$modes[this.$embeds[i]];return o[e].apply(o,t)}}var u=n.apply(this,t);return n?u:undefined},this.transformAction=function(e,t,n,r,i){if(this.$behaviour){var s=this.$behaviour.getBehaviours();for(var o in s)if(s[o][t]){var u=s[o][t].apply(this,arguments);if(u)return u}}},this.getKeywords=function(e){if(!this.completionKeywords){var t=this.$tokenizer.rules,n=[];for(var r in t){var i=t[r];for(var s=0,o=i.length;s<o;s++)if(typeof i[s].token==\"string\")/keyword|support|storage/.test(i[s].token)&&n.push(i[s].regex);else if(typeof i[s].token==\"object\")for(var u=0,a=i[s].token.length;u<a;u++)if(/keyword|support|storage/.test(i[s].token[u])){var r=i[s].regex.match(/\\(.+?\\)/g)[u];n.push(r.substr(1,r.length-2))}}this.completionKeywords=n}return e?n.concat(this.$keywordList||[]):this.$keywordList},this.$createKeywordList=function(){return this.$highlightRules||this.getTokenizer(),this.$keywordList=this.$highlightRules.$keywordList||[]},this.getCompletions=function(e,t,n,r){var i=this.$keywordList||this.$createKeywordList();return i.map(function(e){return{name:e,value:e,score:0,meta:\"keyword\"}})},this.$id=\"ace/mode/text\"}).call(l.prototype),t.Mode=l}),ace.define(\"ace/anchor\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/event_emitter\").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n==\"undefined\"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){var t=e.data,n=t.range;if(n.start.row==n.end.row&&n.start.row!=this.row)return;if(n.start.row>this.row)return;if(n.start.row==this.row&&n.start.column>this.column)return;var r=this.row,i=this.column,s=n.start,o=n.end;if(t.action===\"insertText\")if(s.row===r&&s.column<=i){if(s.column!==i||!this.$insertRight)s.row===o.row?i+=o.column-s.column:(i-=s.column,r+=o.row-s.row)}else s.row!==o.row&&s.row<r&&(r+=o.row-s.row);else t.action===\"insertLines\"?(s.row!==r||i!==0||!this.$insertRight)&&s.row<=r&&(r+=o.row-s.row):t.action===\"removeText\"?s.row===r&&s.column<i?o.column>=i?i=s.column:i=Math.max(0,i-(o.column-s.column)):s.row!==o.row&&s.row<r?(o.row===r&&(i=Math.max(0,i-o.column)+s.column),r-=o.row-s.row):o.row===r&&(r-=o.row-s.row,i=Math.max(0,i-o.column)+s.column):t.action==\"removeLines\"&&s.row<=r&&(o.row<=r?r-=o.row-s.row:(r=s.row,i=0));this.setPosition(r,i,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal(\"change\",{old:i,value:r})},this.detach=function(){this.document.removeEventListener(\"change\",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on(\"change\",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define(\"ace/document\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\",\"ace/range\",\"ace/anchor\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/event_emitter\").EventEmitter,s=e(\"./range\").Range,o=e(\"./anchor\").Anchor,u=function(e){this.$lines=[],e.length===0?this.$lines=[\"\"]:Array.isArray(e)?this._insertLines(0,e):this.insert({row:0,column:0},e)};(function(){r.implement(this,i),this.setValue=function(e){var t=this.getLength();this.remove(new s(0,0,t,this.getLine(t-1).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new o(this,e,t)},\"aaa\".split(/a/).length===0?this.$split=function(e){return e.replace(/\\r\\n|\\r/g,\"\\n\").split(\"\\n\")}:this.$split=function(e){return e.split(/\\r\\n|\\r|\\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\\r\\n|\\r|\\n)/m);this.$autoNewLine=t?t[1]:\"\\n\",this._signal(\"changeNewLineMode\")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case\"windows\":return\"\\r\\n\";case\"unix\":return\"\\n\";default:return this.$autoNewLine||\"\\n\"}},this.$autoNewLine=\"\",this.$newLineMode=\"auto\",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal(\"changeNewLineMode\")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e==\"\\r\\n\"||e==\"\\r\"||e==\"\\n\"},this.getLine=function(e){return this.$lines[e]||\"\"},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){if(e.start.row==e.end.row)return this.getLine(e.start.row).substring(e.start.column,e.end.column);var t=this.getLines(e.start.row,e.end.row);t[0]=(t[0]||\"\").substring(e.start.column);var n=t.length-1;return e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column)),t.join(this.getNewLineCharacter())},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):e.row<0&&(e.row=0),e},this.insert=function(e,t){if(!t||t.length===0)return e;e=this.$clipPosition(e),this.getLength()<=1&&this.$detectNewLine(t);var n=this.$split(t),r=n.splice(0,1)[0],i=n.length==0?null:n.splice(n.length-1,1)[0];return e=this.insertInLine(e,r),i!==null&&(e=this.insertNewLine(e),e=this._insertLines(e.row,n),e=this.insertInLine(e,i||\"\")),e},this.insertLines=function(e,t){return e>=this.getLength()?this.insert({row:e,column:0},\"\\n\"+t.join(\"\\n\")):this._insertLines(Math.max(e,0),t)},this._insertLines=function(e,t){if(t.length==0)return{row:e,column:0};while(t.length>61440){var n=this._insertLines(e,t.slice(0,61440));t=t.slice(61440),e=n.row}var r=[e,0];r.push.apply(r,t),this.$lines.splice.apply(this.$lines,r);var i=new s(e,0,e+t.length,0),o={action:\"insertLines\",range:i,lines:t};return this._signal(\"change\",{data:o}),i.end},this.insertNewLine=function(e){e=this.$clipPosition(e);var t=this.$lines[e.row]||\"\";this.$lines[e.row]=t.substring(0,e.column),this.$lines.splice(e.row+1,0,t.substring(e.column,t.length));var n={row:e.row+1,column:0},r={action:\"insertText\",range:s.fromPoints(e,n),text:this.getNewLineCharacter()};return this._signal(\"change\",{data:r}),n},this.insertInLine=function(e,t){if(t.length==0)return e;var n=this.$lines[e.row]||\"\";this.$lines[e.row]=n.substring(0,e.column)+t+n.substring(e.column);var r={row:e.row,column:e.column+t.length},i={action:\"insertText\",range:s.fromPoints(e,r),text:t};return this._signal(\"change\",{data:i}),r},this.remove=function(e){e instanceof s||(e=s.fromPoints(e.start,e.end)),e.start=this.$clipPosition(e.start),e.end=this.$clipPosition(e.end);if(e.isEmpty())return e.start;var t=e.start.row,n=e.end.row;if(e.isMultiLine()){var r=e.start.column==0?t:t+1,i=n-1;e.end.column>0&&this.removeInLine(n,0,e.end.column),i>=r&&this._removeLines(r,i),r!=t&&(this.removeInLine(t,e.start.column,this.getLine(t).length),this.removeNewLine(e.start.row))}else this.removeInLine(t,e.start.column,e.end.column);return e.start},this.removeInLine=function(e,t,n){if(t==n)return;var r=new s(e,t,e,n),i=this.getLine(e),o=i.substring(t,n),u=i.substring(0,t)+i.substring(n,i.length);this.$lines.splice(e,1,u);var a={action:\"removeText\",range:r,text:o};return this._signal(\"change\",{data:a}),r.start},this.removeLines=function(e,t){return e<0||t>=this.getLength()?this.remove(new s(e,0,t+1,0)):this._removeLines(e,t)},this._removeLines=function(e,t){var n=new s(e,0,t+1,0),r=this.$lines.splice(e,t-e+1),i={action:\"removeLines\",range:n,nl:this.getNewLineCharacter(),lines:r};return this._signal(\"change\",{data:i}),r},this.removeNewLine=function(e){var t=this.getLine(e),n=this.getLine(e+1),r=new s(e,t.length,e+1,0),i=t+n;this.$lines.splice(e,2,i);var o={action:\"removeText\",range:r,text:this.getNewLineCharacter()};this._signal(\"change\",{data:o})},this.replace=function(e,t){e instanceof s||(e=s.fromPoints(e.start,e.end));if(t.length==0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);if(t)var n=this.insert(e.start,t);else n=e.start;return n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action==\"insertLines\"?this.insertLines(r.start.row,n.lines):n.action==\"insertText\"?this.insert(r.start,n.text):n.action==\"removeLines\"?this._removeLines(r.start.row,r.end.row-1):n.action==\"removeText\"&&this.remove(r)}},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action==\"insertLines\"?this._removeLines(r.start.row,r.end.row-1):n.action==\"insertText\"?this.remove(r):n.action==\"removeLines\"?this._insertLines(r.start.row,n.lines):n.action==\"removeText\"&&this.insert(r.start,n.text)}},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:n[s-1].length}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(u.prototype),t.Document=u}),ace.define(\"ace/background_tokenizer\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/event_emitter\").EventEmitter,s=function(e,t){this.running=!1,this.lines=[],this.states=[],this.currentLine=0,this.tokenizer=e;var n=this;this.$worker=function(){if(!n.running)return;var e=new Date,t=n.currentLine,r=-1,i=n.doc;while(n.lines[t])t++;var s=t,o=i.getLength(),u=0;n.running=!1;while(t<o){n.$tokenizeRow(t),r=t;do t++;while(n.lines[t]);u++;if(u%5===0&&new Date-e>20){n.running=setTimeout(n.$worker,20);break}}n.currentLine=t,s<=r&&n.fireUpdateEvent(s,r)}};(function(){r.implement(this,i),this.setTokenizer=function(e){this.tokenizer=e,this.lines=[],this.states=[],this.start(0)},this.setDocument=function(e){this.doc=e,this.lines=[],this.states=[],this.stop()},this.fireUpdateEvent=function(e,t){var n={first:e,last:t};this._signal(\"update\",{data:n})},this.start=function(e){this.currentLine=Math.min(e||0,this.currentLine,this.doc.getLength()),this.lines.splice(this.currentLine,this.lines.length),this.states.splice(this.currentLine,this.states.length),this.stop(),this.running=setTimeout(this.$worker,700)},this.scheduleStart=function(){this.running||(this.running=setTimeout(this.$worker,700))},this.$updateOnChange=function(e){var t=e.range,n=t.start.row,r=t.end.row-n;if(r===0)this.lines[n]=null;else if(e.action==\"removeText\"||e.action==\"removeLines\")this.lines.splice(n,r+1,null),this.states.splice(n,r+1,null);else{var i=Array(r+1);i.unshift(n,1),this.lines.splice.apply(this.lines,i),this.states.splice.apply(this.states,i)}this.currentLine=Math.min(n,this.currentLine,this.doc.getLength()),this.stop()},this.stop=function(){this.running&&clearTimeout(this.running),this.running=!1},this.getTokens=function(e){return this.lines[e]||this.$tokenizeRow(e)},this.getState=function(e){return this.currentLine==e&&this.$tokenizeRow(e),this.states[e]||\"start\"},this.$tokenizeRow=function(e){var t=this.doc.getLine(e),n=this.states[e-1],r=this.tokenizer.getLineTokens(t,n,e);return this.states[e]+\"\"!=r.state+\"\"?(this.states[e]=r.state,this.lines[e+1]=null,this.currentLine>e+1&&(this.currentLine=e+1)):this.currentLine==e&&(this.currentLine=e+1),this.lines[e]=r.tokens}}).call(s.prototype),t.BackgroundTokenizer=s}),ace.define(\"ace/search_highlight\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/lib/oop\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"./lib/lang\"),i=e(\"./lib/oop\"),s=e(\"./range\").Range,o=function(e,t,n){this.setRegexp(e),this.clazz=t,this.type=n||\"text\"};(function(){this.MAX_RANGES=500,this.setRegexp=function(e){if(this.regExp+\"\"==e+\"\")return;this.regExp=e,this.cache=[]},this.update=function(e,t,n,i){if(!this.regExp)return;var o=i.firstRow,u=i.lastRow;for(var a=o;a<=u;a++){var f=this.cache[a];f==null&&(f=r.getMatchOffsets(n.getLine(a),this.regExp),f.length>this.MAX_RANGES&&(f=f.slice(0,this.MAX_RANGES)),f=f.map(function(e){return new s(a,e.offset,a,e.offset+e.length)}),this.cache[a]=f.length?f:\"\");for(var l=f.length;l--;)t.drawSingleLineMarker(e,f[l].toScreenRange(n),this.clazz,i)}}}).call(o.prototype),t.SearchHighlight=o}),ace.define(\"ace/edit_session/fold_line\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";function i(e,t){this.foldData=e,Array.isArray(t)?this.folds=t:t=this.folds=[t];var n=t[t.length-1];this.range=new r(t[0].start.row,t[0].start.column,n.end.row,n.end.column),this.start=this.range.start,this.end=this.range.end,this.folds.forEach(function(e){e.setFoldLine(this)},this)}var r=e(\"../range\").Range;(function(){this.shiftRow=function(e){this.start.row+=e,this.end.row+=e,this.folds.forEach(function(t){t.start.row+=e,t.end.row+=e})},this.addFold=function(e){if(e.sameRow){if(e.start.row<this.startRow||e.endRow>this.endRow)throw new Error(\"Can't add a fold to this FoldLine as it has no connection\");this.folds.push(e),this.folds.sort(function(e,t){return-e.range.compareEnd(t.start.row,t.start.column)}),this.range.compareEnd(e.start.row,e.start.column)>0?(this.end.row=e.end.row,this.end.column=e.end.column):this.range.compareStart(e.end.row,e.end.column)<0&&(this.start.row=e.start.row,this.start.column=e.start.column)}else if(e.start.row==this.end.row)this.folds.push(e),this.end.row=e.end.row,this.end.column=e.end.column;else{if(e.end.row!=this.start.row)throw new Error(\"Trying to add fold to FoldRow that doesn't have a matching row\");this.folds.unshift(e),this.start.row=e.start.row,this.start.column=e.start.column}e.foldLine=this},this.containsRow=function(e){return e>=this.start.row&&e<=this.end.row},this.walk=function(e,t,n){var r=0,i=this.folds,s,o,u,a=!0;t==null&&(t=this.end.row,n=this.end.column);for(var f=0;f<i.length;f++){s=i[f],o=s.range.compareStart(t,n);if(o==-1){e(null,t,n,r,a);return}u=e(null,s.start.row,s.start.column,r,a),u=!u&&e(s.placeholder,s.start.row,s.start.column,r);if(u||o===0)return;a=!s.sameRow,r=s.end.column}e(null,t,n,r,a)},this.getNextFoldTo=function(e,t){var n,r;for(var i=0;i<this.folds.length;i++){n=this.folds[i],r=n.range.compareEnd(e,t);if(r==-1)return{fold:n,kind:\"after\"};if(r===0)return{fold:n,kind:\"inside\"}}return null},this.addRemoveChars=function(e,t,n){var r=this.getNextFoldTo(e,t),i,s;if(r){i=r.fold;if(r.kind==\"inside\"&&i.start.column!=t&&i.start.row!=e)window.console&&window.console.log(e,t,i);else if(i.start.row==e){s=this.folds;var o=s.indexOf(i);o===0&&(this.start.column+=n);for(o;o<s.length;o++){i=s[o],i.start.column+=n;if(!i.sameRow)return;i.end.column+=n}this.end.column+=n}}},this.split=function(e,t){var n=this.getNextFoldTo(e,t);if(!n||n.kind==\"inside\")return null;var r=n.fold,s=this.folds,o=this.foldData,u=s.indexOf(r),a=s[u-1];this.end.row=a.end.row,this.end.column=a.end.column,s=s.splice(u,s.length-u);var f=new i(o,s);return o.splice(o.indexOf(this)+1,0,f),f},this.merge=function(e){var t=e.folds;for(var n=0;n<t.length;n++)this.addFold(t[n]);var r=this.foldData;r.splice(r.indexOf(e),1)},this.toString=function(){var e=[this.range.toString()+\": [\"];return this.folds.forEach(function(t){e.push(\"  \"+t.toString())}),e.push(\"]\"),e.join(\"\\n\")},this.idxToPosition=function(e){var t=0;for(var n=0;n<this.folds.length;n++){var r=this.folds[n];e-=r.start.column-t;if(e<0)return{row:r.start.row,column:r.start.column+e};e-=r.placeholder.length;if(e<0)return r.start;t=r.end.column}return{row:this.end.row,column:this.end.column+e}}}).call(i.prototype),t.FoldLine=i}),ace.define(\"ace/range_list\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"./range\").Range,i=r.comparePoints,s=function(){this.ranges=[]};(function(){this.comparePoints=i,this.pointIndex=function(e,t,n){var r=this.ranges;for(var s=n||0;s<r.length;s++){var o=r[s],u=i(e,o.end);if(u>0)continue;var a=i(e,o.start);return u===0?t&&a!==0?-s-2:s:a>0||a===0&&!t?s:-s-1}return-s-1},this.add=function(e){var t=!e.isEmpty(),n=this.pointIndex(e.start,t);n<0&&(n=-n-1);var r=this.pointIndex(e.end,t,n);return r<0?r=-r-1:r++,this.ranges.splice(n,r-n,e)},this.addList=function(e){var t=[];for(var n=e.length;n--;)t.push.call(t,this.add(e[n]));return t},this.substractPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges.splice(t,1)},this.merge=function(){var e=[],t=this.ranges;t=t.sort(function(e,t){return i(e.start,t.start)});var n=t[0],r;for(var s=1;s<t.length;s++){r=n,n=t[s];var o=i(r.end,n.start);if(o<0)continue;if(o==0&&!r.isEmpty()&&!n.isEmpty())continue;i(r.end,n.end)<0&&(r.end.row=n.end.row,r.end.column=n.end.column),t.splice(s,1),e.push(n),n=r,s--}return this.ranges=t,e},this.contains=function(e,t){return this.pointIndex({row:e,column:t})>=0},this.containsPoint=function(e){return this.pointIndex(e)>=0},this.rangeAtPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges[t]},this.clipRows=function(e,t){var n=this.ranges;if(n[0].start.row>t||n[n.length-1].start.row<e)return[];var r=this.pointIndex({row:e,column:0});r<0&&(r=-r-1);var i=this.pointIndex({row:t,column:0},r);i<0&&(i=-i-1);var s=[];for(var o=r;o<i;o++)s.push(n[o]);return s},this.removeAll=function(){return this.ranges.splice(0,this.ranges.length)},this.attach=function(e){this.session&&this.detach(),this.session=e,this.onChange=this.$onChange.bind(this),this.session.on(\"change\",this.onChange)},this.detach=function(){if(!this.session)return;this.session.removeListener(\"change\",this.onChange),this.session=null},this.$onChange=function(e){var t=e.data.range;if(e.data.action[0]==\"i\")var n=t.start,r=t.end;else var r=t.start,n=t.end;var i=n.row,s=r.row,o=s-i,u=-n.column+r.column,a=this.ranges;for(var f=0,l=a.length;f<l;f++){var c=a[f];if(c.end.row<i)continue;if(c.start.row>i)break;c.start.row==i&&c.start.column>=n.column&&(c.start.column!=n.column||!this.$insertRight)&&(c.start.column+=u,c.start.row+=o);if(c.end.row==i&&c.end.column>=n.column){if(c.end.column==n.column&&this.$insertRight)continue;c.end.column==n.column&&u>0&&f<l-1&&c.end.column>c.start.column&&c.end.column==a[f+1].start.column&&(c.end.column-=u),c.end.column+=u,c.end.row+=o}}if(o!=0&&f<l)for(;f<l;f++){var c=a[f];c.start.row+=o,c.end.row+=o}}}).call(s.prototype),t.RangeList=s}),ace.define(\"ace/edit_session/fold\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/range_list\",\"ace/lib/oop\"],function(e,t,n){\"use strict\";function u(e,t){e.row-=t.row,e.row==0&&(e.column-=t.column)}function a(e,t){u(e.start,t),u(e.end,t)}function f(e,t){e.row==0&&(e.column+=t.column),e.row+=t.row}function l(e,t){f(e.start,t),f(e.end,t)}var r=e(\"../range\").Range,i=e(\"../range_list\").RangeList,s=e(\"../lib/oop\"),o=t.Fold=function(e,t){this.foldLine=null,this.placeholder=t,this.range=e,this.start=e.start,this.end=e.end,this.sameRow=e.start.row==e.end.row,this.subFolds=this.ranges=[]};s.inherits(o,i),function(){this.toString=function(){return'\"'+this.placeholder+'\" '+this.range.toString()},this.setFoldLine=function(e){this.foldLine=e,this.subFolds.forEach(function(t){t.setFoldLine(e)})},this.clone=function(){var e=this.range.clone(),t=new o(e,this.placeholder);return this.subFolds.forEach(function(e){t.subFolds.push(e.clone())}),t.collapseChildren=this.collapseChildren,t},this.addSubFold=function(e){if(this.range.isEqual(e))return;if(!this.range.containsRange(e))throw new Error(\"A fold can't intersect already existing fold\"+e.range+this.range);a(e,this.start);var t=e.start.row,n=e.start.column;for(var r=0,i=-1;r<this.subFolds.length;r++){i=this.subFolds[r].range.compare(t,n);if(i!=1)break}var s=this.subFolds[r];if(i==0)return s.addSubFold(e);var t=e.range.end.row,n=e.range.end.column;for(var o=r,i=-1;o<this.subFolds.length;o++){i=this.subFolds[o].range.compare(t,n);if(i!=1)break}var u=this.subFolds[o];if(i==0)throw new Error(\"A fold can't intersect already existing fold\"+e.range+this.range);var f=this.subFolds.splice(r,o-r,e);return e.setFoldLine(this.foldLine),e},this.restoreRange=function(e){return l(e,this.start)}}.call(o.prototype)}),ace.define(\"ace/edit_session/folding\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/edit_session/fold_line\",\"ace/edit_session/fold\",\"ace/token_iterator\"],function(e,t,n){\"use strict\";function u(){this.getFoldAt=function(e,t,n){var r=this.getFoldLine(e);if(!r)return null;var i=r.folds;for(var s=0;s<i.length;s++){var o=i[s];if(o.range.contains(e,t)){if(n==1&&o.range.isEnd(e,t))continue;if(n==-1&&o.range.isStart(e,t))continue;return o}}},this.getFoldsInRange=function(e){var t=e.start,n=e.end,r=this.$foldData,i=[];t.column+=1,n.column-=1;for(var s=0;s<r.length;s++){var o=r[s].range.compareRange(e);if(o==2)continue;if(o==-2)break;var u=r[s].folds;for(var a=0;a<u.length;a++){var f=u[a];o=f.range.compareRange(e);if(o==-2)break;if(o==2)continue;if(o==42)break;i.push(f)}}return t.column-=1,n.column+=1,i},this.getFoldsInRangeList=function(e){if(Array.isArray(e)){var t=[];e.forEach(function(e){t=t.concat(this.getFoldsInRange(e))},this)}else var t=this.getFoldsInRange(e);return t},this.getAllFolds=function(){var e=[],t=this.$foldData;for(var n=0;n<t.length;n++)for(var r=0;r<t[n].folds.length;r++)e.push(t[n].folds[r]);return e},this.getFoldStringAt=function(e,t,n,r){r=r||this.getFoldLine(e);if(!r)return null;var i={end:{column:0}},s,o;for(var u=0;u<r.folds.length;u++){o=r.folds[u];var a=o.range.compareEnd(e,t);if(a==-1){s=this.getLine(o.start.row).substring(i.end.column,o.start.column);break}if(a===0)return null;i=o}return s||(s=this.getLine(o.start.row).substring(i.end.column)),n==-1?s.substring(0,t-i.end.column):n==1?s.substring(t-i.end.column):s},this.getFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r<n.length;r++){var i=n[r];if(i.start.row<=e&&i.end.row>=e)return i;if(i.end.row>e)return null}return null},this.getNextFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r<n.length;r++){var i=n[r];if(i.end.row>=e)return i}return null},this.getFoldedRowCount=function(e,t){var n=this.$foldData,r=t-e+1;for(var i=0;i<n.length;i++){var s=n[i],o=s.end.row,u=s.start.row;if(o>=t){u<t&&(u>=e?r-=t-u:r=0);break}o>=e&&(u>=e?r-=o-u:r-=o-e+1)}return r},this.$addFoldLine=function(e){return this.$foldData.push(e),this.$foldData.sort(function(e,t){return e.start.row-t.start.row}),e},this.addFold=function(e,t){var n=this.$foldData,r=!1,o;e instanceof s?o=e:(o=new s(t,e),o.collapseChildren=t.collapseChildren),this.$clipRangeToDocument(o.range);var u=o.start.row,a=o.start.column,f=o.end.row,l=o.end.column;if(u<f||u==f&&a<=l-2){var c=this.getFoldAt(u,a,1),h=this.getFoldAt(f,l,-1);if(c&&h==c)return c.addSubFold(o);c&&!c.range.isStart(u,a)&&this.removeFold(c),h&&!h.range.isEnd(f,l)&&this.removeFold(h);var p=this.getFoldsInRange(o.range);p.length>0&&(this.removeFolds(p),p.forEach(function(e){o.addSubFold(e)}));for(var d=0;d<n.length;d++){var v=n[d];if(f==v.start.row){v.addFold(o),r=!0;break}if(u==v.end.row){v.addFold(o),r=!0;if(!o.sameRow){var m=n[d+1];if(m&&m.start.row==f){v.merge(m);break}}break}if(f<=v.start.row)break}return r||(v=this.$addFoldLine(new i(this.$foldData,o))),this.$useWrapMode?this.$updateWrapData(v.start.row,v.start.row):this.$updateRowLengthCache(v.start.row,v.start.row),this.$modified=!0,this._emit(\"changeFold\",{data:o,action:\"add\"}),o}throw new Error(\"The range has to be at least 2 characters width\")},this.addFolds=function(e){e.forEach(function(e){this.addFold(e)},this)},this.removeFold=function(e){var t=e.foldLine,n=t.start.row,r=t.end.row,i=this.$foldData,s=t.folds;if(s.length==1)i.splice(i.indexOf(t),1);else if(t.range.isEnd(e.end.row,e.end.column))s.pop(),t.end.row=s[s.length-1].end.row,t.end.column=s[s.length-1].end.column;else if(t.range.isStart(e.start.row,e.start.column))s.shift(),t.start.row=s[0].start.row,t.start.column=s[0].start.column;else if(e.sameRow)s.splice(s.indexOf(e),1);else{var o=t.split(e.start.row,e.start.column);s=o.folds,s.shift(),o.start.row=s[0].start.row,o.start.column=s[0].start.column}this.$updating||(this.$useWrapMode?this.$updateWrapData(n,r):this.$updateRowLengthCache(n,r)),this.$modified=!0,this._emit(\"changeFold\",{data:e,action:\"remove\"})},this.removeFolds=function(e){var t=[];for(var n=0;n<e.length;n++)t.push(e[n]);t.forEach(function(e){this.removeFold(e)},this),this.$modified=!0},this.expandFold=function(e){this.removeFold(e),e.subFolds.forEach(function(t){e.restoreRange(t),this.addFold(t)},this),e.collapseChildren>0&&this.foldAll(e.start.row+1,e.end.row,e.collapseChildren-1),e.subFolds=[]},this.expandFolds=function(e){e.forEach(function(e){this.expandFold(e)},this)},this.unfold=function(e,t){var n,i;e==null?(n=new r(0,0,this.getLength(),0),t=!0):typeof e==\"number\"?n=new r(e,0,e,this.getLine(e).length):\"row\"in e?n=r.fromPoints(e,e):n=e,i=this.getFoldsInRangeList(n);if(t)this.removeFolds(i);else{var s=i;while(s.length)this.expandFolds(s),s=this.getFoldsInRangeList(n)}if(i.length)return i},this.isRowFolded=function(e,t){return!!this.getFoldLine(e,t)},this.getRowFoldEnd=function(e,t){var n=this.getFoldLine(e,t);return n?n.end.row:e},this.getRowFoldStart=function(e,t){var n=this.getFoldLine(e,t);return n?n.start.row:e},this.getFoldDisplayLine=function(e,t,n,r,i){r==null&&(r=e.start.row),i==null&&(i=0),t==null&&(t=e.end.row),n==null&&(n=this.getLine(t).length);var s=this.doc,o=\"\";return e.walk(function(e,t,n,u){if(t<r)return;if(t==r){if(n<i)return;u=Math.max(i,u)}e!=null?o+=e:o+=s.getLine(t).substring(u,n)},t,n),o},this.getDisplayLine=function(e,t,n,r){var i=this.getFoldLine(e);if(!i){var s;return s=this.doc.getLine(e),s.substring(r||0,t||s.length)}return this.getFoldDisplayLine(i,e,t,n,r)},this.$cloneFoldData=function(){var e=[];return e=this.$foldData.map(function(t){var n=t.folds.map(function(e){return e.clone()});return new i(e,n)}),e},this.toggleFold=function(e){var t=this.selection,n=t.getRange(),r,i;if(n.isEmpty()){var s=n.start;r=this.getFoldAt(s.row,s.column);if(r){this.expandFold(r);return}(i=this.findMatchingBracket(s))?n.comparePoint(i)==1?n.end=i:(n.start=i,n.start.column++,n.end.column--):(i=this.findMatchingBracket({row:s.row,column:s.column+1}))?(n.comparePoint(i)==1?n.end=i:n.start=i,n.start.column++):n=this.getCommentFoldRange(s.row,s.column)||n}else{var o=this.getFoldsInRange(n);if(e&&o.length){this.expandFolds(o);return}o.length==1&&(r=o[0])}r||(r=this.getFoldAt(n.start.row,n.start.column));if(r&&r.range.toString()==n.toString()){this.expandFold(r);return}var u=\"...\";if(!n.isMultiLine()){u=this.getTextRange(n);if(u.length<4)return;u=u.trim().substring(0,2)+\"..\"}this.addFold(u,n)},this.getCommentFoldRange=function(e,t,n){var i=new o(this,e,t),s=i.getCurrentToken();if(s&&/^comment|string/.test(s.type)){var u=new r,a=new RegExp(s.type.replace(/\\..*/,\"\\\\.\"));if(n!=1){do s=i.stepBackward();while(s&&a.test(s.type));i.stepForward()}u.start.row=i.getCurrentTokenRow(),u.start.column=i.getCurrentTokenColumn()+2,i=new o(this,e,t);if(n!=-1){do s=i.stepForward();while(s&&a.test(s.type));s=i.stepBackward()}else s=i.getCurrentToken();return u.end.row=i.getCurrentTokenRow(),u.end.column=i.getCurrentTokenColumn()+s.value.length-2,u}},this.foldAll=function(e,t,n){n==undefined&&(n=1e5);var r=this.foldWidgets;if(!r)return;t=t||this.getLength(),e=e||0;for(var i=e;i<t;i++){r[i]==null&&(r[i]=this.getFoldWidget(i));if(r[i]!=\"start\")continue;var s=this.getFoldWidgetRange(i);if(s&&s.isMultiLine()&&s.end.row<=t&&s.start.row>=e){i=s.end.row;try{var o=this.addFold(\"...\",s);o&&(o.collapseChildren=n)}catch(u){}}}},this.$foldStyles={manual:1,markbegin:1,markbeginend:1},this.$foldStyle=\"markbegin\",this.setFoldStyle=function(e){if(!this.$foldStyles[e])throw new Error(\"invalid fold style: \"+e+\"[\"+Object.keys(this.$foldStyles).join(\", \")+\"]\");if(this.$foldStyle==e)return;this.$foldStyle=e,e==\"manual\"&&this.unfold();var t=this.$foldMode;this.$setFolding(null),this.$setFolding(t)},this.$setFolding=function(e){if(this.$foldMode==e)return;this.$foldMode=e,this.removeListener(\"change\",this.$updateFoldWidgets),this._emit(\"changeAnnotation\");if(!e||this.$foldStyle==\"manual\"){this.foldWidgets=null;return}this.foldWidgets=[],this.getFoldWidget=e.getFoldWidget.bind(e,this,this.$foldStyle),this.getFoldWidgetRange=e.getFoldWidgetRange.bind(e,this,this.$foldStyle),this.$updateFoldWidgets=this.updateFoldWidgets.bind(this),this.on(\"change\",this.$updateFoldWidgets)},this.getParentFoldRangeData=function(e,t){var n=this.foldWidgets;if(!n||t&&n[e])return{};var r=e-1,i;while(r>=0){var s=n[r];s==null&&(s=n[r]=this.getFoldWidget(r));if(s==\"start\"){var o=this.getFoldWidgetRange(r);i||(i=o);if(o&&o.end.row>=e)break}r--}return{range:r!==-1&&o,firstRange:i}},this.onFoldWidgetClick=function(e,t){t=t.domEvent;var n={children:t.shiftKey,all:t.ctrlKey||t.metaKey,siblings:t.altKey},r=this.$toggleFoldWidget(e,n);if(!r){var i=t.target||t.srcElement;i&&/ace_fold-widget/.test(i.className)&&(i.className+=\" ace_invalid\")}},this.$toggleFoldWidget=function(e,t){if(!this.getFoldWidget)return;var n=this.getFoldWidget(e),r=this.getLine(e),i=n===\"end\"?-1:1,s=this.getFoldAt(e,i===-1?0:r.length,i);if(s){t.children||t.all?this.removeFold(s):this.expandFold(s);return}var o=this.getFoldWidgetRange(e,!0);if(o&&!o.isMultiLine()){s=this.getFoldAt(o.start.row,o.start.column,1);if(s&&o.isEqual(s.range)){this.removeFold(s);return}}if(t.siblings){var u=this.getParentFoldRangeData(e);if(u.range)var a=u.range.start.row+1,f=u.range.end.row;this.foldAll(a,f,t.all?1e4:0)}else t.children?(f=o?o.end.row:this.getLength(),this.foldAll(e+1,o.end.row,t.all?1e4:0)):o&&(t.all&&(o.collapseChildren=1e4),this.addFold(\"...\",o));return o},this.toggleFoldWidget=function(e){var t=this.selection.getCursor().row;t=this.getRowFoldStart(t);var n=this.$toggleFoldWidget(t,{});if(n)return;var r=this.getParentFoldRangeData(t,!0);n=r.range||r.firstRange;if(n){t=n.start.row;var i=this.getFoldAt(t,this.getLine(t).length,1);i?this.removeFold(i):this.addFold(\"...\",n)}},this.updateFoldWidgets=function(e){var t=e.data,n=t.range,r=n.start.row,i=n.end.row-r;if(i===0)this.foldWidgets[r]=null;else if(t.action==\"removeText\"||t.action==\"removeLines\")this.foldWidgets.splice(r,i+1,null);else{var s=Array(i+1);s.unshift(r,1),this.foldWidgets.splice.apply(this.foldWidgets,s)}}}var r=e(\"../range\").Range,i=e(\"./fold_line\").FoldLine,s=e(\"./fold\").Fold,o=e(\"../token_iterator\").TokenIterator;t.Folding=u}),ace.define(\"ace/edit_session/bracket_match\",[\"require\",\"exports\",\"module\",\"ace/token_iterator\",\"ace/range\"],function(e,t,n){\"use strict\";function s(){this.findMatchingBracket=function(e,t){if(e.column==0)return null;var n=t||this.getLine(e.row).charAt(e.column-1);if(n==\"\")return null;var r=n.match(/([\\(\\[\\{])|([\\)\\]\\}])/);return r?r[1]?this.$findClosingBracket(r[1],e):this.$findOpeningBracket(r[2],e):null},this.getBracketRange=function(e){var t=this.getLine(e.row),n=!0,r,s=t.charAt(e.column-1),o=s&&s.match(/([\\(\\[\\{])|([\\)\\]\\}])/);o||(s=t.charAt(e.column),e={row:e.row,column:e.column+1},o=s&&s.match(/([\\(\\[\\{])|([\\)\\]\\}])/),n=!1);if(!o)return null;if(o[1]){var u=this.$findClosingBracket(o[1],e);if(!u)return null;r=i.fromPoints(e,u),n||(r.end.column++,r.start.column--),r.cursor=r.end}else{var u=this.$findOpeningBracket(o[2],e);if(!u)return null;r=i.fromPoints(u,e),n||(r.start.column++,r.end.column--),r.cursor=r.start}return r},this.$brackets={\")\":\"(\",\"(\":\")\",\"]\":\"[\",\"[\":\"]\",\"{\":\"}\",\"}\":\"{\"},this.$findOpeningBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp(\"(\\\\.?\"+u.type.replace(\".\",\"\\\\.\").replace(\"rparen\",\".paren\").replace(/\\b(?:end|start|begin)\\b/,\"\")+\")+\"));var a=t.column-o.getCurrentTokenColumn()-2,f=u.value;for(;;){while(a>=0){var l=f.charAt(a);if(l==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else l==e&&(s+=1);a-=1}do u=o.stepBackward();while(u&&!n.test(u.type));if(u==null)break;f=u.value,a=f.length-1}return null},this.$findClosingBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp(\"(\\\\.?\"+u.type.replace(\".\",\"\\\\.\").replace(\"lparen\",\".paren\").replace(/\\b(?:end|start|begin)\\b/,\"\")+\")+\"));var a=t.column-o.getCurrentTokenColumn();for(;;){var f=u.value,l=f.length;while(a<l){var c=f.charAt(a);if(c==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else c==e&&(s+=1);a+=1}do u=o.stepForward();while(u&&!n.test(u.type));if(u==null)break;a=0}return null}}var r=e(\"../token_iterator\").TokenIterator,i=e(\"../range\").Range;t.BracketMatch=s}),ace.define(\"ace/edit_session\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/config\",\"ace/lib/event_emitter\",\"ace/selection\",\"ace/mode/text\",\"ace/range\",\"ace/document\",\"ace/background_tokenizer\",\"ace/search_highlight\",\"ace/edit_session/folding\",\"ace/edit_session/bracket_match\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/lang\"),s=e(\"./config\"),o=e(\"./lib/event_emitter\").EventEmitter,u=e(\"./selection\").Selection,a=e(\"./mode/text\").Mode,f=e(\"./range\").Range,l=e(\"./document\").Document,c=e(\"./background_tokenizer\").BackgroundTokenizer,h=e(\"./search_highlight\").SearchHighlight,p=function(e,t){this.$breakpoints=[],this.$decorations=[],this.$frontMarkers={},this.$backMarkers={},this.$markerId=1,this.$undoSelect=!0,this.$foldData=[],this.$foldData.toString=function(){return this.join(\"\\n\")},this.on(\"changeFold\",this.onChangeFold.bind(this)),this.$onChange=this.onChange.bind(this);if(typeof e!=\"object\"||!e.getLine)e=new l(e);this.setDocument(e),this.selection=new u(this),s.resetOptions(this),this.setMode(t),s._signal(\"session\",this)};(function(){function m(e){return e<4352?!1:e>=4352&&e<=4447||e>=4515&&e<=4519||e>=4602&&e<=4607||e>=9001&&e<=9002||e>=11904&&e<=11929||e>=11931&&e<=12019||e>=12032&&e<=12245||e>=12272&&e<=12283||e>=12288&&e<=12350||e>=12353&&e<=12438||e>=12441&&e<=12543||e>=12549&&e<=12589||e>=12593&&e<=12686||e>=12688&&e<=12730||e>=12736&&e<=12771||e>=12784&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=13054||e>=13056&&e<=19903||e>=19968&&e<=42124||e>=42128&&e<=42182||e>=43360&&e<=43388||e>=44032&&e<=55203||e>=55216&&e<=55238||e>=55243&&e<=55291||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=65281&&e<=65376||e>=65504&&e<=65510}r.implement(this,o),this.setDocument=function(e){this.doc&&this.doc.removeListener(\"change\",this.$onChange),this.doc=e,e.on(\"change\",this.$onChange),this.bgTokenizer&&this.bgTokenizer.setDocument(this.getDocument()),this.resetCaches()},this.getDocument=function(){return this.doc},this.$resetRowCache=function(e){if(!e){this.$docRowCache=[],this.$screenRowCache=[];return}var t=this.$docRowCache.length,n=this.$getRowCacheIndex(this.$docRowCache,e)+1;t>n&&(this.$docRowCache.splice(n,t),this.$screenRowCache.splice(n,t))},this.$getRowCacheIndex=function(e,t){var n=0,r=e.length-1;while(n<=r){var i=n+r>>1,s=e[i];if(t>s)n=i+1;else{if(!(t<s))return i;r=i-1}}return n-1},this.resetCaches=function(){this.$modified=!0,this.$wrapData=[],this.$rowLengthCache=[],this.$resetRowCache(0),this.bgTokenizer&&this.bgTokenizer.start(0)},this.onChangeFold=function(e){var t=e.data;this.$resetRowCache(t.start.row)},this.onChange=function(e){var t=e.data;this.$modified=!0,this.$resetRowCache(t.range.start.row);var n=this.$updateInternalDataOnChange(e);!this.$fromUndo&&this.$undoManager&&!t.ignore&&(this.$deltasDoc.push(t),n&&n.length!=0&&this.$deltasFold.push({action:\"removeFolds\",folds:n}),this.$informUndoManager.schedule()),this.bgTokenizer&&this.bgTokenizer.$updateOnChange(t),this._signal(\"change\",e)},this.setValue=function(e){this.doc.setValue(e),this.selection.moveTo(0,0),this.$resetRowCache(0),this.$deltas=[],this.$deltasDoc=[],this.$deltasFold=[],this.setUndoManager(this.$undoManager),this.getUndoManager().reset()},this.getValue=this.toString=function(){return this.doc.getValue()},this.getSelection=function(){return this.selection},this.getState=function(e){return this.bgTokenizer.getState(e)},this.getTokens=function(e){return this.bgTokenizer.getTokens(e)},this.getTokenAt=function(e,t){var n=this.bgTokenizer.getTokens(e),r,i=0;if(t==null)s=n.length-1,i=this.getLine(e).length;else for(var s=0;s<n.length;s++){i+=n[s].value.length;if(i>=t)break}return r=n[s],r?(r.index=s,r.start=i-r.value.length,r):null},this.setUndoManager=function(e){this.$undoManager=e,this.$deltas=[],this.$deltasDoc=[],this.$deltasFold=[],this.$informUndoManager&&this.$informUndoManager.cancel();if(e){var t=this;this.$syncInformUndoManager=function(){t.$informUndoManager.cancel(),t.$deltasFold.length&&(t.$deltas.push({group:\"fold\",deltas:t.$deltasFold}),t.$deltasFold=[]),t.$deltasDoc.length&&(t.$deltas.push({group:\"doc\",deltas:t.$deltasDoc}),t.$deltasDoc=[]),t.$deltas.length>0&&e.execute({action:\"aceupdate\",args:[t.$deltas,t],merge:t.mergeUndoDeltas}),t.mergeUndoDeltas=!1,t.$deltas=[]},this.$informUndoManager=i.delayedCall(this.$syncInformUndoManager)}},this.markUndoGroup=function(){this.$syncInformUndoManager&&this.$syncInformUndoManager()},this.$defaultUndoManager={undo:function(){},redo:function(){},reset:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?i.stringRepeat(\" \",this.getTabSize()):\"   \"},this.setUseSoftTabs=function(e){this.setOption(\"useSoftTabs\",e)},this.getUseSoftTabs=function(){return this.$useSoftTabs&&!this.$mode.$indentWithTabs},this.setTabSize=function(e){this.setOption(\"tabSize\",e)},this.getTabSize=function(){return this.$tabSize},this.isTabStop=function(e){return this.$useSoftTabs&&e.column%this.$tabSize===0},this.$overwrite=!1,this.setOverwrite=function(e){this.setOption(\"overwrite\",e)},this.getOverwrite=function(){return this.$overwrite},this.toggleOverwrite=function(){this.setOverwrite(!this.$overwrite)},this.addGutterDecoration=function(e,t){this.$decorations[e]||(this.$decorations[e]=\"\"),this.$decorations[e]+=\" \"+t,this._signal(\"changeBreakpoint\",{})},this.removeGutterDecoration=function(e,t){this.$decorations[e]=(this.$decorations[e]||\"\").replace(\" \"+t,\"\"),this._signal(\"changeBreakpoint\",{})},this.getBreakpoints=function(){return this.$breakpoints},this.setBreakpoints=function(e){this.$breakpoints=[];for(var t=0;t<e.length;t++)this.$breakpoints[e[t]]=\"ace_breakpoint\";this._signal(\"changeBreakpoint\",{})},this.clearBreakpoints=function(){this.$breakpoints=[],this._signal(\"changeBreakpoint\",{})},this.setBreakpoint=function(e,t){t===undefined&&(t=\"ace_breakpoint\"),t?this.$breakpoints[e]=t:delete this.$breakpoints[e],this._signal(\"changeBreakpoint\",{})},this.clearBreakpoint=function(e){delete this.$breakpoints[e],this._signal(\"changeBreakpoint\",{})},this.addMarker=function(e,t,n,r){var i=this.$markerId++,s={range:e,type:n||\"line\",renderer:typeof n==\"function\"?n:null,clazz:t,inFront:!!r,id:i};return r?(this.$frontMarkers[i]=s,this._signal(\"changeFrontMarker\")):(this.$backMarkers[i]=s,this._signal(\"changeBackMarker\")),i},this.addDynamicMarker=function(e,t){if(!e.update)return;var n=this.$markerId++;return e.id=n,e.inFront=!!t,t?(this.$frontMarkers[n]=e,this._signal(\"changeFrontMarker\")):(this.$backMarkers[n]=e,this._signal(\"changeBackMarker\")),e},this.removeMarker=function(e){var t=this.$frontMarkers[e]||this.$backMarkers[e];if(!t)return;var n=t.inFront?this.$frontMarkers:this.$backMarkers;t&&(delete n[e],this._signal(t.inFront?\"changeFrontMarker\":\"changeBackMarker\"))},this.getMarkers=function(e){return e?this.$frontMarkers:this.$backMarkers},this.highlight=function(e){if(!this.$searchHighlight){var t=new h(null,\"ace_selected-word\",\"text\");this.$searchHighlight=this.addDynamicMarker(t)}this.$searchHighlight.setRegexp(e)},this.highlightLines=function(e,t,n,r){typeof t!=\"number\"&&(n=t,t=e),n||(n=\"ace_step\");var i=new f(e,0,t,Infinity);return i.id=this.addMarker(i,n,\"fullLine\",r),i},this.setAnnotations=function(e){this.$annotations=e,this._signal(\"changeAnnotation\",{})},this.getAnnotations=function(){return this.$annotations||[]},this.clearAnnotations=function(){this.setAnnotations([])},this.$detectNewLine=function(e){var t=e.match(/^.*?(\\r?\\n)/m);t?this.$autoNewLine=t[1]:this.$autoNewLine=\"\\n\"},this.getWordRange=function(e,t){var n=this.getLine(e),r=!1;t>0&&(r=!!n.charAt(t-1).match(this.tokenRe)),r||(r=!!n.charAt(t).match(this.tokenRe));if(r)var i=this.tokenRe;else if(/^\\s+$/.test(n.slice(t-1,t+1)))var i=/\\s/;else var i=this.nonTokenRe;var s=t;if(s>0){do s--;while(s>=0&&n.charAt(s).match(i));s++}var o=t;while(o<n.length&&n.charAt(o).match(i))o++;return new f(e,s,e,o)},this.getAWordRange=function(e,t){var n=this.getWordRange(e,t),r=this.getLine(n.end.row);while(r.charAt(n.end.column).match(/[ \\t]/))n.end.column+=1;return n},this.setNewLineMode=function(e){this.doc.setNewLineMode(e)},this.getNewLineMode=function(){return this.doc.getNewLineMode()},this.setUseWorker=function(e){this.setOption(\"useWorker\",e)},this.getUseWorker=function(){return this.$useWorker},this.onReloadTokenizer=function(e){var t=e.data;this.bgTokenizer.start(t.first),this._signal(\"tokenizerUpdate\",e)},this.$modes={},this.$mode=null,this.$modeId=null,this.setMode=function(e,t){if(e&&typeof e==\"object\"){if(e.getTokenizer)return this.$onChangeMode(e);var n=e,r=n.path}else r=e||\"ace/mode/text\";this.$modes[\"ace/mode/text\"]||(this.$modes[\"ace/mode/text\"]=new a);if(this.$modes[r]&&!n){this.$onChangeMode(this.$modes[r]),t&&t();return}this.$modeId=r,s.loadModule([\"mode\",r],function(e){if(this.$modeId!==r)return t&&t();if(this.$modes[r]&&!n)return this.$onChangeMode(this.$modes[r]);e&&e.Mode&&(e=new e.Mode(n),n||(this.$modes[r]=e,e.$id=r),this.$onChangeMode(e),t&&t())}.bind(this)),this.$mode||this.$onChangeMode(this.$modes[\"ace/mode/text\"],!0)},this.$onChangeMode=function(e,t){t||(this.$modeId=e.$id);if(this.$mode===e)return;this.$mode=e,this.$stopWorker(),this.$useWorker&&this.$startWorker();var n=e.getTokenizer();if(n.addEventListener!==undefined){var r=this.onReloadTokenizer.bind(this);n.addEventListener(\"update\",r)}if(!this.bgTokenizer){this.bgTokenizer=new c(n);var i=this;this.bgTokenizer.addEventListener(\"update\",function(e){i._signal(\"tokenizerUpdate\",e)})}else this.bgTokenizer.setTokenizer(n);this.bgTokenizer.setDocument(this.getDocument()),this.tokenRe=e.tokenRe,this.nonTokenRe=e.nonTokenRe,t||(e.attachToSession&&e.attachToSession(this),this.$options.wrapMethod.set.call(this,this.$wrapMethod),this.$setFolding(e.foldingRules),this.bgTokenizer.start(0),this._emit(\"changeMode\"))},this.$stopWorker=function(){this.$worker&&(this.$worker.terminate(),this.$worker=null)},this.$startWorker=function(){try{this.$worker=this.$mode.createWorker(this)}catch(e){typeof console==\"object\"&&(console.log(\"Could not load worker\"),console.log(e)),this.$worker=null}},this.getMode=function(){return this.$mode},this.$scrollTop=0,this.setScrollTop=function(e){if(this.$scrollTop===e||isNaN(e))return;this.$scrollTop=e,this._signal(\"changeScrollTop\",e)},this.getScrollTop=function(){return this.$scrollTop},this.$scrollLeft=0,this.setScrollLeft=function(e){if(this.$scrollLeft===e||isNaN(e))return;this.$scrollLeft=e,this._signal(\"changeScrollLeft\",e)},this.getScrollLeft=function(){return this.$scrollLeft},this.getScreenWidth=function(){return this.$computeWidth(),this.lineWidgets?Math.max(this.getLineWidgetMaxWidth(),this.screenWidth):this.screenWidth},this.getLineWidgetMaxWidth=function(){if(this.lineWidgetsWidth!=null)return this.lineWidgetsWidth;var e=0;return this.lineWidgets.forEach(function(t){t&&t.screenWidth>e&&(e=t.screenWidth)}),this.lineWidgetWidth=e},this.$computeWidth=function(e){if(this.$modified||e){this.$modified=!1;if(this.$useWrapMode)return this.screenWidth=this.$wrapLimit;var t=this.doc.getAllLines(),n=this.$rowLengthCache,r=0,i=0,s=this.$foldData[i],o=s?s.start.row:Infinity,u=t.length;for(var a=0;a<u;a++){if(a>o){a=s.end.row+1;if(a>=u)break;s=this.$foldData[i++],o=s?s.start.row:Infinity}n[a]==null&&(n[a]=this.$getStringScreenWidth(t[a])[0]),n[a]>r&&(r=n[a])}this.screenWidth=r}},this.getLine=function(e){return this.doc.getLine(e)},this.getLines=function(e,t){return this.doc.getLines(e,t)},this.getLength=function(){return this.doc.getLength()},this.getTextRange=function(e){return this.doc.getTextRange(e||this.selection.getRange())},this.insert=function(e,t){return this.doc.insert(e,t)},this.remove=function(e){return this.doc.remove(e)},this.undoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;var n=null;for(var r=e.length-1;r!=-1;r--){var i=e[r];i.group==\"doc\"?(this.doc.revertDeltas(i.deltas),n=this.$getUndoSelection(i.deltas,!0,n)):i.deltas.forEach(function(e){this.addFolds(e.folds)},this)}return this.$fromUndo=!1,n&&this.$undoSelect&&!t&&this.selection.setSelectionRange(n),n},this.redoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;var n=null;for(var r=0;r<e.length;r++){var i=e[r];i.group==\"doc\"&&(this.doc.applyDeltas(i.deltas),n=this.$getUndoSelection(i.deltas,!1,n))}return this.$fromUndo=!1,n&&this.$undoSelect&&!t&&this.selection.setSelectionRange(n),n},this.setUndoSelect=function(e){this.$undoSelect=e},this.$getUndoSelection=function(e,t,n){function r(e){var n=e.action===\"insertText\"||e.action===\"insertLines\";return t?!n:n}var i=e[0],s,o,u=!1;r(i)?(s=f.fromPoints(i.range.start,i.range.end),u=!0):(s=f.fromPoints(i.range.start,i.range.start),u=!1);for(var a=1;a<e.length;a++)i=e[a],r(i)?(o=i.range.start,s.compare(o.row,o.column)==-1&&s.setStart(i.range.start),o=i.range.end,s.compare(o.row,o.column)==1&&s.setEnd(i.range.end),u=!0):(o=i.range.start,s.compare(o.row,o.column)==-1&&(s=f.fromPoints(i.range.start,i.range.start)),u=!1);if(n!=null){f.comparePoints(n.start,s.start)===0&&(n.start.column+=s.end.column-s.start.column,n.end.column+=s.end.column-s.start.column);var l=n.compareRange(s);l==1?s.setStart(n.start):l==-1&&s.setEnd(n.end)}return s},this.replace=function(e,t){return this.doc.replace(e,t)},this.moveText=function(e,t,n){var r=this.getTextRange(e),i=this.getFoldsInRange(e),s=f.fromPoints(t,t);if(!n){this.remove(e);var o=e.start.row-e.end.row,u=o?-e.end.column:e.start.column-e.end.column;u&&(s.start.row==e.end.row&&s.start.column>e.end.column&&(s.start.column+=u),s.end.row==e.end.row&&s.end.column>e.end.column&&(s.end.column+=u)),o&&s.start.row>=e.end.row&&(s.start.row+=o,s.end.row+=o)}s.end=this.insert(s.start,r);if(i.length){var a=e.start,l=s.start,o=l.row-a.row,u=l.column-a.column;this.addFolds(i.map(function(e){return e=e.clone(),e.start.row==a.row&&(e.start.column+=u),e.end.row==a.row&&(e.end.column+=u),e.start.row+=o,e.end.row+=o,e}))}return s},this.indentRows=function(e,t,n){n=n.replace(/\\t/g,this.getTabString());for(var r=e;r<=t;r++)this.insert({row:r,column:0},n)},this.outdentRows=function(e){var t=e.collapseRows(),n=new f(0,0,0,0),r=this.getTabSize();for(var i=t.start.row;i<=t.end.row;++i){var s=this.getLine(i);n.start.row=i,n.end.row=i;for(var o=0;o<r;++o)if(s.charAt(o)!=\" \")break;o<r&&s.charAt(o)==\" \"?(n.start.column=o,n.end.column=o+1):(n.start.column=0,n.end.column=o),this.remove(n)}},this.$moveLines=function(e,t,n){e=this.getRowFoldStart(e),t=this.getRowFoldEnd(t);if(n<0){var r=this.getRowFoldStart(e+n);if(r<0)return 0;var i=r-e}else if(n>0){var r=this.getRowFoldEnd(t+n);if(r>this.doc.getLength()-1)return 0;var i=r-t}else{e=this.$clipRowToDocument(e),t=this.$clipRowToDocument(t);var i=t-e+1}var s=new f(e,0,t,Number.MAX_VALUE),o=this.getFoldsInRange(s).map(function(e){return e=e.clone(),e.start.row+=i,e.end.row+=i,e}),u=n==0?this.doc.getLines(e,t):this.doc.removeLines(e,t);return this.doc.insertLines(e+i,u),o.length&&this.addFolds(o),i},this.moveLinesUp=function(e,t){return this.$moveLines(e,t,-1)},this.moveLinesDown=function(e,t){return this.$moveLines(e,t,1)},this.duplicateLines=function(e,t){return this.$moveLines(e,t,0)},this.$clipRowToDocument=function(e){return Math.max(0,Math.min(e,this.doc.getLength()-1))},this.$clipColumnToRow=function(e,t){return t<0?0:Math.min(this.doc.getLine(e).length,t)},this.$clipPositionToDocument=function(e,t){t=Math.max(0,t);if(e<0)e=0,t=0;else{var n=this.doc.getLength();e>=n?(e=n-1,t=this.doc.getLine(n-1).length):t=Math.min(this.doc.getLine(e).length,t)}return{row:e,column:t}},this.$clipRangeToDocument=function(e){e.start.row<0?(e.start.row=0,e.start.column=0):e.start.column=this.$clipColumnToRow(e.start.row,e.start.column);var t=this.doc.getLength()-1;return e.end.row>t?(e.end.row=t,e.end.column=this.doc.getLine(t).length):e.end.column=this.$clipColumnToRow(e.end.row,e.end.column),e},this.$wrapLimit=80,this.$useWrapMode=!1,this.$wrapLimitRange={min:null,max:null},this.setUseWrapMode=function(e){if(e!=this.$useWrapMode){this.$useWrapMode=e,this.$modified=!0,this.$resetRowCache(0);if(e){var t=this.getLength();this.$wrapData=Array(t),this.$updateWrapData(0,t-1)}this._signal(\"changeWrapMode\")}},this.getUseWrapMode=function(){return this.$useWrapMode},this.setWrapLimitRange=function(e,t){if(this.$wrapLimitRange.min!==e||this.$wrapLimitRange.max!==t)this.$wrapLimitRange={min:e,max:t},this.$modified=!0,this._signal(\"changeWrapMode\")},this.adjustWrapLimit=function(e,t){var n=this.$wrapLimitRange;n.max<0&&(n={min:t,max:t});var r=this.$constrainWrapLimit(e,n.min,n.max);return r!=this.$wrapLimit&&r>1?(this.$wrapLimit=r,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this.$resetRowCache(0),this._signal(\"changeWrapLimit\")),!0):!1},this.$constrainWrapLimit=function(e,t,n){return t&&(e=Math.max(t,e)),n&&(e=Math.min(n,e)),e},this.getWrapLimit=function(){return this.$wrapLimit},this.setWrapLimit=function(e){this.setWrapLimitRange(e,e)},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateInternalDataOnChange=function(e){var t=this.$useWrapMode,n,r=e.data.action,i=e.data.range.start.row,s=e.data.range.end.row,o=e.data.range.start,u=e.data.range.end,a=null;r.indexOf(\"Lines\")!=-1?(r==\"insertLines\"?s=i+e.data.lines.length:s=i,n=e.data.lines?e.data.lines.length:s-i):n=s-i,this.$updating=!0;if(n!=0)if(r.indexOf(\"remove\")!=-1){this[t?\"$wrapData\":\"$rowLengthCache\"].splice(i,n);var f=this.$foldData;a=this.getFoldsInRange(e.data.range),this.removeFolds(a);var l=this.getFoldLine(u.row),c=0;if(l){l.addRemoveChars(u.row,u.column,o.column-u.column),l.shiftRow(-n);var h=this.getFoldLine(i);h&&h!==l&&(h.merge(l),l=h),c=f.indexOf(l)+1}for(c;c<f.length;c++){var l=f[c];l.start.row>=u.row&&l.shiftRow(-n)}s=i}else{var p=Array(n);p.unshift(i,0);var d=t?this.$wrapData:this.$rowLengthCache;d.splice.apply(d,p);var f=this.$foldData,l=this.getFoldLine(i),c=0;if(l){var v=l.range.compareInside(o.row,o.column);v==0?(l=l.split(o.row,o.column),l&&(l.shiftRow(n),l.addRemoveChars(s,0,u.column-o.column))):v==-1&&(l.addRemoveChars(i,0,u.column-o.column),l.shiftRow(n)),c=f.indexOf(l)+1}for(c;c<f.length;c++){var l=f[c];l.start.row>=i&&l.shiftRow(n)}}else{n=Math.abs(e.data.range.start.column-e.data.range.end.column),r.indexOf(\"remove\")!=-1&&(a=this.getFoldsInRange(e.data.range),this.removeFolds(a),n=-n);var l=this.getFoldLine(i);l&&l.addRemoveChars(i,o.column,n)}return t&&this.$wrapData.length!=this.doc.getLength()&&console.error(\"doc.getLength() and $wrapData.length have to be the same!\"),this.$updating=!1,t?this.$updateWrapData(i,s):this.$updateRowLengthCache(i,s),a},this.$updateRowLengthCache=function(e,t,n){this.$rowLengthCache[e]=null,this.$rowLengthCache[t]=null},this.$updateWrapData=function(e,t){var r=this.doc.getAllLines(),i=this.getTabSize(),s=this.$wrapData,o=this.$wrapLimit,a,f,l=e;t=Math.min(t,r.length-1);while(l<=t)f=this.getFoldLine(l,f),f?(a=[],f.walk(function(e,t,i,s){var o;if(e!=null){o=this.$getDisplayTokens(e,a.length),o[0]=n;for(var f=1;f<o.length;f++)o[f]=u}else o=this.$getDisplayTokens(r[t].substring(s,i),a.length);a=a.concat(o)}.bind(this),f.end.row,r[f.end.row].length+1),s[f.start.row]=this.$computeWrapSplits(a,o,i),l=f.end.row+1):(a=this.$getDisplayTokens(r[l]),s[l]=this.$computeWrapSplits(a,o,i),l++)};var e=1,t=2,n=3,u=4,l=9,p=10,d=11,v=12;this.$computeWrapSplits=function(e,r){function c(t){var n=e.slice(o,t),r=n.length;n.join(\"\").replace(/12/g,function(){r-=1}).replace(/2/g,function(){r-=1}),a+=r,i.push(a),o=t}if(e.length==0)return[];var i=[],s=e.length,o=0,a=0,f=this.$wrapAsCode;while(s-o>r){var h=o+r;if(e[h-1]>=p&&e[h]>=p){c(h);continue}if(e[h]==n||e[h]==u){for(h;h!=o-1;h--)if(e[h]==n)break;if(h>o){c(h);continue}h=o+r;for(h;h<e.length;h++)if(e[h]!=u)break;if(h==e.length)break;c(h);continue}var d=Math.max(h-(f?10:r-(r>>2)),o-1);while(h>d&&e[h]<n)h--;if(f){while(h>d&&e[h]<n)h--;while(h>d&&e[h]==l)h--}else while(h>d&&e[h]<p)h--;if(h>d){c(++h);continue}h=o+r,e[h]==t&&h--,c(h)}return i},this.$getDisplayTokens=function(n,r){var i=[],s;r=r||0;for(var o=0;o<n.length;o++){var u=n.charCodeAt(o);if(u==9){s=this.getScreenTabSize(i.length+r),i.push(d);for(var a=1;a<s;a++)i.push(v)}else u==32?i.push(p):u>39&&u<48||u>57&&u<64?i.push(l):u>=4352&&m(u)?i.push(e,t):i.push(e)}return i},this.$getStringScreenWidth=function(e,t,n){if(t==0)return[0,0];t==null&&(t=Infinity),n=n||0;var r,i;for(i=0;i<e.length;i++){r=e.charCodeAt(i),r==9?n+=this.getScreenTabSize(n):r>=4352&&m(r)?n+=2:n+=1;if(n>t)break}return[n,i]},this.lineWidgets=null,this.getRowLength=function(e){if(this.lineWidgets)var t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0;else t=0;return!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.getRowLineCount=function(e){return!this.$useWrapMode||!this.$wrapData[e]?1:this.$wrapData[e].length+1},this.getScreenLastRowColumn=function(e){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE);return this.documentToScreenColumn(t.row,t.column)},this.getDocumentLastRowColumn=function(e,t){var n=this.documentToScreenRow(e,t);return this.getScreenLastRowColumn(n)},this.getDocumentLastRowColumnPosition=function(e,t){var n=this.documentToScreenRow(e,t);return this.screenToDocumentPosition(n,Number.MAX_VALUE/10)},this.getRowSplitData=function(e){return this.$useWrapMode?this.$wrapData[e]:undefined},this.getScreenTabSize=function(e){return this.$tabSize-e%this.$tabSize},this.screenToDocumentRow=function(e,t){return this.screenToDocumentPosition(e,t).row},this.screenToDocumentColumn=function(e,t){return this.screenToDocumentPosition(e,t).column},this.screenToDocumentPosition=function(e,t){if(e<0)return{row:0,column:0};var n,r=0,i=0,s,o=0,u=0,a=this.$screenRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var o=a[f],r=this.$docRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getLength()-1,p=this.getNextFoldLine(r),d=p?p.start.row:Infinity;while(o<=e){u=this.getRowLength(r);if(o+u>e||r>=h)break;o+=u,r++,r>d&&(r=p.end.row+1,p=this.getNextFoldLine(r,p),d=p?p.start.row:Infinity),c&&(this.$docRowCache.push(r),this.$screenRowCache.push(o))}if(p&&p.start.row<=r)n=this.getFoldDisplayLine(p),r=p.start.row;else{if(o+u<=e||r>h)return{row:h,column:this.getLine(h).length};n=this.getLine(r),p=null}if(this.$useWrapMode){var v=this.$wrapData[r];if(v){var m=Math.floor(e-o);s=v[m],m>0&&v.length&&(i=v[m-1]||v[v.length-1],n=n.substring(i))}}return i+=this.$getStringScreenWidth(n,t)[1],this.$useWrapMode&&i>=s&&(i=s-1),p?p.idxToPosition(i):{row:r,column:i}},this.documentToScreenPosition=function(e,t){if(typeof t==\"undefined\")var n=this.$clipPositionToDocument(e.row,e.column);else n=this.$clipPositionToDocument(e,t);e=n.row,t=n.column;var r=0,i=null,s=null;s=this.getFoldAt(e,t,1),s&&(e=s.start.row,t=s.start.column);var o,u=0,a=this.$docRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var u=a[f],r=this.$screenRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getNextFoldLine(u),p=h?h.start.row:Infinity;while(u<e){if(u>=p){o=h.end.row+1;if(o>e)break;h=this.getNextFoldLine(o,h),p=h?h.start.row:Infinity}else o=u+1;r+=this.getRowLength(u),u=o,c&&(this.$docRowCache.push(u),this.$screenRowCache.push(r))}var d=\"\";h&&u>=p?(d=this.getFoldDisplayLine(h,e,t),i=h.start.row):(d=this.getLine(e).substring(0,t),i=e);if(this.$useWrapMode){var v=this.$wrapData[i];if(v){var m=0;while(d.length>=v[m])r++,m++;d=d.substring(v[m-1]||0,d.length)}}return{row:r,column:this.$getStringScreenWidth(d)[0]}},this.documentToScreenColumn=function(e,t){return this.documentToScreenPosition(e,t).column},this.documentToScreenRow=function(e,t){return this.documentToScreenPosition(e,t).row},this.getScreenLength=function(){var e=0,t=null;if(!this.$useWrapMode){e=this.getLength();var n=this.$foldData;for(var r=0;r<n.length;r++)t=n[r],e-=t.end.row-t.start.row}else{var i=this.$wrapData.length,s=0,r=0,t=this.$foldData[r++],o=t?t.start.row:Infinity;while(s<i){var u=this.$wrapData[s];e+=u?u.length+1:1,s++,s>o&&(s=t.end.row+1,t=this.$foldData[r++],o=t?t.start.row:Infinity)}}return this.lineWidgets&&(e+=this.$getWidgetScreenLength()),e},this.$setFontMetrics=function(e){},this.destroy=function(){this.bgTokenizer&&(this.bgTokenizer.setDocument(null),this.bgTokenizer=null),this.$stopWorker()}}).call(p.prototype),e(\"./edit_session/folding\").Folding.call(p.prototype),e(\"./edit_session/bracket_match\").BracketMatch.call(p.prototype),s.defineOptions(p.prototype,\"session\",{wrap:{set:function(e){!e||e==\"off\"?e=!1:e==\"free\"?e=!0:e==\"printMargin\"?e=-1:typeof e==\"string\"&&(e=parseInt(e,10)||!1);if(this.$wrap==e)return;if(!e)this.setUseWrapMode(!1);else{var t=typeof e==\"number\"?e:null;this.setWrapLimitRange(t,t),this.setUseWrapMode(!0)}this.$wrap=e},get:function(){return this.getUseWrapMode()?this.$wrap==-1?\"printMargin\":this.getWrapLimitRange().min?this.$wrap:\"free\":\"off\"},handlesSet:!0},wrapMethod:{set:function(e){e=e==\"auto\"?this.$mode.type!=\"text\":e!=\"text\",e!=this.$wrapAsCode&&(this.$wrapAsCode=e,this.$useWrapMode&&(this.$modified=!0,this.$resetRowCache(0),this.$updateWrapData(0,this.getLength()-1)))},initialValue:\"auto\"},firstLineNumber:{set:function(){this._signal(\"changeBreakpoint\")},initialValue:1},useWorker:{set:function(e){this.$useWorker=e,this.$stopWorker(),e&&this.$startWorker()},initialValue:!0},useSoftTabs:{initialValue:!0},tabSize:{set:function(e){if(isNaN(e)||this.$tabSize===e)return;this.$modified=!0,this.$rowLengthCache=[],this.$tabSize=e,this._signal(\"changeTabSize\")},initialValue:4,handlesSet:!0},overwrite:{set:function(e){this._signal(\"changeOverwrite\")},initialValue:!1},newLineMode:{set:function(e){this.doc.setNewLineMode(e)},get:function(){return this.doc.getNewLineMode()},handlesSet:!0},mode:{set:function(e){this.setMode(e)},get:function(){return this.$modeId}}}),t.EditSession=p}),ace.define(\"ace/search\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/lib/oop\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"./lib/lang\"),i=e(\"./lib/oop\"),s=e(\"./range\").Range,o=function(){this.$options={}};(function(){this.set=function(e){return i.mixin(this.$options,e),this},this.getOptions=function(){return r.copyObject(this.$options)},this.setOptions=function(e){this.$options=e},this.find=function(e){var t=this.$matchIterator(e,this.$options);if(!t)return!1;var n=null;return t.forEach(function(e,t,r){if(!e.start){var i=e.offset+(r||0);n=new s(t,i,t,i+e.length)}else n=e;return!0}),n},this.findAll=function(e){var t=this.$options;if(!t.needle)return[];this.$assembleRegExp(t);var n=t.range,i=n?e.getLines(n.start.row,n.end.row):e.doc.getAllLines(),o=[],u=t.re;if(t.$isMultiLine){var a=u.length,f=i.length-a,l;e:for(var c=u.offset||0;c<=f;c++){for(var h=0;h<a;h++)if(i[c+h].search(u[h])==-1)continue e;var p=i[c],d=i[c+a-1],v=p.length-p.match(u[0])[0].length,m=d.match(u[a-1])[0].length;if(l&&l.end.row===c&&l.end.column>v)continue;o.push(l=new s(c,v,c+a-1,m)),a>2&&(c=c+a-2)}}else for(var g=0;g<i.length;g++){var y=r.getMatchOffsets(i[g],u);for(var h=0;h<y.length;h++){var b=y[h];o.push(new s(g,b.offset,g,b.offset+b.length))}}if(n){var w=n.start.column,E=n.start.column,g=0,h=o.length-1;while(g<h&&o[g].start.column<w&&o[g].start.row==n.start.row)g++;while(g<h&&o[h].end.column>E&&o[h].end.row==n.end.row)h--;o=o.slice(g,h+1);for(g=0,h=o.length;g<h;g++)o[g].start.row+=n.start.row,o[g].end.row+=n.start.row}return o},this.replace=function(e,t){var n=this.$options,r=this.$assembleRegExp(n);if(n.$isMultiLine)return t;if(!r)return;var i=r.exec(e);if(!i||i[0].length!=e.length)return null;t=e.replace(r,t);if(n.preserveCase){t=t.split(\"\");for(var s=Math.min(e.length,e.length);s--;){var o=e[s];o&&o.toLowerCase()!=o?t[s]=t[s].toUpperCase():t[s]=t[s].toLowerCase()}t=t.join(\"\")}return t},this.$matchIterator=function(e,t){var n=this.$assembleRegExp(t);if(!n)return!1;var i=this,o,u=t.backwards;if(t.$isMultiLine)var a=n.length,f=function(t,r,i){var u=t.search(n[0]);if(u==-1)return;for(var f=1;f<a;f++){t=e.getLine(r+f);if(t.search(n[f])==-1)return}var l=t.match(n[a-1])[0].length,c=new s(r,u,r+a-1,l);n.offset==1?(c.start.row--,c.start.column=Number.MAX_VALUE):i&&(c.start.column+=i);if(o(c))return!0};else if(u)var f=function(e,t,i){var s=r.getMatchOffsets(e,n);for(var u=s.length-1;u>=0;u--)if(o(s[u],t,i))return!0};else var f=function(e,t,i){var s=r.getMatchOffsets(e,n);for(var u=0;u<s.length;u++)if(o(s[u],t,i))return!0};return{forEach:function(n){o=n,i.$lineIterator(e,t).forEach(f)}}},this.$assembleRegExp=function(e,t){if(e.needle instanceof RegExp)return e.re=e.needle;var n=e.needle;if(!e.needle)return e.re=!1;e.regExp||(n=r.escapeRegExp(n)),e.wholeWord&&(n=\"\\\\b\"+n+\"\\\\b\");var i=e.caseSensitive?\"gm\":\"gmi\";e.$isMultiLine=!t&&/[\\n\\r]/.test(n);if(e.$isMultiLine)return e.re=this.$assembleMultilineRegExp(n,i);try{var s=new RegExp(n,i)}catch(o){s=!1}return e.re=s},this.$assembleMultilineRegExp=function(e,t){var n=e.replace(/\\r\\n|\\r|\\n/g,\"$\\n^\").split(\"\\n\"),r=[];for(var i=0;i<n.length;i++)try{r.push(new RegExp(n[i],t))}catch(s){return!1}return n[0]==\"\"?(r.shift(),r.offset=1):r.offset=0,r},this.$lineIterator=function(e,t){var n=t.backwards==1,r=t.skipCurrent!=0,i=t.range,s=t.start;s||(s=i?i[n?\"end\":\"start\"]:e.selection.getRange()),s.start&&(s=s[r!=n?\"end\":\"start\"]);var o=i?i.start.row:0,u=i?i.end.row:e.getLength()-1,a=n?function(n){var r=s.row,i=e.getLine(r).substring(0,s.column);if(n(i,r))return;for(r--;r>=o;r--)if(n(e.getLine(r),r))return;if(t.wrap==0)return;for(r=u,o=s.row;r>=o;r--)if(n(e.getLine(r),r))return}:function(n){var r=s.row,i=e.getLine(r).substr(s.column);if(n(i,r,s.column))return;for(r+=1;r<=u;r++)if(n(e.getLine(r),r))return;if(t.wrap==0)return;for(r=o,u=s.row;r<=u;r++)if(n(e.getLine(r),r))return};return{forEach:a}}}).call(o.prototype),t.Search=o}),ace.define(\"ace/keyboard/hash_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/keys\",\"ace/lib/useragent\"],function(e,t,n){\"use strict\";function o(e,t){this.platform=t||(i.isMac?\"mac\":\"win\"),this.commands={},this.commandKeyBinding={},this.addCommands(e),this.$singleCommand=!0}function u(e,t){o.call(this,e,t),this.$singleCommand=!1}var r=e(\"../lib/keys\"),i=e(\"../lib/useragent\"),s=r.KEY_MODS;u.prototype=o.prototype,function(){this.addCommand=function(e){this.commands[e.name]&&this.removeCommand(e),this.commands[e.name]=e,e.bindKey&&this._buildKeyHash(e)},this.removeCommand=function(e,t){var n=e&&(typeof e==\"string\"?e:e.name);e=this.commands[n],t||delete this.commands[n];var r=this.commandKeyBinding;for(var i in r){var s=r[i];if(s==e)delete r[i];else if(Array.isArray(s)){var o=s.indexOf(e);o!=-1&&(s.splice(o,1),s.length==1&&(r[i]=s[0]))}}},this.bindKey=function(e,t,n){typeof e==\"object\"&&(e=e[this.platform]);if(!e)return;if(typeof t==\"function\")return this.addCommand({exec:t,bindKey:e,name:t.name||e});e.split(\"|\").forEach(function(e){var r=\"\";if(e.indexOf(\" \")!=-1){var i=e.split(/\\s+/);e=i.pop(),i.forEach(function(e){var t=this.parseKeys(e),n=s[t.hashId]+t.key;r+=(r?\" \":\"\")+n,this._addCommandToBinding(r,\"chainKeys\")},this),r+=\" \"}var o=this.parseKeys(e),u=s[o.hashId]+o.key;this._addCommandToBinding(r+u,t,n)},this)},this._addCommandToBinding=function(e,t,n){var r=this.commandKeyBinding,i;t?!r[e]||this.$singleCommand?r[e]=t:(Array.isArray(r[e])?(i=r[e].indexOf(t))!=-1&&r[e].splice(i,1):r[e]=[r[e]],n||t.isDefault?r[e].unshift(t):r[e].push(t)):delete r[e]},this.addCommands=function(e){e&&Object.keys(e).forEach(function(t){var n=e[t];if(!n)return;if(typeof n==\"string\")return this.bindKey(n,t);typeof n==\"function\"&&(n={exec:n});if(typeof n!=\"object\")return;n.name||(n.name=t),this.addCommand(n)},this)},this.removeCommands=function(e){Object.keys(e).forEach(function(t){this.removeCommand(e[t])},this)},this.bindKeys=function(e){Object.keys(e).forEach(function(t){this.bindKey(t,e[t])},this)},this._buildKeyHash=function(e){this.bindKey(e.bindKey,e)},this.parseKeys=function(e){var t=e.toLowerCase().split(/[\\-\\+]([\\-\\+])?/).filter(function(e){return e}),n=t.pop(),i=r[n];if(r.FUNCTION_KEYS[i])n=r.FUNCTION_KEYS[i].toLowerCase();else{if(!t.length)return{key:n,hashId:-1};if(t.length==1&&t[0]==\"shift\")return{key:n.toUpperCase(),hashId:-1}}var s=0;for(var o=t.length;o--;){var u=r.KEY_MODS[t[o]];if(u==null)return typeof console!=\"undefined\"&&console.error(\"invalid modifier \"+t[o]+\" in \"+e),!1;s|=u}return{key:n,hashId:s}},this.findKeyCommand=function(t,n){var r=s[t]+n;return this.commandKeyBinding[r]},this.handleKeyboard=function(e,t,n,r){var i=s[t]+n,o=this.commandKeyBinding[i];e.$keyChain&&(e.$keyChain+=\" \"+i,o=this.commandKeyBinding[e.$keyChain]||o);if(o)if(o==\"chainKeys\"||o[o.length-1]==\"chainKeys\")return e.$keyChain=e.$keyChain||i,{command:\"null\"};return e.$keyChain&&r>0&&(e.$keyChain=\"\"),{command:o}}}.call(o.prototype),t.HashHandler=o,t.MultiHashHandler=u}),ace.define(\"ace/commands/command_manager\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/keyboard/hash_handler\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"../keyboard/hash_handler\").MultiHashHandler,s=e(\"../lib/event_emitter\").EventEmitter,o=function(e,t){i.call(this,t,e),this.byName=this.commands,this.setDefaultHandler(\"exec\",function(e){return e.command.exec(e.editor,e.args||{})})};r.inherits(o,i),function(){r.implement(this,s),this.exec=function(e,t,n){if(Array.isArray(e)){for(var r=e.length;r--;)if(this.exec(e[r],t,n))return!0;return!1}typeof e==\"string\"&&(e=this.commands[e]);if(!e)return!1;if(t&&t.$readOnly&&!e.readOnly)return!1;var i={editor:t,command:e,args:n};return i.returnValue=this._emit(\"exec\",i),this._signal(\"afterExec\",i),i.returnValue===!1?!1:!0},this.toggleRecording=function(e){if(this.$inReplay)return;return e&&e._emit(\"changeStatus\"),this.recording?(this.macro.pop(),this.removeEventListener(\"exec\",this.$addCommandToMacro),this.macro.length||(this.macro=this.oldMacro),this.recording=!1):(this.$addCommandToMacro||(this.$addCommandToMacro=function(e){this.macro.push([e.command,e.args])}.bind(this)),this.oldMacro=this.macro,this.macro=[],this.on(\"exec\",this.$addCommandToMacro),this.recording=!0)},this.replay=function(e){if(this.$inReplay||!this.macro)return;if(this.recording)return this.toggleRecording(e);try{this.$inReplay=!0,this.macro.forEach(function(t){typeof t==\"string\"?this.exec(t,e):this.exec(t[0],e,t[1])},this)}finally{this.$inReplay=!1}},this.trimMacro=function(e){return e.map(function(e){return typeof e[0]!=\"string\"&&(e[0]=e[0].name),e[1]||(e=e[0]),e})}}.call(o.prototype),t.CommandManager=o}),ace.define(\"ace/commands/default_commands\",[\"require\",\"exports\",\"module\",\"ace/lib/lang\",\"ace/config\",\"ace/range\"],function(e,t,n){\"use strict\";function o(e,t){return{win:e,mac:t}}var r=e(\"../lib/lang\"),i=e(\"../config\"),s=e(\"../range\").Range;t.commands=[{name:\"showSettingsMenu\",bindKey:o(\"Ctrl-,\",\"Command-,\"),exec:function(e){i.loadModule(\"ace/ext/settings_menu\",function(t){t.init(e),e.showSettingsMenu()})},readOnly:!0},{name:\"goToNextError\",bindKey:o(\"Alt-E\",\"Ctrl-E\"),exec:function(e){i.loadModule(\"ace/ext/error_marker\",function(t){t.showErrorMarker(e,1)})},scrollIntoView:\"animate\",readOnly:!0},{name:\"goToPreviousError\",bindKey:o(\"Alt-Shift-E\",\"Ctrl-Shift-E\"),exec:function(e){i.loadModule(\"ace/ext/error_marker\",function(t){t.showErrorMarker(e,-1)})},scrollIntoView:\"animate\",readOnly:!0},{name:\"selectall\",bindKey:o(\"Ctrl-A\",\"Command-A\"),exec:function(e){e.selectAll()},readOnly:!0},{name:\"centerselection\",bindKey:o(null,\"Ctrl-L\"),exec:function(e){e.centerSelection()},readOnly:!0},{name:\"gotoline\",bindKey:o(\"Ctrl-L\",\"Command-L\"),exec:function(e){var t=parseInt(prompt(\"Enter line number:\"),10);isNaN(t)||e.gotoLine(t)},readOnly:!0},{name:\"fold\",bindKey:o(\"Alt-L|Ctrl-F1\",\"Command-Alt-L|Command-F1\"),exec:function(e){e.session.toggleFold(!1)},scrollIntoView:\"center\",readOnly:!0},{name:\"unfold\",bindKey:o(\"Alt-Shift-L|Ctrl-Shift-F1\",\"Command-Alt-Shift-L|Command-Shift-F1\"),exec:function(e){e.session.toggleFold(!0)},scrollIntoView:\"center\",readOnly:!0},{name:\"toggleFoldWidget\",bindKey:o(\"F2\",\"F2\"),exec:function(e){e.session.toggleFoldWidget()},scrollIntoView:\"center\",readOnly:!0},{name:\"toggleParentFoldWidget\",bindKey:o(\"Alt-F2\",\"Alt-F2\"),exec:function(e){e.session.toggleFoldWidget(!0)},scrollIntoView:\"center\",readOnly:!0},{name:\"foldall\",bindKey:o(\"Ctrl-Alt-0\",\"Ctrl-Command-Option-0\"),exec:function(e){e.session.foldAll()},scrollIntoView:\"center\",readOnly:!0},{name:\"foldOther\",bindKey:o(\"Alt-0\",\"Command-Option-0\"),exec:function(e){e.session.foldAll(),e.session.unfold(e.selection.getAllRanges())},scrollIntoView:\"center\",readOnly:!0},{name:\"unfoldall\",bindKey:o(\"Alt-Shift-0\",\"Command-Option-Shift-0\"),exec:function(e){e.session.unfold()},scrollIntoView:\"center\",readOnly:!0},{name:\"findnext\",bindKey:o(\"Ctrl-K\",\"Command-G\"),exec:function(e){e.findNext()},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"findprevious\",bindKey:o(\"Ctrl-Shift-K\",\"Command-Shift-G\"),exec:function(e){e.findPrevious()},multiSelectAction:\"forEach\",scrollIntoView:\"center\",readOnly:!0},{name:\"selectOrFindNext\",bindKey:o(\"Alt-K\",\"Ctrl-G\"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findNext()},readOnly:!0},{name:\"selectOrFindPrevious\",bindKey:o(\"Alt-Shift-K\",\"Ctrl-Shift-G\"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findPrevious()},readOnly:!0},{name:\"find\",bindKey:o(\"Ctrl-F\",\"Command-F\"),exec:function(e){i.loadModule(\"ace/ext/searchbox\",function(t){t.Search(e)})},readOnly:!0},{name:\"overwrite\",bindKey:\"Insert\",exec:function(e){e.toggleOverwrite()},readOnly:!0},{name:\"selecttostart\",bindKey:o(\"Ctrl-Shift-Home\",\"Command-Shift-Up\"),exec:function(e){e.getSelection().selectFileStart()},multiSelectAction:\"forEach\",readOnly:!0,scrollIntoView:\"animate\",aceCommandGroup:\"fileJump\"},{name:\"gotostart\",bindKey:o(\"Ctrl-Home\",\"Command-Home|Command-Up\"),exec:function(e){e.navigateFileStart()},multiSelectAction:\"forEach\",readOnly:!0,scrollIntoView:\"animate\",aceCommandGroup:\"fileJump\"},{name:\"selectup\",bindKey:o(\"Shift-Up\",\"Shift-Up\"),exec:function(e){e.getSelection().selectUp()},multiSelectAction:\"forEach\",readOnly:!0},{name:\"golineup\",bindKey:o(\"Up\",\"Up|Ctrl-P\"),exec:function(e,t){e.navigateUp(t.times)},multiSelectAction:\"forEach\",readOnly:!0},{name:\"selecttoend\",bindKey:o(\"Ctrl-Shift-End\",\"Command-Shift-Down\"),exec:function(e){e.getSelection().selectFileEnd()},multiSelectAction:\"forEach\",readOnly:!0,scrollIntoView:\"animate\",aceCommandGroup:\"fileJump\"},{name:\"gotoend\",bindKey:o(\"Ctrl-End\",\"Command-End|Command-Down\"),exec:function(e){e.navigateFileEnd()},multiSelectAction:\"forEach\",readOnly:!0,scrollIntoView:\"animate\",aceCommandGroup:\"fileJump\"},{name:\"selectdown\",bindKey:o(\"Shift-Down\",\"Shift-Down\"),exec:function(e){e.getSelection().selectDown()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"golinedown\",bindKey:o(\"Down\",\"Down|Ctrl-N\"),exec:function(e,t){e.navigateDown(t.times)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectwordleft\",bindKey:o(\"Ctrl-Shift-Left\",\"Option-Shift-Left\"),exec:function(e){e.getSelection().selectWordLeft()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotowordleft\",bindKey:o(\"Ctrl-Left\",\"Option-Left\"),exec:function(e){e.navigateWordLeft()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selecttolinestart\",bindKey:o(\"Alt-Shift-Left\",\"Command-Shift-Left\"),exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotolinestart\",bindKey:o(\"Alt-Left|Home\",\"Command-Left|Home|Ctrl-A\"),exec:function(e){e.navigateLineStart()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectleft\",bindKey:o(\"Shift-Left\",\"Shift-Left\"),exec:function(e){e.getSelection().selectLeft()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotoleft\",bindKey:o(\"Left\",\"Left|Ctrl-B\"),exec:function(e,t){e.navigateLeft(t.times)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectwordright\",bindKey:o(\"Ctrl-Shift-Right\",\"Option-Shift-Right\"),exec:function(e){e.getSelection().selectWordRight()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotowordright\",bindKey:o(\"Ctrl-Right\",\"Option-Right\"),exec:function(e){e.navigateWordRight()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selecttolineend\",bindKey:o(\"Alt-Shift-Right\",\"Command-Shift-Right\"),exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotolineend\",bindKey:o(\"Alt-Right|End\",\"Command-Right|End|Ctrl-E\"),exec:function(e){e.navigateLineEnd()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectright\",bindKey:o(\"Shift-Right\",\"Shift-Right\"),exec:function(e){e.getSelection().selectRight()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"gotoright\",bindKey:o(\"Right\",\"Right|Ctrl-F\"),exec:function(e,t){e.navigateRight(t.times)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectpagedown\",bindKey:\"Shift-PageDown\",exec:function(e){e.selectPageDown()},readOnly:!0},{name:\"pagedown\",bindKey:o(null,\"Option-PageDown\"),exec:function(e){e.scrollPageDown()},readOnly:!0},{name:\"gotopagedown\",bindKey:o(\"PageDown\",\"PageDown|Ctrl-V\"),exec:function(e){e.gotoPageDown()},readOnly:!0},{name:\"selectpageup\",bindKey:\"Shift-PageUp\",exec:function(e){e.selectPageUp()},readOnly:!0},{name:\"pageup\",bindKey:o(null,\"Option-PageUp\"),exec:function(e){e.scrollPageUp()},readOnly:!0},{name:\"gotopageup\",bindKey:\"PageUp\",exec:function(e){e.gotoPageUp()},readOnly:!0},{name:\"scrollup\",bindKey:o(\"Ctrl-Up\",null),exec:function(e){e.renderer.scrollBy(0,-2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:\"scrolldown\",bindKey:o(\"Ctrl-Down\",null),exec:function(e){e.renderer.scrollBy(0,2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:\"selectlinestart\",bindKey:\"Shift-Home\",exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"selectlineend\",bindKey:\"Shift-End\",exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"togglerecording\",bindKey:o(\"Ctrl-Alt-E\",\"Command-Option-E\"),exec:function(e){e.commands.toggleRecording(e)},readOnly:!0},{name:\"replaymacro\",bindKey:o(\"Ctrl-Shift-E\",\"Command-Shift-E\"),exec:function(e){e.commands.replay(e)},readOnly:!0},{name:\"jumptomatching\",bindKey:o(\"Ctrl-P\",\"Ctrl-P\"),exec:function(e){e.jumpToMatching()},multiSelectAction:\"forEach\",readOnly:!0},{name:\"selecttomatching\",bindKey:o(\"Ctrl-Shift-P\",\"Ctrl-Shift-P\"),exec:function(e){e.jumpToMatching(!0)},multiSelectAction:\"forEach\",readOnly:!0},{name:\"passKeysToBrowser\",bindKey:o(\"null\",\"null\"),exec:function(){},passEvent:!0,readOnly:!0},{name:\"cut\",exec:function(e){var t=e.getSelectionRange();e._emit(\"cut\",t),e.selection.isEmpty()||(e.session.remove(t),e.clearSelection())},scrollIntoView:\"cursor\",multiSelectAction:\"forEach\"},{name:\"removeline\",bindKey:o(\"Ctrl-D\",\"Command-D\"),exec:function(e){e.removeLines()},scrollIntoView:\"cursor\",multiSelectAction:\"forEachLine\"},{name:\"duplicateSelection\",bindKey:o(\"Ctrl-Shift-D\",\"Command-Shift-D\"),exec:function(e){e.duplicateSelection()},scrollIntoView:\"cursor\",multiSelectAction:\"forEach\"},{name:\"sortlines\",bindKey:o(\"Ctrl-Alt-S\",\"Command-Alt-S\"),exec:function(e){e.sortLines()},scrollIntoView:\"selection\",multiSelectAction:\"forEachLine\"},{name:\"togglecomment\",bindKey:o(\"Ctrl-/\",\"Command-/\"),exec:function(e){e.toggleCommentLines()},multiSelectAction:\"forEachLine\",scrollIntoView:\"selectionPart\"},{name:\"toggleBlockComment\",bindKey:o(\"Ctrl-Shift-/\",\"Command-Shift-/\"),exec:function(e){e.toggleBlockComment()},multiSelectAction:\"forEach\",scrollIntoView:\"selectionPart\"},{name:\"modifyNumberUp\",bindKey:o(\"Ctrl-Shift-Up\",\"Alt-Shift-Up\"),exec:function(e){e.modifyNumber(1)},multiSelectAction:\"forEach\"},{name:\"modifyNumberDown\",bindKey:o(\"Ctrl-Shift-Down\",\"Alt-Shift-Down\"),exec:function(e){e.modifyNumber(-1)},multiSelectAction:\"forEach\"},{name:\"replace\",bindKey:o(\"Ctrl-H\",\"Command-Option-F\"),exec:function(e){i.loadModule(\"ace/ext/searchbox\",function(t){t.Search(e,!0)})}},{name:\"undo\",bindKey:o(\"Ctrl-Z\",\"Command-Z\"),exec:function(e){e.undo()}},{name:\"redo\",bindKey:o(\"Ctrl-Shift-Z|Ctrl-Y\",\"Command-Shift-Z|Command-Y\"),exec:function(e){e.redo()}},{name:\"copylinesup\",bindKey:o(\"Alt-Shift-Up\",\"Command-Option-Up\"),exec:function(e){e.copyLinesUp()},scrollIntoView:\"cursor\"},{name:\"movelinesup\",bindKey:o(\"Alt-Up\",\"Option-Up\"),exec:function(e){e.moveLinesUp()},scrollIntoView:\"cursor\"},{name:\"copylinesdown\",bindKey:o(\"Alt-Shift-Down\",\"Command-Option-Down\"),exec:function(e){e.copyLinesDown()},scrollIntoView:\"cursor\"},{name:\"movelinesdown\",bindKey:o(\"Alt-Down\",\"Option-Down\"),exec:function(e){e.moveLinesDown()},scrollIntoView:\"cursor\"},{name:\"del\",bindKey:o(\"Delete\",\"Delete|Ctrl-D|Shift-Delete\"),exec:function(e){e.remove(\"right\")},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"backspace\",bindKey:o(\"Shift-Backspace|Backspace\",\"Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H\"),exec:function(e){e.remove(\"left\")},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"cut_or_delete\",bindKey:o(\"Shift-Delete\",null),exec:function(e){if(!e.selection.isEmpty())return!1;e.remove(\"left\")},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removetolinestart\",bindKey:o(\"Alt-Backspace\",\"Command-Backspace\"),exec:function(e){e.removeToLineStart()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removetolineend\",bindKey:o(\"Alt-Delete\",\"Ctrl-K\"),exec:function(e){e.removeToLineEnd()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removewordleft\",bindKey:o(\"Ctrl-Backspace\",\"Alt-Backspace|Ctrl-Alt-Backspace\"),exec:function(e){e.removeWordLeft()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"removewordright\",bindKey:o(\"Ctrl-Delete\",\"Alt-Delete\"),exec:function(e){e.removeWordRight()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"outdent\",bindKey:o(\"Shift-Tab\",\"Shift-Tab\"),exec:function(e){e.blockOutdent()},multiSelectAction:\"forEach\",scrollIntoView:\"selectionPart\"},{name:\"indent\",bindKey:o(\"Tab\",\"Tab\"),exec:function(e){e.indent()},multiSelectAction:\"forEach\",scrollIntoView:\"selectionPart\"},{name:\"blockoutdent\",bindKey:o(\"Ctrl-[\",\"Ctrl-[\"),exec:function(e){e.blockOutdent()},multiSelectAction:\"forEachLine\",scrollIntoView:\"selectionPart\"},{name:\"blockindent\",bindKey:o(\"Ctrl-]\",\"Ctrl-]\"),exec:function(e){e.blockIndent()},multiSelectAction:\"forEachLine\",scrollIntoView:\"selectionPart\"},{name:\"insertstring\",exec:function(e,t){e.insert(t)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"inserttext\",exec:function(e,t){e.insert(r.stringRepeat(t.text||\"\",t.times||1))},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"splitline\",bindKey:o(null,\"Ctrl-O\"),exec:function(e){e.splitLine()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"transposeletters\",bindKey:o(\"Ctrl-T\",\"Ctrl-T\"),exec:function(e){e.transposeLetters()},multiSelectAction:function(e){e.transposeSelections(1)},scrollIntoView:\"cursor\"},{name:\"touppercase\",bindKey:o(\"Ctrl-U\",\"Ctrl-U\"),exec:function(e){e.toUpperCase()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"tolowercase\",bindKey:o(\"Ctrl-Shift-U\",\"Ctrl-Shift-U\"),exec:function(e){e.toLowerCase()},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\"},{name:\"expandtoline\",bindKey:o(\"Ctrl-Shift-L\",\"Command-Shift-L\"),exec:function(e){var t=e.selection.getRange();t.start.column=t.end.column=0,t.end.row++,e.selection.setRange(t,!1)},multiSelectAction:\"forEach\",scrollIntoView:\"cursor\",readOnly:!0},{name:\"joinlines\",bindKey:o(null,null),exec:function(e){var t=e.selection.isBackwards(),n=t?e.selection.getSelectionLead():e.selection.getSelectionAnchor(),i=t?e.selection.getSelectionAnchor():e.selection.getSelectionLead(),o=e.session.doc.getLine(n.row).length,u=e.session.doc.getTextRange(e.selection.getRange()),a=u.replace(/\\n\\s*/,\" \").length,f=e.session.doc.getLine(n.row);for(var l=n.row+1;l<=i.row+1;l++){var c=r.stringTrimLeft(r.stringTrimRight(e.session.doc.getLine(l)));c.length!==0&&(c=\" \"+c),f+=c}i.row+1<e.session.doc.getLength()-1&&(f+=e.session.doc.getNewLineCharacter()),e.clearSelection(),e.session.doc.replace(new s(n.row,0,i.row+2,0),f),a>0?(e.selection.moveCursorTo(n.row,n.column),e.selection.selectTo(n.row,n.column+a)):(o=e.session.doc.getLine(n.row).length>o?o+1:o,e.selection.moveCursorTo(n.row,o))},multiSelectAction:\"forEach\",readOnly:!0},{name:\"invertSelection\",bindKey:o(null,null),exec:function(e){var t=e.session.doc.getLength()-1,n=e.session.doc.getLine(t).length,r=e.selection.rangeList.ranges,i=[];r.length<1&&(r=[e.selection.getRange()]);for(var o=0;o<r.length;o++)o==r.length-1&&(r[o].end.row!==t||r[o].end.column!==n)&&i.push(new s(r[o].end.row,r[o].end.column,t,n)),o===0?(r[o].start.row!==0||r[o].start.column!==0)&&i.push(new s(0,0,r[o].start.row,r[o].start.column)):i.push(new s(r[o-1].end.row,r[o-1].end.column,r[o].start.row,r[o].start.column));e.exitMultiSelectMode(),e.clearSelection();for(var o=0;o<i.length;o++)e.selection.addRange(i[o],!1)},readOnly:!0,scrollIntoView:\"none\"}]}),ace.define(\"ace/editor\",[\"require\",\"exports\",\"module\",\"ace/lib/fixoldbrowsers\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/lib/useragent\",\"ace/keyboard/textinput\",\"ace/mouse/mouse_handler\",\"ace/mouse/fold_handler\",\"ace/keyboard/keybinding\",\"ace/edit_session\",\"ace/search\",\"ace/range\",\"ace/lib/event_emitter\",\"ace/commands/command_manager\",\"ace/commands/default_commands\",\"ace/config\",\"ace/token_iterator\"],function(e,t,n){\"use strict\";e(\"./lib/fixoldbrowsers\");var r=e(\"./lib/oop\"),i=e(\"./lib/dom\"),s=e(\"./lib/lang\"),o=e(\"./lib/useragent\"),u=e(\"./keyboard/textinput\").TextInput,a=e(\"./mouse/mouse_handler\").MouseHandler,f=e(\"./mouse/fold_handler\").FoldHandler,l=e(\"./keyboard/keybinding\").KeyBinding,c=e(\"./edit_session\").EditSession,h=e(\"./search\").Search,p=e(\"./range\").Range,d=e(\"./lib/event_emitter\").EventEmitter,v=e(\"./commands/command_manager\").CommandManager,m=e(\"./commands/default_commands\").commands,g=e(\"./config\"),y=e(\"./token_iterator\").TokenIterator,b=function(e,t){var n=e.getContainerElement();this.container=n,this.renderer=e,this.commands=new v(o.isMac?\"mac\":\"win\",m),this.textInput=new u(e.getTextAreaContainer(),this),this.renderer.textarea=this.textInput.getElement(),this.keyBinding=new l(this),this.$mouseHandler=new a(this),new f(this),this.$blockScrolling=0,this.$search=(new h).set({wrap:!0}),this.$historyTracker=this.$historyTracker.bind(this),this.commands.on(\"exec\",this.$historyTracker),this.$initOperationListeners(),this._$emitInputEvent=s.delayedCall(function(){this._signal(\"input\",{}),this.session&&this.session.bgTokenizer&&this.session.bgTokenizer.scheduleStart()}.bind(this)),this.on(\"change\",function(e,t){t._$emitInputEvent.schedule(31)}),this.setSession(t||new c(\"\")),g.resetOptions(this),g._signal(\"editor\",this)};(function(){r.implement(this,d),this.$initOperationListeners=function(){function e(e){return e[e.length-1]}this.selections=[],this.commands.on(\"exec\",this.startOperation.bind(this),!0),this.commands.on(\"afterExec\",this.endOperation.bind(this),!0),this.$opResetTimer=s.delayedCall(this.endOperation.bind(this)),this.on(\"change\",function(){this.curOp||this.startOperation(),this.curOp.docChanged=!0}.bind(this),!0),this.on(\"changeSelection\",function(){this.curOp||this.startOperation(),this.curOp.selectionChanged=!0}.bind(this),!0)},this.curOp=null,this.prevOp={},this.startOperation=function(e){if(this.curOp){if(!e||this.curOp.command)return;this.prevOp=this.curOp}e||(this.previousCommand=null,e={}),this.$opResetTimer.schedule(),this.curOp={command:e.command||{},args:e.args,scrollTop:this.renderer.scrollTop}},this.endOperation=function(e){if(this.curOp){if(e&&e.returnValue===!1)return this.curOp=null;var t=this.curOp.command;if(t&&t.scrollIntoView){switch(t.scrollIntoView){case\"center\":this.renderer.scrollCursorIntoView(null,.5);break;case\"animate\":case\"cursor\":this.renderer.scrollCursorIntoView();break;case\"selectionPart\":var n=this.selection.getRange(),r=this.renderer.layerConfig;(n.start.row>=r.lastRow||n.end.row<=r.firstRow)&&this.renderer.scrollSelectionIntoView(this.selection.anchor,this.selection.lead);break;default:}t.scrollIntoView==\"animate\"&&this.renderer.animateScrolling(this.curOp.scrollTop)}this.prevOp=this.curOp,this.curOp=null}},this.$mergeableCommands=[\"backspace\",\"del\",\"insertstring\"],this.$historyTracker=function(e){if(!this.$mergeUndoDeltas)return;var t=this.prevOp,n=this.$mergeableCommands,r=t.command&&e.command.name==t.command.name;if(e.command.name==\"insertstring\"){var i=e.args;this.mergeNextCommand===undefined&&(this.mergeNextCommand=!0),r=r&&this.mergeNextCommand&&(!/\\s/.test(i)||/\\s/.test(t.args)),this.mergeNextCommand=!0}else r=r&&n.indexOf(e.command.name)!==-1;this.$mergeUndoDeltas!=\"always\"&&Date.now()-this.sequenceStartTime>2e3&&(r=!1),r?this.session.mergeUndoDeltas=!0:n.indexOf(e.command.name)!==-1&&(this.sequenceStartTime=Date.now())},this.setKeyboardHandler=function(e,t){if(e&&typeof e==\"string\"){this.$keybindingId=e;var n=this;g.loadModule([\"keybinding\",e],function(r){n.$keybindingId==e&&n.keyBinding.setKeyboardHandler(r&&r.handler),t&&t()})}else this.$keybindingId=null,this.keyBinding.setKeyboardHandler(e),t&&t()},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(e){if(this.session==e)return;var t=this.session;if(t){this.session.removeEventListener(\"change\",this.$onDocumentChange),this.session.removeEventListener(\"changeMode\",this.$onChangeMode),this.session.removeEventListener(\"tokenizerUpdate\",this.$onTokenizerUpdate),this.session.removeEventListener(\"changeTabSize\",this.$onChangeTabSize),this.session.removeEventListener(\"changeWrapLimit\",this.$onChangeWrapLimit),this.session.removeEventListener(\"changeWrapMode\",this.$onChangeWrapMode),this.session.removeEventListener(\"onChangeFold\",this.$onChangeFold),this.session.removeEventListener(\"changeFrontMarker\",this.$onChangeFrontMarker),this.session.removeEventListener(\"changeBackMarker\",this.$onChangeBackMarker),this.session.removeEventListener(\"changeBreakpoint\",this.$onChangeBreakpoint),this.session.removeEventListener(\"changeAnnotation\",this.$onChangeAnnotation),this.session.removeEventListener(\"changeOverwrite\",this.$onCursorChange),this.session.removeEventListener(\"changeScrollTop\",this.$onScrollTopChange),this.session.removeEventListener(\"changeScrollLeft\",this.$onScrollLeftChange);var n=this.session.getSelection();n.removeEventListener(\"changeCursor\",this.$onCursorChange),n.removeEventListener(\"changeSelection\",this.$onSelectionChange)}this.session=e,e?(this.$onDocumentChange=this.onDocumentChange.bind(this),e.addEventListener(\"change\",this.$onDocumentChange),this.renderer.setSession(e),this.$onChangeMode=this.onChangeMode.bind(this),e.addEventListener(\"changeMode\",this.$onChangeMode),this.$onTokenizerUpdate=this.onTokenizerUpdate.bind(this),e.addEventListener(\"tokenizerUpdate\",this.$onTokenizerUpdate),this.$onChangeTabSize=this.renderer.onChangeTabSize.bind(this.renderer),e.addEventListener(\"changeTabSize\",this.$onChangeTabSize),this.$onChangeWrapLimit=this.onChangeWrapLimit.bind(this),e.addEventListener(\"changeWrapLimit\",this.$onChangeWrapLimit),this.$onChangeWrapMode=this.onChangeWrapMode.bind(this),e.addEventListener(\"changeWrapMode\",this.$onChangeWrapMode),this.$onChangeFold=this.onChangeFold.bind(this),e.addEventListener(\"changeFold\",this.$onChangeFold),this.$onChangeFrontMarker=this.onChangeFrontMarker.bind(this),this.session.addEventListener(\"changeFrontMarker\",this.$onChangeFrontMarker),this.$onChangeBackMarker=this.onChangeBackMarker.bind(this),this.session.addEventListener(\"changeBackMarker\",this.$onChangeBackMarker),this.$onChangeBreakpoint=this.onChangeBreakpoint.bind(this),this.session.addEventListener(\"changeBreakpoint\",this.$onChangeBreakpoint),this.$onChangeAnnotation=this.onChangeAnnotation.bind(this),this.session.addEventListener(\"changeAnnotation\",this.$onChangeAnnotation),this.$onCursorChange=this.onCursorChange.bind(this),this.session.addEventListener(\"changeOverwrite\",this.$onCursorChange),this.$onScrollTopChange=this.onScrollTopChange.bind(this),this.session.addEventListener(\"changeScrollTop\",this.$onScrollTopChange),this.$onScrollLeftChange=this.onScrollLeftChange.bind(this),this.session.addEventListener(\"changeScrollLeft\",this.$onScrollLeftChange),this.selection=e.getSelection(),this.selection.addEventListener(\"changeCursor\",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.addEventListener(\"changeSelection\",this.$onSelectionChange),this.onChangeMode(),this.$blockScrolling+=1,this.onCursorChange(),this.$blockScrolling-=1,this.onScrollTopChange(),this.onScrollLeftChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onChangeBreakpoint(),this.onChangeAnnotation(),this.session.getUseWrapMode()&&this.renderer.adjustWrapLimit(),this.renderer.updateFull()):(this.selection=null,this.renderer.setSession(e)),this._signal(\"changeSession\",{session:e,oldSession:t}),t&&t._signal(\"changeEditor\",{oldEditor:this}),e&&e._signal(\"changeEditor\",{editor:this})},this.getSession=function(){return this.session},this.setValue=function(e,t){return this.session.doc.setValue(e),t?t==1?this.navigateFileEnd():t==-1&&this.navigateFileStart():this.selectAll(),e},this.getValue=function(){return this.session.getValue()},this.getSelection=function(){return this.selection},this.resize=function(e){this.renderer.onResize(e)},this.setTheme=function(e,t){this.renderer.setTheme(e,t)},this.getTheme=function(){return this.renderer.getTheme()},this.setStyle=function(e){this.renderer.setStyle(e)},this.unsetStyle=function(e){this.renderer.unsetStyle(e)},this.getFontSize=function(){return this.getOption(\"fontSize\")||i.computedStyle(this.container,\"fontSize\")},this.setFontSize=function(e){this.setOption(\"fontSize\",e)},this.$highlightBrackets=function(){this.session.$bracketHighlight&&(this.session.removeMarker(this.session.$bracketHighlight),this.session.$bracketHighlight=null);if(this.$highlightPending)return;var e=this;this.$highlightPending=!0,setTimeout(function(){e.$highlightPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=t.findMatchingBracket(e.getCursorPosition());if(n)var r=new p(n.row,n.column,n.row,n.column+1);else if(t.$mode.getMatching)var r=t.$mode.getMatching(e.session);r&&(t.$bracketHighlight=t.addMarker(r,\"ace_bracket\",\"text\"))},50)},this.$highlightTags=function(){if(this.$highlightTagPending)return;var e=this;this.$highlightTagPending=!0,setTimeout(function(){e.$highlightTagPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=e.getCursorPosition(),r=new y(e.session,n.row,n.column),i=r.getCurrentToken();if(!i||i.type.indexOf(\"tag-name\")===-1){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}var s=i.value,o=0,u=r.stepBackward();if(u.value==\"<\"){do u=i,i=r.stepForward(),i&&i.value===s&&i.type.indexOf(\"tag-name\")!==-1&&(u.value===\"<\"?o++:u.value===\"</\"&&o--);while(i&&o>=0)}else{do i=u,u=r.stepBackward(),i&&i.value===s&&i.type.indexOf(\"tag-name\")!==-1&&(u.value===\"<\"?o++:u.value===\"</\"&&o--);while(u&&o<=0);r.stepForward()}if(!i){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}var a=r.getCurrentTokenRow(),f=r.getCurrentTokenColumn(),l=new p(a,f,a,f+i.value.length);t.$tagHighlight&&l.compareRange(t.$backMarkers[t.$tagHighlight].range)!==0&&(t.removeMarker(t.$tagHighlight),t.$tagHighlight=null),l&&!t.$tagHighlight&&(t.$tagHighlight=t.addMarker(l,\"ace_bracket\",\"text\"))},50)},this.focus=function(){var e=this;setTimeout(function(){e.textInput.focus()}),this.textInput.focus()},this.isFocused=function(){return this.textInput.isFocused()},this.blur=function(){this.textInput.blur()},this.onFocus=function(e){if(this.$isFocused)return;this.$isFocused=!0,this.renderer.showCursor(),this.renderer.visualizeFocus(),this._emit(\"focus\",e)},this.onBlur=function(e){if(!this.$isFocused)return;this.$isFocused=!1,this.renderer.hideCursor(),this.renderer.visualizeBlur(),this._emit(\"blur\",e)},this.$cursorChange=function(){this.renderer.updateCursor()},this.onDocumentChange=function(e){var t=e.data,n=t.range,r;n.start.row==n.end.row&&t.action!=\"insertLines\"&&t.action!=\"removeLines\"?r=n.end.row:r=Infinity,this.renderer.updateLines(n.start.row,r,this.session.$useWrapMode),this._signal(\"change\",e),this.$cursorChange(),this.$updateHighlightActiveLine()},this.onTokenizerUpdate=function(e){var t=e.data;this.renderer.updateLines(t.first,t.last)},this.onScrollTopChange=function(){this.renderer.scrollToY(this.session.getScrollTop())},this.onScrollLeftChange=function(){this.renderer.scrollToX(this.session.getScrollLeft())},this.onCursorChange=function(){this.$cursorChange(),this.$blockScrolling||this.renderer.scrollCursorIntoView(),this.$highlightBrackets(),this.$highlightTags(),this.$updateHighlightActiveLine(),this._signal(\"changeSelection\")},this.$updateHighlightActiveLine=function(){var e=this.getSession(),t;if(this.$highlightActiveLine){if(this.$selectionStyle!=\"line\"||!this.selection.isMultiLine())t=this.getCursorPosition();this.renderer.$maxLines&&this.session.getLength()===1&&!(this.renderer.$minLines>1)&&(t=!1)}if(e.$highlightLineMarker&&!t)e.removeMarker(e.$highlightLineMarker.id),e.$highlightLineMarker=null;else if(!e.$highlightLineMarker&&t){var n=new p(t.row,t.column,t.row,Infinity);n.id=e.addMarker(n,\"ace_active-line\",\"screenLine\"),e.$highlightLineMarker=n}else t&&(e.$highlightLineMarker.start.row=t.row,e.$highlightLineMarker.end.row=t.row,e.$highlightLineMarker.start.column=t.column,e._signal(\"changeBackMarker\"))},this.onSelectionChange=function(e){var t=this.session;t.$selectionMarker&&t.removeMarker(t.$selectionMarker),t.$selectionMarker=null;if(!this.selection.isEmpty()){var n=this.selection.getRange(),r=this.getSelectionStyle();t.$selectionMarker=t.addMarker(n,\"ace_selection\",r)}else this.$updateHighlightActiveLine();var i=this.$highlightSelectedWord&&this.$getSelectionHighLightRegexp();this.session.highlight(i),this._signal(\"changeSelection\")},this.$getSelectionHighLightRegexp=function(){var e=this.session,t=this.getSelectionRange();if(t.isEmpty()||t.isMultiLine())return;var n=t.start.column-1,r=t.end.column+1,i=e.getLine(t.start.row),s=i.length,o=i.substring(Math.max(n,0),Math.min(r,s));if(n>=0&&/^[\\w\\d]/.test(o)||r<=s&&/[\\w\\d]$/.test(o))return;o=i.substring(t.start.column,t.end.column);if(!/^[\\w\\d]+$/.test(o))return;var u=this.$search.$assembleRegExp({wholeWord:!0,caseSensitive:!0,needle:o});return u},this.onChangeFrontMarker=function(){this.renderer.updateFrontMarkers()},this.onChangeBackMarker=function(){this.renderer.updateBackMarkers()},this.onChangeBreakpoint=function(){this.renderer.updateBreakpoints()},this.onChangeAnnotation=function(){this.renderer.setAnnotations(this.session.getAnnotations())},this.onChangeMode=function(e){this.renderer.updateText(),this._emit(\"changeMode\",e)},this.onChangeWrapLimit=function(){this.renderer.updateFull()},this.onChangeWrapMode=function(){this.renderer.onResize(!0)},this.onChangeFold=function(){this.$updateHighlightActiveLine(),this.renderer.updateFull()},this.getSelectedText=function(){return this.session.getTextRange(this.getSelectionRange())},this.getCopyText=function(){var e=this.getSelectedText();return this._signal(\"copy\",e),e},this.onCopy=function(){this.commands.exec(\"copy\",this)},this.onCut=function(){this.commands.exec(\"cut\",this)},this.onPaste=function(e){if(this.$readOnly)return;var t={text:e};this._signal(\"paste\",t),this.insert(t.text,!0)},this.execCommand=function(e,t){return this.commands.exec(e,this,t)},this.insert=function(e,t){var n=this.session,r=n.getMode(),i=this.getCursorPosition();if(this.getBehavioursEnabled()&&!t){var s=r.transformAction(n.getState(i.row),\"insertion\",this,n,e);s&&(e!==s.text&&(this.session.mergeUndoDeltas=!1,this.$mergeNextCommand=!1),e=s.text)}e==\"    \"&&(e=this.session.getTabString());if(!this.selection.isEmpty()){var o=this.getSelectionRange();i=this.session.remove(o),this.clearSelection()}else if(this.session.getOverwrite()){var o=new p.fromPoints(i,i);o.end.column+=e.length,this.session.remove(o)}if(e==\"\\n\"||e==\"\\r\\n\"){var u=n.getLine(i.row);if(i.column>u.search(/\\S|$/)){var a=u.substr(i.column).search(/\\S|$/);n.doc.removeInLine(i.row,i.column,i.column+a)}}this.clearSelection();var f=i.column,l=n.getState(i.row),u=n.getLine(i.row),c=r.checkOutdent(l,u,e),h=n.insert(i,e);s&&s.selection&&(s.selection.length==2?this.selection.setSelectionRange(new p(i.row,f+s.selection[0],i.row,f+s.selection[1])):this.selection.setSelectionRange(new p(i.row+s.selection[0],s.selection[1],i.row+s.selection[2],s.selection[3])));if(n.getDocument().isNewLine(e)){var d=r.getNextLineIndent(l,u.slice(0,i.column),n.getTabString());n.insert({row:i.row+1,column:0},d)}c&&r.autoOutdent(l,n,i.row)},this.onTextInput=function(e){this.keyBinding.onTextInput(e)},this.onCommandKey=function(e,t,n){this.keyBinding.onCommandKey(e,t,n)},this.setOverwrite=function(e){this.session.setOverwrite(e)},this.getOverwrite=function(){return this.session.getOverwrite()},this.toggleOverwrite=function(){this.session.toggleOverwrite()},this.setScrollSpeed=function(e){this.setOption(\"scrollSpeed\",e)},this.getScrollSpeed=function(){return this.getOption(\"scrollSpeed\")},this.setDragDelay=function(e){this.setOption(\"dragDelay\",e)},this.getDragDelay=function(){return this.getOption(\"dragDelay\")},this.setSelectionStyle=function(e){this.setOption(\"selectionStyle\",e)},this.getSelectionStyle=function(){return this.getOption(\"selectionStyle\")},this.setHighlightActiveLine=function(e){this.setOption(\"highlightActiveLine\",e)},this.getHighlightActiveLine=function(){return this.getOption(\"highlightActiveLine\")},this.setHighlightGutterLine=function(e){this.setOption(\"highlightGutterLine\",e)},this.getHighlightGutterLine=function(){return this.getOption(\"highlightGutterLine\")},this.setHighlightSelectedWord=function(e){this.setOption(\"highlightSelectedWord\",e)},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setAnimatedScroll=function(e){this.renderer.setAnimatedScroll(e)},this.getAnimatedScroll=function(){return this.renderer.getAnimatedScroll()},this.setShowInvisibles=function(e){this.renderer.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.renderer.getShowInvisibles()},this.setDisplayIndentGuides=function(e){this.renderer.setDisplayIndentGuides(e)},this.getDisplayIndentGuides=function(){return this.renderer.getDisplayIndentGuides()},this.setShowPrintMargin=function(e){this.renderer.setShowPrintMargin(e)},this.getShowPrintMargin=function(){return this.renderer.getShowPrintMargin()},this.setPrintMarginColumn=function(e){this.renderer.setPrintMarginColumn(e)},this.getPrintMarginColumn=function(){return this.renderer.getPrintMarginColumn()},this.setReadOnly=function(e){this.setOption(\"readOnly\",e)},this.getReadOnly=function(){return this.getOption(\"readOnly\")},this.setBehavioursEnabled=function(e){this.setOption(\"behavioursEnabled\",e)},this.getBehavioursEnabled=function(){return this.getOption(\"behavioursEnabled\")},this.setWrapBehavioursEnabled=function(e){this.setOption(\"wrapBehavioursEnabled\",e)},this.getWrapBehavioursEnabled=function(){return this.getOption(\"wrapBehavioursEnabled\")},this.setShowFoldWidgets=function(e){this.setOption(\"showFoldWidgets\",e)},this.getShowFoldWidgets=function(){return this.getOption(\"showFoldWidgets\")},this.setFadeFoldWidgets=function(e){this.setOption(\"fadeFoldWidgets\",e)},this.getFadeFoldWidgets=function(){return this.getOption(\"fadeFoldWidgets\")},this.remove=function(e){this.selection.isEmpty()&&(e==\"left\"?this.selection.selectLeft():this.selection.selectRight());var t=this.getSelectionRange();if(this.getBehavioursEnabled()){var n=this.session,r=n.getState(t.start.row),i=n.getMode().transformAction(r,\"deletion\",this,n,t);if(t.end.column===0){var s=n.getTextRange(t);if(s[s.length-1]==\"\\n\"){var o=n.getLine(t.end.row);/^\\s+$/.test(o)&&(t.end.column=o.length)}}i&&(t=i)}this.session.remove(t),this.clearSelection()},this.removeWordRight=function(){this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeWordLeft=function(){this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineStart=function(){this.selection.isEmpty()&&this.selection.selectLineStart(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineEnd=function(){this.selection.isEmpty()&&this.selection.selectLineEnd();var e=this.getSelectionRange();e.start.column==e.end.column&&e.start.row==e.end.row&&(e.end.column=0,e.end.row++),this.session.remove(e),this.clearSelection()},this.splitLine=function(){this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection());var e=this.getCursorPosition();this.insert(\"\\n\"),this.moveCursorToPosition(e)},this.transposeLetters=function(){if(!this.selection.isEmpty())return;var e=this.getCursorPosition(),t=e.column;if(t===0)return;var n=this.session.getLine(e.row),r,i;t<n.length?(r=n.charAt(t)+n.charAt(t-1),i=new p(e.row,t-1,e.row,t+1)):(r=n.charAt(t-1)+n.charAt(t-2),i=new p(e.row,t-2,e.row,t)),this.session.replace(i,r)},this.toLowerCase=function(){var e=this.getSelectionRange();this.selection.isEmpty()&&this.selection.selectWord();var t=this.getSelectionRange(),n=this.session.getTextRange(t);this.session.replace(t,n.toLowerCase()),this.selection.setSelectionRange(e)},this.toUpperCase=function(){var e=this.getSelectionRange();this.selection.isEmpty()&&this.selection.selectWord();var t=this.getSelectionRange(),n=this.session.getTextRange(t);this.session.replace(t,n.toUpperCase()),this.selection.setSelectionRange(e)},this.indent=function(){var e=this.session,t=this.getSelectionRange();if(t.start.row<t.end.row){var n=this.$getSelectedRows();e.indentRows(n.first,n.last,\"    \");return}if(t.start.column<t.end.column){var r=e.getTextRange(t);if(!/^\\s+$/.test(r)){var n=this.$getSelectedRows();e.indentRows(n.first,n.last,\"  \");return}}var i=e.getLine(t.start.row),o=t.start,u=e.getTabSize(),a=e.documentToScreenColumn(o.row,o.column);if(this.session.getUseSoftTabs())var f=u-a%u,l=s.stringRepeat(\" \",f);else{var f=a%u;while(i[t.start.column]==\" \"&&f)t.start.column--,f--;this.selection.setSelectionRange(t),l=\"  \"}return this.insert(l)},this.blockIndent=function(){var e=this.$getSelectedRows();this.session.indentRows(e.first,e.last,\" \")},this.blockOutdent=function(){var e=this.session.getSelection();this.session.outdentRows(e.getRange())},this.sortLines=function(){var e=this.$getSelectedRows(),t=this.session,n=[];for(i=e.first;i<=e.last;i++)n.push(t.getLine(i));n.sort(function(e,t){return e.toLowerCase()<t.toLowerCase()?-1:e.toLowerCase()>t.toLowerCase()?1:0});var r=new p(0,0,0,0);for(var i=e.first;i<=e.last;i++){var s=t.getLine(i);r.start.row=i,r.end.row=i,r.end.column=s.length,t.replace(r,n[i-e.first])}},this.toggleCommentLines=function(){var e=this.session.getState(this.getCursorPosition().row),t=this.$getSelectedRows();this.session.getMode().toggleCommentLines(e,this.session,t.first,t.last)},this.toggleBlockComment=function(){var e=this.getCursorPosition(),t=this.session.getState(e.row),n=this.getSelectionRange();this.session.getMode().toggleBlockComment(t,this.session,n,e)},this.getNumberAt=function(e,t){var n=/[\\-]?[0-9]+(?:\\.[0-9]+)?/g;n.lastIndex=0;var r=this.session.getLine(e);while(n.lastIndex<t){var i=n.exec(r);if(i.index<=t&&i.index+i[0].length>=t){var s={value:i[0],start:i.index,end:i.index+i[0].length};return s}}return null},this.modifyNumber=function(e){var t=this.selection.getCursor().row,n=this.selection.getCursor().column,r=new p(t,n-1,t,n),i=this.session.getTextRange(r);if(!isNaN(parseFloat(i))&&isFinite(i)){var s=this.getNumberAt(t,n);if(s){var o=s.value.indexOf(\".\")>=0?s.start+s.value.indexOf(\".\")+1:s.end,u=s.start+s.value.length-o,a=parseFloat(s.value);a*=Math.pow(10,u),o!==s.end&&n<o?e*=Math.pow(10,s.end-n-1):e*=Math.pow(10,s.end-n),a+=e,a/=Math.pow(10,u);var f=a.toFixed(u),l=new p(t,s.start,t,s.end);this.session.replace(l,f),this.moveCursorTo(t,Math.max(s.start+1,n+f.length-s.value.length))}}},this.removeLines=function(){var e=this.$getSelectedRows(),t;e.first===0||e.last+1<this.session.getLength()?t=new p(e.first,0,e.last+1,0):t=new p(e.first-1,this.session.getLine(e.first-1).length,e.last,this.session.getLine(e.last).length),this.session.remove(t),this.clearSelection()},this.duplicateSelection=function(){var e=this.selection,t=this.session,n=e.getRange(),r=e.isBackwards();if(n.isEmpty()){var i=n.start.row;t.duplicateLines(i,i)}else{var s=r?n.start:n.end,o=t.insert(s,t.getTextRange(n),!1);n.start=s,n.end=o,e.setSelectionRange(n,r)}},this.moveLinesDown=function(){this.$moveLines(function(e,t){return this.session.moveLinesDown(e,t)})},this.moveLinesUp=function(){this.$moveLines(function(e,t){return this.session.moveLinesUp(e,t)})},this.moveText=function(e,t,n){return this.session.moveText(e,t,n)},this.copyLinesUp=function(){this.$moveLines(function(e,t){return this.session.duplicateLines(e,t),0})},this.copyLinesDown=function(){this.$moveLines(function(e,t){return this.session.duplicateLines(e,t)})},this.$moveLines=function(e){var t=this.selection;if(!t.inMultiSelectMode||this.inVirtualSelectionMode){var n=t.toOrientedRange(),r=this.$getSelectedRows(n),i=e.call(this,r.first,r.last);n.moveBy(i,0),t.fromOrientedRange(n)}else{var s=t.rangeList.ranges;t.rangeList.detach(this.session);for(var o=s.length;o--;){var u=o,r=s[o].collapseRows(),a=r.end.row,f=r.start.row;while(o--){r=s[o].collapseRows();if(!(f-r.end.row<=1))break;f=r.end.row}o++;var i=e.call(this,f,a);while(u>=o)s[u].moveBy(i,0),u--}t.fromOrientedRange(t.ranges[0]),t.rangeList.attach(this.session)}},this.$getSelectedRows=function(){var e=this.getSelectionRange().collapseRows();return{first:this.session.getRowFoldStart(e.start.row),last:this.session.getRowFoldEnd(e.end.row)}},this.onCompositionStart=function(e){this.renderer.showComposition(this.getCursorPosition())},this.onCompositionUpdate=function(e){this.renderer.setCompositionText(e)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(e){return e>=this.getFirstVisibleRow()&&e<=this.getLastVisibleRow()},this.isRowFullyVisible=function(e){return e>=this.renderer.getFirstFullyVisibleRow()&&e<=this.renderer.getLastFullyVisibleRow()},this.$getVisibleRowCount=function(){return this.renderer.getScrollBottomRow()-this.renderer.getScrollTopRow()+1},this.$moveByPage=function(e,t){var n=this.renderer,r=this.renderer.layerConfig,i=e*Math.floor(r.height/r.lineHeight);this.$blockScrolling++,t===!0?this.selection.$moveSelection(function(){this.moveCursorBy(i,0)}):t===!1&&(this.selection.moveCursorBy(i,0),this.selection.clearSelection()),this.$blockScrolling--;var s=n.scrollTop;n.scrollBy(0,i*r.lineHeight),t!=null&&n.scrollCursorIntoView(null,.5),n.animateScrolling(s)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(e){this.renderer.scrollToRow(e)},this.scrollToLine=function(e,t,n,r){this.renderer.scrollToLine(e,t,n,r)},this.centerSelection=function(){var e=this.getSelectionRange(),t={row:Math.floor(e.start.row+(e.end.row-e.start.row)/2),column:Math.floor(e.start.column+(e.end.column-e.start.column)/2)};this.renderer.alignCursor(t,.5)},this.getCursorPosition=function(){return this.selection.getCursor()},this.getCursorPositionScreen=function(){return this.session.documentToScreenPosition(this.getCursorPosition())},this.getSelectionRange=function(){return this.selection.getRange()},this.selectAll=function(){this.$blockScrolling+=1,this.selection.selectAll(),this.$blockScrolling-=1},this.clearSelection=function(){this.selection.clearSelection()},this.moveCursorTo=function(e,t){this.selection.moveCursorTo(e,t)},this.moveCursorToPosition=function(e){this.selection.moveCursorToPosition(e)},this.jumpToMatching=function(e,t){var n=this.getCursorPosition(),r=new y(this.session,n.row,n.column),i=r.getCurrentToken(),s=i||r.stepForward();if(!s)return;var o,u=!1,a={},f=n.column-s.start,l,c={\")\":\"(\",\"(\":\"(\",\"]\":\"[\",\"[\":\"[\",\"{\":\"{\",\"}\":\"{\"};do{if(s.value.match(/[{}()\\[\\]]/g))for(;f<s.value.length&&!u;f++){if(!c[s.value[f]])continue;l=c[s.value[f]]+\".\"+s.type.replace(\"rparen\",\"lparen\"),isNaN(a[l])&&(a[l]=0);switch(s.value[f]){case\"(\":case\"[\":case\"{\":a[l]++;break;case\")\":case\"]\":case\"}\":a[l]--,a[l]===-1&&(o=\"bracket\",u=!0)}}else s&&s.type.indexOf(\"tag-name\")!==-1&&(isNaN(a[s.value])&&(a[s.value]=0),i.value===\"<\"?a[s.value]++:i.value===\"</\"&&a[s.value]--,a[s.value]===-1&&(o=\"tag\",u=!0));u||(i=s,s=r.stepForward(),f=0)}while(s&&!u);if(!o)return;var h,d;if(o===\"bracket\"){h=this.session.getBracketRange(n);if(!h){h=new p(r.getCurrentTokenRow(),r.getCurrentTokenColumn()+f-1,r.getCurrentTokenRow(),r.getCurrentTokenColumn()+f-1),d=h.start;if(t||d.row===n.row&&Math.abs(d.column-n.column)<2)h=this.session.getBracketRange(d)}}else if(o===\"tag\"){if(!s||s.type.indexOf(\"tag-name\")===-1)return;var v=s.value;h=new p(r.getCurrentTokenRow(),r.getCurrentTokenColumn()-2,r.getCurrentTokenRow(),r.getCurrentTokenColumn()-2);if(h.compare(n.row,n.column)===0){u=!1;do s=i,i=r.stepBackward(),i&&(i.type.indexOf(\"tag-close\")!==-1&&h.setEnd(r.getCurrentTokenRow(),r.getCurrentTokenColumn()+1),s.value===v&&s.type.indexOf(\"tag-name\")!==-1&&(i.value===\"<\"?a[v]++:i.value===\"</\"&&a[v]--,a[v]===0&&(u=!0)));while(i&&!u)}s&&s.type.indexOf(\"tag-name\")&&(d=h.start,d.row==n.row&&Math.abs(d.column-n.column)<2&&(d=h.end))}d=h&&h.cursor||d,d&&(e?h&&t?this.selection.setRange(h):h&&h.isEqual(this.getSelectionRange())?this.clearSelection():this.selection.selectTo(d.row,d.column):this.selection.moveTo(d.row,d.column))},this.gotoLine=function(e,t,n){this.selection.clearSelection(),this.session.unfold({row:e-1,column:t||0}),this.$blockScrolling+=1,this.exitMultiSelectMode&&this.exitMultiSelectMode(),this.moveCursorTo(e-1,t||0),this.$blockScrolling-=1,this.isRowFullyVisible(e-1)||this.scrollToLine(e-1,!0,n)},this.navigateTo=function(e,t){this.selection.moveTo(e,t)},this.navigateUp=function(e){if(this.selection.isMultiLine()&&!this.selection.isBackwards()){var t=this.selection.anchor.getPosition();return this.moveCursorToPosition(t)}this.selection.clearSelection(),this.selection.moveCursorBy(-e||-1,0)},this.navigateDown=function(e){if(this.selection.isMultiLine()&&this.selection.isBackwards()){var t=this.selection.anchor.getPosition();return this.moveCursorToPosition(t)}this.selection.clearSelection(),this.selection.moveCursorBy(e||1,0)},this.navigateLeft=function(e){if(!this.selection.isEmpty()){var t=this.getSelectionRange().start;this.moveCursorToPosition(t)}else{e=e||1;while(e--)this.selection.moveCursorLeft()}this.clearSelection()},this.navigateRight=function(e){if(!this.selection.isEmpty()){var t=this.getSelectionRange().end;this.moveCursorToPosition(t)}else{e=e||1;while(e--)this.selection.moveCursorRight()}this.clearSelection()},this.navigateLineStart=function(){this.selection.moveCursorLineStart(),this.clearSelection()},this.navigateLineEnd=function(){this.selection.moveCursorLineEnd(),this.clearSelection()},this.navigateFileEnd=function(){this.selection.moveCursorFileEnd(),this.clearSelection()},this.navigateFileStart=function(){this.selection.moveCursorFileStart(),this.clearSelection()},this.navigateWordRight=function(){this.selection.moveCursorWordRight(),this.clearSelection()},this.navigateWordLeft=function(){this.selection.moveCursorWordLeft(),this.clearSelection()},this.replace=function(e,t){t&&this.$search.set(t);var n=this.$search.find(this.session),r=0;return n?(this.$tryReplace(n,e)&&(r=1),n!==null&&(this.selection.setSelectionRange(n),this.renderer.scrollSelectionIntoView(n.start,n.end)),r):r},this.replaceAll=function(e,t){t&&this.$search.set(t);var n=this.$search.findAll(this.session),r=0;if(!n.length)return r;this.$blockScrolling+=1;var i=this.getSelectionRange();this.selection.moveTo(0,0);for(var s=n.length-1;s>=0;--s)this.$tryReplace(n[s],e)&&r++;return this.selection.setSelectionRange(i),this.$blockScrolling-=1,r},this.$tryReplace=function(e,t){var n=this.session.getTextRange(e);return t=this.$search.replace(n,t),t!==null?(e.end=this.session.replace(e,t),e):null},this.getLastSearchOptions=function(){return this.$search.getOptions()},this.find=function(e,t,n){t||(t={}),typeof e==\"string\"||e instanceof RegExp?t.needle=e:typeof e==\"object\"&&r.mixin(t,e);var i=this.selection.getRange();t.needle==null&&(e=this.session.getTextRange(i)||this.$search.$options.needle,e||(i=this.session.getWordRange(i.start.row,i.start.column),e=this.session.getTextRange(i)),this.$search.set({needle:e})),this.$search.set(t),t.start||this.$search.set({start:i});var s=this.$search.find(this.session);if(t.preventScroll)return s;if(s)return this.revealRange(s,n),s;t.backwards?i.start=i.end:i.end=i.start,this.selection.setRange(i)},this.findNext=function(e,t){this.find({skipCurrent:!0,backwards:!1},e,t)},this.findPrevious=function(e,t){this.find(e,{skipCurrent:!0,backwards:!0},t)},this.revealRange=function(e,t){this.$blockScrolling+=1,this.session.unfold(e),this.selection.setSelectionRange(e),this.$blockScrolling-=1;var n=this.renderer.scrollTop;this.renderer.scrollSelectionIntoView(e.start,e.end,.5),t!==!1&&this.renderer.animateScrolling(n)},this.undo=function(){this.$blockScrolling++,this.session.getUndoManager().undo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.redo=function(){this.$blockScrolling++,this.session.getUndoManager().redo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.destroy=function(){this.renderer.destroy(),this._signal(\"destroy\",this),this.session&&this.session.destroy()},this.setAutoScrollEditorIntoView=function(e){if(!e)return;var t,n=this,r=!1;this.$scrollAnchor||(this.$scrollAnchor=document.createElement(\"div\"));var i=this.$scrollAnchor;i.style.cssText=\"position:absolute\",this.container.insertBefore(i,this.container.firstChild);var s=this.on(\"changeSelection\",function(){r=!0}),o=this.renderer.on(\"beforeRender\",function(){r&&(t=n.renderer.container.getBoundingClientRect())}),u=this.renderer.on(\"afterRender\",function(){if(r&&t&&(n.isFocused()||n.searchBox&&n.searchBox.isFocused())){var e=n.renderer,s=e.$cursorLayer.$pixelPos,o=e.layerConfig,u=s.top-o.offset;s.top>=0&&u+t.top<0?r=!0:s.top<o.height&&s.top+t.top+o.lineHeight>window.innerHeight?r=!1:r=null,r!=null&&(i.style.top=u+\"px\",i.style.left=s.left+\"px\",i.style.height=o.lineHeight+\"px\",i.scrollIntoView(r)),r=t=null}});this.setAutoScrollEditorIntoView=function(e){if(e)return;delete this.setAutoScrollEditorIntoView,this.removeEventListener(\"changeSelection\",s),this.renderer.removeEventListener(\"afterRender\",u),this.renderer.removeEventListener(\"beforeRender\",o)}},this.$resetCursorStyle=function(){var e=this.$cursorStyle||\"ace\",t=this.renderer.$cursorLayer;if(!t)return;t.setSmoothBlinking(/smooth/.test(e)),t.isBlinking=!this.$readOnly&&e!=\"wide\",i.setCssClass(t.element,\"ace_slim-cursors\",/slim/.test(e))}}).call(b.prototype),g.defineOptions(b.prototype,\"editor\",{selectionStyle:{set:function(e){this.onSelectionChange(),this._signal(\"changeSelectionStyle\",{data:e})},initialValue:\"line\"},highlightActiveLine:{set:function(){this.$updateHighlightActiveLine()},initialValue:!0},highlightSelectedWord:{set:function(e){this.$onSelectionChange()},initialValue:!0},readOnly:{set:function(e){this.$resetCursorStyle()},initialValue:!1},cursorStyle:{set:function(e){this.$resetCursorStyle()},values:[\"ace\",\"slim\",\"smooth\",\"wide\"],initialValue:\"ace\"},mergeUndoDeltas:{values:[!1,!0,\"always\"],initialValue:!0},behavioursEnabled:{initialValue:!0},wrapBehavioursEnabled:{initialValue:!0},autoScrollEditorIntoView:{set:function(e){this.setAutoScrollEditorIntoView(e)}},hScrollBarAlwaysVisible:\"renderer\",vScrollBarAlwaysVisible:\"renderer\",highlightGutterLine:\"renderer\",animatedScroll:\"renderer\",showInvisibles:\"renderer\",showPrintMargin:\"renderer\",printMarginColumn:\"renderer\",printMargin:\"renderer\",fadeFoldWidgets:\"renderer\",showFoldWidgets:\"renderer\",showLineNumbers:\"renderer\",showGutter:\"renderer\",displayIndentGuides:\"renderer\",fontSize:\"renderer\",fontFamily:\"renderer\",maxLines:\"renderer\",minLines:\"renderer\",scrollPastEnd:\"renderer\",fixedWidthGutter:\"renderer\",theme:\"renderer\",scrollSpeed:\"$mouseHandler\",dragDelay:\"$mouseHandler\",dragEnabled:\"$mouseHandler\",focusTimout:\"$mouseHandler\",tooltipFollowsMouse:\"$mouseHandler\",firstLineNumber:\"session\",overwrite:\"session\",newLineMode:\"session\",useWorker:\"session\",useSoftTabs:\"session\",tabSize:\"session\",wrap:\"session\",foldStyle:\"session\",mode:\"session\"}),t.Editor=b}),ace.define(\"ace/undomanager\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=function(){this.reset()};(function(){this.execute=function(e){var t=e.args[0];this.$doc=e.args[1],e.merge&&this.hasUndo()&&(this.dirtyCounter--,t=this.$undoStack.pop().concat(t)),this.$undoStack.push(t),this.$redoStack=[],this.dirtyCounter<0&&(this.dirtyCounter=NaN),this.dirtyCounter++},this.undo=function(e){var t=this.$undoStack.pop(),n=null;return t&&(n=this.$doc.undoChanges(t,e),this.$redoStack.push(t),this.dirtyCounter--),n},this.redo=function(e){var t=this.$redoStack.pop(),n=null;return t&&(n=this.$doc.redoChanges(t,e),this.$undoStack.push(t),this.dirtyCounter++),n},this.reset=function(){this.$undoStack=[],this.$redoStack=[],this.dirtyCounter=0},this.hasUndo=function(){return this.$undoStack.length>0},this.hasRedo=function(){return this.$redoStack.length>0},this.markClean=function(){this.dirtyCounter=0},this.isClean=function(){return this.dirtyCounter===0}}).call(r.prototype),t.UndoManager=r}),ace.define(\"ace/layer/gutter\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\",\"ace/lib/oop\",\"ace/lib/lang\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"../lib/dom\"),i=e(\"../lib/oop\"),s=e(\"../lib/lang\"),o=e(\"../lib/event_emitter\").EventEmitter,u=function(e){this.element=r.createElement(\"div\"),this.element.className=\"ace_layer ace_gutter-layer\",e.appendChild(this.element),this.setShowFoldWidgets(this.$showFoldWidgets),this.gutterWidth=0,this.$annotations=[],this.$updateAnnotations=this.$updateAnnotations.bind(this),this.$cells=[]};(function(){i.implement(this,o),this.setSession=function(e){this.session&&this.session.removeEventListener(\"change\",this.$updateAnnotations),this.session=e,e&&e.on(\"change\",this.$updateAnnotations)},this.addGutterDecoration=function(e,t){window.console&&console.warn&&console.warn(\"deprecated use session.addGutterDecoration\"),this.session.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){window.console&&console.warn&&console.warn(\"deprecated use session.removeGutterDecoration\"),this.session.removeGutterDecoration(e,t)},this.setAnnotations=function(e){this.$annotations=[];for(var t=0;t<e.length;t++){var n=e[t],r=n.row,i=this.$annotations[r];i||(i=this.$annotations[r]={text:[]});var o=n.text;o=o?s.escapeHTML(o):n.html||\"\",i.text.indexOf(o)===-1&&i.text.push(o);var u=n.type;u==\"error\"?i.className=\" ace_error\":u==\"warning\"&&i.className!=\" ace_error\"?i.className=\" ace_warning\":u==\"info\"&&!i.className&&(i.className=\" ace_info\")}},this.$updateAnnotations=function(e){if(!this.$annotations.length)return;var t=e.data,n=t.range,r=n.start.row,i=n.end.row-r;if(i!==0)if(t.action==\"removeText\"||t.action==\"removeLines\")this.$annotations.splice(r,i+1,null);else{var s=new Array(i+1);s.unshift(r,1),this.$annotations.splice.apply(this.$annotations,s)}},this.update=function(e){var t=this.session,n=e.firstRow,i=Math.min(e.lastRow+e.gutterOffset,t.getLength()-1),s=t.getNextFoldLine(n),o=s?s.start.row:Infinity,u=this.$showFoldWidgets&&t.foldWidgets,a=t.$breakpoints,f=t.$decorations,l=t.$firstLineNumber,c=0,h=t.gutterRenderer||this.$renderer,p=null,d=-1,v=n;for(;;){v>o&&(v=s.end.row+1,s=t.getNextFoldLine(v,s),o=s?s.start.row:Infinity);if(v>i){while(this.$cells.length>d+1)p=this.$cells.pop(),this.element.removeChild(p.element);break}p=this.$cells[++d],p||(p={element:null,textNode:null,foldWidget:null},p.element=r.createElement(\"div\"),p.textNode=document.createTextNode(\"\"),p.element.appendChild(p.textNode),this.element.appendChild(p.element),this.$cells[d]=p);var m=\"ace_gutter-cell \";a[v]&&(m+=a[v]),f[v]&&(m+=f[v]),this.$annotations[v]&&(m+=this.$annotations[v].className),p.element.className!=m&&(p.element.className=m);var g=t.getRowLength(v)*e.lineHeight+\"px\";g!=p.element.style.height&&(p.element.style.height=g);if(u){var y=u[v];y==null&&(y=u[v]=t.getFoldWidget(v))}if(y){p.foldWidget||(p.foldWidget=r.createElement(\"span\"),p.element.appendChild(p.foldWidget));var m=\"ace_fold-widget ace_\"+y;y==\"start\"&&v==o&&v<s.end.row?m+=\" ace_closed\":m+=\" ace_open\",p.foldWidget.className!=m&&(p.foldWidget.className=m);var g=e.lineHeight+\"px\";p.foldWidget.style.height!=g&&(p.foldWidget.style.height=g)}else p.foldWidget&&(p.element.removeChild(p.foldWidget),p.foldWidget=null);var b=c=h?h.getText(t,v):v+l;b!=p.textNode.data&&(p.textNode.data=b),v++}this.element.style.height=e.minHeight+\"px\";if(this.$fixedWidth||t.$useWrapMode)c=t.getLength()+l;var w=h?h.getWidth(t,c,e):c.toString().length*e.characterWidth,E=this.$padding||this.$computePadding();w+=E.left+E.right,w!==this.gutterWidth&&!isNaN(w)&&(this.gutterWidth=w,this.element.style.width=Math.ceil(this.gutterWidth)+\"px\",this._emit(\"changeGutterWidth\",w))},this.$fixedWidth=!1,this.$showLineNumbers=!0,this.$renderer=\"\",this.setShowLineNumbers=function(e){this.$renderer=!e&&{getWidth:function(){return\"\"},getText:function(){return\"\"}}},this.getShowLineNumbers=function(){return this.$showLineNumbers},this.$showFoldWidgets=!0,this.setShowFoldWidgets=function(e){e?r.addCssClass(this.element,\"ace_folding-enabled\"):r.removeCssClass(this.element,\"ace_folding-enabled\"),this.$showFoldWidgets=e,this.$padding=null},this.getShowFoldWidgets=function(){return this.$showFoldWidgets},this.$computePadding=function(){if(!this.element.firstChild)return{left:0,right:0};var e=r.computedStyle(this.element.firstChild);return this.$padding={},this.$padding.left=parseInt(e.paddingLeft)+1||0,this.$padding.right=parseInt(e.paddingRight)||0,this.$padding},this.getRegion=function(e){var t=this.$padding||this.$computePadding(),n=this.element.getBoundingClientRect();if(e.x<t.left+n.left)return\"markers\";if(this.$showFoldWidgets&&e.x>n.right-t.right)return\"foldWidgets\"}}).call(u.prototype),t.Gutter=u}),ace.define(\"ace/layer/marker\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";var r=e(\"../range\").Range,i=e(\"../lib/dom\"),s=function(e){this.element=i.createElement(\"div\"),this.element.className=\"ace_layer ace_marker-layer\",e.appendChild(this.element)};(function(){this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setMarkers=function(e){this.markers=e},this.update=function(e){var e=e||this.config;if(!e)return;this.config=e;var t=[];for(var n in this.markers){var r=this.markers[n];if(!r.range){r.update(t,this,this.session,e);continue}var i=r.range.clipRows(e.firstRow,e.lastRow);if(i.isEmpty())continue;i=i.toScreenRange(this.session);if(r.renderer){var s=this.$getTop(i.start.row,e),o=this.$padding+i.start.column*e.characterWidth;r.renderer(t,i,o,s,e)}else r.type==\"fullLine\"?this.drawFullLineMarker(t,i,r.clazz,e):r.type==\"screenLine\"?this.drawScreenLineMarker(t,i,r.clazz,e):i.isMultiLine()?r.type==\"text\"?this.drawTextMarker(t,i,r.clazz,e):this.drawMultiLineMarker(t,i,r.clazz,e):this.drawSingleLineMarker(t,i,r.clazz+\" ace_start\",e)}this.element.innerHTML=t.join(\"\")},this.$getTop=function(e,t){return(e-t.firstRowScreen)*t.lineHeight},this.drawTextMarker=function(e,t,n,i,s){var o=t.start.row,u=new r(o,t.start.column,o,this.session.getScreenLastRowColumn(o));this.drawSingleLineMarker(e,u,n+\" ace_start\",i,1,s),o=t.end.row,u=new r(o,0,o,t.end.column),this.drawSingleLineMarker(e,u,n,i,0,s);for(o=t.start.row+1;o<t.end.row;o++)u.start.row=o,u.end.row=o,u.end.column=this.session.getScreenLastRowColumn(o),this.drawSingleLineMarker(e,u,n,i,1,s)},this.drawMultiLineMarker=function(e,t,n,r,i){var s=this.$padding,o=r.lineHeight,u=this.$getTop(t.start.row,r),a=s+t.start.column*r.characterWidth;i=i||\"\",e.push(\"<div class='\",n,\" ace_start' style='\",\"height:\",o,\"px;\",\"right:0;\",\"top:\",u,\"px;\",\"left:\",a,\"px;\",i,\"'></div>\"),u=this.$getTop(t.end.row,r);var f=t.end.column*r.characterWidth;e.push(\"<div class='\",n,\"' style='\",\"height:\",o,\"px;\",\"width:\",f,\"px;\",\"top:\",u,\"px;\",\"left:\",s,\"px;\",i,\"'></div>\"),o=(t.end.row-t.start.row-1)*r.lineHeight;if(o<0)return;u=this.$getTop(t.start.row+1,r),e.push(\"<div class='\",n,\"' style='\",\"height:\",o,\"px;\",\"right:0;\",\"top:\",u,\"px;\",\"left:\",s,\"px;\",i,\"'></div>\")},this.drawSingleLineMarker=function(e,t,n,r,i,s){var o=r.lineHeight,u=(t.end.column+(i||0)-t.start.column)*r.characterWidth,a=this.$getTop(t.start.row,r),f=this.$padding+t.start.column*r.characterWidth;e.push(\"<div class='\",n,\"' style='\",\"height:\",o,\"px;\",\"width:\",u,\"px;\",\"top:\",a,\"px;\",\"left:\",f,\"px;\",s||\"\",\"'></div>\")},this.drawFullLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;t.start.row!=t.end.row&&(o+=this.$getTop(t.end.row,r)-s),e.push(\"<div class='\",n,\"' style='\",\"height:\",o,\"px;\",\"top:\",s,\"px;\",\"left:0;right:0;\",i||\"\",\"'></div>\")},this.drawScreenLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;e.push(\"<div class='\",n,\"' style='\",\"height:\",o,\"px;\",\"top:\",s,\"px;\",\"left:0;right:0;\",i||\"\",\"'></div>\")}}).call(s.prototype),t.Marker=s}),ace.define(\"ace/layer/text\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/lib/useragent\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"../lib/dom\"),s=e(\"../lib/lang\"),o=e(\"../lib/useragent\"),u=e(\"../lib/event_emitter\").EventEmitter,a=function(e){this.element=i.createElement(\"div\"),this.element.className=\"ace_layer ace_text-layer\",e.appendChild(this.element),this.$updateEolChar=this.$updateEolChar.bind(this)};(function(){r.implement(this,u),this.EOF_CHAR=\"\\u00b6\",this.EOL_CHAR_LF=\"\\u00ac\",this.EOL_CHAR_CRLF=\"\\u00a4\",this.EOL_CHAR=this.EOL_CHAR_LF,this.TAB_CHAR=\"\\u2192\",this.SPACE_CHAR=\"\\u00b7\",this.$padding=0,this.$updateEolChar=function(){var e=this.session.doc.getNewLineCharacter()==\"\\n\"?this.EOL_CHAR_LF:this.EOL_CHAR_CRLF;if(this.EOL_CHAR!=e)return this.EOL_CHAR=e,!0},this.setPadding=function(e){this.$padding=e,this.element.style.padding=\"0 \"+e+\"px\"},this.getLineHeight=function(){return this.$fontMetrics.$characterSize.height||0},this.getCharacterWidth=function(){return this.$fontMetrics.$characterSize.width||0},this.$setFontMetrics=function(e){this.$fontMetrics=e,this.$fontMetrics.on(\"changeCharacterSize\",function(e){this._signal(\"changeCharacterSize\",e)}.bind(this)),this.$pollSizeChanges()},this.checkForSizeChanges=function(){this.$fontMetrics.checkForSizeChanges()},this.$pollSizeChanges=function(){return this.$pollSizeChangesTimer=this.$fontMetrics.$pollSizeChanges()},this.setSession=function(e){this.session=e,e&&this.$computeTabString()},this.showInvisibles=!1,this.setShowInvisibles=function(e){return this.showInvisibles==e?!1:(this.showInvisibles=e,this.$computeTabString(),!0)},this.displayIndentGuides=!0,this.setDisplayIndentGuides=function(e){return this.displayIndentGuides==e?!1:(this.displayIndentGuides=e,this.$computeTabString(),!0)},this.$tabStrings=[],this.onChangeTabSize=this.$computeTabString=function(){var e=this.session.getTabSize();this.tabSize=e;var t=this.$tabStrings=[0];for(var n=1;n<e+1;n++)this.showInvisibles?t.push(\"<span class='ace_invisible ace_invisible_tab'>\"+this.TAB_CHAR+s.stringRepeat(\"\\u00a0\",n-1)+\"</span>\"):t.push(s.stringRepeat(\"\\u00a0\",n));if(this.displayIndentGuides){this.$indentGuideRe=/\\s\\S| \\t|\\t |\\s$/;var r=\"ace_indent-guide\",i=\"\",o=\"\";if(this.showInvisibles){r+=\" ace_invisible\",i=\" ace_invisible_space\",o=\" ace_invisible_tab\";var u=s.stringRepeat(this.SPACE_CHAR,this.tabSize),a=this.TAB_CHAR+s.stringRepeat(\"\\u00a0\",this.tabSize-1)}else var u=s.stringRepeat(\"\\u00a0\",this.tabSize),a=u;this.$tabStrings[\" \"]=\"<span class='\"+r+i+\"'>\"+u+\"</span>\",this.$tabStrings[\"  \"]=\"<span class='\"+r+o+\"'>\"+a+\"</span>\"}},this.updateLines=function(e,t,n){(this.config.lastRow!=e.lastRow||this.config.firstRow!=e.firstRow)&&this.scrollLines(e),this.config=e;var r=Math.max(t,e.firstRow),i=Math.min(n,e.lastRow),s=this.element.childNodes,o=0;for(var u=e.firstRow;u<r;u++){var a=this.session.getFoldLine(u);if(a){if(a.containsRow(r)){r=a.start.row;break}u=a.end.row}o++}var u=r,a=this.session.getNextFoldLine(u),f=a?a.start.row:Infinity;for(;;){u>f&&(u=a.end.row+1,a=this.session.getNextFoldLine(u,a),f=a?a.start.row:Infinity);if(u>i)break;var l=s[o++];if(l){var c=[];this.$renderLine(c,u,!this.$useLineGroups(),u==f?a:!1),l.style.height=e.lineHeight*this.session.getRowLength(u)+\"px\",l.innerHTML=c.join(\"\")}u++}},this.scrollLines=function(e){var t=this.config;this.config=e;if(!t||t.lastRow<e.firstRow)return this.update(e);if(e.lastRow<t.firstRow)return this.update(e);var n=this.element;if(t.firstRow<e.firstRow)for(var r=this.session.getFoldedRowCount(t.firstRow,e.firstRow-1);r>0;r--)n.removeChild(n.firstChild);if(t.lastRow>e.lastRow)for(var r=this.session.getFoldedRowCount(e.lastRow+1,t.lastRow);r>0;r--)n.removeChild(n.lastChild);if(e.firstRow<t.firstRow){var i=this.$renderLinesFragment(e,e.firstRow,t.firstRow-1);n.firstChild?n.insertBefore(i,n.firstChild):n.appendChild(i)}if(e.lastRow>t.lastRow){var i=this.$renderLinesFragment(e,t.lastRow+1,e.lastRow);n.appendChild(i)}},this.$renderLinesFragment=function(e,t,n){var r=this.element.ownerDocument.createDocumentFragment(),s=t,o=this.session.getNextFoldLine(s),u=o?o.start.row:Infinity;for(;;){s>u&&(s=o.end.row+1,o=this.session.getNextFoldLine(s,o),u=o?o.start.row:Infinity);if(s>n)break;var a=i.createElement(\"div\"),f=[];this.$renderLine(f,s,!1,s==u?o:!1),a.innerHTML=f.join(\"\");if(this.$useLineGroups())a.className=\"ace_line_group\",r.appendChild(a),a.style.height=e.lineHeight*this.session.getRowLength(s)+\"px\";else while(a.firstChild)r.appendChild(a.firstChild);s++}return r},this.update=function(e){this.config=e;var t=[],n=e.firstRow,r=e.lastRow,i=n,s=this.session.getNextFoldLine(i),o=s?s.start.row:Infinity;for(;;){i>o&&(i=s.end.row+1,s=this.session.getNextFoldLine(i,s),o=s?s.start.row:Infinity);if(i>r)break;this.$useLineGroups()&&t.push(\"<div class='ace_line_group' style='height:\",e.lineHeight*this.session.getRowLength(i),\"px'>\"),this.$renderLine(t,i,!1,i==o?s:!1),this.$useLineGroups()&&t.push(\"</div>\"),i++}this.element.innerHTML=t.join(\"\")},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(e,t,n,r){var i=this,o=/\\t|&|<|( +)|([\\x00-\\x1f\\x80-\\xa0\\xad\\u1680\\u180E\\u2000-\\u200f\\u2028\\u2029\\u202F\\u205F\\u3000\\uFEFF])|[\\u1100-\\u115F\\u11A3-\\u11A7\\u11FA-\\u11FF\\u2329-\\u232A\\u2E80-\\u2E99\\u2E9B-\\u2EF3\\u2F00-\\u2FD5\\u2FF0-\\u2FFB\\u3000-\\u303E\\u3041-\\u3096\\u3099-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u3190-\\u31BA\\u31C0-\\u31E3\\u31F0-\\u321E\\u3220-\\u3247\\u3250-\\u32FE\\u3300-\\u4DBF\\u4E00-\\uA48C\\uA490-\\uA4C6\\uA960-\\uA97C\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFAFF\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE66\\uFE68-\\uFE6B\\uFF01-\\uFF60\\uFFE0-\\uFFE6]/g,u=function(e,n,r,o,u){if(n)return i.showInvisibles?\"<span class='ace_invisible ace_invisible_space'>\"+s.stringRepeat(i.SPACE_CHAR,e.length)+\"</span>\":s.stringRepeat(\"\\u00a0\",e.length);if(e==\"&\")return\"&#38;\";if(e==\"<\")return\"&#60;\";if(e==\"    \"){var a=i.session.getScreenTabSize(t+o);return t+=a-1,i.$tabStrings[a]}if(e==\"\\u3000\"){var f=i.showInvisibles?\"ace_cjk ace_invisible ace_invisible_space\":\"ace_cjk\",l=i.showInvisibles?i.SPACE_CHAR:\"\";return t+=1,\"<span class='\"+f+\"' style='width:\"+i.config.characterWidth*2+\"px'>\"+l+\"</span>\"}return r?\"<span class='ace_invisible ace_invisible_space ace_invalid'>\"+i.SPACE_CHAR+\"</span>\":(t+=1,\"<span class='ace_cjk' style='width:\"+i.config.characterWidth*2+\"px'>\"+e+\"</span>\")},a=r.replace(o,u);if(!this.$textToken[n.type]){var f=\"ace_\"+n.type.replace(/\\./g,\" ace_\"),l=\"\";n.type==\"fold\"&&(l=\" style='width:\"+n.value.length*this.config.characterWidth+\"px;' \"),e.push(\"<span class='\",f,\"'\",l,\">\",a,\"</span>\")}else e.push(a);return t+r.length},this.renderIndentGuide=function(e,t,n){var r=t.search(this.$indentGuideRe);return r<=0||r>=n?t:t[0]==\" \"?(r-=r%this.tabSize,e.push(s.stringRepeat(this.$tabStrings[\" \"],r/this.tabSize)),t.substr(r)):t[0]==\" \"?(e.push(s.stringRepeat(this.$tabStrings[\" \"],r)),t.substr(r)):t},this.$renderWrappedLine=function(e,t,n,r){var i=0,s=0,o=n[0],u=0;for(var a=0;a<t.length;a++){var f=t[a],l=f.value;if(a==0&&this.displayIndentGuides){i=l.length,l=this.renderIndentGuide(e,l,o);if(!l)continue;i-=l.length}if(i+l.length<o)u=this.$renderToken(e,u,f,l),i+=l.length;else{while(i+l.length>=o)u=this.$renderToken(e,u,f,l.substring(0,o-i)),l=l.substring(o-i),i=o,r||e.push(\"</div>\",\"<div class='ace_line' style='height:\",this.config.lineHeight,\"px'>\"),s++,u=0,o=n[s]||Number.MAX_VALUE;l.length!=0&&(i+=l.length,u=this.$renderToken(e,u,f,l))}}},this.$renderSimpleLine=function(e,t){var n=0,r=t[0],i=r.value;this.displayIndentGuides&&(i=this.renderIndentGuide(e,i)),i&&(n=this.$renderToken(e,n,r,i));for(var s=1;s<t.length;s++)r=t[s],i=r.value,n=this.$renderToken(e,n,r,i)},this.$renderLine=function(e,t,n,r){!r&&r!=0&&(r=this.session.getFoldLine(t));if(r)var i=this.$getFoldLineTokens(t,r);else var i=this.session.getTokens(t);n||e.push(\"<div class='ace_line' style='height:\",this.config.lineHeight*(this.$useLineGroups()?1:this.session.getRowLength(t)),\"px'>\");if(i.length){var s=this.session.getRowSplitData(t);s&&s.length?this.$renderWrappedLine(e,i,s,n):this.$renderSimpleLine(e,i)}this.showInvisibles&&(r&&(t=r.end.row),e.push(\"<span class='ace_invisible ace_invisible_eol'>\",t==this.session.getLength()-1?this.EOF_CHAR:this.EOL_CHAR,\"</span>\")),n||e.push(\"</div>\")},this.$getFoldLineTokens=function(e,t){function i(e,t,n){var i=0,s=0;while(s+e[i].value.length<t){s+=e[i].value.length,i++;if(i==e.length)return}if(s!=t){var o=e[i].value.substring(t-s);o.length>n-t&&(o=o.substring(0,n-t)),r.push({type:e[i].type,value:o}),s=t+o.length,i+=1}while(s<n&&i<e.length){var o=e[i].value;o.length+s>n?r.push({type:e[i].type,value:o.substring(0,n-s)}):r.push(e[i]),s+=o.length,i+=1}}var n=this.session,r=[],s=n.getTokens(e);return t.walk(function(e,t,o,u,a){e!=null?r.push({type:\"fold\",value:e}):(a&&(s=n.getTokens(t)),s.length&&i(s,u,o))},t.end.row,this.session.getLine(t.end.row).length),r},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$measureNode&&this.$measureNode.parentNode.removeChild(this.$measureNode),delete this.$measureNode}}).call(a.prototype),t.Text=a}),ace.define(\"ace/layer/cursor\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";var r=e(\"../lib/dom\"),i,s=function(e){this.element=r.createElement(\"div\"),this.element.className=\"ace_layer ace_cursor-layer\",e.appendChild(this.element),i===undefined&&(i=\"opacity\"in this.element),this.isVisible=!1,this.isBlinking=!0,this.blinkInterval=1e3,this.smoothBlinking=!1,this.cursors=[],this.cursor=this.addCursor(),r.addCssClass(this.element,\"ace_hidden-cursors\"),this.$updateCursors=this.$updateVisibility.bind(this)};(function(){this.$updateVisibility=function(e){var t=this.cursors;for(var n=t.length;n--;)t[n].style.visibility=e?\"\":\"hidden\"},this.$updateOpacity=function(e){var t=this.cursors;for(var n=t.length;n--;)t[n].style.opacity=e?\"\":\"0\"},this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setBlinking=function(e){e!=this.isBlinking&&(this.isBlinking=e,this.restartTimer())},this.setBlinkInterval=function(e){e!=this.blinkInterval&&(this.blinkInterval=e,this.restartTimer())},this.setSmoothBlinking=function(e){e!=this.smoothBlinking&&!i&&(this.smoothBlinking=e,r.setCssClass(this.element,\"ace_smooth-blinking\",e),this.$updateCursors(!0),this.$updateCursors=(e?this.$updateOpacity:this.$updateVisibility).bind(this),this.restartTimer())},this.addCursor=function(){var e=r.createElement(\"div\");return e.className=\"ace_cursor\",this.element.appendChild(e),this.cursors.push(e),e},this.removeCursor=function(){if(this.cursors.length>1){var e=this.cursors.pop();return e.parentNode.removeChild(e),e}},this.hideCursor=function(){this.isVisible=!1,r.addCssClass(this.element,\"ace_hidden-cursors\"),this.restartTimer()},this.showCursor=function(){this.isVisible=!0,r.removeCssClass(this.element,\"ace_hidden-cursors\"),this.restartTimer()},this.restartTimer=function(){var e=this.$updateCursors;clearInterval(this.intervalId),clearTimeout(this.timeoutId),this.smoothBlinking&&r.removeCssClass(this.element,\"ace_smooth-blinking\"),e(!0);if(!this.isBlinking||!this.blinkInterval||!this.isVisible)return;this.smoothBlinking&&setTimeout(function(){r.addCssClass(this.element,\"ace_smooth-blinking\")}.bind(this));var t=function(){this.timeoutId=setTimeout(function(){e(!1)},.6*this.blinkInterval)}.bind(this);this.intervalId=setInterval(function(){e(!0),t()},this.blinkInterval),t()},this.getPixelPosition=function(e,t){if(!this.config||!this.session)return{left:0,top:0};e||(e=this.session.selection.getCursor());var n=this.session.documentToScreenPosition(e),r=this.$padding+n.column*this.config.characterWidth,i=(n.row-(t?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:r,top:i}},this.update=function(e){this.config=e;var t=this.session.$selectionMarkers,n=0,r=0;if(t===undefined||t.length===0)t=[{cursor:null}];for(var n=0,i=t.length;n<i;n++){var s=this.getPixelPosition(t[n].cursor,!0);if((s.top>e.height+e.offset||s.top<0)&&n>1)continue;var o=(this.cursors[r++]||this.addCursor()).style;o.left=s.left+\"px\",o.top=s.top+\"px\",o.width=e.characterWidth+\"px\",o.height=e.lineHeight+\"px\"}while(this.cursors.length>r)this.removeCursor();var u=this.session.getOverwrite();this.$setOverwrite(u),this.$pixelPos=s,this.restartTimer()},this.$setOverwrite=function(e){e!=this.overwrite&&(this.overwrite=e,e?r.addCssClass(this.element,\"ace_overwrite-cursors\"):r.removeCssClass(this.element,\"ace_overwrite-cursors\"))},this.destroy=function(){clearInterval(this.intervalId),clearTimeout(this.timeoutId)}}).call(s.prototype),t.Cursor=s}),ace.define(\"ace/scrollbar\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/dom\"),s=e(\"./lib/event\"),o=e(\"./lib/event_emitter\").EventEmitter,u=function(e){this.element=i.createElement(\"div\"),this.element.className=\"ace_scrollbar ace_scrollbar\"+this.classSuffix,this.inner=i.createElement(\"div\"),this.inner.className=\"ace_scrollbar-inner\",this.element.appendChild(this.inner),e.appendChild(this.element),this.setVisible(!1),this.skipEvent=!1,s.addListener(this.element,\"scroll\",this.onScroll.bind(this)),s.addListener(this.element,\"mousedown\",s.preventDefault)};(function(){r.implement(this,o),this.setVisible=function(e){this.element.style.display=e?\"\":\"none\",this.isVisible=e}}).call(u.prototype);var a=function(e,t){u.call(this,e),this.scrollTop=0,t.$scrollbarWidth=this.width=i.scrollbarWidth(e.ownerDocument),this.inner.style.width=this.element.style.width=(this.width||15)+5+\"px\"};r.inherits(a,u),function(){this.classSuffix=\"-v\",this.onScroll=function(){this.skipEvent||(this.scrollTop=this.element.scrollTop,this._emit(\"scroll\",{data:this.scrollTop})),this.skipEvent=!1},this.getWidth=function(){return this.isVisible?this.width:0},this.setHeight=function(e){this.element.style.height=e+\"px\"},this.setInnerHeight=function(e){this.inner.style.height=e+\"px\"},this.setScrollHeight=function(e){this.inner.style.height=e+\"px\"},this.setScrollTop=function(e){this.scrollTop!=e&&(this.skipEvent=!0,this.scrollTop=this.element.scrollTop=e)}}.call(a.prototype);var f=function(e,t){u.call(this,e),this.scrollLeft=0,this.height=t.$scrollbarWidth,this.inner.style.height=this.element.style.height=(this.height||15)+5+\"px\"};r.inherits(f,u),function(){this.classSuffix=\"-h\",this.onScroll=function(){this.skipEvent||(this.scrollLeft=this.element.scrollLeft,this._emit(\"scroll\",{data:this.scrollLeft})),this.skipEvent=!1},this.getHeight=function(){return this.isVisible?this.height:0},this.setWidth=function(e){this.element.style.width=e+\"px\"},this.setInnerWidth=function(e){this.inner.style.width=e+\"px\"},this.setScrollWidth=function(e){this.inner.style.width=e+\"px\"},this.setScrollLeft=function(e){this.scrollLeft!=e&&(this.skipEvent=!0,this.scrollLeft=this.element.scrollLeft=e)}}.call(f.prototype),t.ScrollBar=a,t.ScrollBarV=a,t.ScrollBarH=f,t.VScrollBar=a,t.HScrollBar=f}),ace.define(\"ace/renderloop\",[\"require\",\"exports\",\"module\",\"ace/lib/event\"],function(e,t,n){\"use strict\";var r=e(\"./lib/event\"),i=function(e,t){this.onRender=e,this.pending=!1,this.changes=0,this.window=t||window};(function(){this.schedule=function(e){this.changes=this.changes|e;if(!this.pending&&this.changes){this.pending=!0;var t=this;r.nextFrame(function(){t.pending=!1;var e;while(e=t.changes)t.changes=0,t.onRender(e)},this.window)}}}).call(i.prototype),t.RenderLoop=i}),ace.define(\"ace/layer/font_metrics\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/lib/lang\",\"ace/lib/useragent\",\"ace/lib/event_emitter\"],function(e,t,n){var r=e(\"../lib/oop\"),i=e(\"../lib/dom\"),s=e(\"../lib/lang\"),o=e(\"../lib/useragent\"),u=e(\"../lib/event_emitter\").EventEmitter,a=0,f=t.FontMetrics=function(e,t){this.el=i.createElement(\"div\"),this.$setMeasureNodeStyles(this.el.style,!0),this.$main=i.createElement(\"div\"),this.$setMeasureNodeStyles(this.$main.style),this.$measureNode=i.createElement(\"div\"),this.$setMeasureNodeStyles(this.$measureNode.style),this.el.appendChild(this.$main),this.el.appendChild(this.$measureNode),e.appendChild(this.el),a||this.$testFractionalRect(),this.$measureNode.innerHTML=s.stringRepeat(\"X\",a),this.$characterSize={width:0,height:0},this.checkForSizeChanges()};(function(){r.implement(this,u),this.$characterSize={width:0,height:0},this.$testFractionalRect=function(){var e=i.createElement(\"div\");this.$setMeasureNodeStyles(e.style),e.style.width=\"0.2px\",document.documentElement.appendChild(e);var t=e.getBoundingClientRect().width;t>0&&t<1?a=50:a=100,e.parentNode.removeChild(e)},this.$setMeasureNodeStyles=function(e,t){e.width=e.height=\"auto\",e.left=e.top=\"-100px\",e.visibility=\"hidden\",e.position=\"fixed\",e.whiteSpace=\"pre\",o.isIE<8?e[\"font-family\"]=\"inherit\":e.font=\"inherit\",e.overflow=t?\"hidden\":\"visible\"},this.checkForSizeChanges=function(){var e=this.$measureSizes();if(e&&(this.$characterSize.width!==e.width||this.$characterSize.height!==e.height)){this.$measureNode.style.fontWeight=\"bold\";var t=this.$measureSizes();this.$measureNode.style.fontWeight=\"\",this.$characterSize=e,this.charSizes=Object.create(null),this.allowBoldFonts=t&&t.width===e.width&&t.height===e.height,this._emit(\"changeCharacterSize\",{data:e})}},this.$pollSizeChanges=function(){if(this.$pollSizeChangesTimer)return this.$pollSizeChangesTimer;var e=this;return this.$pollSizeChangesTimer=setInterval(function(){e.checkForSizeChanges()},500)},this.setPolling=function(e){e?this.$pollSizeChanges():this.$pollSizeChangesTimer&&this.$pollSizeChangesTimer},this.$measureSizes=function(){if(a===50){var e=null;try{e=this.$measureNode.getBoundingClientRect()}catch(t){e={width:0,height:0}}var n={height:e.height,width:e.width/a}}else var n={height:this.$measureNode.clientHeight,width:this.$measureNode.clientWidth/a};return n.width===0||n.height===0?null:n},this.$measureCharWidth=function(e){this.$main.innerHTML=s.stringRepeat(e,a);var t=this.$main.getBoundingClientRect();return t.width/a},this.getCharacterWidth=function(e){var t=this.charSizes[e];return t===undefined&&(this.charSizes[e]=this.$measureCharWidth(e)/this.$characterSize.width),t},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.el&&this.el.parentNode&&this.el.parentNode.removeChild(this.el)}}).call(f.prototype)}),ace.define(\"ace/virtual_renderer\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/config\",\"ace/lib/useragent\",\"ace/layer/gutter\",\"ace/layer/marker\",\"ace/layer/text\",\"ace/layer/cursor\",\"ace/scrollbar\",\"ace/scrollbar\",\"ace/renderloop\",\"ace/layer/font_metrics\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/dom\"),s=e(\"./config\"),o=e(\"./lib/useragent\"),u=e(\"./layer/gutter\").Gutter,a=e(\"./layer/marker\").Marker,f=e(\"./layer/text\").Text,l=e(\"./layer/cursor\").Cursor,c=e(\"./scrollbar\").HScrollBar,h=e(\"./scrollbar\").VScrollBar,p=e(\"./renderloop\").RenderLoop,d=e(\"./layer/font_metrics\").FontMetrics,v=e(\"./lib/event_emitter\").EventEmitter,m='.ace_editor {position: relative;overflow: hidden;font: 12px/normal \\'Monaco\\', \\'Menlo\\', \\'Ubuntu Mono\\', \\'Consolas\\', \\'source-code-pro\\', monospace;direction: ltr;}.ace_scroller {position: absolute;overflow: hidden;top: 0;bottom: 0;background-color: inherit;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;cursor: text;}.ace_content {position: absolute;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;min-width: 100%;}.ace_dragging .ace_scroller:before{position: absolute;top: 0;left: 0;right: 0;bottom: 0;content: \\'\\';background: rgba(250, 250, 250, 0.01);z-index: 1000;}.ace_dragging.ace_dark .ace_scroller:before{background: rgba(0, 0, 0, 0.01);}.ace_selecting, .ace_selecting * {cursor: text !important;}.ace_gutter {position: absolute;overflow : hidden;width: auto;top: 0;bottom: 0;left: 0;cursor: default;z-index: 4;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;}.ace_gutter-active-line {position: absolute;left: 0;right: 0;}.ace_scroller.ace_scroll-left {box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;}.ace_gutter-cell {padding-left: 19px;padding-right: 6px;background-repeat: no-repeat;}.ace_gutter-cell.ace_error {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==\");background-repeat: no-repeat;background-position: 2px center;}.ace_gutter-cell.ace_warning {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==\");background-position: 2px center;}.ace_gutter-cell.ace_info {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=\");background-position: 2px center;}.ace_dark .ace_gutter-cell.ace_info {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC\");}.ace_scrollbar {position: absolute;right: 0;bottom: 0;z-index: 6;}.ace_scrollbar-inner {position: absolute;cursor: text;left: 0;top: 0;}.ace_scrollbar-v{overflow-x: hidden;overflow-y: scroll;top: 0;}.ace_scrollbar-h {overflow-x: scroll;overflow-y: hidden;left: 0;}.ace_print-margin {position: absolute;height: 100%;}.ace_text-input {position: absolute;z-index: 0;width: 0.5em;height: 1em;opacity: 0;background: transparent;-moz-appearance: none;appearance: none;border: none;resize: none;outline: none;overflow: hidden;font: inherit;padding: 0 1px;margin: 0 -1px;text-indent: -1em;-ms-user-select: text;-moz-user-select: text;-webkit-user-select: text;user-select: text;}.ace_text-input.ace_composition {background: inherit;color: inherit;z-index: 1000;opacity: 1;text-indent: 0;}.ace_layer {z-index: 1;position: absolute;overflow: hidden;white-space: pre;height: 100%;width: 100%;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;pointer-events: none;}.ace_gutter-layer {position: relative;width: auto;text-align: right;pointer-events: auto;}.ace_text-layer {font: inherit !important;}.ace_cjk {display: inline-block;text-align: center;}.ace_cursor-layer {z-index: 4;}.ace_cursor {z-index: 4;position: absolute;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;border-left: 2px solid}.ace_slim-cursors .ace_cursor {border-left-width: 1px;}.ace_overwrite-cursors .ace_cursor {border-left-width: 0;border-bottom: 1px solid;}.ace_hidden-cursors .ace_cursor {opacity: 0.2;}.ace_smooth-blinking .ace_cursor {-webkit-transition: opacity 0.18s;transition: opacity 0.18s;}.ace_editor.ace_multiselect .ace_cursor {border-left-width: 1px;}.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {position: absolute;z-index: 3;}.ace_marker-layer .ace_selection {position: absolute;z-index: 5;}.ace_marker-layer .ace_bracket {position: absolute;z-index: 6;}.ace_marker-layer .ace_active-line {position: absolute;z-index: 2;}.ace_marker-layer .ace_selected-word {position: absolute;z-index: 4;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;}.ace_line .ace_fold {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;display: inline-block;height: 11px;margin-top: -2px;vertical-align: middle;background-image:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=\");background-repeat: no-repeat, repeat-x;background-position: center center, top left;color: transparent;border: 1px solid black;border-radius: 2px;cursor: pointer;pointer-events: auto;}.ace_dark .ace_fold {}.ace_fold:hover{background-image:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC\");}.ace_tooltip {background-color: #FFF;background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));border: 1px solid gray;border-radius: 1px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);color: black;max-width: 100%;padding: 3px 4px;position: fixed;z-index: 999999;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;cursor: default;white-space: pre;word-wrap: break-word;line-height: normal;font-style: normal;font-weight: normal;letter-spacing: normal;pointer-events: none;}.ace_folding-enabled > .ace_gutter-cell {padding-right: 13px;}.ace_fold-widget {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;margin: 0 -12px 0 1px;display: none;width: 11px;vertical-align: top;background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==\");background-repeat: no-repeat;background-position: center;border-radius: 3px;border: 1px solid transparent;cursor: pointer;}.ace_folding-enabled .ace_fold-widget {display: inline-block;   }.ace_fold-widget.ace_end {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==\");}.ace_fold-widget.ace_closed {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==\");}.ace_fold-widget:hover {border: 1px solid rgba(0, 0, 0, 0.3);background-color: rgba(255, 255, 255, 0.2);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);}.ace_fold-widget:active {border: 1px solid rgba(0, 0, 0, 0.4);background-color: rgba(0, 0, 0, 0.05);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);}.ace_dark .ace_fold-widget {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\");}.ace_dark .ace_fold-widget.ace_end {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\");}.ace_dark .ace_fold-widget.ace_closed {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\");}.ace_dark .ace_fold-widget:hover {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);background-color: rgba(255, 255, 255, 0.1);}.ace_dark .ace_fold-widget:active {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);}.ace_fold-widget.ace_invalid {background-color: #FFB4B4;border-color: #DE5555;}.ace_fade-fold-widgets .ace_fold-widget {-webkit-transition: opacity 0.4s ease 0.05s;transition: opacity 0.4s ease 0.05s;opacity: 0;}.ace_fade-fold-widgets:hover .ace_fold-widget {-webkit-transition: opacity 0.05s ease 0.05s;transition: opacity 0.05s ease 0.05s;opacity:1;}.ace_underline {text-decoration: underline;}.ace_bold {font-weight: bold;}.ace_nobold .ace_bold {font-weight: normal;}.ace_italic {font-style: italic;}.ace_error-marker {background-color: rgba(255, 0, 0,0.2);position: absolute;z-index: 9;}.ace_highlight-marker {background-color: rgba(255, 255, 0,0.2);position: absolute;z-index: 8;}';i.importCssString(m,\"ace_editor\");var g=function(e,t){var n=this;this.container=e||i.createElement(\"div\"),this.$keepTextAreaAtCursor=!o.isOldIE,i.addCssClass(this.container,\"ace_editor\"),this.setTheme(t),this.$gutter=i.createElement(\"div\"),this.$gutter.className=\"ace_gutter\",this.container.appendChild(this.$gutter),this.scroller=i.createElement(\"div\"),this.scroller.className=\"ace_scroller\",this.container.appendChild(this.scroller),this.content=i.createElement(\"div\"),this.content.className=\"ace_content\",this.scroller.appendChild(this.content),this.$gutterLayer=new u(this.$gutter),this.$gutterLayer.on(\"changeGutterWidth\",this.onGutterResize.bind(this)),this.$markerBack=new a(this.content);var r=this.$textLayer=new f(this.content);this.canvas=r.element,this.$markerFront=new a(this.content),this.$cursorLayer=new l(this.content),this.$horizScroll=!1,this.$vScroll=!1,this.scrollBar=this.scrollBarV=new h(this.container,this),this.scrollBarH=new c(this.container,this),this.scrollBarV.addEventListener(\"scroll\",function(e){n.$scrollAnimation||n.session.setScrollTop(e.data-n.scrollMargin.top)}),this.scrollBarH.addEventListener(\"scroll\",function(e){n.$scrollAnimation||n.session.setScrollLeft(e.data-n.scrollMargin.left)}),this.scrollTop=0,this.scrollLeft=0,this.cursorPos={row:0,column:0},this.$fontMetrics=new d(this.container,500),this.$textLayer.$setFontMetrics(this.$fontMetrics),this.$textLayer.addEventListener(\"changeCharacterSize\",function(e){n.updateCharacterSize(),n.onResize(!0,n.gutterWidth,n.$size.width,n.$size.height),n._signal(\"changeCharacterSize\",e)}),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0,$dirty:!0},this.layerConfig={width:1,padding:0,firstRow:0,firstRowScreen:0,lastRow:0,lineHeight:0,characterWidth:0,minHeight:1,maxHeight:1,offset:0,height:1,gutterOffset:1},this.scrollMargin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.$loop=new p(this.$renderChanges.bind(this),this.container.ownerDocument.defaultView),this.$loop.schedule(this.CHANGE_FULL),this.updateCharacterSize(),this.setPadding(4),s.resetOptions(this),s._emit(\"renderer\",this)};(function(){this.CHANGE_CURSOR=1,this.CHANGE_MARKER=2,this.CHANGE_GUTTER=4,this.CHANGE_SCROLL=8,this.CHANGE_LINES=16,this.CHANGE_TEXT=32,this.CHANGE_SIZE=64,this.CHANGE_MARKER_BACK=128,this.CHANGE_MARKER_FRONT=256,this.CHANGE_FULL=512,this.CHANGE_H_SCROLL=1024,r.implement(this,v),this.updateCharacterSize=function(){this.$textLayer.allowBoldFonts!=this.$allowBoldFonts&&(this.$allowBoldFonts=this.$textLayer.allowBoldFonts,this.setStyle(\"ace_nobold\",!this.$allowBoldFonts)),this.layerConfig.characterWidth=this.characterWidth=this.$textLayer.getCharacterWidth(),this.layerConfig.lineHeight=this.lineHeight=this.$textLayer.getLineHeight(),this.$updatePrintMargin()},this.setSession=function(e){this.session&&this.session.doc.off(\"changeNewLineMode\",this.onChangeNewLineMode),this.session=e,e&&this.scrollMargin.top&&e.getScrollTop()<=0&&e.setScrollTop(-this.scrollMargin.top),this.$cursorLayer.setSession(e),this.$markerBack.setSession(e),this.$markerFront.setSession(e),this.$gutterLayer.setSession(e),this.$textLayer.setSession(e);if(!e)return;this.$loop.schedule(this.CHANGE_FULL),this.session.$setFontMetrics(this.$fontMetrics),this.onChangeNewLineMode=this.onChangeNewLineMode.bind(this),this.onChangeNewLineMode(),this.session.doc.on(\"changeNewLineMode\",this.onChangeNewLineMode)},this.updateLines=function(e,t,n){t===undefined&&(t=Infinity),this.$changedLines?(this.$changedLines.firstRow>e&&(this.$changedLines.firstRow=e),this.$changedLines.lastRow<t&&(this.$changedLines.lastRow=t)):this.$changedLines={firstRow:e,lastRow:t};if(this.$changedLines.lastRow<this.layerConfig.firstRow){if(!n)return;this.$changedLines.lastRow=this.layerConfig.lastRow}if(this.$changedLines.firstRow>this.layerConfig.lastRow)return;this.$loop.schedule(this.CHANGE_LINES)},this.onChangeNewLineMode=function(){this.$loop.schedule(this.CHANGE_TEXT),this.$textLayer.$updateEolChar()},this.onChangeTabSize=function(){this.$loop.schedule(this.CHANGE_TEXT|this.CHANGE_MARKER),this.$textLayer.onChangeTabSize()},this.updateText=function(){this.$loop.schedule(this.CHANGE_TEXT)},this.updateFull=function(e){e?this.$renderChanges(this.CHANGE_FULL,!0):this.$loop.schedule(this.CHANGE_FULL)},this.updateFontSize=function(){this.$textLayer.checkForSizeChanges()},this.$changes=0,this.$updateSizeAsync=function(){this.$loop.pending?this.$size.$dirty=!0:this.onResize()},this.onResize=function(e,t,n,r){if(this.resizing>2)return;this.resizing>0?this.resizing++:this.resizing=e?1:0;var i=this.container;r||(r=i.clientHeight||i.scrollHeight),n||(n=i.clientWidth||i.scrollWidth);var s=this.$updateCachedSize(e,t,n,r);if(!this.$size.scrollerHeight||!n&&!r)return this.resizing=0;e&&(this.$gutterLayer.$padding=null),e?this.$renderChanges(s|this.$changes,!0):this.$loop.schedule(s|this.$changes),this.resizing&&(this.resizing=0)},this.$updateCachedSize=function(e,t,n,r){r-=this.$extraHeight||0;var i=0,s=this.$size,o={width:s.width,height:s.height,scrollerHeight:s.scrollerHeight,scrollerWidth:s.scrollerWidth};r&&(e||s.height!=r)&&(s.height=r,i|=this.CHANGE_SIZE,s.scrollerHeight=s.height,this.$horizScroll&&(s.scrollerHeight-=this.scrollBarH.getHeight()),this.scrollBarV.element.style.bottom=this.scrollBarH.getHeight()+\"px\",i|=this.CHANGE_SCROLL);if(n&&(e||s.width!=n)){i|=this.CHANGE_SIZE,s.width=n,t==null&&(t=this.$showGutter?this.$gutter.offsetWidth:0),this.gutterWidth=t,this.scrollBarH.element.style.left=this.scroller.style.left=t+\"px\",s.scrollerWidth=Math.max(0,n-t-this.scrollBarV.getWidth()),this.scrollBarH.element.style.right=this.scroller.style.right=this.scrollBarV.getWidth()+\"px\",this.scroller.style.bottom=this.scrollBarH.getHeight()+\"px\";if(this.session&&this.session.getUseWrapMode()&&this.adjustWrapLimit()||e)i|=this.CHANGE_FULL}return s.$dirty=!n||!r,i&&this._signal(\"resize\",o),i},this.onGutterResize=function(){var e=this.$showGutter?this.$gutter.offsetWidth:0;e!=this.gutterWidth&&(this.$changes|=this.$updateCachedSize(!0,e,this.$size.width,this.$size.height)),this.session.getUseWrapMode()&&this.adjustWrapLimit()?this.$loop.schedule(this.CHANGE_FULL):this.$size.$dirty?this.$loop.schedule(this.CHANGE_FULL):(this.$computeLayerConfig(),this.$loop.schedule(this.CHANGE_MARKER))},this.adjustWrapLimit=function(){var e=this.$size.scrollerWidth-this.$padding*2,t=Math.floor(e/this.characterWidth);return this.session.adjustWrapLimit(t,this.$showPrintMargin&&this.$printMarginColumn)},this.setAnimatedScroll=function(e){this.setOption(\"animatedScroll\",e)},this.getAnimatedScroll=function(){return this.$animatedScroll},this.setShowInvisibles=function(e){this.setOption(\"showInvisibles\",e)},this.getShowInvisibles=function(){return this.getOption(\"showInvisibles\")},this.getDisplayIndentGuides=function(){return this.getOption(\"displayIndentGuides\")},this.setDisplayIndentGuides=function(e){this.setOption(\"displayIndentGuides\",e)},this.setShowPrintMargin=function(e){this.setOption(\"showPrintMargin\",e)},this.getShowPrintMargin=function(){return this.getOption(\"showPrintMargin\")},this.setPrintMarginColumn=function(e){this.setOption(\"printMarginColumn\",e)},this.getPrintMarginColumn=function(){return this.getOption(\"printMarginColumn\")},this.getShowGutter=function(){return this.getOption(\"showGutter\")},this.setShowGutter=function(e){return this.setOption(\"showGutter\",e)},this.getFadeFoldWidgets=function(){return this.getOption(\"fadeFoldWidgets\")},this.setFadeFoldWidgets=function(e){this.setOption(\"fadeFoldWidgets\",e)},this.setHighlightGutterLine=function(e){this.setOption(\"highlightGutterLine\",e)},this.getHighlightGutterLine=function(){return this.getOption(\"highlightGutterLine\")},this.$updateGutterLineHighlight=function(){var e=this.$cursorLayer.$pixelPos,t=this.layerConfig.lineHeight;if(this.session.getUseWrapMode()){var n=this.session.selection.getCursor();n.column=0,e=this.$cursorLayer.getPixelPosition(n,!0),t*=this.session.getRowLength(n.row)}this.$gutterLineHighlight.style.top=e.top-this.layerConfig.offset+\"px\",this.$gutterLineHighlight.style.height=t+\"px\"},this.$updatePrintMargin=function(){if(!this.$showPrintMargin&&!this.$printMarginEl)return;if(!this.$printMarginEl){var e=i.createElement(\"div\");e.className=\"ace_layer ace_print-margin-layer\",this.$printMarginEl=i.createElement(\"div\"),this.$printMarginEl.className=\"ace_print-margin\",e.appendChild(this.$printMarginEl),this.content.insertBefore(e,this.content.firstChild)}var t=this.$printMarginEl.style;t.left=this.characterWidth*this.$printMarginColumn+this.$padding+\"px\",t.visibility=this.$showPrintMargin?\"visible\":\"hidden\",this.session&&this.session.$wrap==-1&&this.adjustWrapLimit()},this.getContainerElement=function(){return this.container},this.getMouseEventTarget=function(){return this.content},this.getTextAreaContainer=function(){return this.container},this.$moveTextAreaToCursor=function(){if(!this.$keepTextAreaAtCursor)return;var e=this.layerConfig,t=this.$cursorLayer.$pixelPos.top,n=this.$cursorLayer.$pixelPos.left;t-=e.offset;var r=this.lineHeight;if(t<0||t>e.height-r)return;var i=this.characterWidth;if(this.$composition){var s=this.textarea.value.replace(/^\\x01+/,\"\");i*=this.session.$getStringScreenWidth(s)[0]+2,r+=2}n-=this.scrollLeft,n>this.$size.scrollerWidth-i&&(n=this.$size.scrollerWidth-i),n+=this.gutterWidth,this.textarea.style.height=r+\"px\",this.textarea.style.width=i+\"px\",this.textarea.style.left=Math.min(n,this.$size.scrollerWidth-i)+\"px\",this.textarea.style.top=Math.min(t,this.$size.height-r)+\"px\"},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(this.layerConfig.offset===0?0:1)},this.getLastFullyVisibleRow=function(){var e=Math.floor((this.layerConfig.height+this.layerConfig.offset)/this.layerConfig.lineHeight);return this.layerConfig.firstRow-1+e},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(e){this.$padding=e,this.$textLayer.setPadding(e),this.$cursorLayer.setPadding(e),this.$markerFront.setPadding(e),this.$markerBack.setPadding(e),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.setScrollMargin=function(e,t,n,r){var i=this.scrollMargin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,i.top&&this.scrollTop<=0&&this.session&&this.session.setScrollTop(-i.top),this.updateFull()},this.getHScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setHScrollBarAlwaysVisible=function(e){this.setOption(\"hScrollBarAlwaysVisible\",e)},this.getVScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setVScrollBarAlwaysVisible=function(e){this.setOption(\"vScrollBarAlwaysVisible\",e)},this.$updateScrollBarV=function(){var e=this.layerConfig.maxHeight,t=this.$size.scrollerHeight;!this.$maxLines&&this.$scrollPastEnd&&(e-=(t-this.lineHeight)*this.$scrollPastEnd,this.scrollTop>e-t&&(e=this.scrollTop+t,this.scrollBarV.scrollTop=null)),this.scrollBarV.setScrollHeight(e+this.scrollMargin.v),this.scrollBarV.setScrollTop(this.scrollTop+this.scrollMargin.top)},this.$updateScrollBarH=function(){this.scrollBarH.setScrollWidth(this.layerConfig.width+2*this.$padding+this.scrollMargin.h),this.scrollBarH.setScrollLeft(this.scrollLeft+this.scrollMargin.left)},this.$frozen=!1,this.freeze=function(){this.$frozen=!0},this.unfreeze=function(){this.$frozen=!1},this.$renderChanges=function(e,t){this.$changes&&(e|=this.$changes,this.$changes=0);if(!this.session||!this.container.offsetWidth||this.$frozen||!e&&!t){this.$changes|=e;return}if(this.$size.$dirty)return this.$changes|=e,this.onResize(!0);this.lineHeight||this.$textLayer.checkForSizeChanges(),this._signal(\"beforeRender\");var n=this.layerConfig;if(e&this.CHANGE_FULL||e&this.CHANGE_SIZE||e&this.CHANGE_TEXT||e&this.CHANGE_LINES||e&this.CHANGE_SCROLL||e&this.CHANGE_H_SCROLL){e|=this.$computeLayerConfig();if(n.firstRow!=this.layerConfig.firstRow&&n.firstRowScreen==this.layerConfig.firstRowScreen){var r=this.scrollTop+(n.firstRow-this.layerConfig.firstRow)*this.lineHeight;r>0&&(this.scrollTop=r,e|=this.CHANGE_SCROLL,e|=this.$computeLayerConfig())}n=this.layerConfig,this.$updateScrollBarV(),e&this.CHANGE_H_SCROLL&&this.$updateScrollBarH(),this.$gutterLayer.element.style.marginTop=-n.offset+\"px\",this.content.style.marginTop=-n.offset+\"px\",this.content.style.width=n.width+2*this.$padding+\"px\",this.content.style.height=n.minHeight+\"px\"}e&this.CHANGE_H_SCROLL&&(this.content.style.marginLeft=-this.scrollLeft+\"px\",this.scroller.className=this.scrollLeft<=0?\"ace_scroller\":\"ace_scroller ace_scroll-left\");if(e&this.CHANGE_FULL){this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight(),this._signal(\"afterRender\");return}if(e&this.CHANGE_SCROLL){e&this.CHANGE_TEXT||e&this.CHANGE_LINES?this.$textLayer.update(n):this.$textLayer.scrollLines(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$highlightGutterLine&&this.$updateGutterLineHighlight(),this.$moveTextAreaToCursor(),this._signal(\"afterRender\");return}e&this.CHANGE_TEXT?(this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n)):e&this.CHANGE_LINES?(this.$updateLines()||e&this.CHANGE_GUTTER&&this.$showGutter)&&this.$gutterLayer.update(n):(e&this.CHANGE_TEXT||e&this.CHANGE_GUTTER)&&this.$showGutter&&this.$gutterLayer.update(n),e&this.CHANGE_CURSOR&&(this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight()),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_FRONT)&&this.$markerFront.update(n),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_BACK)&&this.$markerBack.update(n),this._signal(\"afterRender\")},this.$autosize=function(){var e=this.session.getScreenLength()*this.lineHeight,t=this.$maxLines*this.lineHeight,n=Math.max((this.$minLines||1)*this.lineHeight,Math.min(t,e))+this.scrollMargin.v+(this.$extraHeight||0),r=e>t;if(n!=this.desiredHeight||this.$size.height!=this.desiredHeight||r!=this.$vScroll){r!=this.$vScroll&&(this.$vScroll=r,this.scrollBarV.setVisible(r));var i=this.container.clientWidth;this.container.style.height=n+\"px\",this.$updateCachedSize(!0,this.$gutterWidth,i,n),this.desiredHeight=n,this._signal(\"autosize\")}},this.$computeLayerConfig=function(){this.$maxLines&&this.lineHeight>1&&this.$autosize();var e=this.session,t=this.$size,n=t.height<=2*this.lineHeight,r=this.session.getScreenLength(),i=r*this.lineHeight,s=this.scrollTop%this.lineHeight,o=t.scrollerHeight+this.lineHeight,u=this.$getLongestLine(),a=!n&&(this.$hScrollBarAlwaysVisible||t.scrollerWidth-u-2*this.$padding<0),f=this.$horizScroll!==a;f&&(this.$horizScroll=a,this.scrollBarH.setVisible(a));var l=!this.$maxLines&&this.$scrollPastEnd?(t.scrollerHeight-this.lineHeight)*this.$scrollPastEnd:0;i+=l,this.session.setScrollTop(Math.max(-this.scrollMargin.top,Math.min(this.scrollTop,i-t.scrollerHeight+this.scrollMargin.bottom))),this.session.setScrollLeft(Math.max(-this.scrollMargin.left,Math.min(this.scrollLeft,u+2*this.$padding-t.scrollerWidth+this.scrollMargin.right)));var c=!n&&(this.$vScrollBarAlwaysVisible||t.scrollerHeight-i+l<0||this.scrollTop),h=this.$vScroll!==c;h&&(this.$vScroll=c,this.scrollBarV.setVisible(c));var p=Math.ceil(o/this.lineHeight)-1,d=Math.max(0,Math.round((this.scrollTop-s)/this.lineHeight)),v=d+p,m,g,y=this.lineHeight;d=e.screenToDocumentRow(d,0);var b=e.getFoldLine(d);b&&(d=b.start.row),m=e.documentToScreenRow(d,0),g=e.getRowLength(d)*y,v=Math.min(e.screenToDocumentRow(v,0),e.getLength()-1),o=t.scrollerHeight+e.getRowLength(v)*y+g,s=this.scrollTop-m*y;var w=0;this.layerConfig.width!=u&&(w=this.CHANGE_H_SCROLL);if(f||h)w=this.$updateCachedSize(!0,this.gutterWidth,t.width,t.height),this._signal(\"scrollbarVisibilityChanged\"),h&&(u=this.$getLongestLine());return this.layerConfig={width:u,padding:this.$padding,firstRow:d,firstRowScreen:m,lastRow:v,lineHeight:y,characterWidth:this.characterWidth,minHeight:o,maxHeight:i,offset:s,gutterOffset:Math.max(0,Math.ceil((s+t.height-t.scrollerHeight)/y)),height:this.$size.scrollerHeight},w},this.$updateLines=function(){var e=this.$changedLines.firstRow,t=this.$changedLines.lastRow;this.$changedLines=null;var n=this.layerConfig;if(e>n.lastRow+1)return;if(t<n.firstRow)return;if(t===Infinity){this.$showGutter&&this.$gutterLayer.update(n),this.$textLayer.update(n);return}return this.$textLayer.updateLines(n,e,t),!0},this.$getLongestLine=function(){var e=this.session.getScreenWidth();return this.showInvisibles&&!this.session.$useWrapMode&&(e+=1),Math.max(this.$size.scrollerWidth-2*this.$padding,Math.round(e*this.characterWidth))},this.updateFrontMarkers=function(){this.$markerFront.setMarkers(this.session.getMarkers(!0)),this.$loop.schedule(this.CHANGE_MARKER_FRONT)},this.updateBackMarkers=function(){this.$markerBack.setMarkers(this.session.getMarkers()),this.$loop.schedule(this.CHANGE_MARKER_BACK)},this.addGutterDecoration=function(e,t){this.$gutterLayer.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){this.$gutterLayer.removeGutterDecoration(e,t)},this.updateBreakpoints=function(e){this.$loop.schedule(this.CHANGE_GUTTER)},this.setAnnotations=function(e){this.$gutterLayer.setAnnotations(e),this.$loop.schedule(this.CHANGE_GUTTER)},this.updateCursor=function(){this.$loop.schedule(this.CHANGE_CURSOR)},this.hideCursor=function(){this.$cursorLayer.hideCursor()},this.showCursor=function(){this.$cursorLayer.showCursor()},this.scrollSelectionIntoView=function(e,t,n){this.scrollCursorIntoView(e,n),this.scrollCursorIntoView(t,n)},this.scrollCursorIntoView=function(e,t,n){if(this.$size.scrollerHeight===0)return;var r=this.$cursorLayer.getPixelPosition(e),i=r.left,s=r.top,o=n&&n.top||0,u=n&&n.bottom||0,a=this.$scrollAnimation?this.session.getScrollTop():this.scrollTop;a+o>s?(t&&(s-=t*this.$size.scrollerHeight),s===0&&(s=-this.scrollMargin.top),this.session.setScrollTop(s)):a+this.$size.scrollerHeight-u<s+this.lineHeight&&(t&&(s+=t*this.$size.scrollerHeight),this.session.setScrollTop(s+this.lineHeight-this.$size.scrollerHeight));var f=this.scrollLeft;f>i?(i<this.$padding+2*this.layerConfig.characterWidth&&(i=-this.scrollMargin.left),this.session.setScrollLeft(i)):f+this.$size.scrollerWidth<i+this.characterWidth?this.session.setScrollLeft(Math.round(i+this.characterWidth-this.$size.scrollerWidth)):f<=this.$padding&&i-f<this.characterWidth&&this.session.setScrollLeft(0)},this.getScrollTop=function(){return this.session.getScrollTop()},this.getScrollLeft=function(){return this.session.getScrollLeft()},this.getScrollTopRow=function(){return this.scrollTop/this.lineHeight},this.getScrollBottomRow=function(){return Math.max(0,Math.floor((this.scrollTop+this.$size.scrollerHeight)/this.lineHeight)-1)},this.scrollToRow=function(e){this.session.setScrollTop(e*this.lineHeight)},this.alignCursor=function(e,t){typeof e==\"number\"&&(e={row:e,column:0});var n=this.$cursorLayer.getPixelPosition(e),r=this.$size.scrollerHeight-this.lineHeight,i=n.top-r*(t||0);return this.session.setScrollTop(i),i},this.STEPS=8,this.$calcSteps=function(e,t){var n=0,r=this.STEPS,i=[],s=function(e,t,n){return n*(Math.pow(e-1,3)+1)+t};for(n=0;n<r;++n)i.push(s(n/this.STEPS,e,t-e));return i},this.scrollToLine=function(e,t,n,r){var i=this.$cursorLayer.getPixelPosition({row:e,column:0}),s=i.top;t&&(s-=this.$size.scrollerHeight/2);var o=this.scrollTop;this.session.setScrollTop(s),n!==!1&&this.animateScrolling(o,r)},this.animateScrolling=function(e,t){var n=this.scrollTop;if(!this.$animatedScroll)return;var r=this;if(e==n)return;if(this.$scrollAnimation){var i=this.$scrollAnimation.steps;if(i.length){e=i[0];if(e==n)return}}var s=r.$calcSteps(e,n);this.$scrollAnimation={from:e,to:n,steps:s},clearInterval(this.$timer),r.session.setScrollTop(s.shift()),r.session.$scrollTop=n,this.$timer=setInterval(function(){s.length?(r.session.setScrollTop(s.shift()),r.session.$scrollTop=n):n!=null?(r.session.$scrollTop=-1,r.session.setScrollTop(n),n=null):(r.$timer=clearInterval(r.$timer),r.$scrollAnimation=null,t&&t())},10)},this.scrollToY=function(e){this.scrollTop!==e&&(this.$loop.schedule(this.CHANGE_SCROLL),this.scrollTop=e)},this.scrollToX=function(e){this.scrollLeft!==e&&(this.scrollLeft=e),this.$loop.schedule(this.CHANGE_H_SCROLL)},this.scrollTo=function(e,t){this.session.setScrollTop(t),this.session.setScrollLeft(t)},this.scrollBy=function(e,t){t&&this.session.setScrollTop(this.session.getScrollTop()+t),e&&this.session.setScrollLeft(this.session.getScrollLeft()+e)},this.isScrollableBy=function(e,t){if(t<0&&this.session.getScrollTop()>=1-this.scrollMargin.top)return!0;if(t>0&&this.session.getScrollTop()+this.$size.scrollerHeight-this.layerConfig.maxHeight<-1+this.scrollMargin.bottom)return!0;if(e<0&&this.session.getScrollLeft()>=1-this.scrollMargin.left)return!0;if(e>0&&this.session.getScrollLeft()+this.$size.scrollerWidth-this.layerConfig.width<-1+this.scrollMargin.right)return!0},this.pixelToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=(e+this.scrollLeft-n.left-this.$padding)/this.characterWidth,i=Math.floor((t+this.scrollTop-n.top)/this.lineHeight),s=Math.round(r);return{row:i,column:s,side:r-s>0?1:-1}},this.screenToTextCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=Math.round((e+this.scrollLeft-n.left-this.$padding)/this.characterWidth),i=(t+this.scrollTop-n.top)/this.lineHeight;return this.session.screenToDocumentPosition(i,Math.max(r,0))},this.textToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=this.session.documentToScreenPosition(e,t),i=this.$padding+Math.round(r.column*this.characterWidth),s=r.row*this.lineHeight;return{pageX:n.left+i-this.scrollLeft,pageY:n.top+s-this.scrollTop}},this.visualizeFocus=function(){i.addCssClass(this.container,\"ace_focus\")},this.visualizeBlur=function(){i.removeCssClass(this.container,\"ace_focus\")},this.showComposition=function(e){this.$composition||(this.$composition={keepTextAreaAtCursor:this.$keepTextAreaAtCursor,cssText:this.textarea.style.cssText}),this.$keepTextAreaAtCursor=!0,i.addCssClass(this.textarea,\"ace_composition\"),this.textarea.style.cssText=\"\",this.$moveTextAreaToCursor()},this.setCompositionText=function(e){this.$moveTextAreaToCursor()},this.hideComposition=function(){if(!this.$composition)return;i.removeCssClass(this.textarea,\"ace_composition\"),this.$keepTextAreaAtCursor=this.$composition.keepTextAreaAtCursor,this.textarea.style.cssText=this.$composition.cssText,this.$composition=null},this.setTheme=function(e,t){function o(r){if(n.$themeId!=e)return t&&t();if(!r.cssClass)return;i.importCssString(r.cssText,r.cssClass,n.container.ownerDocument),n.theme&&i.removeCssClass(n.container,n.theme.cssClass);var s=\"padding\"in r?r.padding:\"padding\"in(n.theme||{})?4:n.$padding;n.$padding&&s!=n.$padding&&n.setPadding(s),n.$theme=r.cssClass,n.theme=r,i.addCssClass(n.container,r.cssClass),i.setCssClass(n.container,\"ace_dark\",r.isDark),n.$size&&(n.$size.width=0,n.$updateSizeAsync()),n._dispatchEvent(\"themeLoaded\",{theme:r}),t&&t()}var n=this;this.$themeId=e,n._dispatchEvent(\"themeChange\",{theme:e});if(!e||typeof e==\"string\"){var r=e||this.$options.theme.initialValue;s.loadModule([\"theme\",r],o)}else o(e)},this.getTheme=function(){return this.$themeId},this.setStyle=function(e,t){i.setCssClass(this.container,e,t!==!1)},this.unsetStyle=function(e){i.removeCssClass(this.container,e)},this.setCursorStyle=function(e){this.scroller.style.cursor!=e&&(this.scroller.style.cursor=e)},this.setMouseCursor=function(e){this.scroller.style.cursor=e},this.destroy=function(){this.$textLayer.destroy(),this.$cursorLayer.destroy()}}).call(g.prototype),s.defineOptions(g.prototype,\"renderer\",{animatedScroll:{initialValue:!1},showInvisibles:{set:function(e){this.$textLayer.setShowInvisibles(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!1},showPrintMargin:{set:function(){this.$updatePrintMargin()},initialValue:!0},printMarginColumn:{set:function(){this.$updatePrintMargin()},initialValue:80},printMargin:{set:function(e){typeof e==\"number\"&&(this.$printMarginColumn=e),this.$showPrintMargin=!!e,this.$updatePrintMargin()},get:function(){return this.$showPrintMargin&&this.$printMarginColumn}},showGutter:{set:function(e){this.$gutter.style.display=e?\"block\":\"none\",this.$loop.schedule(this.CHANGE_FULL),this.onGutterResize()},initialValue:!0},fadeFoldWidgets:{set:function(e){i.setCssClass(this.$gutter,\"ace_fade-fold-widgets\",e)},initialValue:!1},showFoldWidgets:{set:function(e){this.$gutterLayer.setShowFoldWidgets(e)},initialValue:!0},showLineNumbers:{set:function(e){this.$gutterLayer.setShowLineNumbers(e),this.$loop.schedule(this.CHANGE_GUTTER)},initialValue:!0},displayIndentGuides:{set:function(e){this.$textLayer.setDisplayIndentGuides(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!0},highlightGutterLine:{set:function(e){if(!this.$gutterLineHighlight){this.$gutterLineHighlight=i.createElement(\"div\"),this.$gutterLineHighlight.className=\"ace_gutter-active-line\",this.$gutter.appendChild(this.$gutterLineHighlight);return}this.$gutterLineHighlight.style.display=e?\"\":\"none\",this.$cursorLayer.$pixelPos&&this.$updateGutterLineHighlight()},initialValue:!1,value:!0},hScrollBarAlwaysVisible:{set:function(e){(!this.$hScrollBarAlwaysVisible||!this.$horizScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},vScrollBarAlwaysVisible:{set:function(e){(!this.$vScrollBarAlwaysVisible||!this.$vScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},fontSize:{set:function(e){typeof e==\"number\"&&(e+=\"px\"),this.container.style.fontSize=e,this.updateFontSize()},initialValue:12},fontFamily:{set:function(e){this.container.style.fontFamily=e,this.updateFontSize()}},maxLines:{set:function(e){this.updateFull()}},minLines:{set:function(e){this.updateFull()}},scrollPastEnd:{set:function(e){e=+e||0;if(this.$scrollPastEnd==e)return;this.$scrollPastEnd=e,this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:0,handlesSet:!0},fixedWidthGutter:{set:function(e){this.$gutterLayer.$fixedWidth=!!e,this.$loop.schedule(this.CHANGE_GUTTER)}},theme:{set:function(e){this.setTheme(e)},get:function(){return this.$themeId||this.theme},initialValue:\"./theme/textmate\",handlesSet:!0}}),t.VirtualRenderer=g}),ace.define(\"ace/worker/worker_client\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/net\",\"ace/lib/event_emitter\",\"ace/config\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"../lib/net\"),s=e(\"../lib/event_emitter\").EventEmitter,o=e(\"../config\"),u=function(t,n,r,i){this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.onMessage=this.onMessage.bind(this),e.nameToUrl&&!e.toUrl&&(e.toUrl=e.nameToUrl);if(o.get(\"packaged\")||!e.toUrl)i=i||o.moduleUrl(n,\"worker\");else{var s=this.$normalizePath;i=i||s(e.toUrl(\"ace/worker/worker.js\",null,\"_\"));var u={};t.forEach(function(t){u[t]=s(e.toUrl(t,null,\"_\").replace(/(\\.js)?(\\?.*)?$/,\"\"))})}try{this.$worker=new Worker(i)}catch(a){if(!(a instanceof window.DOMException))throw a;var f=this.$workerBlob(i),l=window.URL||window.webkitURL,c=l.createObjectURL(f);this.$worker=new Worker(c),l.revokeObjectURL(c)}this.$worker.postMessage({init:!0,tlns:u,module:n,classname:r}),this.callbackId=1,this.callbacks={},this.$worker.onmessage=this.onMessage};(function(){r.implement(this,s),this.onMessage=function(e){var t=e.data;switch(t.type){case\"event\":this._signal(t.name,{data:t.data});break;case\"call\":var n=this.callbacks[t.id];n&&(n(t.data),delete this.callbacks[t.id]);break;case\"error\":this.reportError(t.data);break;case\"log\":window.console&&console.log&&console.log.apply(console,t.data)}},this.reportError=function(e){window.console&&console.error&&console.error(e)},this.$normalizePath=function(e){return i.qualifyURL(e)},this.terminate=function(){this._signal(\"terminate\",{}),this.deltaQueue=null,this.$worker.terminate(),this.$worker=null,this.$doc&&this.$doc.off(\"change\",this.changeListener),this.$doc=null},this.send=function(e,t){this.$worker.postMessage({command:e,args:t})},this.call=function(e,t,n){if(n){var r=this.callbackId++;this.callbacks[r]=n,t.push(r)}this.send(e,t)},this.emit=function(e,t){try{this.$worker.postMessage({event:e,data:{data:t.data}})}catch(n){console.error(n.stack)}},this.attachToDocument=function(e){this.$doc&&this.terminate(),this.$doc=e,this.call(\"setValue\",[e.getValue()]),e.on(\"change\",this.changeListener)},this.changeListener=function(e){this.deltaQueue?this.deltaQueue.push(e.data):(this.deltaQueue=[e.data],setTimeout(this.$sendDeltaQueue,0))},this.$sendDeltaQueue=function(){var e=this.deltaQueue;if(!e)return;this.deltaQueue=null,e.length>20&&e.length>this.$doc.getLength()>>1?this.call(\"setValue\",[this.$doc.getValue()]):this.emit(\"change\",{data:e})},this.$workerBlob=function(e){var t=\"importScripts('\"+i.qualifyURL(e)+\"');\";try{return new Blob([t],{type:\"application/javascript\"})}catch(n){var r=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder,s=new r;return s.append(t),s.getBlob(\"application/javascript\")}}}).call(u.prototype);var a=function(e,t,n){this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.callbackId=1,this.callbacks={},this.messageBuffer=[];var r=null,i=!1,u=Object.create(s),a=this;this.$worker={},this.$worker.terminate=function(){},this.$worker.postMessage=function(e){a.messageBuffer.push(e),r&&(i?setTimeout(f):f())},this.setEmitSync=function(e){i=e};var f=function(){var e=a.messageBuffer.shift();e.command?r[e.command].apply(r,e.args):e.event&&u._signal(e.event,e.data)};u.postMessage=function(e){a.onMessage({data:e})},u.callback=function(e,t){this.postMessage({type:\"call\",id:t,data:e})},u.emit=function(e,t){this.postMessage({type:\"event\",name:e,data:t})},o.loadModule([\"worker\",t],function(e){r=new e[n](u);while(a.messageBuffer.length)f()})};a.prototype=u.prototype,t.UIWorkerClient=a,t.WorkerClient=u}),ace.define(\"ace/placeholder\",[\"require\",\"exports\",\"module\",\"ace/range\",\"ace/lib/event_emitter\",\"ace/lib/oop\"],function(e,t,n){\"use strict\";var r=e(\"./range\").Range,i=e(\"./lib/event_emitter\").EventEmitter,s=e(\"./lib/oop\"),o=function(e,t,n,r,i,s){var o=this;this.length=t,this.session=e,this.doc=e.getDocument(),this.mainClass=i,this.othersClass=s,this.$onUpdate=this.onUpdate.bind(this),this.doc.on(\"change\",this.$onUpdate),this.$others=r,this.$onCursorChange=function(){setTimeout(function(){o.onCursorChange()})},this.$pos=n;var u=e.getUndoManager().$undoStack||e.getUndoManager().$undostack||{length:-1};this.$undoStackDepth=u.length,this.setup(),e.selection.on(\"changeCursor\",this.$onCursorChange)};(function(){s.implement(this,i),this.setup=function(){var e=this,t=this.doc,n=this.session,i=this.$pos;this.selectionBefore=n.selection.toJSON(),n.selection.inMultiSelectMode&&n.selection.toSingleRange(),this.pos=t.createAnchor(i.row,i.column),this.markerId=n.addMarker(new r(i.row,i.column,i.row,i.column+this.length),this.mainClass,null,!1),this.pos.on(\"change\",function(t){n.removeMarker(e.markerId),e.markerId=n.addMarker(new r(t.value.row,t.value.column,t.value.row,t.value.column+e.length),e.mainClass,null,!1)}),this.others=[],this.$others.forEach(function(n){var r=t.createAnchor(n.row,n.column);e.others.push(r)}),n.setUndoSelect(!1)},this.showOtherMarkers=function(){if(this.othersActive)return;var e=this.session,t=this;this.othersActive=!0,this.others.forEach(function(n){n.markerId=e.addMarker(new r(n.row,n.column,n.row,n.column+t.length),t.othersClass,null,!1),n.on(\"change\",function(i){e.removeMarker(n.markerId),n.markerId=e.addMarker(new r(i.value.row,i.value.column,i.value.row,i.value.column+t.length),t.othersClass,null,!1)})})},this.hideOtherMarkers=function(){if(!this.othersActive)return;this.othersActive=!1;for(var e=0;e<this.others.length;e++)this.session.removeMarker(this.others[e].markerId)},this.onUpdate=function(e){var t=e.data,n=t.range;if(n.start.row!==n.end.row)return;if(n.start.row!==this.pos.row)return;if(this.$updating)return;this.$updating=!0;var i=t.action===\"insertText\"?n.end.column-n.start.column:n.start.column-n.end.column;if(n.start.column>=this.pos.column&&n.start.column<=this.pos.column+this.length+1){var s=n.start.column-this.pos.column;this.length+=i;if(!this.session.$fromUndo){if(t.action===\"insertText\")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};u.row===n.start.row&&n.start.column<u.column&&(a.column+=i),this.doc.insert(a,t.text)}else if(t.action===\"removeText\")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};u.row===n.start.row&&n.start.column<u.column&&(a.column+=i),this.doc.remove(new r(a.row,a.column,a.row,a.column-i))}n.start.column===this.pos.column&&t.action===\"insertText\"?setTimeout(function(){this.pos.setPosition(this.pos.row,this.pos.column-i);for(var e=0;e<this.others.length;e++){var t=this.others[e],r={row:t.row,column:t.column-i};t.row===n.start.row&&n.start.column<t.column&&(r.column+=i),t.setPosition(r.row,r.column)}}.bind(this),0):n.start.column===this.pos.column&&t.action===\"removeText\"&&setTimeout(function(){for(var e=0;e<this.others.length;e++){var t=this.others[e];t.row===n.start.row&&n.start.column<t.column&&t.setPosition(t.row,t.column-i)}}.bind(this),0)}this.pos._emit(\"change\",{value:this.pos});for(var o=0;o<this.others.length;o++)this.others[o]._emit(\"change\",{value:this.others[o]})}this.$updating=!1},this.onCursorChange=function(e){if(this.$updating||!this.session)return;var t=this.session.selection.getCursor();t.row===this.pos.row&&t.column>=this.pos.column&&t.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit(\"cursorEnter\",e)):(this.hideOtherMarkers(),this._emit(\"cursorLeave\",e))},this.detach=function(){this.session.removeMarker(this.markerId),this.hideOtherMarkers(),this.doc.removeEventListener(\"change\",this.$onUpdate),this.session.selection.removeEventListener(\"changeCursor\",this.$onCursorChange),this.pos.detach();for(var e=0;e<this.others.length;e++)this.others[e].detach();this.session.setUndoSelect(!0),this.session=null},this.cancel=function(){if(this.$undoStackDepth===-1)throw Error(\"Canceling placeholders only supported with undo manager attached to session.\");var e=this.session.getUndoManager(),t=(e.$undoStack||e.$undostack).length-this.$undoStackDepth;for(var n=0;n<t;n++)e.undo(!0);this.selectionBefore&&this.session.selection.fromJSON(this.selectionBefore)}}).call(o.prototype),t.PlaceHolder=o}),ace.define(\"ace/mouse/multi_select_handler\",[\"require\",\"exports\",\"module\",\"ace/lib/event\",\"ace/lib/useragent\"],function(e,t,n){function s(e,t){return e.row==t.row&&e.column==t.column}function o(e){var t=e.domEvent,n=t.altKey,o=t.shiftKey,u=t.ctrlKey,a=e.getAccelKey(),f=e.getButton();u&&i.isMac&&(f=t.button);if(e.editor.inMultiSelectMode&&f==2){e.editor.textInput.onContextMenu(e.domEvent);return}if(!u&&!n&&!a){f===0&&e.editor.inMultiSelectMode&&e.editor.exitMultiSelectMode();return}if(f!==0)return;var l=e.editor,c=l.selection,h=l.inMultiSelectMode,p=e.getDocumentPosition(),d=c.getCursor(),v=e.inSelection()||c.isEmpty()&&s(p,d),m=e.x,g=e.y,y=function(e){m=e.clientX,g=e.clientY},b=l.session,w=l.renderer.pixelToScreenCoordinates(m,g),E=w,S;if(l.$mouseHandler.$enableJumpToDef)u&&n||a&&n?S=\"add\":n&&(S=\"block\");else if(a&&!n){S=\"add\";if(!h&&o)return}else n&&(S=\"block\");S&&i.isMac&&t.ctrlKey&&l.$mouseHandler.cancelContextMenu();if(S==\"add\"){if(!h&&v)return;if(!h){var x=c.toOrientedRange();l.addSelectionMarker(x)}var T=c.rangeList.rangeAtPoint(p);l.$blockScrolling++,l.inVirtualSelectionMode=!0,o&&(T=null,x=c.ranges[0],l.removeSelectionMarker(x)),l.once(\"mouseup\",function(){var e=c.toOrientedRange();T&&e.isEmpty()&&s(T.cursor,e.cursor)?c.substractPoint(e.cursor):(o?c.substractPoint(x.cursor):x&&(l.removeSelectionMarker(x),c.addRange(x)),c.addRange(e)),l.$blockScrolling--,l.inVirtualSelectionMode=!1})}else if(S==\"block\"){e.stop(),l.inVirtualSelectionMode=!0;var N,C=[],k=function(){var e=l.renderer.pixelToScreenCoordinates(m,g),t=b.screenToDocumentPosition(e.row,e.column);if(s(E,e)&&s(t,c.lead))return;E=e,l.selection.moveToPosition(t),l.renderer.scrollCursorIntoView(),l.removeSelectionMarkers(C),C=c.rectangularRangeBlock(E,w),l.$mouseHandler.$clickSelection&&C.length==1&&C[0].isEmpty()&&(C[0]=l.$mouseHandler.$clickSelection.clone()),C.forEach(l.addSelectionMarker,l),l.updateSelectionMarkers()};h&&!a?c.toSingleRange():!h&&a&&(N=c.toOrientedRange(),l.addSelectionMarker(N)),o?w=b.documentToScreenPosition(c.lead):c.moveToPosition(p),E={row:-1,column:-1};var L=function(e){clearInterval(O),l.removeSelectionMarkers(C),C.length||(C=[c.toOrientedRange()]),l.$blockScrolling++,N&&(l.removeSelectionMarker(N),c.toSingleRange(N));for(var t=0;t<C.length;t++)c.addRange(C[t]);l.inVirtualSelectionMode=!1,l.$mouseHandler.$clickSelection=null,l.$blockScrolling--},A=k;r.capture(l.container,y,L);var O=setInterval(function(){A()},20);return e.preventDefault()}}var r=e(\"../lib/event\"),i=e(\"../lib/useragent\");t.onMouseDown=o}),ace.define(\"ace/commands/multi_select_commands\",[\"require\",\"exports\",\"module\",\"ace/keyboard/hash_handler\"],function(e,t,n){t.defaultCommands=[{name:\"addCursorAbove\",exec:function(e){e.selectMoreLines(-1)},bindKey:{win:\"Ctrl-Alt-Up\",mac:\"Ctrl-Alt-Up\"},readonly:!0},{name:\"addCursorBelow\",exec:function(e){e.selectMoreLines(1)},bindKey:{win:\"Ctrl-Alt-Down\",mac:\"Ctrl-Alt-Down\"},readonly:!0},{name:\"addCursorAboveSkipCurrent\",exec:function(e){e.selectMoreLines(-1,!0)},bindKey:{win:\"Ctrl-Alt-Shift-Up\",mac:\"Ctrl-Alt-Shift-Up\"},readonly:!0},{name:\"addCursorBelowSkipCurrent\",exec:function(e){e.selectMoreLines(1,!0)},bindKey:{win:\"Ctrl-Alt-Shift-Down\",mac:\"Ctrl-Alt-Shift-Down\"},readonly:!0},{name:\"selectMoreBefore\",exec:function(e){e.selectMore(-1)},bindKey:{win:\"Ctrl-Alt-Left\",mac:\"Ctrl-Alt-Left\"},readonly:!0},{name:\"selectMoreAfter\",exec:function(e){e.selectMore(1)},bindKey:{win:\"Ctrl-Alt-Right\",mac:\"Ctrl-Alt-Right\"},readonly:!0},{name:\"selectNextBefore\",exec:function(e){e.selectMore(-1,!0)},bindKey:{win:\"Ctrl-Alt-Shift-Left\",mac:\"Ctrl-Alt-Shift-Left\"},readonly:!0},{name:\"selectNextAfter\",exec:function(e){e.selectMore(1,!0)},bindKey:{win:\"Ctrl-Alt-Shift-Right\",mac:\"Ctrl-Alt-Shift-Right\"},readonly:!0},{name:\"splitIntoLines\",exec:function(e){e.multiSelect.splitIntoLines()},bindKey:{win:\"Ctrl-Alt-L\",mac:\"Ctrl-Alt-L\"},readonly:!0},{name:\"alignCursors\",exec:function(e){e.alignCursors()},bindKey:{win:\"Ctrl-Alt-A\",mac:\"Ctrl-Alt-A\"}},{name:\"findAll\",exec:function(e){e.findAll()},bindKey:{win:\"Ctrl-Alt-K\",mac:\"Ctrl-Alt-G\"},readonly:!0}],t.multiSelectCommands=[{name:\"singleSelection\",bindKey:\"esc\",exec:function(e){e.exitMultiSelectMode()},readonly:!0,isAvailable:function(e){return e&&e.inMultiSelectMode}}];var r=e(\"../keyboard/hash_handler\").HashHandler;t.keyboardHandler=new r(t.multiSelectCommands)}),ace.define(\"ace/multi_select\",[\"require\",\"exports\",\"module\",\"ace/range_list\",\"ace/range\",\"ace/selection\",\"ace/mouse/multi_select_handler\",\"ace/lib/event\",\"ace/lib/lang\",\"ace/commands/multi_select_commands\",\"ace/search\",\"ace/edit_session\",\"ace/editor\",\"ace/config\"],function(e,t,n){function h(e,t,n){return c.$options.wrap=!0,c.$options.needle=t,c.$options.backwards=n==-1,c.find(e)}function v(e,t){return e.row==t.row&&e.column==t.column}function m(e){if(e.$multiselectOnSessionChange)return;e.$onAddRange=e.$onAddRange.bind(e),e.$onRemoveRange=e.$onRemoveRange.bind(e),e.$onMultiSelect=e.$onMultiSelect.bind(e),e.$onSingleSelect=e.$onSingleSelect.bind(e),e.$multiselectOnSessionChange=t.onSessionChange.bind(e),e.$checkMultiselectChange=e.$checkMultiselectChange.bind(e),e.$multiselectOnSessionChange(e),e.on(\"changeSession\",e.$multiselectOnSessionChange),e.on(\"mousedown\",o),e.commands.addCommands(f.defaultCommands),g(e)}function g(e){function r(t){n&&(e.renderer.setMouseCursor(\"\"),n=!1)}var t=e.textInput.getElement(),n=!1;u.addListener(t,\"keydown\",function(t){t.keyCode==18&&!(t.ctrlKey||t.shiftKey||t.metaKey)?n||(e.renderer.setMouseCursor(\"crosshair\"),n=!0):n&&r()}),u.addListener(t,\"keyup\",r),u.addListener(t,\"blur\",r)}var r=e(\"./range_list\").RangeList,i=e(\"./range\").Range,s=e(\"./selection\").Selection,o=e(\"./mouse/multi_select_handler\").onMouseDown,u=e(\"./lib/event\"),a=e(\"./lib/lang\"),f=e(\"./commands/multi_select_commands\");t.commands=f.defaultCommands.concat(f.multiSelectCommands);var l=e(\"./search\").Search,c=new l,p=e(\"./edit_session\").EditSession;(function(){this.getSelectionMarkers=function(){return this.$selectionMarkers}}).call(p.prototype),function(){this.ranges=null,this.rangeList=null,this.addRange=function(e,t){if(!e)return;if(!this.inMultiSelectMode&&this.rangeCount===0){var n=this.toOrientedRange();this.rangeList.add(n),this.rangeList.add(e);if(this.rangeList.ranges.length!=2)return this.rangeList.removeAll(),t||this.fromOrientedRange(e);this.rangeList.removeAll(),this.rangeList.add(n),this.$onAddRange(n)}e.cursor||(e.cursor=e.end);var r=this.rangeList.add(e);return this.$onAddRange(e),r.length&&this.$onRemoveRange(r),this.rangeCount>1&&!this.inMultiSelectMode&&(this._signal(\"multiSelect\"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),t||this.fromOrientedRange(e)},this.toSingleRange=function(e){e=e||this.ranges[0];var t=this.rangeList.removeAll();t.length&&this.$onRemoveRange(t),e&&this.fromOrientedRange(e)},this.substractPoint=function(e){var t=this.rangeList.substractPoint(e);if(t)return this.$onRemoveRange(t),t[0]},this.mergeOverlappingRanges=function(){var e=this.rangeList.merge();e.length?this.$onRemoveRange(e):this.ranges[0]&&this.fromOrientedRange(this.ranges[0])},this.$onAddRange=function(e){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(e),this._signal(\"addRange\",{range:e})},this.$onRemoveRange=function(e){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var t=this.rangeList.ranges.pop();e.push(t),this.rangeCount=0}for(var n=e.length;n--;){var r=this.ranges.indexOf(e[n]);this.ranges.splice(r,1)}this._signal(\"removeRange\",{ranges:e}),this.rangeCount===0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._signal(\"singleSelect\"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),t=t||this.ranges[0],t&&!t.isEqual(this.getRange())&&this.fromOrientedRange(t)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new r,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeCount?this.rangeList.ranges.concat():[this.getRange()]},this.splitIntoLines=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var n=this.getRange(),r=this.isBackwards(),s=n.start.row,o=n.end.row;if(s==o){if(r)var u=n.end,a=n.start;else var u=n.start,a=n.end;this.addRange(i.fromPoints(a,a)),this.addRange(i.fromPoints(u,u));return}var f=[],l=this.getLineRange(s,!0);l.start.column=n.start.column,f.push(l);for(var c=s+1;c<o;c++)f.push(this.getLineRange(c,!0));l=this.getLineRange(o,!0),l.end.column=n.end.column,f.push(l),f.forEach(this.addRange,this)}},this.toggleBlockSelection=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var r=this.session.documentToScreenPosition(this.selectionLead),s=this.session.documentToScreenPosition(this.selectionAnchor),o=this.rectangularRangeBlock(r,s);o.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(e,t,n){var r=[],s=e.column<t.column;if(s)var o=e.column,u=t.column;else var o=t.column,u=e.column;var a=e.row<t.row;if(a)var f=e.row,l=t.row;else var f=t.row,l=e.row;o<0&&(o=0),f<0&&(f=0),f==l&&(n=!0);for(var c=f;c<=l;c++){var h=i.fromPoints(this.session.screenToDocumentPosition(c,o),this.session.screenToDocumentPosition(c,u));if(h.isEmpty()){if(p&&v(h.end,p))break;var p=h.end}h.cursor=s?h.start:h.end,r.push(h)}a&&r.reverse();if(!n){var d=r.length-1;while(r[d].isEmpty()&&d>0)d--;if(d>0){var m=0;while(r[m].isEmpty())m++}for(var g=d;g>=m;g--)r[g].isEmpty()&&r.splice(g,1)}return r}}.call(s.prototype);var d=e(\"./editor\").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(e){e.cursor||(e.cursor=e.end);var t=this.getSelectionStyle();return e.marker=this.session.addMarker(e,\"ace_selection\",t),this.session.$selectionMarkers.push(e),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,e},this.removeSelectionMarker=function(e){if(!e.marker)return;this.session.removeMarker(e.marker);var t=this.session.$selectionMarkers.indexOf(e);t!=-1&&this.session.$selectionMarkers.splice(t,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(e){var t=this.session.$selectionMarkers;for(var n=e.length;n--;){var r=e[n];if(!r.marker)continue;this.session.removeMarker(r.marker);var i=t.indexOf(r);i!=-1&&t.splice(i,1)}this.session.selectionMarkerCount=t.length},this.$onAddRange=function(e){this.addSelectionMarker(e.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(e){this.removeSelectionMarkers(e.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(e){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle(\"ace_multiselect\"),this.keyBinding.addKeyboardHandler(f.keyboardHandler),this.commands.setDefaultHandler(\"exec\",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(e){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle(\"ace_multiselect\"),this.keyBinding.removeKeyboardHandler(f.keyboardHandler),this.commands.removeDefaultHandler(\"exec\",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers(),this._emit(\"changeSelection\")},this.$onMultiSelectExec=function(e){var t=e.command,n=e.editor;if(!n.multiSelect)return;if(!t.multiSelectAction){var r=t.exec(n,e.args||{});n.multiSelect.addRange(n.multiSelect.toOrientedRange()),n.multiSelect.mergeOverlappingRanges()}else t.multiSelectAction==\"forEach\"?r=n.forEachSelection(t,e.args):t.multiSelectAction==\"forEachLine\"?r=n.forEachSelection(t,e.args,!0):t.multiSelectAction==\"single\"?(n.exitMultiSelectMode(),r=t.exec(n,e.args||{})):r=t.multiSelectAction(n,e.args||{});return r},this.forEachSelection=function(e,t,n){if(this.inVirtualSelectionMode)return;var r=n&&n.keepOrder,i=n==1||n&&n.$byLines,o=this.session,u=this.selection,a=u.rangeList,f=(r?u:a).ranges,l;if(!f.length)return e.exec?e.exec(this,t||{}):e(this,t||{});var c=u._eventRegistry;u._eventRegistry={};var h=new s(o);this.inVirtualSelectionMode=!0;for(var p=f.length;p--;){if(i)while(p>0&&f[p].start.row==f[p-1].end.row)p--;h.fromOrientedRange(f[p]),h.index=p,this.selection=o.selection=h;var d=e.exec?e.exec(this,t||{}):e(this,t||{});!l&&d!==undefined&&(l=d),h.toOrientedRange(f[p])}h.detach(),this.selection=o.selection=u,this.inVirtualSelectionMode=!1,u._eventRegistry=c,u.mergeOverlappingRanges();var v=this.renderer.$scrollAnimation;return this.onCursorChange(),this.onSelectionChange(),v&&v.from==v.to&&this.renderer.animateScrolling(v.from),l},this.exitMultiSelectMode=function(){if(!this.inMultiSelectMode||this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getSelectedText=function(){var e=\"\";if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var t=this.multiSelect.rangeList.ranges,n=[];for(var r=0;r<t.length;r++)n.push(this.session.getTextRange(t[r]));var i=this.session.getDocument().getNewLineCharacter();e=n.join(i),e.length==(n.length-1)*i.length&&(e=\"\")}else this.selection.isEmpty()||(e=this.session.getTextRange(this.getSelectionRange()));return e},this.$checkMultiselectChange=function(e,t){if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var n=this.multiSelect.ranges[0];if(this.multiSelect.isEmpty()&&t==this.multiSelect.anchor)return;var r=t==this.multiSelect.anchor?n.cursor==n.start?n.end:n.start:n.cursor;v(r,t)||this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange())}},this.onPaste=function(e){if(this.$readOnly)return;var t={text:e};this._signal(\"paste\",t),e=t.text;if(!this.inMultiSelectMode||this.inVirtualSelectionMode)return this.insert(e);var n=e.split(/\\r\\n|\\r|\\n/),r=this.selection.rangeList.ranges;if(n.length>r.length||n.length<2||!n[1])return this.commands.exec(\"insertstring\",this,e);for(var i=r.length;i--;){var s=r[i];s.isEmpty()||this.session.remove(s),this.session.insert(s.start,n[i])}},this.findAll=function(e,t,n){t=t||{},t.needle=e||t.needle;if(t.needle==undefined){var r=this.selection.isEmpty()?this.selection.getWordRange():this.selection.getRange();t.needle=this.session.getTextRange(r)}this.$search.set(t);var i=this.$search.findAll(this.session);if(!i.length)return 0;this.$blockScrolling+=1;var s=this.multiSelect;n||s.toSingleRange(i[0]);for(var o=i.length;o--;)s.addRange(i[o],!0);return r&&s.rangeList.rangeAtPoint(r.start)&&s.addRange(r,!0),this.$blockScrolling-=1,i.length},this.selectMoreLines=function(e,t){var n=this.selection.toOrientedRange(),r=n.cursor==n.end,s=this.session.documentToScreenPosition(n.cursor);this.selection.$desiredColumn&&(s.column=this.selection.$desiredColumn);var o=this.session.screenToDocumentPosition(s.row+e,s.column);if(!n.isEmpty())var u=this.session.documentToScreenPosition(r?n.end:n.start),a=this.session.screenToDocumentPosition(u.row+e,u.column);else var a=o;if(r){var f=i.fromPoints(o,a);f.cursor=f.start}else{var f=i.fromPoints(a,o);f.cursor=f.end}f.desiredColumn=s.column;if(!this.selection.inMultiSelectMode)this.selection.addRange(n);else if(t)var l=n.cursor;this.selection.addRange(f),l&&this.selection.substractPoint(l)},this.transposeSelections=function(e){var t=this.session,n=t.multiSelect,r=n.ranges;for(var i=r.length;i--;){var s=r[i];if(s.isEmpty()){var o=t.getWordRange(s.start.row,s.start.column);s.start.row=o.start.row,s.start.column=o.start.column,s.end.row=o.end.row,s.end.column=o.end.column}}n.mergeOverlappingRanges();var u=[];for(var i=r.length;i--;){var s=r[i];u.unshift(t.getTextRange(s))}e<0?u.unshift(u.pop()):u.push(u.shift());for(var i=r.length;i--;){var s=r[i],o=s.clone();t.replace(s,u[i]),s.start.row=o.start.row,s.start.column=o.start.column}},this.selectMore=function(e,t,n){var r=this.session,i=r.multiSelect,s=i.toOrientedRange();if(s.isEmpty()){s=r.getWordRange(s.start.row,s.start.column),s.cursor=e==-1?s.start:s.end,this.multiSelect.addRange(s);if(n)return}var o=r.getTextRange(s),u=h(r,o,e);u&&(u.cursor=e==-1?u.start:u.end,this.$blockScrolling+=1,this.session.unfold(u),this.multiSelect.addRange(u),this.$blockScrolling-=1,this.renderer.scrollCursorIntoView(null,.5)),t&&this.multiSelect.substractPoint(s.cursor)},this.alignCursors=function(){var e=this.session,t=e.multiSelect,n=t.ranges,r=-1,s=n.filter(function(e){if(e.cursor.row==r)return!0;r=e.cursor.row});if(!n.length||s.length==n.length-1){var o=this.selection.getRange(),u=o.start.row,f=o.end.row,l=u==f;if(l){var c=this.session.getLength(),h;do h=this.session.getLine(f);while(/[=:]/.test(h)&&++f<c);do h=this.session.getLine(u);while(/[=:]/.test(h)&&--u>0);u<0&&(u=0),f>=c&&(f=c-1)}var p=this.session.doc.removeLines(u,f);p=this.$reAlignText(p,l),this.session.doc.insert({row:u,column:0},p.join(\"\\n\")+\"\\n\"),l||(o.start.column=0,o.end.column=p[p.length-1].length),this.selection.setRange(o)}else{s.forEach(function(e){t.substractPoint(e.cursor)});var d=0,v=Infinity,m=n.map(function(t){var n=t.cursor,r=e.getLine(n.row),i=r.substr(n.column).search(/\\S/g);return i==-1&&(i=0),n.column>d&&(d=n.column),i<v&&(v=i),i});n.forEach(function(t,n){var r=t.cursor,s=d-r.column,o=m[n]-v;s>o?e.insert(r,a.stringRepeat(\" \",s-o)):e.remove(new i(r.row,r.column,r.row,r.column-s+o)),t.start.column=t.end.column=d,t.start.row=t.end.row=r.row,t.cursor=t.end}),t.fromOrientedRange(n[0]),this.renderer.updateCursor(),this.renderer.updateBackMarkers()}},this.$reAlignText=function(e,t){function u(e){return a.stringRepeat(\" \",e)}function f(e){return e[2]?u(i)+e[2]+u(s-e[2].length+o)+e[4].replace(/^([=:])\\s+/,\"$1 \"):e[0]}function l(e){return e[2]?u(i+s-e[2].length)+e[2]+u(o,\" \")+e[4].replace(/^([=:])\\s+/,\"$1 \"):e[0]}function c(e){return e[2]?u(i)+e[2]+u(o)+e[4].replace(/^([=:])\\s+/,\"$1 \"):e[0]}var n=!0,r=!0,i,s,o;return e.map(function(e){var t=e.match(/(\\s*)(.*?)(\\s*)([=:].*)/);return t?i==null?(i=t[1].length,s=t[2].length,o=t[3].length,t):(i+s+o!=t[1].length+t[2].length+t[3].length&&(r=!1),i!=t[1].length&&(n=!1),i>t[1].length&&(i=t[1].length),s<t[2].length&&(s=t[2].length),o>t[3].length&&(o=t[3].length),t):[e]}).map(t?f:n?r?l:f:c)}}).call(d.prototype),t.onSessionChange=function(e){var t=e.session;t&&!t.multiSelect&&(t.$selectionMarkers=[],t.selection.$initRangeList(),t.multiSelect=t.selection),this.multiSelect=t&&t.multiSelect;var n=e.oldSession;n&&(n.multiSelect.off(\"addRange\",this.$onAddRange),n.multiSelect.off(\"removeRange\",this.$onRemoveRange),n.multiSelect.off(\"multiSelect\",this.$onMultiSelect),n.multiSelect.off(\"singleSelect\",this.$onSingleSelect),n.multiSelect.lead.off(\"change\",this.$checkMultiselectChange),n.multiSelect.anchor.off(\"change\",this.$checkMultiselectChange)),t&&(t.multiSelect.on(\"addRange\",this.$onAddRange),t.multiSelect.on(\"removeRange\",this.$onRemoveRange),t.multiSelect.on(\"multiSelect\",this.$onMultiSelect),t.multiSelect.on(\"singleSelect\",this.$onSingleSelect),t.multiSelect.lead.on(\"change\",this.$checkMultiselectChange),t.multiSelect.anchor.on(\"change\",this.$checkMultiselectChange)),t&&this.inMultiSelectMode!=t.selection.inMultiSelectMode&&(t.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},t.MultiSelect=m,e(\"./config\").defineOptions(d.prototype,\"editor\",{enableMultiselect:{set:function(e){m(this),e?(this.on(\"changeSession\",this.$multiselectOnSessionChange),this.on(\"mousedown\",o)):(this.off(\"changeSession\",this.$multiselectOnSessionChange),this.off(\"mousedown\",o))},value:!0}})}),ace.define(\"ace/mode/folding/fold_mode\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../../range\").Range,i=t.FoldMode=function(){};(function(){this.foldingStartMarker=null,this.foldingStopMarker=null,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?\"start\":t==\"markbeginend\"&&this.foldingStopMarker&&this.foldingStopMarker.test(r)?\"end\":\"\"},this.getFoldWidgetRange=function(e,t,n){return null},this.indentationBlock=function(e,t,n){var i=/\\S/,s=e.getLine(t),o=s.search(i);if(o==-1)return;var u=n||s.length,a=e.getLength(),f=t,l=t;while(++t<a){var c=e.getLine(t).search(i);if(c==-1)continue;if(c<=o)break;l=t}if(l>f){var h=e.getLine(l).length;return new r(f,u,l,h)}},this.openingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i+1},u=e.$findClosingBracket(t,o,s);if(!u)return;var a=e.foldWidgets[u.row];return a==null&&(a=e.getFoldWidget(u.row)),a==\"start\"&&u.row>o.row&&(u.row--,u.column=e.getLine(u.row).length),r.fromPoints(o,u)},this.closingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i},u=e.$findOpeningBracket(t,o);if(!u)return;return u.column++,o.column--,r.fromPoints(u,o)}}).call(i.prototype)}),ace.define(\"ace/theme/textmate\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){\"use strict\";t.isDark=!1,t.cssClass=\"ace-tm\",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;border-radius: 2px;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;}';var r=e(\"../lib/dom\");r.importCssString(t.cssText,t.cssClass)}),ace.define(\"ace/line_widgets\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/dom\",\"ace/range\"],function(e,t,n){\"use strict\";function o(e){this.session=e,this.session.widgetManager=this,this.session.getRowLength=this.getRowLength,this.session.$getWidgetScreenLength=this.$getWidgetScreenLength,this.updateOnChange=this.updateOnChange.bind(this),this.renderWidgets=this.renderWidgets.bind(this),this.measureWidgets=this.measureWidgets.bind(this),this.session._changedWidgets=[],this.$onChangeEditor=this.$onChangeEditor.bind(this),this.session.on(\"change\",this.updateOnChange),this.session.on(\"changeEditor\",this.$onChangeEditor)}var r=e(\"./lib/oop\"),i=e(\"./lib/dom\"),s=e(\"./range\").Range;(function(){this.getRowLength=function(e){var t;return this.lineWidgets?t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0:t=0,!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.$getWidgetScreenLength=function(){var e=0;return this.lineWidgets.forEach(function(t){t&&t.rowCount&&(e+=t.rowCount)}),e},this.$onChangeEditor=function(e){this.attach(e.editor)},this.attach=function(e){e&&e.widgetManager&&e.widgetManager!=this&&e.widgetManager.detach();if(this.editor==e)return;this.detach(),this.editor=e,e&&(e.widgetManager=this,e.renderer.on(\"beforeRender\",this.measureWidgets),e.renderer.on(\"afterRender\",this.renderWidgets))},this.detach=function(e){var t=this.editor;if(!t)return;this.editor=null,t.widgetManager=null,t.renderer.off(\"beforeRender\",this.measureWidgets),t.renderer.off(\"afterRender\",this.renderWidgets);var n=this.session.lineWidgets;n&&n.forEach(function(e){e&&e.el&&e.el.parentNode&&(e._inDocument=!1,e.el.parentNode.removeChild(e.el))})},this.updateOnChange=function(e){var t=this.session.lineWidgets;if(!t)return;var n=e.data,r=n.range,i=r.start.row,s=r.end.row-i;if(s!==0)if(n.action==\"removeText\"||n.action==\"removeLines\"){var o=t.splice(i+1,s);o.forEach(function(e){e&&this.removeLineWidget(e)},this),this.$updateRows()}else{var u=new Array(s);u.unshift(i,0),t.splice.apply(t,u),this.$updateRows()}},this.$updateRows=function(){var e=this.session.lineWidgets;if(!e)return;var t=!0;e.forEach(function(e,n){e&&(t=!1,e.row=n)}),t&&(this.session.lineWidgets=null)},this.addLineWidget=function(e){this.session.lineWidgets||(this.session.lineWidgets=new Array(this.session.getLength())),this.session.lineWidgets[e.row]=e;var t=this.editor.renderer;return e.html&&!e.el&&(e.el=i.createElement(\"div\"),e.el.innerHTML=e.html),e.el&&(i.addCssClass(e.el,\"ace_lineWidgetContainer\"),e.el.style.position=\"absolute\",e.el.style.zIndex=5,t.container.appendChild(e.el),e._inDocument=!0),e.coverGutter||(e.el.style.zIndex=3),e.pixelHeight||(e.pixelHeight=e.el.offsetHeight),e.rowCount==null&&(e.rowCount=e.pixelHeight/t.layerConfig.lineHeight),this.session._emit(\"changeFold\",{data:{start:{row:e.row}}}),this.$updateRows(),this.renderWidgets(null,t),e},this.removeLineWidget=function(e){e._inDocument=!1,e.el&&e.el.parentNode&&e.el.parentNode.removeChild(e.el);if(e.editor&&e.editor.destroy)try{e.editor.destroy()}catch(t){}this.session.lineWidgets&&(this.session.lineWidgets[e.row]=undefined),this.session._emit(\"changeFold\",{data:{start:{row:e.row}}}),this.$updateRows()},this.onWidgetChanged=function(e){this.session._changedWidgets.push(e),this.editor&&this.editor.renderer.updateFull()},this.measureWidgets=function(e,t){var n=this.session._changedWidgets,r=t.layerConfig;if(!n||!n.length)return;var i=Infinity;for(var s=0;s<n.length;s++){var o=n[s];o._inDocument||(o._inDocument=!0,t.container.appendChild(o.el)),o.h=o.el.offsetHeight,o.fixedWidth||(o.w=o.el.offsetWidth,o.screenWidth=Math.ceil(o.w/r.characterWidth));var u=o.h/r.lineHeight;o.coverLine&&(u-=this.session.getRowLineCount(o.row),u<0&&(u=0)),o.rowCount!=u&&(o.rowCount=u,o.row<i&&(i=o.row))}i!=Infinity&&(this.session._emit(\"changeFold\",{data:{start:{row:i}}}),this.session.lineWidgetWidth=null),this.session._changedWidgets=[]},this.renderWidgets=function(e,t){var n=t.layerConfig,r=this.session.lineWidgets;if(!r)return;var i=Math.min(this.firstRow,n.firstRow),s=Math.max(this.lastRow,n.lastRow,r.length);while(i>0&&!r[i])i--;this.firstRow=n.firstRow,this.lastRow=n.lastRow,t.$cursorLayer.config=n;for(var o=i;o<=s;o++){var u=r[o];if(!u||!u.el)continue;u._inDocument||(u._inDocument=!0,t.container.appendChild(u.el));var a=t.$cursorLayer.getPixelPosition({row:o,column:0},!0).top;u.coverLine||(a+=n.lineHeight*this.session.getRowLineCount(u.row)),u.el.style.top=a-n.offset+\"px\";var f=u.coverGutter?0:t.gutterWidth;u.fixedWidth||(f-=t.scrollLeft),u.el.style.left=f+\"px\",u.fixedWidth?u.el.style.right=t.scrollBar.getWidth()+\"px\":u.el.style.right=\"\"}}}).call(o.prototype),t.LineWidgets=o}),ace.define(\"ace/ext/error_marker\",[\"require\",\"exports\",\"module\",\"ace/line_widgets\",\"ace/lib/dom\",\"ace/range\"],function(e,t,n){\"use strict\";function o(e,t,n){var r=0,i=e.length-1;while(r<=i){var s=r+i>>1,o=n(t,e[s]);if(o>0)r=s+1;else{if(!(o<0))return s;i=s-1}}return-(r+1)}function u(e,t,n){var r=e.getAnnotations().sort(s.comparePoints);if(!r.length)return;var i=o(r,{row:t,column:-1},s.comparePoints);i<0&&(i=-i-1),i>=r.length-1?i=n>0?0:r.length-1:i===0&&n<0&&(i=r.length-1);var u=r[i];if(!u||!n)return;if(u.row===t){do u=r[i+=n];while(u&&u.row===t);if(!u)return r.slice()}var a=[];t=u.row;do a[n<0?\"unshift\":\"push\"](u),u=r[i+=n];while(u&&u.row==t);return a.length&&a}var r=e(\"../line_widgets\").LineWidgets,i=e(\"../lib/dom\"),s=e(\"../range\").Range;t.showErrorMarker=function(e,t){var n=e.session;n.widgetManager||(n.widgetManager=new r(n),n.widgetManager.attach(e));var s=e.getCursorPosition(),o=s.row,a=n.lineWidgets&&n.lineWidgets[o];a?a.destroy():o-=t;var f=u(n,o,t),l;if(f){var c=f[0];s.column=(c.pos&&typeof c.column!=\"number\"?c.pos.sc:c.column)||0,s.row=c.row,l=e.renderer.$gutterLayer.$annotations[s.row]}else{if(a)return;l={text:[\"Looks good!\"],className:\"ace_ok\"}}e.session.unfold(s.row),e.selection.moveToPosition(s);var h={row:s.row,fixedWidth:!0,coverGutter:!0,el:i.createElement(\"div\")},p=h.el.appendChild(i.createElement(\"div\")),d=h.el.appendChild(i.createElement(\"div\"));d.className=\"error_widget_arrow \"+l.className;var v=e.renderer.$cursorLayer.getPixelPosition(s).left;d.style.left=v+e.renderer.gutterWidth-5+\"px\",h.el.className=\"error_widget_wrapper\",p.className=\"error_widget \"+l.className,p.innerHTML=l.text.join(\"<br>\"),p.appendChild(i.createElement(\"div\"));var m=function(e,t,n){if(t===0&&(n===\"esc\"||n===\"return\"))return h.destroy(),{command:\"null\"}};h.destroy=function(){if(e.$mouseHandler.isMousePressed)return;e.keyBinding.removeKeyboardHandler(m),n.widgetManager.removeLineWidget(h),e.off(\"changeSelection\",h.destroy),e.off(\"changeSession\",h.destroy),e.off(\"mouseup\",h.destroy),e.off(\"change\",h.destroy)},e.keyBinding.addKeyboardHandler(m),e.on(\"changeSelection\",h.destroy),e.on(\"changeSession\",h.destroy),e.on(\"mouseup\",h.destroy),e.on(\"change\",h.destroy),e.session.widgetManager.addLineWidget(h),h.el.onmousedown=e.focus.bind(e),e.renderer.scrollCursorIntoView(null,.5,{bottom:h.el.offsetHeight})},i.importCssString(\"    .error_widget_wrapper {        background: inherit;        color: inherit;        border:none    }    .error_widget {        border-top: solid 2px;        border-bottom: solid 2px;        margin: 5px 0;        padding: 10px 40px;        white-space: pre-wrap;    }    .error_widget.ace_error, .error_widget_arrow.ace_error{        border-color: #ff5a5a    }    .error_widget.ace_warning, .error_widget_arrow.ace_warning{        border-color: #F1D817    }    .error_widget.ace_info, .error_widget_arrow.ace_info{        border-color: #5a5a5a    }    .error_widget.ace_ok, .error_widget_arrow.ace_ok{        border-color: #5aaa5a    }    .error_widget_arrow {        position: absolute;        border: solid 5px;        border-top-color: transparent!important;        border-right-color: transparent!important;        border-left-color: transparent!important;        top: -5px;    }\",\"\")}),ace.define(\"ace/ace\",[\"require\",\"exports\",\"module\",\"ace/lib/fixoldbrowsers\",\"ace/lib/dom\",\"ace/lib/event\",\"ace/editor\",\"ace/edit_session\",\"ace/undomanager\",\"ace/virtual_renderer\",\"ace/worker/worker_client\",\"ace/keyboard/hash_handler\",\"ace/placeholder\",\"ace/multi_select\",\"ace/mode/folding/fold_mode\",\"ace/theme/textmate\",\"ace/ext/error_marker\",\"ace/config\"],function(e,t,n){\"use strict\";e(\"./lib/fixoldbrowsers\");var r=e(\"./lib/dom\"),i=e(\"./lib/event\"),s=e(\"./editor\").Editor,o=e(\"./edit_session\").EditSession,u=e(\"./undomanager\").UndoManager,a=e(\"./virtual_renderer\").VirtualRenderer;e(\"./worker/worker_client\"),e(\"./keyboard/hash_handler\"),e(\"./placeholder\"),e(\"./multi_select\"),e(\"./mode/folding/fold_mode\"),e(\"./theme/textmate\"),e(\"./ext/error_marker\"),t.config=e(\"./config\"),t.require=e,t.edit=function(e){if(typeof e==\"string\"){var n=e;e=document.getElementById(n);if(!e)throw new Error(\"ace.edit can't find div #\"+n)}if(e&&e.env&&e.env.editor instanceof s)return e.env.editor;var o=\"\";if(e&&/input|textarea/i.test(e.tagName)){var u=e;o=u.value,e=r.createElement(\"pre\"),u.parentNode.replaceChild(e,u)}else o=r.getInnerText(e),e.innerHTML=\"\";var f=t.createEditSession(o),l=new s(new a(e));l.setSession(f);var c={document:f,editor:l,onResize:l.resize.bind(l,null)};return u&&(c.textarea=u),i.addListener(window,\"resize\",c.onResize),l.on(\"destroy\",function(){i.removeListener(window,\"resize\",c.onResize),c.editor.container.env=null}),l.container.env=l.env=c,l},t.createEditSession=function(e,t){var n=new o(e,t);return n.setUndoManager(new u),n},t.EditSession=o,t.UndoManager=u});\n            (function() {\n                ace.require([\"ace/ace\"], function(a) {\n                    a && a.config.init(true);\n                    if (!window.ace)\n                        window.ace = a;\n                    for (var key in a) if (a.hasOwnProperty(key))\n                        window.ace[key] = a[key];\n                });\n            })();\n\n"
  },
  {
    "path": "docs/js/ace/mode-javascript.js",
    "content": "ace.define(\"ace/mode/doc_comment_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text_highlight_rules\").TextHighlightRules,s=function(){this.$rules={start:[{token:\"comment.doc.tag\",regex:\"@[\\\\w\\\\d_]+\"},s.getTagRule(),{defaultToken:\"comment.doc\",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:\"comment.doc.tag.storage.type\",regex:\"\\\\b(?:TODO|FIXME|XXX|HACK)\\\\b\"}},s.getStartRule=function(e){return{token:\"comment.doc\",regex:\"\\\\/\\\\*(?=\\\\*)\",next:e}},s.getEndRule=function(e){return{token:\"comment.doc\",regex:\"\\\\*\\\\/\",next:e}},t.DocCommentHighlightRules=s}),ace.define(\"ace/mode/javascript_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/doc_comment_highlight_rules\",\"ace/mode/text_highlight_rules\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./doc_comment_highlight_rules\").DocCommentHighlightRules,s=e(\"./text_highlight_rules\").TextHighlightRules,o=function(e){var t=this.createKeywordMapper({\"variable.language\":\"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document\",keyword:\"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static\",\"storage.type\":\"const|let|var|function\",\"constant.language\":\"null|Infinity|NaN|undefined\",\"support.function\":\"alert\",\"constant.language.boolean\":\"true|false\"},\"identifier\"),n=\"case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void\",r=\"[a-zA-Z\\\\$_\\u00a1-\\uffff][a-zA-Z\\\\d\\\\$_\\u00a1-\\uffff]*\\\\b\",s=\"\\\\\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)\";this.$rules={no_regex:[{token:\"comment\",regex:\"\\\\/\\\\/\",next:\"line_comment\"},i.getStartRule(\"doc-start\"),{token:\"comment\",regex:/\\/\\*/,next:\"comment\"},{token:\"string\",regex:\"'(?=.)\",next:\"qstring\"},{token:\"string\",regex:'\"(?=.)',next:\"qqstring\"},{token:\"constant.numeric\",regex:/0[xX][0-9a-fA-F]+\\b/},{token:\"constant.numeric\",regex:/[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b/},{token:[\"storage.type\",\"punctuation.operator\",\"support.function\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\"],regex:\"(\"+r+\")(\\\\.)(prototype)(\\\\.)(\"+r+\")(\\\\s*)(=)\",next:\"function_arguments\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+r+\")(\\\\.)(\"+r+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+r+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"storage.type\",\"punctuation.operator\",\"entity.name.function\",\"text\",\"keyword.operator\",\"text\",\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(\"+r+\")(\\\\.)(\"+r+\")(\\\\s*)(=)(\\\\s*)(function)(\\\\s+)(\\\\w+)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"storage.type\",\"text\",\"entity.name.function\",\"text\",\"paren.lparen\"],regex:\"(function)(\\\\s+)(\"+r+\")(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"entity.name.function\",\"text\",\"punctuation.operator\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(\"+r+\")(\\\\s*)(:)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:[\"text\",\"text\",\"storage.type\",\"text\",\"paren.lparen\"],regex:\"(:)(\\\\s*)(function)(\\\\s*)(\\\\()\",next:\"function_arguments\"},{token:\"keyword\",regex:\"(?:\"+n+\")\\\\b\",next:\"start\"},{token:[\"punctuation.operator\",\"support.function\"],regex:/(\\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\\b(?=\\()/},{token:[\"punctuation.operator\",\"support.function.dom\"],regex:/(\\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\\b(?=\\()/},{token:[\"punctuation.operator\",\"support.constant\"],regex:/(\\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\\b/},{token:[\"support.constant\"],regex:/that\\b/},{token:[\"storage.type\",\"punctuation.operator\",\"support.function.firebug\"],regex:/(console)(\\.)(warn|info|log|error|time|trace|timeEnd|assert)\\b/},{token:t,regex:r},{token:\"keyword.operator\",regex:/--|\\+\\+|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|[!$%&*+\\-~\\/^]=?/,next:\"start\"},{token:\"punctuation.operator\",regex:/[?:,;.]/,next:\"start\"},{token:\"paren.lparen\",regex:/[\\[({]/,next:\"start\"},{token:\"paren.rparen\",regex:/[\\])}]/},{token:\"comment\",regex:/^#!.*$/}],start:[i.getStartRule(\"doc-start\"),{token:\"comment\",regex:\"\\\\/\\\\*\",next:\"comment_regex_allowed\"},{token:\"comment\",regex:\"\\\\/\\\\/\",next:\"line_comment_regex_allowed\"},{token:\"string.regexp\",regex:\"\\\\/\",next:\"regex\"},{token:\"text\",regex:\"\\\\s+|^$\",next:\"start\"},{token:\"empty\",regex:\"\",next:\"no_regex\"}],regex:[{token:\"regexp.keyword.operator\",regex:\"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"},{token:\"string.regexp\",regex:\"/[sxngimy]*\",next:\"no_regex\"},{token:\"invalid\",regex:/\\{\\d+\\b,?\\d*\\}[+*]|[+*$^?][+*]|[$^][?]|\\?{3,}/},{token:\"constant.language.escape\",regex:/\\(\\?[:=!]|\\)|\\{\\d+\\b,?\\d*\\}|[+*]\\?|[()$^+*?.]/},{token:\"constant.language.delimiter\",regex:/\\|/},{token:\"constant.language.escape\",regex:/\\[\\^?/,next:\"regex_character_class\"},{token:\"empty\",regex:\"$\",next:\"no_regex\"},{defaultToken:\"string.regexp\"}],regex_character_class:[{token:\"regexp.charclass.keyword.operator\",regex:\"\\\\\\\\(?:u[\\\\da-fA-F]{4}|x[\\\\da-fA-F]{2}|.)\"},{token:\"constant.language.escape\",regex:\"]\",next:\"regex\"},{token:\"constant.language.escape\",regex:\"-\"},{token:\"empty\",regex:\"$\",next:\"no_regex\"},{defaultToken:\"string.regexp.charachterclass\"}],function_arguments:[{token:\"variable.parameter\",regex:r},{token:\"punctuation.operator\",regex:\"[, ]+\"},{token:\"punctuation.operator\",regex:\"$\"},{token:\"empty\",regex:\"\",next:\"no_regex\"}],comment_regex_allowed:[i.getTagRule(),{token:\"comment\",regex:\"\\\\*\\\\/\",next:\"start\"},{defaultToken:\"comment\",caseInsensitive:!0}],comment:[i.getTagRule(),{token:\"comment\",regex:\"\\\\*\\\\/\",next:\"no_regex\"},{defaultToken:\"comment\",caseInsensitive:!0}],line_comment_regex_allowed:[i.getTagRule(),{token:\"comment\",regex:\"$|^\",next:\"start\"},{defaultToken:\"comment\",caseInsensitive:!0}],line_comment:[i.getTagRule(),{token:\"comment\",regex:\"$|^\",next:\"no_regex\"},{defaultToken:\"comment\",caseInsensitive:!0}],qqstring:[{token:\"constant.language.escape\",regex:s},{token:\"string\",regex:\"\\\\\\\\$\",next:\"qqstring\"},{token:\"string\",regex:'\"|$',next:\"no_regex\"},{defaultToken:\"string\"}],qstring:[{token:\"constant.language.escape\",regex:s},{token:\"string\",regex:\"\\\\\\\\$\",next:\"qstring\"},{token:\"string\",regex:\"'|$\",next:\"no_regex\"},{defaultToken:\"string\"}]},(!e||!e.noES6)&&this.$rules.no_regex.unshift({regex:\"[{}]\",onMatch:function(e,t,n){this.next=e==\"{\"?this.nextState:\"\";if(e==\"{\"&&n.length)return n.unshift(\"start\",t),\"paren\";if(e==\"}\"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf(\"string\")!=-1)return\"paren.quasi.end\"}return e==\"{\"?\"paren.lparen\":\"paren.rparen\"},nextState:\"start\"},{token:\"string.quasi.start\",regex:/`/,push:[{token:\"constant.language.escape\",regex:s},{token:\"paren.quasi.start\",regex:/\\${/,push:\"start\"},{token:\"string.quasi.end\",regex:/`/,next:\"pop\"},{defaultToken:\"string.quasi\"}]}),this.embedRules(i,\"doc-\",[i.getEndRule(\"no_regex\")]),this.normalizeRules()};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define(\"ace/mode/matching_brace_outdent\",[\"require\",\"exports\",\"module\",\"ace/range\"],function(e,t,n){\"use strict\";var r=e(\"../range\").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\\s+$/.test(e)?/^\\s*\\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\\s*\\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define(\"ace/mode/behaviour/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/behaviour\",\"ace/token_iterator\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"../behaviour\").Behaviour,s=e(\"../../token_iterator\").TokenIterator,o=e(\"../../lib/lang\"),u=[\"text\",\"paren.rparen\",\"punctuation.operator\"],a=[\"text\",\"paren.rparen\",\"punctuation.operator\",\"comment\"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:\"\",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:\"\",maybeInsertedLineEnd:\"\"}},h=function(){this.add(\"braces\",\"insertion\",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i==\"{\"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==\"\"&&l!==\"{\"&&n.getWrapBehavioursEnabled())return{text:\"{\"+l+\"}\",selection:!1};if(h.isSaneInsertion(n,r))return/[\\]\\}\\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,\"}\"),{text:\"{}\",selection:[1,1]}):(h.recordMaybeInsert(n,r,\"{\"),{text:\"{\",selection:[1,1]})}else if(i==\"}\"){c(n);var p=u.substring(s.column,s.column+1);if(p==\"}\"){var d=r.$findOpeningBracket(\"}\",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}else{if(i==\"\\n\"||i==\"\\r\\n\"){c(n);var v=\"\";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat(\"}\",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p===\"}\"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},\"}\");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:\"\\n\"+y+\"\\n\"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add(\"braces\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"{\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u==\"}\")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add(\"parens\",\"insertion\",function(e,t,n,r,i){if(i==\"(\"){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return{text:\"(\"+o+\")\",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,\")\"),{text:\"()\",selection:[1,1]}}else if(i==\")\"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\")\"){var l=r.$findOpeningBracket(\")\",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"parens\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"(\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\")\")return i.end.column++,i}}),this.add(\"brackets\",\"insertion\",function(e,t,n,r,i){if(i==\"[\"){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==\"\"&&n.getWrapBehavioursEnabled())return{text:\"[\"+o+\"]\",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,\"]\"),{text:\"[]\",selection:[1,1]}}else if(i==\"]\"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==\"]\"){var l=r.$findOpeningBracket(\"]\",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:\"\",selection:[1,1]}}}}),this.add(\"brackets\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s==\"[\"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==\"]\")return i.end.column++,i}}),this.add(\"string_dquotes\",\"insertion\",function(e,t,n,r,i){if(i=='\"'||i==\"'\"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==\"\"&&u!==\"'\"&&u!='\"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l==\"\\\\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type==\"string\"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!==\"comment\"&&(v.type!==\"string\"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type===\"string\"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:\"\",selection:[1,1]}}}}),this.add(\"string_dquotes\",\"deletion\",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='\"'||s==\"'\")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||\"text\",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||\"text\",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||\"text\",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define(\"ace/mode/folding/cstyle\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/range\",\"ace/mode/folding/fold_mode\"],function(e,t,n){\"use strict\";var r=e(\"../../lib/oop\"),i=e(\"../../range\").Range,s=e(\"./fold_mode\").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\\|[^|]*?$/,\"|\"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\\|[^|]*?$/,\"|\"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\\{|\\[)[^\\}\\]]*$|^\\s*(\\/\\*)/,this.foldingStopMarker=/^[^\\[\\{]*(\\}|\\])|^[\\s\\*]*(\\*\\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!=\"all\"&&(u=null)),u}if(t===\"markbegin\")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,\"all\",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define(\"ace/mode/javascript\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text\",\"ace/mode/javascript_highlight_rules\",\"ace/mode/matching_brace_outdent\",\"ace/range\",\"ace/worker/worker_client\",\"ace/mode/behaviour/cstyle\",\"ace/mode/folding/cstyle\"],function(e,t,n){\"use strict\";var r=e(\"../lib/oop\"),i=e(\"./text\").Mode,s=e(\"./javascript_highlight_rules\").JavaScriptHighlightRules,o=e(\"./matching_brace_outdent\").MatchingBraceOutdent,u=e(\"../range\").Range,a=e(\"../worker/worker_client\").WorkerClient,f=e(\"./behaviour/cstyle\").CstyleBehaviour,l=e(\"./folding/cstyle\").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart=\"//\",this.blockComment={start:\"/*\",end:\"*/\"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type==\"comment\")return r;if(e==\"start\"||e==\"no_regex\"){var u=t.match(/^.*(?:\\bcase\\b.*\\:|[\\{\\(\\[])\\s*$/);u&&(r+=n)}else if(e==\"doc-start\"){if(o==\"start\"||o==\"no_regex\")return\"\";var u=t.match(/^\\s*(\\/?)\\*/);u&&(u[1]&&(r+=\" \"),r+=\"* \")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a([\"ace\"],\"ace/mode/javascript_worker\",\"JavaScriptWorker\");return t.attachToDocument(e.getDocument()),t.on(\"jslint\",function(t){e.setAnnotations(t.data)}),t.on(\"terminate\",function(){e.clearAnnotations()}),t},this.$id=\"ace/mode/javascript\"}.call(c.prototype),t.Mode=c})\n"
  },
  {
    "path": "docs/js/ace/theme-tomorrow.js",
    "content": "ace.define(\"ace/theme/tomorrow\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){t.isDark=!1,t.cssClass=\"ace-tomorrow\",t.cssText=\".ace-tomorrow .ace_gutter {background: #f6f6f6;color: #4D4D4C}.ace-tomorrow .ace_print-margin {width: 1px;background: #f6f6f6}.ace-tomorrow {background-color: #FFFFFF;color: #4D4D4C}.ace-tomorrow .ace_cursor {color: #AEAFAD}.ace-tomorrow .ace_marker-layer .ace_selection {background: #D6D6D6}.ace-tomorrow.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #FFFFFF;border-radius: 2px}.ace-tomorrow .ace_marker-layer .ace_step {background: rgb(255, 255, 0)}.ace-tomorrow .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #D1D1D1}.ace-tomorrow .ace_marker-layer .ace_active-line {background: #EFEFEF}.ace-tomorrow .ace_gutter-active-line {background-color : #dcdcdc}.ace-tomorrow .ace_marker-layer .ace_selected-word {border: 1px solid #D6D6D6}.ace-tomorrow .ace_invisible {color: #D1D1D1}.ace-tomorrow .ace_keyword,.ace-tomorrow .ace_meta,.ace-tomorrow .ace_storage,.ace-tomorrow .ace_storage.ace_type,.ace-tomorrow .ace_support.ace_type {color: #8959A8}.ace-tomorrow .ace_keyword.ace_operator {color: #3E999F}.ace-tomorrow .ace_constant.ace_character,.ace-tomorrow .ace_constant.ace_language,.ace-tomorrow .ace_constant.ace_numeric,.ace-tomorrow .ace_keyword.ace_other.ace_unit,.ace-tomorrow .ace_support.ace_constant,.ace-tomorrow .ace_variable.ace_parameter {color: #F5871F}.ace-tomorrow .ace_constant.ace_other {color: #666969}.ace-tomorrow .ace_invalid {color: #FFFFFF;background-color: #C82829}.ace-tomorrow .ace_invalid.ace_deprecated {color: #FFFFFF;background-color: #8959A8}.ace-tomorrow .ace_fold {background-color: #4271AE;border-color: #4D4D4C}.ace-tomorrow .ace_entity.ace_name.ace_function,.ace-tomorrow .ace_support.ace_function,.ace-tomorrow .ace_variable {color: #4271AE}.ace-tomorrow .ace_support.ace_class,.ace-tomorrow .ace_support.ace_type {color: #C99E00}.ace-tomorrow .ace_heading,.ace-tomorrow .ace_markup.ace_heading,.ace-tomorrow .ace_string {color: #718C00}.ace-tomorrow .ace_entity.ace_name.ace_tag,.ace-tomorrow .ace_entity.ace_other.ace_attribute-name,.ace-tomorrow .ace_meta.ace_tag,.ace-tomorrow .ace_string.ace_regexp,.ace-tomorrow .ace_variable {color: #C82829}.ace-tomorrow .ace_comment {color: #8E908C}.ace-tomorrow .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bdu3f/BwAlfgctduB85QAAAABJRU5ErkJggg==) right repeat-y}\";var r=e(\"../lib/dom\");r.importCssString(t.cssText,t.cssClass)})\n"
  },
  {
    "path": "docs/js/ace/worker-javascript.js",
    "content": "\"no use strict\";(function(e){if(typeof e.window!=\"undefined\"&&e.document)return;e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:\"log\",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console,e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){postMessage({type:\"error\",data:{message:e,file:t,line:n,col:r,stack:i.stack}})},e.normalizeModule=function(t,n){if(n.indexOf(\"!\")!==-1){var r=n.split(\"!\");return e.normalizeModule(t,r[0])+\"!\"+e.normalizeModule(t,r[1])}if(n.charAt(0)==\".\"){var i=t.split(\"/\").slice(0,-1).join(\"/\");n=(i?i+\"/\":\"\")+n;while(n.indexOf(\".\")!==-1&&s!=n){var s=n;n=n.replace(/^\\.\\//,\"\").replace(/\\/\\.\\//,\"/\").replace(/[^\\/]+\\/\\.\\.\\//,\"\")}}return n},e.require=function(t,n){n||(n=t,t=null);if(!n.charAt)throw new Error(\"worker.js require() accepts only (parentId, id) as arguments\");n=e.normalizeModule(t,n);var r=e.require.modules[n];if(r)return r.initialized||(r.initialized=!0,r.exports=r.factory().exports),r.exports;var i=n.split(\"/\");if(!e.require.tlns)return console.log(\"unable to load \"+n);i[0]=e.require.tlns[i[0]]||i[0];var s=i.join(\"/\")+\".js\";return e.require.id=n,importScripts(s),e.require(t,n)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!=\"string\"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id);if(typeof r!=\"function\"){e.require.modules[t]={exports:r,initialized:!0};return}n.length||(n=[\"require\",\"exports\",\"module\"]);var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.map(function(t){switch(t){case\"require\":return i;case\"exports\":return e.exports;case\"module\":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},e.initBaseUrls=function(t){require.tlns=t},e.initSender=function(){var n=e.require(\"ace/lib/event_emitter\").EventEmitter,r=e.require(\"ace/lib/oop\"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:\"call\",id:t,data:e})},this.emit=function(e,t){postMessage({type:\"event\",name:e,data:t})}}.call(i.prototype),new i};var t=e.main=null,n=e.sender=null;e.onmessage=function(r){var i=r.data;if(i.command){if(!t[i.command])throw new Error(\"Unknown command:\"+i.command);t[i.command].apply(t,i.args)}else if(i.init){initBaseUrls(i.tlns),require(\"ace/lib/es5-shim\"),n=e.sender=initSender();var s=require(i.module)[i.classname];t=e.main=new s(n)}else i.event&&n&&n._signal(i.event,i.data)}})(this),ace.define(\"ace/lib/oop\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define(\"ace/lib/event_emitter\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!=\"object\"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;t&&this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t){var i=n[e];r&&this.setDefaultHandler(e,r.pop())}else if(r){var s=r.indexOf(t);s!=-1&&r.splice(s,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?\"unshift\":\"push\"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define(\"ace/range\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return\"Range: [\"+this.start.row+\"/\"+this.start.column+\"] -> [\"+this.end.row+\"/\"+this.end.column+\"]\"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e==\"object\"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e==\"object\"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define(\"ace/anchor\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/event_emitter\").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n==\"undefined\"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){var t=e.data,n=t.range;if(n.start.row==n.end.row&&n.start.row!=this.row)return;if(n.start.row>this.row)return;if(n.start.row==this.row&&n.start.column>this.column)return;var r=this.row,i=this.column,s=n.start,o=n.end;if(t.action===\"insertText\")if(s.row===r&&s.column<=i){if(s.column!==i||!this.$insertRight)s.row===o.row?i+=o.column-s.column:(i-=s.column,r+=o.row-s.row)}else s.row!==o.row&&s.row<r&&(r+=o.row-s.row);else t.action===\"insertLines\"?(s.row!==r||i!==0||!this.$insertRight)&&s.row<=r&&(r+=o.row-s.row):t.action===\"removeText\"?s.row===r&&s.column<i?o.column>=i?i=s.column:i=Math.max(0,i-(o.column-s.column)):s.row!==o.row&&s.row<r?(o.row===r&&(i=Math.max(0,i-o.column)+s.column),r-=o.row-s.row):o.row===r&&(r-=o.row-s.row,i=Math.max(0,i-o.column)+s.column):t.action==\"removeLines\"&&s.row<=r&&(o.row<=r?r-=o.row-s.row:(r=s.row,i=0));this.setPosition(r,i,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal(\"change\",{old:i,value:r})},this.detach=function(){this.document.removeEventListener(\"change\",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on(\"change\",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define(\"ace/document\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/lib/event_emitter\",\"ace/range\",\"ace/anchor\"],function(e,t,n){\"use strict\";var r=e(\"./lib/oop\"),i=e(\"./lib/event_emitter\").EventEmitter,s=e(\"./range\").Range,o=e(\"./anchor\").Anchor,u=function(e){this.$lines=[],e.length===0?this.$lines=[\"\"]:Array.isArray(e)?this._insertLines(0,e):this.insert({row:0,column:0},e)};(function(){r.implement(this,i),this.setValue=function(e){var t=this.getLength();this.remove(new s(0,0,t,this.getLine(t-1).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new o(this,e,t)},\"aaa\".split(/a/).length===0?this.$split=function(e){return e.replace(/\\r\\n|\\r/g,\"\\n\").split(\"\\n\")}:this.$split=function(e){return e.split(/\\r\\n|\\r|\\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\\r\\n|\\r|\\n)/m);this.$autoNewLine=t?t[1]:\"\\n\",this._signal(\"changeNewLineMode\")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case\"windows\":return\"\\r\\n\";case\"unix\":return\"\\n\";default:return this.$autoNewLine||\"\\n\"}},this.$autoNewLine=\"\",this.$newLineMode=\"auto\",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal(\"changeNewLineMode\")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e==\"\\r\\n\"||e==\"\\r\"||e==\"\\n\"},this.getLine=function(e){return this.$lines[e]||\"\"},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){if(e.start.row==e.end.row)return this.getLine(e.start.row).substring(e.start.column,e.end.column);var t=this.getLines(e.start.row,e.end.row);t[0]=(t[0]||\"\").substring(e.start.column);var n=t.length-1;return e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column)),t.join(this.getNewLineCharacter())},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):e.row<0&&(e.row=0),e},this.insert=function(e,t){if(!t||t.length===0)return e;e=this.$clipPosition(e),this.getLength()<=1&&this.$detectNewLine(t);var n=this.$split(t),r=n.splice(0,1)[0],i=n.length==0?null:n.splice(n.length-1,1)[0];return e=this.insertInLine(e,r),i!==null&&(e=this.insertNewLine(e),e=this._insertLines(e.row,n),e=this.insertInLine(e,i||\"\")),e},this.insertLines=function(e,t){return e>=this.getLength()?this.insert({row:e,column:0},\"\\n\"+t.join(\"\\n\")):this._insertLines(Math.max(e,0),t)},this._insertLines=function(e,t){if(t.length==0)return{row:e,column:0};while(t.length>61440){var n=this._insertLines(e,t.slice(0,61440));t=t.slice(61440),e=n.row}var r=[e,0];r.push.apply(r,t),this.$lines.splice.apply(this.$lines,r);var i=new s(e,0,e+t.length,0),o={action:\"insertLines\",range:i,lines:t};return this._signal(\"change\",{data:o}),i.end},this.insertNewLine=function(e){e=this.$clipPosition(e);var t=this.$lines[e.row]||\"\";this.$lines[e.row]=t.substring(0,e.column),this.$lines.splice(e.row+1,0,t.substring(e.column,t.length));var n={row:e.row+1,column:0},r={action:\"insertText\",range:s.fromPoints(e,n),text:this.getNewLineCharacter()};return this._signal(\"change\",{data:r}),n},this.insertInLine=function(e,t){if(t.length==0)return e;var n=this.$lines[e.row]||\"\";this.$lines[e.row]=n.substring(0,e.column)+t+n.substring(e.column);var r={row:e.row,column:e.column+t.length},i={action:\"insertText\",range:s.fromPoints(e,r),text:t};return this._signal(\"change\",{data:i}),r},this.remove=function(e){e instanceof s||(e=s.fromPoints(e.start,e.end)),e.start=this.$clipPosition(e.start),e.end=this.$clipPosition(e.end);if(e.isEmpty())return e.start;var t=e.start.row,n=e.end.row;if(e.isMultiLine()){var r=e.start.column==0?t:t+1,i=n-1;e.end.column>0&&this.removeInLine(n,0,e.end.column),i>=r&&this._removeLines(r,i),r!=t&&(this.removeInLine(t,e.start.column,this.getLine(t).length),this.removeNewLine(e.start.row))}else this.removeInLine(t,e.start.column,e.end.column);return e.start},this.removeInLine=function(e,t,n){if(t==n)return;var r=new s(e,t,e,n),i=this.getLine(e),o=i.substring(t,n),u=i.substring(0,t)+i.substring(n,i.length);this.$lines.splice(e,1,u);var a={action:\"removeText\",range:r,text:o};return this._signal(\"change\",{data:a}),r.start},this.removeLines=function(e,t){return e<0||t>=this.getLength()?this.remove(new s(e,0,t+1,0)):this._removeLines(e,t)},this._removeLines=function(e,t){var n=new s(e,0,t+1,0),r=this.$lines.splice(e,t-e+1),i={action:\"removeLines\",range:n,nl:this.getNewLineCharacter(),lines:r};return this._signal(\"change\",{data:i}),r},this.removeNewLine=function(e){var t=this.getLine(e),n=this.getLine(e+1),r=new s(e,t.length,e+1,0),i=t+n;this.$lines.splice(e,2,i);var o={action:\"removeText\",range:r,text:this.getNewLineCharacter()};this._signal(\"change\",{data:o})},this.replace=function(e,t){e instanceof s||(e=s.fromPoints(e.start,e.end));if(t.length==0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);if(t)var n=this.insert(e.start,t);else n=e.start;return n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action==\"insertLines\"?this.insertLines(r.start.row,n.lines):n.action==\"insertText\"?this.insert(r.start,n.text):n.action==\"removeLines\"?this._removeLines(r.start.row,r.end.row-1):n.action==\"removeText\"&&this.remove(r)}},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action==\"insertLines\"?this._removeLines(r.start.row,r.end.row-1):n.action==\"insertText\"?this.remove(r):n.action==\"removeLines\"?this._insertLines(r.start.row,n.lines):n.action==\"removeText\"&&this.insert(r.start,n.text)}},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:n[s-1].length}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(u.prototype),t.Document=u}),ace.define(\"ace/lib/lang\",[\"require\",\"exports\",\"module\"],function(e,t,n){\"use strict\";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split(\"\").reverse().join(\"\")},t.stringRepeat=function(e,t){var n=\"\";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\\s\\s*/,i=/\\s\\s*$/;t.stringTrimLeft=function(e){return e.replace(r,\"\")},t.stringTrimRight=function(e){return e.replace(i,\"\")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]==\"object\"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function(e){if(typeof e!=\"object\"||!e)return e;var n=e.constructor;if(n===RegExp)return e;var r=n();for(var i in e)typeof e[i]==\"object\"?r[i]=t.deepCopy(e[i]):r[i]=e[i];return r},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\\]\\/\\\\])/g,\"\\\\$1\")},t.escapeHTML=function(e){return e.replace(/&/g,\"&#38;\").replace(/\"/g,\"&#34;\").replace(/'/g,\"&#39;\").replace(/</g,\"&#60;\")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define(\"ace/worker/mirror\",[\"require\",\"exports\",\"module\",\"ace/document\",\"ace/lib/lang\"],function(e,t,n){\"use strict\";var r=e(\"../document\").Document,i=e(\"../lib/lang\"),s=t.Mirror=function(e){this.sender=e;var t=this.doc=new r(\"\"),n=this.deferredUpdate=i.delayedCall(this.onUpdate.bind(this)),s=this;e.on(\"change\",function(e){t.applyDeltas(e.data);if(s.$timeout)return n.schedule(s.$timeout);s.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(s.prototype)}),ace.define(\"ace/mode/javascript/jshint\",[\"require\",\"exports\",\"module\"],function(e,t,n){n.exports=function r(t,n,i){function s(u,a){if(!n[u]){if(!t[u]){var f=typeof e==\"function\"&&e;if(!a&&f)return f(u,!0);if(o)return o(u,!0);throw new Error(\"Cannot find module '\"+u+\"'\")}var l=n[u]={exports:{}};t[u][0].call(l.exports,function(e){var n=t[u][1][e];return s(n?n:e)},l,l.exports,r,t,n,i)}return n[u].exports}var o=typeof e==\"function\"&&e;for(var u=0;u<i.length;u++)s(i[u]);return s}({1:[function(e,t,n){var r=[];for(var i=0;i<128;i++)r[i]=i===36||i>=65&&i<=90||i===95||i>=97&&i<=122;var s=[];for(var i=0;i<128;i++)s[i]=r[i]||i>=48&&i<=57;t.exports={asciiIdentifierStartTable:r,asciiIdentifierPartTable:s}},{}],2:[function(e,t,n){(function(){var e=this,r=e._,i={},s=Array.prototype,o=Object.prototype,u=Function.prototype,a=s.push,f=s.slice,l=s.concat,c=o.toString,h=o.hasOwnProperty,p=s.forEach,d=s.map,v=s.reduce,m=s.reduceRight,g=s.filter,y=s.every,b=s.some,w=s.indexOf,E=s.lastIndexOf,S=Array.isArray,x=Object.keys,T=u.bind,N=function(e){if(e instanceof N)return e;if(!(this instanceof N))return new N(e);this._wrapped=e};typeof n!=\"undefined\"?(typeof t!=\"undefined\"&&t.exports&&(n=t.exports=N),n._=N):e._=N,N.VERSION=\"1.6.0\";var C=N.each=N.forEach=function(e,t,n){if(e==null)return e;if(p&&e.forEach===p)e.forEach(t,n);else if(e.length===+e.length){for(var r=0,s=e.length;r<s;r++)if(t.call(n,e[r],r,e)===i)return}else{var o=N.keys(e);for(var r=0,s=o.length;r<s;r++)if(t.call(n,e[o[r]],o[r],e)===i)return}return e};N.map=N.collect=function(e,t,n){var r=[];return e==null?r:d&&e.map===d?e.map(t,n):(C(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var k=\"Reduce of empty array with no initial value\";N.reduce=N.foldl=N.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(v&&e.reduce===v)return r&&(t=N.bind(t,r)),i?e.reduce(t,n):e.reduce(t);C(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(k);return n},N.reduceRight=N.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(m&&e.reduceRight===m)return r&&(t=N.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=N.keys(e);s=o.length}C(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(k);return n},N.find=N.detect=function(e,t,n){var r;return L(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},N.filter=N.select=function(e,t,n){var r=[];return e==null?r:g&&e.filter===g?e.filter(t,n):(C(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},N.reject=function(e,t,n){return N.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},N.every=N.all=function(e,t,n){t||(t=N.identity);var r=!0;return e==null?r:y&&e.every===y?e.every(t,n):(C(e,function(e,s,o){if(!(r=r&&t.call(n,e,s,o)))return i}),!!r)};var L=N.some=N.any=function(e,t,n){t||(t=N.identity);var r=!1;return e==null?r:b&&e.some===b?e.some(t,n):(C(e,function(e,s,o){if(r||(r=t.call(n,e,s,o)))return i}),!!r)};N.contains=N.include=function(e,t){return e==null?!1:w&&e.indexOf===w?e.indexOf(t)!=-1:L(e,function(e){return e===t})},N.invoke=function(e,t){var n=f.call(arguments,2),r=N.isFunction(t);return N.map(e,function(e){return(r?t:e[t]).apply(e,n)})},N.pluck=function(e,t){return N.map(e,N.property(t))},N.where=function(e,t){return N.filter(e,N.matches(t))},N.findWhere=function(e,t){return N.find(e,N.matches(t))},N.max=function(e,t,n){if(!t&&N.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);var r=-Infinity,i=-Infinity;return C(e,function(e,s,o){var u=t?t.call(n,e,s,o):e;u>i&&(r=e,i=u)}),r},N.min=function(e,t,n){if(!t&&N.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);var r=Infinity,i=Infinity;return C(e,function(e,s,o){var u=t?t.call(n,e,s,o):e;u<i&&(r=e,i=u)}),r},N.shuffle=function(e){var t,n=0,r=[];return C(e,function(e){t=N.random(n++),r[n-1]=r[t],r[t]=e}),r},N.sample=function(e,t,n){return t==null||n?(e.length!==+e.length&&(e=N.values(e)),e[N.random(e.length-1)]):N.shuffle(e).slice(0,Math.max(0,t))};var A=function(e){return e==null?N.identity:N.isFunction(e)?e:N.property(e)};N.sortBy=function(e,t,n){return t=A(t),N.pluck(N.map(e,function(e,r,i){return{value:e,index:r,criteria:t.call(n,e,r,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index-t.index}),\"value\")};var O=function(e){return function(t,n,r){var i={};return n=A(n),C(t,function(s,o){var u=n.call(r,s,o,t);e(i,u,s)}),i}};N.groupBy=O(function(e,t,n){N.has(e,t)?e[t].push(n):e[t]=[n]}),N.indexBy=O(function(e,t,n){e[t]=n}),N.countBy=O(function(e,t){N.has(e,t)?e[t]++:e[t]=1}),N.sortedIndex=function(e,t,n,r){n=A(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},N.toArray=function(e){return e?N.isArray(e)?f.call(e):e.length===+e.length?N.map(e,N.identity):N.values(e):[]},N.size=function(e){return e==null?0:e.length===+e.length?e.length:N.keys(e).length},N.first=N.head=N.take=function(e,t,n){return e==null?void 0:t==null||n?e[0]:t<0?[]:f.call(e,0,t)},N.initial=function(e,t,n){return f.call(e,0,e.length-(t==null||n?1:t))},N.last=function(e,t,n){return e==null?void 0:t==null||n?e[e.length-1]:f.call(e,Math.max(e.length-t,0))},N.rest=N.tail=N.drop=function(e,t,n){return f.call(e,t==null||n?1:t)},N.compact=function(e){return N.filter(e,N.identity)};var M=function(e,t,n){return t&&N.every(e,N.isArray)?l.apply(n,e):(C(e,function(e){N.isArray(e)||N.isArguments(e)?t?a.apply(n,e):M(e,t,n):n.push(e)}),n)};N.flatten=function(e,t){return M(e,t,[])},N.without=function(e){return N.difference(e,f.call(arguments,1))},N.partition=function(e,t){var n=[],r=[];return C(e,function(e){(t(e)?n:r).push(e)}),[n,r]},N.uniq=N.unique=function(e,t,n,r){N.isFunction(t)&&(r=n,n=t,t=!1);var i=n?N.map(e,n,r):e,s=[],o=[];return C(i,function(n,r){if(t?!r||o[o.length-1]!==n:!N.contains(o,n))o.push(n),s.push(e[r])}),s},N.union=function(){return N.uniq(N.flatten(arguments,!0))},N.intersection=function(e){var t=f.call(arguments,1);return N.filter(N.uniq(e),function(e){return N.every(t,function(t){return N.contains(t,e)})})},N.difference=function(e){var t=l.apply(s,f.call(arguments,1));return N.filter(e,function(e){return!N.contains(t,e)})},N.zip=function(){var e=N.max(N.pluck(arguments,\"length\").concat(0)),t=new Array(e);for(var n=0;n<e;n++)t[n]=N.pluck(arguments,\"\"+n);return t},N.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},N.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!=\"number\")return r=N.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(w&&e.indexOf===w)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},N.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(E&&e.lastIndexOf===E)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},N.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var _=function(){};N.bind=function(e,t){var n,r;if(T&&e.bind===T)return T.apply(e,f.call(arguments,1));if(!N.isFunction(e))throw new TypeError;return n=f.call(arguments,2),r=function(){if(this instanceof r){_.prototype=e.prototype;var i=new _;_.prototype=null;var s=e.apply(i,n.concat(f.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(f.call(arguments)))}},N.partial=function(e){var t=f.call(arguments,1);return function(){var n=0,r=t.slice();for(var i=0,s=r.length;i<s;i++)r[i]===N&&(r[i]=arguments[n++]);while(n<arguments.length)r.push(arguments[n++]);return e.apply(this,r)}},N.bindAll=function(e){var t=f.call(arguments,1);if(t.length===0)throw new Error(\"bindAll must be passed function names\");return C(t,function(t){e[t]=N.bind(e[t],e)}),e},N.memoize=function(e,t){var n={};return t||(t=N.identity),function(){var r=t.apply(this,arguments);return N.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},N.delay=function(e,t){var n=f.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},N.defer=function(e){return N.delay.apply(N,[e,1].concat(f.call(arguments,1)))},N.throttle=function(e,t,n){var r,i,s,o=null,u=0;n||(n={});var a=function(){u=n.leading===!1?0:N.now(),o=null,s=e.apply(r,i),r=i=null};return function(){var f=N.now();!u&&n.leading===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(o),o=null,u=f,s=e.apply(r,i),r=i=null):!o&&n.trailing!==!1&&(o=setTimeout(a,l)),s}},N.debounce=function(e,t,n){var r,i,s,o,u,a=function(){var f=N.now()-o;f<t?r=setTimeout(a,t-f):(r=null,n||(u=e.apply(s,i),s=i=null))};return function(){s=this,i=arguments,o=N.now();var f=n&&!r;return r||(r=setTimeout(a,t)),f&&(u=e.apply(s,i),s=i=null),u}},N.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},N.wrap=function(e,t){return N.partial(t,e)},N.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},N.after=function(e,t){return function(){if(--e<1)return t.apply(this,arguments)}},N.keys=function(e){if(!N.isObject(e))return[];if(x)return x(e);var t=[];for(var n in e)N.has(e,n)&&t.push(n);return t},N.values=function(e){var t=N.keys(e),n=t.length,r=new Array(n);for(var i=0;i<n;i++)r[i]=e[t[i]];return r},N.pairs=function(e){var t=N.keys(e),n=t.length,r=new Array(n);for(var i=0;i<n;i++)r[i]=[t[i],e[t[i]]];return r},N.invert=function(e){var t={},n=N.keys(e);for(var r=0,i=n.length;r<i;r++)t[e[n[r]]]=n[r];return t},N.functions=N.methods=function(e){var t=[];for(var n in e)N.isFunction(e[n])&&t.push(n);return t.sort()},N.extend=function(e){return C(f.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},N.pick=function(e){var t={},n=l.apply(s,f.call(arguments,1));return C(n,function(n){n in e&&(t[n]=e[n])}),t},N.omit=function(e){var t={},n=l.apply(s,f.call(arguments,1));for(var r in e)N.contains(n,r)||(t[r]=e[r]);return t},N.defaults=function(e){return C(f.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},N.clone=function(e){return N.isObject(e)?N.isArray(e)?e.slice():N.extend({},e):e},N.tap=function(e,t){return t(e),e};var D=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof N&&(e=e._wrapped),t instanceof N&&(t=t._wrapped);var i=c.call(e);if(i!=c.call(t))return!1;switch(i){case\"[object String]\":return e==String(t);case\"[object Number]\":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case\"[object Date]\":case\"[object Boolean]\":return+e==+t;case\"[object RegExp]\":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!=\"object\"||typeof t!=\"object\")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;var o=e.constructor,u=t.constructor;if(o!==u&&!(N.isFunction(o)&&o instanceof o&&N.isFunction(u)&&u instanceof u)&&\"constructor\"in e&&\"constructor\"in t)return!1;n.push(e),r.push(t);var a=0,f=!0;if(i==\"[object Array]\"){a=e.length,f=a==t.length;if(f)while(a--)if(!(f=D(e[a],t[a],n,r)))break}else{for(var l in e)if(N.has(e,l)){a++;if(!(f=N.has(t,l)&&D(e[l],t[l],n,r)))break}if(f){for(l in t)if(N.has(t,l)&&!(a--))break;f=!a}}return n.pop(),r.pop(),f};N.isEqual=function(e,t){return D(e,t,[],[])},N.isEmpty=function(e){if(e==null)return!0;if(N.isArray(e)||N.isString(e))return e.length===0;for(var t in e)if(N.has(e,t))return!1;return!0},N.isElement=function(e){return!!e&&e.nodeType===1},N.isArray=S||function(e){return c.call(e)==\"[object Array]\"},N.isObject=function(e){return e===Object(e)},C([\"Arguments\",\"Function\",\"String\",\"Number\",\"Date\",\"RegExp\"],function(e){N[\"is\"+e]=function(t){return c.call(t)==\"[object \"+e+\"]\"}}),N.isArguments(arguments)||(N.isArguments=function(e){return!!e&&!!N.has(e,\"callee\")}),typeof /./!=\"function\"&&(N.isFunction=function(e){return typeof e==\"function\"}),N.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},N.isNaN=function(e){return N.isNumber(e)&&e!=+e},N.isBoolean=function(e){return e===!0||e===!1||c.call(e)==\"[object Boolean]\"},N.isNull=function(e){return e===null},N.isUndefined=function(e){return e===void 0},N.has=function(e,t){return h.call(e,t)},N.noConflict=function(){return e._=r,this},N.identity=function(e){return e},N.constant=function(e){return function(){return e}},N.property=function(e){return function(t){return t[e]}},N.matches=function(e){return function(t){if(t===e)return!0;for(var n in e)if(e[n]!==t[n])return!1;return!0}},N.times=function(e,t,n){var r=Array(Math.max(0,e));for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},N.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))},N.now=Date.now||function(){return(new Date).getTime()};var P={escape:{\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#x27;\"}};P.unescape=N.invert(P.escape);var H={escape:new RegExp(\"[\"+N.keys(P.escape).join(\"\")+\"]\",\"g\"),unescape:new RegExp(\"(\"+N.keys(P.unescape).join(\"|\")+\")\",\"g\")};N.each([\"escape\",\"unescape\"],function(e){N[e]=function(t){return t==null?\"\":(\"\"+t).replace(H[e],function(t){return P[e][t]})}}),N.result=function(e,t){if(e==null)return void 0;var n=e[t];return N.isFunction(n)?n.call(e):n},N.mixin=function(e){C(N.functions(e),function(t){var n=N[t]=e[t];N.prototype[t]=function(){var e=[this._wrapped];return a.apply(e,arguments),q.call(this,n.apply(N,e))}})};var B=0;N.uniqueId=function(e){var t=++B+\"\";return e?e+t:t},N.templateSettings={evaluate:/<%([\\s\\S]+?)%>/g,interpolate:/<%=([\\s\\S]+?)%>/g,escape:/<%-([\\s\\S]+?)%>/g};var j=/(.)^/,F={\"'\":\"'\",\"\\\\\":\"\\\\\",\"\\r\":\"r\",\"\\n\":\"n\",\"  \":\"t\",\"\\u2028\":\"u2028\",\"\\u2029\":\"u2029\"},I=/\\\\|'|\\r|\\n|\\t|\\u2028|\\u2029/g;N.template=function(e,t,n){var r;n=N.defaults({},n,N.templateSettings);var i=new RegExp([(n.escape||j).source,(n.interpolate||j).source,(n.evaluate||j).source].join(\"|\")+\"|$\",\"g\"),s=0,o=\"__p+='\";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(I,function(e){return\"\\\\\"+F[e]}),n&&(o+=\"'+\\n((__t=(\"+n+\"))==null?'':_.escape(__t))+\\n'\"),r&&(o+=\"'+\\n((__t=(\"+r+\"))==null?'':__t)+\\n'\"),i&&(o+=\"';\\n\"+i+\"\\n__p+='\"),s=u+t.length,t}),o+=\"';\\n\",n.variable||(o=\"with(obj||{}){\\n\"+o+\"}\\n\"),o=\"var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\\n\"+o+\"return __p;\\n\";try{r=new Function(n.variable||\"obj\",\"_\",o)}catch(u){throw u.source=o,u}if(t)return r(t,N);var a=function(e){return r.call(this,e,N)};return a.source=\"function(\"+(n.variable||\"obj\")+\"){\\n\"+o+\"}\",a},N.chain=function(e){return N(e).chain()};var q=function(e){return this._chain?N(e).chain():e};N.mixin(N),C([\"pop\",\"push\",\"reverse\",\"shift\",\"sort\",\"splice\",\"unshift\"],function(e){var t=s[e];N.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e==\"shift\"||e==\"splice\")&&n.length===0&&delete n[0],q.call(this,n)}}),C([\"concat\",\"join\",\"slice\"],function(e){var t=s[e];N.prototype[e]=function(){return q.call(this,t.apply(this._wrapped,arguments))}}),N.extend(N.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}}),typeof define==\"function\"&&define.amd&&ace.define(\"underscore\",[],function(){return N})}).call(this)},{}],3:[function(e,t,n){var r=e(\"underscore\"),i=e(\"events\"),s=e(\"./vars.js\"),o=e(\"./messages.js\"),u=e(\"./lex.js\").Lexer,a=e(\"./reg.js\"),f=e(\"./state.js\").state,l=e(\"./style.js\"),c=function(){\"use strict\";function I(e,t){return e=e.trim(),/^[+-]W\\d{3}$/g.test(e)?!0:p[e]===undefined&&h[e]===undefined&&t.type!==\"jslint\"&&!m[e]?(G(\"E001\",t,e),!1):!0}function q(e){return Object.prototype.toString.call(e)===\"[object String]\"}function R(e,t){return e?!e.identifier||e.value!==t?!1:!0:!1}function U(e){if(!e.reserved)return!1;var t=e.meta;if(t&&t.isFutureReservedWord&&f.option.inES5()){if(!t.es5)return!1;if(t.strictOnly&&!f.option.strict&&!f.directive[\"use strict\"])return!1;if(e.isProperty)return!1}return!0}function z(e,t){return e.replace(/\\{([^{}]*)\\}/g,function(e,n){var r=t[n];return typeof r==\"string\"||typeof r==\"number\"?r:e})}function W(e,t){Object.keys(t).forEach(function(n){if(r.has(c.blacklist,n))return;e[n]=t[n]})}function X(){f.option.esnext&&W(M,s.newEcmaIdentifiers),f.option.couch&&W(M,s.couch),f.option.qunit&&W(M,s.qunit),f.option.rhino&&W(M,s.rhino),f.option.shelljs&&(W(M,s.shelljs),W(M,s.node)),f.option.typed&&W(M,s.typed),f.option.phantom&&W(M,s.phantom),f.option.prototypejs&&W(M,s.prototypejs),f.option.node&&(W(M,s.node),W(M,s.typed)),f.option.devel&&W(M,s.devel),f.option.dojo&&W(M,s.dojo),f.option.browser&&(W(M,s.browser),W(M,s.typed)),f.option.nonstandard&&W(M,s.nonstandard),f.option.jasmine&&W(M,s.jasmine),f.option.jquery&&W(M,s.jquery),f.option.mootools&&W(M,s.mootools),f.option.worker&&W(M,s.worker),f.option.wsh&&W(M,s.wsh),f.option.globalstrict&&f.option.strict!==!1&&(f.option.strict=!0),f.option.yui&&W(M,s.yui),f.option.mocha&&W(M,s.mocha),f.option.inMoz=function(e){return f.option.moz},f.option.inESNext=function(e){return f.option.moz||f.option.esnext},f.option.inES5=function(){return!f.option.es3},f.option.inES3=function(e){return e?!f.option.moz&&!f.option.esnext&&f.option.es3:f.option.es3}}function V(e,t,n){var r=Math.floor(t/f.lines.length*100),i=o.errors[e].desc;throw{name:\"JSHintError\",line:t,character:n,message:i+\" (\"+r+\"% scanned).\",raw:i,code:e}}function $(e,t,n,r){return c.undefs.push([e,t,n,r])}function J(){var e=f.ignoredLines;if(r.isEmpty(e))return;c.errors=r.reject(c.errors,function(t){return e[t.line]})}function K(e,t,n,r,i,s){var u,a,l,h;if(/^W\\d{3}$/.test(e)){if(f.ignored[e])return;h=o.warnings[e]}else/E\\d{3}/.test(e)?h=o.errors[e]:/I\\d{3}/.test(e)&&(h=o.info[e]);return t=t||f.tokens.next,t.id===\"(end)\"&&(t=f.tokens.curr),a=t.line||0,u=t.from||0,l={id:\"(error)\",raw:h.desc,code:h.code,evidence:f.lines[a-1]||\"\",line:a,character:u,scope:c.scope,a:n,b:r,c:i,d:s},l.reason=z(h.desc,l),c.errors.push(l),J(),c.errors.length>=f.option.maxerr&&V(\"E043\",a,u),l}function Q(e,t,n,r,i,s,o){return K(e,{line:t,from:n},r,i,s,o)}function G(e,t,n,r,i,s){K(e,t,n,r,i,s)}function Y(e,t,n,r,i,s,o){return G(e,{line:t,from:n},r,i,s,o)}function Z(e,t){var n;return n={id:\"(internal)\",elem:e,value:t},c.internals.push(n),n}function et(e,t){t=t||{};var n=t.type,i=t.token,s=t.islet;n===\"exception\"&&r.has(w[\"(context)\"],e)&&w[e]!==!0&&!f.option.node&&K(\"W002\",f.tokens.next,e),r.has(w,e)&&!w[\"(global)\"]&&(w[e]===!0?f.option.latedef&&(f.option.latedef===!0&&r.contains([w[e],n],\"unction\")||!r.contains([w[e],n],\"unction\"))&&K(\"W003\",f.tokens.next,e):((!f.option.shadow||r.contains([\"inner\",\"outer\"],f.option.shadow))&&n!==\"exception\"||w[\"(blockscope)\"].getlabel(e))&&K(\"W004\",f.tokens.next,e)),w[\"(context)\"]&&r.has(w[\"(context)\"],e)&&n!==\"function\"&&f.option.shadow===\"outer\"&&K(\"W123\",f.tokens.next,e),s?w[\"(blockscope)\"].current.add(e,n,f.tokens.curr):(w[\"(blockscope)\"].shadow(e),w[e]=n,i&&(w[\"(tokens)\"][e]=i),Xt(w,e,{unused:t.unused||!1}),w[\"(global)\"]?(S[e]=w,r.has(x,e)&&(f.option.latedef&&(f.option.latedef===!0&&r.contains([w[e],n],\"unction\")||!r.contains([w[e],n],\"unction\"))&&K(\"W003\",f.tokens.next,e),delete x[e])):D[e]=w)}function tt(){var e=f.tokens.next,t=e.body.match(/(-\\s+)?[^\\s,:]+(?:\\s*:\\s*(-\\s+)?[^\\s,]+)?/g)||[],n={};if(e.type===\"globals\"){t.forEach(function(e){e=e.split(\":\");var t=(e[0]||\"\").trim(),r=(e[1]||\"\").trim();t.charAt(0)===\"-\"?(t=t.slice(1),r=!1,c.blacklist[t]=t,delete M[t]):n[t]=r===\"true\"}),W(M,n);for(var i in n)r.has(n,i)&&(g[i]=e)}e.type===\"exported\"&&t.forEach(function(e){y[e]=!0}),e.type===\"members\"&&(A=A||{},t.forEach(function(e){var t=e.charAt(0),n=e.charAt(e.length-1);t===n&&(t==='\"'||t===\"'\")&&(e=e.substr(1,e.length-2).replace('\\\\\"','\"')),A[e]=!1}));var s=[\"maxstatements\",\"maxparams\",\"maxdepth\",\"maxcomplexity\",\"maxerr\",\"maxlen\",\"indent\"];if(e.type===\"jshint\"||e.type===\"jslint\")t.forEach(function(t){t=t.split(\":\");var n=(t[0]||\"\").trim(),r=(t[1]||\"\").trim();if(!I(n,e))return;if(s.indexOf(n)>=0){if(r!==\"false\"){r=+r;if(typeof r!=\"number\"||!isFinite(r)||r<=0||Math.floor(r)!==r){G(\"E032\",e,t[1].trim());return}f.option[n]=r}else f.option[n]=n===\"indent\"?4:!1;return}if(n===\"validthis\"){if(w[\"(global)\"])return void G(\"E009\");if(r!==\"true\"&&r!==\"false\")return void G(\"E002\",e);f.option.validthis=r===\"true\";return}if(n===\"quotmark\"){switch(r){case\"true\":case\"false\":f.option.quotmark=r===\"true\";break;case\"double\":case\"single\":f.option.quotmark=r;break;default:G(\"E002\",e)}return}if(n===\"shadow\"){switch(r){case\"true\":f.option.shadow=!0;break;case\"outer\":f.option.shadow=\"outer\";break;case\"false\":case\"inner\":f.option.shadow=\"inner\";break;default:G(\"E002\",e)}return}if(n===\"unused\"){switch(r){case\"true\":f.option.unused=!0;break;case\"false\":f.option.unused=!1;break;case\"vars\":case\"strict\":f.option.unused=r;break;default:G(\"E002\",e)}return}if(n===\"latedef\"){switch(r){case\"true\":f.option.latedef=!0;break;case\"false\":f.option.latedef=!1;break;case\"nofunc\":f.option.latedef=\"nofunc\";break;default:G(\"E002\",e)}return}if(n===\"ignore\"){switch(r){case\"start\":f.ignoreLinterErrors=!0;break;case\"end\":f.ignoreLinterErrors=!1;break;case\"line\":f.ignoredLines[e.line]=!0,J();break;default:G(\"E002\",e)}return}var i=/^([+-])(W\\d{3})$/g.exec(n);if(i){f.ignored[i[2]]=i[1]===\"-\";return}var o;if(r===\"true\"||r===\"false\"){e.type===\"jslint\"?(o=v[n]||n,f.option[o]=r===\"true\",d[o]!==undefined&&(f.option[o]=!f.option[o])):f.option[n]=r===\"true\",n===\"newcap\"&&(f.option[\"(explicitNewcap)\"]=!0);return}G(\"E002\",e)}),X()}function nt(e){var t=e||0,n=0,r;while(n<=t)r=C[n],r||(r=C[n]=k.token()),n+=1;return r}function rt(t,n){switch(f.tokens.curr.id){case\"(number)\":f.tokens.next.id===\".\"&&K(\"W005\",f.tokens.curr);break;case\"-\":(f.tokens.next.id===\"-\"||f.tokens.next.id===\"--\")&&K(\"W006\");break;case\"+\":(f.tokens.next.id===\"+\"||f.tokens.next.id===\"++\")&&K(\"W007\")}if(f.tokens.curr.type===\"(string)\"||f.tokens.curr.identifier)e=f.tokens.curr.value;t&&f.tokens.next.id!==t&&(n?f.tokens.next.id===\"(end)\"?G(\"E019\",n,n.id):G(\"E020\",f.tokens.next,t,n.id,n.line,f.tokens.next.value):(f.tokens.next.type!==\"(identifier)\"||f.tokens.next.value!==t)&&K(\"W116\",f.tokens.next,t,f.tokens.next.value)),f.tokens.prev=f.tokens.curr,f.tokens.curr=f.tokens.next;for(;;){f.tokens.next=C.shift()||k.token(),f.tokens.next||V(\"E041\",f.tokens.curr.line);if(f.tokens.next.id===\"(end)\"||f.tokens.next.id===\"(error)\")return;f.tokens.next.check&&f.tokens.next.check();if(f.tokens.next.isSpecial)tt();else if(f.tokens.next.id!==\"(endline)\")break}}function it(e){return e.infix||!e.identifier&&!!e.led}function st(){var e=f.tokens.curr,t=f.tokens.next;return t.id===\";\"||t.id===\"}\"||t.id===\":\"?!0:it(t)===it(e)||e.id===\"yield\"&&f.option.inMoz(!0)?e.line!==t.line:!1}function ot(t,n){var i,s=!1,o=!1,u=!1;!n&&f.tokens.next.value===\"let\"&&nt(0).value===\"(\"&&(f.option.inMoz(!0)||K(\"W118\",f.tokens.next,\"let expressions\"),u=!0,w[\"(blockscope)\"].stack(),rt(\"let\"),rt(\"(\"),f.syntax.let.fud.call(f.syntax.let.fud,!1),rt(\")\")),f.tokens.next.id===\"(end)\"&&G(\"E006\",f.tokens.curr);var a=f.option.asi&&f.tokens.prev.line<f.tokens.curr.line&&r.contains([\"]\",\")\"],f.tokens.prev.id)&&r.contains([\"[\",\"(\"],f.tokens.curr.id);a&&K(\"W014\",f.tokens.curr,f.tokens.curr.id),rt(),n&&(e=\"anonymous\",w[\"(verb)\"]=f.tokens.curr.value);if(n===!0&&f.tokens.curr.fud)i=f.tokens.curr.fud();else{f.tokens.curr.nud?i=f.tokens.curr.nud():G(\"E030\",f.tokens.curr,f.tokens.curr.id);while(t<f.tokens.next.lbp&&!st())s=f.tokens.curr.value===\"Array\",o=f.tokens.curr.value===\"Object\",i&&(i.value||i.first&&i.first.value)&&(i.value!==\"new\"||i.first&&i.first.value&&i.first.value===\".\")&&(s=!1,i.value!==f.tokens.curr.value&&(o=!1)),rt(),s&&f.tokens.curr.id===\"(\"&&f.tokens.next.id===\")\"&&K(\"W009\",f.tokens.curr),o&&f.tokens.curr.id===\"(\"&&f.tokens.next.id===\")\"&&K(\"W010\",f.tokens.curr),i&&f.tokens.curr.led?i=f.tokens.curr.led(i):G(\"E033\",f.tokens.curr,f.tokens.curr.id)}return u&&w[\"(blockscope)\"].unstack(),i}function ut(e,t){e=e||f.tokens.curr,t=t||f.tokens.next,!f.option.laxbreak&&e.line!==t.line&&K(\"W014\",t,t.value)}function at(e){e=e||f.tokens.curr,e.line!==f.tokens.next.line&&K(\"E022\",e,e.value)}function ft(e,t){e.line!==t.line&&(f.option.laxcomma||(lt.first&&(K(\"I001\"),lt.first=!1),K(\"W014\",e,t.value)))}function lt(e){e=e||{},e.peek?ft(f.tokens.prev,f.tokens.curr):(ft(f.tokens.curr,f.tokens.next),rt(\",\"));if(f.tokens.next.identifier&&(!e.property||!f.option.inES5()))switch(f.tokens.next.value){case\"break\":case\"case\":case\"catch\":case\"continue\":case\"default\":case\"do\":case\"else\":case\"finally\":case\"for\":case\"if\":case\"in\":case\"instanceof\":case\"return\":case\"switch\":case\"throw\":case\"try\":case\"var\":case\"let\":case\"while\":case\"with\":return G(\"E024\",f.tokens.next,f.tokens.next.value),!1}if(f.tokens.next.type===\"(punctuator)\")switch(f.tokens.next.value){case\"}\":case\"]\":case\",\":if(e.allowTrailing)return!0;case\")\":return G(\"E024\",f.tokens.next,f.tokens.next.value),!1}return!0}function ct(e,t){var n=f.syntax[e];if(!n||typeof n!=\"object\")f.syntax[e]=n={id:e,lbp:t,value:e};return n}function ht(e){return ct(e,0)}function pt(e,t){var n=ht(e);return n.identifier=n.reserved=!0,n.fud=t,n}function dt(e,t){var n=pt(e,t);return n.block=!0,n}function vt(e){var t=e.id.charAt(0);if(t>=\"a\"&&t<=\"z\"||t>=\"A\"&&t<=\"Z\")e.identifier=e.reserved=!0;return e}function mt(e,t){var n=ct(e,150);return vt(n),n.nud=typeof t==\"function\"?t:function(){this.right=ot(150),this.arity=\"unary\";if(this.id===\"++\"||this.id===\"--\")f.option.plusplus?K(\"W016\",this,this.id):this.right&&(!this.right.identifier||U(this.right))&&this.right.id!==\".\"&&this.right.id!==\"[\"&&K(\"W017\",this);return this},n}function gt(e,t){var n=ht(e);return n.type=e,n.nud=t,n}function yt(e,t){var n=gt(e,t);return n.identifier=!0,n.reserved=!0,n}function bt(e,t){var n=gt(e,t&&t.nud||function(){return this});return t=t||{},t.isFutureReservedWord=!0,n.value=e,n.identifier=!0,n.reserved=!0,n.meta=t,n}function wt(e,t){return yt(e,function(){return typeof t==\"function\"&&t(this),this})}function Et(e,t,n,r){var i=ct(e,n);return vt(i),i.infix=!0,i.led=function(i){return r||ut(f.tokens.prev,f.tokens.curr),e===\"in\"&&i.id===\"!\"&&K(\"W018\",i,\"!\"),typeof t==\"function\"?t(i,this):(this.left=i,this.right=ot(n),this)},i}function St(e){var t=ct(e,42);return t.led=function(e){return f.option.inESNext()||K(\"W104\",f.tokens.curr,\"arrow function syntax (=>)\"),ut(f.tokens.prev,f.tokens.curr),this.left=e,this.right=Jt(undefined,undefined,!1,e),this},t}function xt(e,t){var n=ct(e,100);return n.led=function(e){ut(f.tokens.prev,f.tokens.curr);var n=ot(100);return R(e,\"NaN\")||R(n,\"NaN\")?K(\"W019\",this):t&&t.apply(this,[e,n]),(!e||!n)&&V(\"E041\",f.tokens.curr.line),e.id===\"!\"&&K(\"W018\",e,\"!\"),n.id===\"!\"&&K(\"W018\",n,\"!\"),this.left=e,this.right=n,this},n}function Tt(e){return e&&(e.type===\"(number)\"&&+e.value===0||e.type===\"(string)\"&&e.value===\"\"||e.type===\"null\"&&!f.option.eqnull||e.type===\"true\"||e.type===\"false\"||e.type===\"undefined\")}function Nt(e,t){if(f.option.notypeof)return!1;if(!e||!t)return!1;var n=[\"undefined\",\"object\",\"boolean\",\"number\",\"string\",\"function\",\"xml\",\"object\",\"unknown\"];return t.type===\"(identifier)\"&&t.value===\"typeof\"&&e.type===\"(string)\"?!r.contains(n,e.value):!1}function Ct(e){function n(e){if(typeof e!=\"object\")return;return e.right===\"prototype\"?e:n(e.left)}function r(e){while(!e.identifier&&typeof e.left==\"object\")e=e.left;if(e.identifier&&t.indexOf(e.value)>=0)return e.value}var t=[\"Array\",\"ArrayBuffer\",\"Boolean\",\"Collator\",\"DataView\",\"Date\",\"DateTimeFormat\",\"Error\",\"EvalError\",\"Float32Array\",\"Float64Array\",\"Function\",\"Infinity\",\"Intl\",\"Int16Array\",\"Int32Array\",\"Int8Array\",\"Iterator\",\"Number\",\"NumberFormat\",\"Object\",\"RangeError\",\"ReferenceError\",\"RegExp\",\"StopIteration\",\"String\",\"SyntaxError\",\"TypeError\",\"Uint16Array\",\"Uint32Array\",\"Uint8Array\",\"Uint8ClampedArray\",\"URIError\"],i=n(e);if(i)return r(i)}function kt(e,t,n){var r=Et(e,typeof t==\"function\"?t:function(e,t){t.left=e;if(e){if(f.option.freeze){var n=Ct(e);n&&K(\"W121\",e,n)}M[e.value]===!1&&D[e.value][\"(global)\"]===!0?K(\"W020\",e):e[\"function\"]&&K(\"W021\",e,e.value),w[e.value]===\"const\"&&G(\"E013\",e,e.value);if(e.id===\".\")return e.left?e.left.value===\"arguments\"&&!f.directive[\"use strict\"]&&K(\"E031\",t):K(\"E031\",t),t.right=ot(10),t;if(e.id===\"[\")return f.tokens.curr.left.first?f.tokens.curr.left.first.forEach(function(e){e&&w[e.value]===\"const\"&&G(\"E013\",e,e.value)}):e.left?e.left.value===\"arguments\"&&!f.directive[\"use strict\"]&&K(\"E031\",t):K(\"E031\",t),t.right=ot(10),t;if(e.identifier&&!U(e))return w[e.value]===\"exception\"&&K(\"W022\",e),t.right=ot(10),t;e===f.syntax[\"function\"]&&K(\"W023\",f.tokens.curr)}G(\"E031\",t)},n);return r.exps=!0,r.assign=!0,r}function Lt(e,t,n){var r=ct(e,n);return vt(r),r.led=typeof t==\"function\"?t:function(e){return f.option.bitwise&&K(\"W016\",this,this.id),this.left=e,this.right=ot(n),this},r}function At(e){return kt(e,function(e,t){f.option.bitwise&&K(\"W016\",t,t.id);if(e)return e.id===\".\"||e.id===\"[\"||e.identifier&&!U(e)?(ot(10),t):(e===f.syntax[\"function\"]&&K(\"W023\",f.tokens.curr),t);G(\"E031\",t)},20)}function Ot(e){var t=ct(e,150);return t.led=function(e){return f.option.plusplus?K(\"W016\",this,this.id):(!e.identifier||U(e))&&e.id!==\".\"&&e.id!==\"[\"&&K(\"W017\",this),this.left=e,this},t}function Mt(e,t){if(!f.tokens.next.identifier)return;rt();var n=f.tokens.curr,r=f.tokens.curr.value;return U(n)?t&&f.option.inES5()?r:e&&r===\"undefined\"?r:(K(\"W024\",f.tokens.curr,f.tokens.curr.id),r):r}function _t(e,t){var n=Mt(e,t);if(n)return n;f.tokens.curr.id===\"function\"&&f.tokens.next.id===\"(\"?K(\"W025\"):G(\"E030\",f.tokens.next,f.tokens.next.value)}function Dt(e){var t=0,n;if(f.tokens.next.id!==\";\"||O)return;for(;;){do n=nt(t),t+=1;while(n.id!=\"(end)\"&&n.id===\"(comment)\");if(n.reach)return;if(n.id!==\"(endline)\"){if(n.id===\"function\"){f.option.latedef===!0&&K(\"W026\",n);break}K(\"W027\",n,n.value,e);break}}}function Pt(){f.tokens.next.id!==\";\"?f.option.asi||(!f.option.lastsemic||f.tokens.next.id!==\"}\"||f.tokens.next.line!==f.tokens.curr.line)&&Q(\"W033\",f.tokens.curr.line,f.tokens.curr.character):rt(\";\")}function Ht(){var e,t=N,n,i=D,s=f.tokens.next;if(s.id===\";\"){rt(\";\");return}var o=U(s);o&&s.meta&&s.meta.isFutureReservedWord&&nt().id===\":\"&&(K(\"W024\",s,s.id),o=!1);if(s.value===\"module\"&&s.type===\"(identifier)\"&&nt().type===\"(identifier)\"){f.option.inESNext()||K(\"W119\",f.tokens.curr,\"module\"),rt(\"module\");var u=_t();et(u,{type:\"unused\",token:f.tokens.curr}),rt(\"from\"),rt(\"(string)\"),Pt();return}if(r.has([\"[\",\"{\"],s.value)&&on().isDestAssign){f.option.inESNext()||K(\"W104\",f.tokens.curr,\"destructuring expression\"),e=Yt(),e.forEach(function(e){$(w,\"W117\",e.token,e.id)}),rt(\"=\"),Zt(e,ot(10,!0)),rt(\";\");return}s.identifier&&!o&&nt().id===\":\"&&(rt(),rt(\":\"),D=Object.create(i),et(s.value,{type:\"label\"}),!f.tokens.next.labelled&&f.tokens.next.value!==\"{\"&&K(\"W028\",f.tokens.next,s.value,f.tokens.next.value),f.tokens.next.label=s.value,s=f.tokens.next);if(s.id===\"{\"){var a=w[\"(verb)\"]===\"case\"&&f.tokens.curr.value===\":\";Ft(!0,!0,!1,!1,a);return}return n=ot(0,!0),n&&(!n.identifier||n.value!==\"function\")&&n.type!==\"(punctuator)\"&&!f.directive[\"use strict\"]&&f.option.globalstrict&&f.option.strict&&K(\"E007\"),s.block||(!f.option.expr&&(!n||!n.exps)?K(\"W030\",f.tokens.curr):f.option.nonew&&n&&n.left&&n.id===\"(\"&&n.left.id===\"new\"&&K(\"W031\",s),Pt()),N=t,D=i,n}function Bt(e){var t=[],n;while(!f.tokens.next.reach&&f.tokens.next.id!==\"(end)\")f.tokens.next.id===\";\"?(n=nt(),(!n||n.id!==\"(\"&&n.id!==\"[\")&&K(\"W032\"),rt(\";\")):t.push(Ht(e===f.tokens.next.line));return t}function jt(){var e,t,n;for(;;){if(f.tokens.next.id===\"(string)\"){t=nt(0);if(t.id===\"(endline)\"){e=1;do n=nt(e),e+=1;while(n.id===\"(endline)\");if(n.id!==\";\"){if(n.id!==\"(string)\"&&n.id!==\"(number)\"&&n.id!==\"(regexp)\"&&n.identifier!==!0&&n.id!==\"}\")break;K(\"W033\",f.tokens.next)}else t=n}else if(t.id===\"}\")K(\"W033\",t);else if(t.id!==\";\")break;rt(),f.directive[f.tokens.curr.value]&&K(\"W034\",f.tokens.curr,f.tokens.curr.value),f.tokens.curr.value===\"use strict\"&&(f.option[\"(explicitNewcap)\"]||(f.option.newcap=!0),f.option.undef=!0),f.directive[f.tokens.curr.value]=!0,t.id===\";\"&&rt(\";\");continue}break}}function Ft(e,t,n,i,s){var o,u=T,a=N,l,c=D,h,p,d;T=e;if(!e||!f.option.funcscope)D=Object.create(D);h=f.tokens.next;var v=w[\"(metrics)\"];v.nestedBlockDepth+=1,v.verifyMaxNestedBlockDepthPerFunction();if(f.tokens.next.id===\"{\"){rt(\"{\"),w[\"(blockscope)\"].stack(),p=f.tokens.curr.line;if(f.tokens.next.id!==\"}\"){N+=f.option.indent;while(!e&&f.tokens.next.from>N)N+=f.option.indent;if(n){l={};for(d in f.directive)r.has(f.directive,d)&&(l[d]=f.directive[d]);jt(),f.option.strict&&w[\"(context)\"][\"(global)\"]&&!l[\"use strict\"]&&!f.directive[\"use strict\"]&&K(\"E007\")}o=Bt(p),v.statementCount+=o.length,n&&(f.directive=l),N-=f.option.indent}rt(\"}\",h),w[\"(blockscope)\"].unstack(),N=a}else if(!e)if(n){l={},t&&!i&&!f.option.inMoz(!0)&&G(\"W118\",f.tokens.curr,\"function closure expressions\");if(!t)for(d in f.directive)r.has(f.directive,d)&&(l[d]=f.directive[d]);ot(10),f.option.strict&&w[\"(context)\"][\"(global)\"]&&!l[\"use strict\"]&&!f.directive[\"use strict\"]&&K(\"E007\")}else G(\"E021\",f.tokens.next,\"{\",f.tokens.next.value);else w[\"(nolet)\"]=!0,(!t||f.option.curly)&&K(\"W116\",f.tokens.next,\"{\",f.tokens.next.value),O=!0,N+=f.option.indent,o=[Ht()],N-=f.option.indent,O=!1,delete w[\"(nolet)\"];switch(w[\"(verb)\"]){case\"break\":case\"continue\":case\"return\":case\"throw\":if(s)break;default:w[\"(verb)\"]=null}if(!e||!f.option.funcscope)D=c;return T=u,e&&f.option.noempty&&(!o||o.length===0)&&K(\"W035\"),v.nestedBlockDepth-=1,o}function It(e){A&&typeof A[e]!=\"boolean\"&&K(\"W036\",f.tokens.curr,e),typeof L[e]==\"number\"?L[e]+=1:L[e]=1}function qt(e){var t=e.value,n=Object.getOwnPropertyDescriptor(x,t);n?n.value.push(e.line):x[t]=[e.line]}function Ut(){var e={};e.exps=!0,w[\"(comparray)\"].stack();var t=!1;return f.tokens.next.value!==\"for\"&&(t=!0,f.option.inMoz(!0)||K(\"W116\",f.tokens.next,\"for\",f.tokens.next.value),w[\"(comparray)\"].setState(\"use\"),e.right=ot(10)),rt(\"for\"),f.tokens.next.value===\"each\"&&(rt(\"each\"),f.option.inMoz(!0)||K(\"W118\",f.tokens.curr,\"for each\")),rt(\"(\"),w[\"(comparray)\"].setState(\"define\"),e.left=ot(130),r.contains([\"in\",\"of\"],f.tokens.next.value)?rt():G(\"E045\",f.tokens.curr),w[\"(comparray)\"].setState(\"generate\"),ot(10),rt(\")\"),f.tokens.next.value===\"if\"&&(rt(\"if\"),rt(\"(\"),w[\"(comparray)\"].setState(\"filter\"),e.filter=ot(10),rt(\")\")),t||(w[\"(comparray)\"].setState(\"use\"),e.right=ot(10)),rt(\"]\"),w[\"(comparray)\"].unstack(),e}function zt(){var e=Mt(!1,!0);return e||(f.tokens.next.id===\"(string)\"?(e=f.tokens.next.value,rt()):f.tokens.next.id===\"(number)\"&&(e=f.tokens.next.value.toString(),rt())),e===\"hasOwnProperty\"&&K(\"W001\"),e}function Wt(e){var t,n,i=[],s,o=[],u,a=!1;if(e){if(Array.isArray(e)){for(var l in e){t=e[l];if(t.value===\"...\"){f.option.inESNext()||K(\"W104\",t,\"spread/rest operator\");continue}t.value!==\",\"&&(i.push(t.value),et(t.value,{type:\"unused\",token:t}))}return i}if(e.identifier===!0)return et(e.value,{type:\"unused\",token:e}),[e]}n=f.tokens.next,rt(\"(\");if(f.tokens.next.id===\")\"){rt(\")\");return}for(;;){if(r.contains([\"{\",\"[\"],f.tokens.next.id)){o=Yt();for(u in o)u=o[u],u.id&&(i.push(u.id),et(u.id,{type:\"unused\",token:u.token}))}else f.tokens.next.value===\"...\"?(f.option.inESNext()||K(\"W104\",f.tokens.next,\"spread/rest operator\"),rt(\"...\"),s=_t(!0),i.push(s),et(s,{type:\"unused\",token:f.tokens.curr})):(s=_t(!0),i.push(s),et(s,{type:\"unused\",token:f.tokens.curr}));a&&f.tokens.next.id!==\"=\"&&G(\"E051\",f.tokens.current),f.tokens.next.id===\"=\"&&(f.option.inESNext()||K(\"W119\",f.tokens.next,\"default parameters\"),rt(\"=\"),a=!0,ot(10));if(f.tokens.next.id!==\",\")return rt(\")\",n),i;lt()}}function Xt(e,t,n){e[\"(properties)\"][t]||(e[\"(properties)\"][t]={unused:!1}),r.extend(e[\"(properties)\"][t],n)}function Vt(e,t,n){return e[\"(properties)\"][t]?e[\"(properties)\"][t][n]||null:null}function $t(e,t,n,i){var s={\"(name)\":e,\"(breakage)\":0,\"(loopage)\":0,\"(scope)\":n,\"(tokens)\":{},\"(properties)\":{},\"(catch)\":!1,\"(global)\":!1,\"(line)\":null,\"(character)\":null,\"(metrics)\":null,\"(statement)\":null,\"(context)\":null,\"(blockscope)\":null,\"(comparray)\":null,\"(generator)\":null,\"(params)\":null};return t&&r.extend(s,{\"(line)\":t.line,\"(character)\":t.character,\"(metrics)\":Kt(t)}),r.extend(s,i),s[\"(context)\"]&&(s[\"(blockscope)\"]=s[\"(context)\"][\"(blockscope)\"],s[\"(comparray)\"]=s[\"(context)\"][\"(comparray)\"]),s}function Jt(t,n,i,s){var o,u=f.option,a=f.ignored,l=D;return f.option=Object.create(f.option),f.ignored=Object.create(f.ignored),D=Object.create(D),w=$t(t||'\"'+e+'\"',f.tokens.next,D,{\"(statement)\":n,\"(context)\":w,\"(generator)\":i?!0:null}),o=w,f.tokens.curr.funct=w,E.push(w),t&&et(t,{type:\"function\"}),w[\"(params)\"]=Wt(s),w[\"(metrics)\"].verifyMaxParametersPerFunction(w[\"(params)\"]),c.undefs=r.filter(c.undefs,function(e){return!r.contains(r.union(s),e[2])}),Ft(!1,!0,!0,s?!0:!1),!f.option.noyield&&i&&w[\"(generator)\"]!==\"yielded\"&&K(\"W124\",f.tokens.curr),w[\"(metrics)\"].verifyMaxStatementsPerFunction(),w[\"(metrics)\"].verifyMaxComplexityPerFunction(),w[\"(unusedOption)\"]=f.option.unused,D=l,f.option=u,f.ignored=a,w[\"(last)\"]=f.tokens.curr.line,w[\"(lastcharacter)\"]=f.tokens.curr.character,r.map(Object.keys(w),function(e){if(e[0]===\"(\")return;w[\"(blockscope)\"].unshadow(e)}),w=w[\"(context)\"],o}function Kt(e){return{statementCount:0,nestedBlockDepth:-1,ComplexityCount:1,verifyMaxStatementsPerFunction:function(){f.option.maxstatements&&this.statementCount>f.option.maxstatements&&K(\"W071\",e,this.statementCount)},verifyMaxParametersPerFunction:function(t){t=t||[],f.option.maxparams&&t.length>f.option.maxparams&&K(\"W072\",e,t.length)},verifyMaxNestedBlockDepthPerFunction:function(){f.option.maxdepth&&this.nestedBlockDepth>0&&this.nestedBlockDepth===f.option.maxdepth+1&&K(\"W073\",null,this.nestedBlockDepth)},verifyMaxComplexityPerFunction:function(){var t=f.option.maxcomplexity,n=this.ComplexityCount;t&&n>t&&K(\"W074\",e,n)}}}function Qt(){w[\"(metrics)\"].ComplexityCount+=1}function Gt(e){var t,n;e&&(t=e.id,n=e.paren,t===\",\"&&(e=e.exprs[e.exprs.length-1])&&(t=e.id,n=n||e.paren));switch(t){case\"=\":case\"+=\":case\"-=\":case\"*=\":case\"%=\":case\"&=\":case\"|=\":case\"^=\":case\"/=\":!n&&!f.option.boss&&K(\"W084\")}}function Yt(){var e,t,n=[];f.option.inESNext()||K(\"W104\",f.tokens.curr,\"destructuring expression\");var i=function(){var e;if(r.contains([\"[\",\"{\"],f.tokens.next.value)){t=Yt();for(var s in t)s=t[s],n.push({id:s.id,token:s.token})}else f.tokens.next.value===\",\"?n.push({id:null,token:f.tokens.curr}):f.tokens.next.value===\"(\"?(rt(\"(\"),i(),rt(\")\")):(e=_t(),e&&n.push({id:e,token:f.tokens.curr}))};if(f.tokens.next.value===\"[\"){rt(\"[\"),i();while(f.tokens.next.value!==\"]\")rt(\",\"),i();rt(\"]\")}else if(f.tokens.next.value===\"{\"){rt(\"{\"),e=_t(),f.tokens.next.value===\":\"?(rt(\":\"),i()):n.push({id:e,token:f.tokens.curr});while(f.tokens.next.value!==\"}\")rt(\",\"),e=_t(),f.tokens.next.value===\":\"?(rt(\":\"),i()):n.push({id:e,token:f.tokens.curr});rt(\"}\")}return n}function Zt(e,t){var n=t.first;if(!n)return;r.zip(e,Array.isArray(n)?n:[n]).forEach(function(e){var t=e[0],n=e[1];t&&n?t.first=n:t&&t.first&&!n&&K(\"W080\",t.first,t.first.value)})}function rn(e){return f.option.inESNext()||K(\"W104\",f.tokens.curr,\"class\"),e?(this.name=_t(),et(this.name,{type:\"unused\",token:f.tokens.curr})):f.tokens.next.identifier&&f.tokens.next.value!==\"extends\"&&(this.name=_t()),sn(this),this}function sn(e){var t=f.directive[\"use strict\"];f.tokens.next.value===\"extends\"&&(rt(\"extends\"),e.heritage=ot(10)),f.directive[\"use strict\"]=!0,rt(\"{\"),e.body=f.syntax[\"{\"].nud(!0),f.directive[\"use strict\"]=t}function un(){var e=on();e.notJson?(!f.option.inESNext()&&e.isDestAssign&&K(\"W104\",f.tokens.curr,\"destructuring assignment\"),Bt()):(f.option.laxbreak=!0,f.jsonMode=!0,fn())}function fn(){function e(){var e={},t=f.tokens.next;rt(\"{\");if(f.tokens.next.id!==\"}\")for(;;){if(f.tokens.next.id===\"(end)\")G(\"E026\",f.tokens.next,t.line);else{if(f.tokens.next.id===\"}\"){K(\"W094\",f.tokens.curr);break}f.tokens.next.id===\",\"?G(\"E028\",f.tokens.next):f.tokens.next.id!==\"(string)\"&&K(\"W095\",f.tokens.next,f.tokens.next.value)}e[f.tokens.next.value]===!0?K(\"W075\",f.tokens.next,f.tokens.next.value):f.tokens.next.value===\"__proto__\"&&!f.option.proto||f.tokens.next.value===\"__iterator__\"&&!f.option.iterator?K(\"W096\",f.tokens.next,f.tokens.next.value):e[f.tokens.next.value]=!0,rt(),rt(\":\"),fn();if(f.tokens.next.id!==\",\")break;rt(\",\")}rt(\"}\")}function t(){var e=f.tokens.next;rt(\"[\");if(f.tokens.next.id!==\"]\")for(;;){if(f.tokens.next.id===\"(end)\")G(\"E027\",f.tokens.next,e.line);else{if(f.tokens.next.id===\"]\"){K(\"W094\",f.tokens.curr);break}f.tokens.next.id===\",\"&&G(\"E028\",f.tokens.next)}fn();if(f.tokens.next.id!==\",\")break;rt(\",\")}rt(\"]\")}switch(f.tokens.next.id){case\"{\":e();break;case\"[\":t();break;case\"true\":case\"false\":case\"null\":case\"(number)\":case\"(string)\":rt();break;case\"-\":rt(\"-\"),rt(\"(number)\");break;default:G(\"E003\",f.tokens.next)}}var e,t,n={\"<\":!0,\"<=\":!0,\"==\":!0,\"===\":!0,\"!==\":!0,\"!=\":!0,\">\":!0,\">=\":!0,\"+\":!0,\"-\":!0,\"*\":!0,\"/\":!0,\"%\":!0},h={asi:!0,bitwise:!0,boss:!0,browser:!0,camelcase:!0,couch:!0,curly:!0,debug:!0,devel:!0,dojo:!0,eqeqeq:!0,eqnull:!0,notypeof:!0,es3:!0,es5:!0,esnext:!0,moz:!0,evil:!0,expr:!0,forin:!0,funcscope:!0,globalstrict:!0,immed:!0,iterator:!0,jasmine:!0,jquery:!0,lastsemic:!0,laxbreak:!0,laxcomma:!0,loopfunc:!0,mootools:!0,multistr:!0,freeze:!0,newcap:!0,noarg:!0,node:!0,noempty:!0,nonbsp:!0,nonew:!0,nonstandard:!0,phantom:!0,plusplus:!0,proto:!0,prototypejs:!0,qunit:!0,rhino:!0,shelljs:!0,typed:!0,undef:!0,scripturl:!0,strict:!0,sub:!0,supernew:!0,validthis:!0,withstmt:!0,worker:!0,wsh:!0,yui:!0,mocha:!0,noyield:!0,onecase:!0,regexp:!0,regexdash:!0},p={maxlen:!1,indent:!1,maxerr:!1,predef:!1,globals:!1,quotmark:!1,scope:!1,maxstatements:!1,maxdepth:!1,maxparams:!1,maxcomplexity:!1,shadow:!1,unused:!0,latedef:!1,ignore:!1},d={bitwise:!0,forin:!0,newcap:!0,plusplus:!0,regexp:!0,undef:!0,eqeqeq:!0,strict:!0},v={eqeq:\"eqeqeq\",windows:\"wsh\",sloppy:\"strict\"},m={nomen:!0,onevar:!0,passfail:!0,white:!0,gcl:!0,smarttabs:!0,trailing:!0},g,y,b=[\"closure\",\"exception\",\"global\",\"label\",\"outer\",\"unused\",\"var\"],w,E,S,x,T,N,C,k,L,A,O,M,D,P,H,B,j=[],F=new i.EventEmitter;gt(\"(number)\",function(){return this}),gt(\"(string)\",function(){return this}),gt(\"(template)\",function(){return this}),f.syntax[\"(identifier)\"]={type:\"(identifier)\",lbp:0,identifier:!0,nud:function(){var t=this.value,n=D[t],r,i;typeof n==\"function\"?n=undefined:!w[\"(blockscope)\"].current.has(t)&&typeof n==\"boolean\"&&(r=w,w=E[0],et(t,{type:\"var\"}),n=w,w=r),i=w[\"(blockscope)\"].getlabel(t);if(w===n||i)switch(i?i[t][\"(type)\"]:w[t]){case\"unused\":i?i[t][\"(type)\"]=\"var\":w[t]=\"var\";break;case\"unction\":i?i[t][\"(type)\"]=\"function\":w[t]=\"function\",this[\"function\"]=!0;break;case\"const\":Xt(w,t,{unused:!1});break;case\"function\":this[\"function\"]=!0;break;case\"label\":K(\"W037\",f.tokens.curr,t)}else if(w[\"(global)\"])typeof M[t]!=\"boolean\"&&(e!==\"typeof\"&&e!==\"delete\"||f.tokens.next&&(f.tokens.next.value===\".\"||f.tokens.next.value===\"[\"))&&(w[\"(comparray)\"].check(t)||$(w,\"W117\",f.tokens.curr,t)),qt(f.tokens.curr);else switch(w[t]){case\"closure\":case\"function\":case\"var\":case\"unused\":K(\"W038\",f.tokens.curr,t);break;case\"label\":K(\"W037\",f.tokens.curr,t);break;case\"outer\":case\"global\":break;default:if(n===!0)w[t]=!0;else if(n===null)K(\"W039\",f.tokens.curr,t),qt(f.tokens.curr);else if(typeof n!=\"object\")(e!==\"typeof\"&&e!==\"delete\"||f.tokens.next&&(f.tokens.next.value===\".\"||f.tokens.next.value===\"[\"))&&$(w,\"W117\",f.tokens.curr,t),w[t]=!0,qt(f.tokens.curr);else switch(n[t]){case\"function\":case\"unction\":this[\"function\"]=!0,n[t]=\"closure\",w[t]=n[\"(global)\"]?\"global\":\"outer\";break;case\"var\":case\"unused\":n[t]=\"closure\",w[t]=n[\"(global)\"]?\"global\":\"outer\";break;case\"const\":Xt(n,t,{unused:!1});break;case\"closure\":w[t]=n[\"(global)\"]?\"global\":\"outer\";break;case\"label\":K(\"W037\",f.tokens.curr,t)}}return this},led:function(){G(\"E033\",f.tokens.next,f.tokens.next.value)}},gt(\"(regexp)\",function(){return this}),ht(\"(endline)\"),ht(\"(begin)\"),ht(\"(end)\").reach=!0,ht(\"(error)\").reach=!0,ht(\"}\").reach=!0,ht(\")\"),ht(\"]\"),ht('\"').reach=!0,ht(\"'\").reach=!0,ht(\";\"),ht(\":\").reach=!0,ht(\"#\"),yt(\"else\"),yt(\"case\").reach=!0,yt(\"catch\"),yt(\"default\").reach=!0,yt(\"finally\"),wt(\"arguments\",function(e){f.directive[\"use strict\"]&&w[\"(global)\"]&&K(\"E008\",e)}),wt(\"eval\"),wt(\"false\"),wt(\"Infinity\"),wt(\"null\"),wt(\"this\",function(e){f.directive[\"use strict\"]&&!f.option.validthis&&(w[\"(statement)\"]&&w[\"(name)\"].charAt(0)>\"Z\"||w[\"(global)\"])&&K(\"W040\",e)}),wt(\"true\"),wt(\"undefined\"),kt(\"=\",\"assign\",20),kt(\"+=\",\"assignadd\",20),kt(\"-=\",\"assignsub\",20),kt(\"*=\",\"assignmult\",20),kt(\"/=\",\"assigndiv\",20).nud=function(){G(\"E014\")},kt(\"%=\",\"assignmod\",20),At(\"&=\",\"assignbitand\",20),At(\"|=\",\"assignbitor\",20),At(\"^=\",\"assignbitxor\",20),At(\"<<=\",\"assignshiftleft\",20),At(\">>=\",\"assignshiftright\",20),At(\">>>=\",\"assignshiftrightunsigned\",20),Et(\",\",function(e,t){var n;t.exprs=[e];if(!lt({peek:!0}))return t;for(;;){if(!(n=ot(10)))break;t.exprs.push(n);if(f.tokens.next.value!==\",\"||!lt())break}return t},10,!0),Et(\"?\",function(e,t){return Qt(),t.left=e,t.right=ot(10),rt(\":\"),t[\"else\"]=ot(10),t},30);var Rt=40;Et(\"||\",function(e,t){return Qt(),t.left=e,t.right=ot(Rt),t},Rt),Et(\"&&\",\"and\",50),Lt(\"|\",\"bitor\",70),Lt(\"^\",\"bitxor\",80),Lt(\"&\",\"bitand\",90),xt(\"==\",function(e,t){var n=f.option.eqnull&&(e.value===\"null\"||t.value===\"null\");switch(!0){case!n&&f.option.eqeqeq:this.from=this.character,K(\"W116\",this,\"===\",\"==\");break;case Tt(e):K(\"W041\",this,\"===\",e.value);break;case Tt(t):K(\"W041\",this,\"===\",t.value);break;case Nt(t,e):K(\"W122\",this,t.value);break;case Nt(e,t):K(\"W122\",this,e.value)}return this}),xt(\"===\",function(e,t){return Nt(t,e)?K(\"W122\",this,t.value):Nt(e,t)&&K(\"W122\",this,e.value),this}),xt(\"!=\",function(e,t){var n=f.option.eqnull&&(e.value===\"null\"||t.value===\"null\");return!n&&f.option.eqeqeq?(this.from=this.character,K(\"W116\",this,\"!==\",\"!=\")):Tt(e)?K(\"W041\",this,\"!==\",e.value):Tt(t)?K(\"W041\",this,\"!==\",t.value):Nt(t,e)?K(\"W122\",this,t.value):Nt(e,t)&&K(\"W122\",this,e.value),this}),xt(\"!==\",function(e,t){return Nt(t,e)?K(\"W122\",this,t.value):Nt(e,t)&&K(\"W122\",this,e.value),this}),xt(\"<\"),xt(\">\"),xt(\"<=\"),xt(\">=\"),Lt(\"<<\",\"shiftleft\",120),Lt(\">>\",\"shiftright\",120),Lt(\">>>\",\"shiftrightunsigned\",120),Et(\"in\",\"in\",120),Et(\"instanceof\",\"instanceof\",120),Et(\"+\",function(e,t){var n=ot(130);return e&&n&&e.id===\"(string)\"&&n.id===\"(string)\"?(e.value+=n.value,e.character=n.character,!f.option.scripturl&&a.javascriptURL.test(e.value)&&K(\"W050\",e),e):(t.left=e,t.right=n,t)},130),mt(\"+\",\"num\"),mt(\"+++\",function(){return K(\"W007\"),this.right=ot(150),this.arity=\"unary\",this}),Et(\"+++\",function(e){return K(\"W007\"),this.left=e,this.right=ot(130),this},130),Et(\"-\",\"sub\",130),mt(\"-\",\"neg\"),mt(\"---\",function(){return K(\"W006\"),this.right=ot(150),this.arity=\"unary\",this}),Et(\"---\",function(e){return K(\"W006\"),this.left=e,this.right=ot(130),this},130),Et(\"*\",\"mult\",140),Et(\"/\",\"div\",140),Et(\"%\",\"mod\",140),Ot(\"++\",\"postinc\"),mt(\"++\",\"preinc\"),f.syntax[\"++\"].exps=!0,Ot(\"--\",\"postdec\"),mt(\"--\",\"predec\"),f.syntax[\"--\"].exps=!0,mt(\"delete\",function(){var e=ot(10);return(!e||e.id!==\".\"&&e.id!==\"[\")&&K(\"W051\"),this.first=e,this}).exps=!0,mt(\"~\",function(){return f.option.bitwise&&K(\"W052\",this,\"~\"),ot(150),this}),mt(\"...\",function(){return f.option.inESNext()||K(\"W104\",this,\"spread/rest operator\"),f.tokens.next.identifier||G(\"E030\",f.tokens.next,f.tokens.next.value),ot(150),this}),mt(\"!\",function(){return this.right=ot(150),this.arity=\"unary\",this.right||V(\"E041\",this.line||0),n[this.right.id]===!0&&K(\"W018\",this,\"!\"),this}),mt(\"typeof\",\"typeof\"),mt(\"new\",function(){var e=ot(155),t;if(e&&e.id!==\"function\")if(e.identifier){e[\"new\"]=!0;switch(e.value){case\"Number\":case\"String\":case\"Boolean\":case\"Math\":case\"JSON\":K(\"W053\",f.tokens.prev,e.value);break;case\"Function\":f.option.evil||K(\"W054\");break;case\"Date\":case\"RegExp\":case\"this\":break;default:e.id!==\"function\"&&(t=e.value.substr(0,1),f.option.newcap&&(t<\"A\"||t>\"Z\")&&!r.has(S,e.value)&&K(\"W055\",f.tokens.curr))}}else e.id!==\".\"&&e.id!==\"[\"&&e.id!==\"(\"&&K(\"W056\",f.tokens.curr);else f.option.supernew||K(\"W057\",this);return f.tokens.next.id!==\"(\"&&!f.option.supernew&&K(\"W058\",f.tokens.curr,f.tokens.curr.value),this.first=e,this}),f.syntax[\"new\"].exps=!0,mt(\"void\").exps=!0,Et(\".\",function(e,t){var n=_t(!1,!0);return typeof n==\"string\"&&It(n),t.left=e,t.right=n,n&&n===\"hasOwnProperty\"&&f.tokens.next.value===\"=\"&&K(\"W001\"),!e||e.value!==\"arguments\"||n!==\"callee\"&&n!==\"caller\"?!f.option.evil&&e&&e.value===\"document\"&&(n===\"write\"||n===\"writeln\")&&K(\"W060\",e):f.option.noarg?K(\"W059\",e,n):f.directive[\"use strict\"]&&G(\"E008\"),!f.option.evil&&(n===\"eval\"||n===\"execScript\")&&K(\"W061\"),t},160,!0),Et(\"(\",function(e,t){f.option.immed&&e&&!e.immed&&e.id===\"function\"&&K(\"W062\");var n=0,r=[];e&&e.type===\"(identifier)\"&&e.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)&&\"Number String Boolean Date Object Error\".indexOf(e.value)===-1&&(e.value===\"Math\"?K(\"W063\",e):f.option.newcap&&K(\"W064\",e));if(f.tokens.next.id!==\")\")for(;;){r[r.length]=ot(10),n+=1;if(f.tokens.next.id!==\",\")break;lt()}return rt(\")\"),typeof e==\"object\"&&(f.option.inES3()&&e.value===\"parseInt\"&&n===1&&K(\"W065\",f.tokens.curr),f.option.evil||(e.value===\"eval\"||e.value===\"Function\"||e.value===\"execScript\"?(K(\"W061\",e),r[0]&&[0].id===\"(string)\"&&Z(e,r[0].value)):!r[0]||r[0].id!==\"(string)\"||e.value!==\"setTimeout\"&&e.value!==\"setInterval\"?r[0]&&r[0].id===\"(string)\"&&e.value===\".\"&&e.left.value===\"window\"&&(e.right===\"setTimeout\"||e.right===\"setInterval\")&&(K(\"W066\",e),Z(e,r[0].value)):(K(\"W066\",e),Z(e,r[0].value))),!e.identifier&&e.id!==\".\"&&e.id!==\"[\"&&e.id!==\"(\"&&e.id!==\"&&\"&&e.id!==\"||\"&&e.id!==\"?\"&&K(\"W067\",e)),t.left=e,t},155,!0).exps=!0,mt(\"(\",function(){var e,t=[],n,i,s=0,o,u=1;do n=nt(s),n.value===\"(\"?u+=1:n.value===\")\"&&(u-=1),s+=1,i=nt(s);while((u!==0||n.value!==\")\")&&i.value!==\"=>\"&&i.value!==\";\"&&i.type!==\"(end)\");f.tokens.next.id===\"function\"&&(f.tokens.next.immed=!0);var a=[];if(f.tokens.next.id!==\")\")for(;;){if(i.value===\"=>\"&&r.contains([\"{\",\"[\"],f.tokens.next.value)){e=f.tokens.next,e.left=Yt(),t.push(e);for(var l in e.left)a.push(e.left[l].token)}else a.push(ot(10));if(f.tokens.next.id!==\",\")break;lt()}rt(\")\",this),f.option.immed&&a[0]&&a[0].id===\"function\"&&f.tokens.next.id!==\"(\"&&(f.tokens.next.id!==\".\"||nt().value!==\"call\"&&nt().value!==\"apply\")&&K(\"W068\",this);if(f.tokens.next.value===\"=>\")return a;if(!a.length)return;return a.length>1?(o=Object.create(f.syntax[\",\"]),o.exprs=a):o=a[0],o&&(o.paren=!0),o}),St(\"=>\"),Et(\"[\",function(e,t){var n=ot(10),r;return n&&n.type===\"(string)\"&&(!f.option.evil&&(n.value===\"eval\"||n.value===\"execScript\")&&K(\"W061\",t),It(n.value),!f.option.sub&&a.identifier.test(n.value)&&(r=f.syntax[n.value],(!r||!U(r))&&K(\"W069\",f.tokens.prev,n.value))),rt(\"]\",t),n&&n.value===\"hasOwnProperty\"&&f.tokens.next.value===\"=\"&&K(\"W001\"),t.left=e,t.right=n,t},160,!0),mt(\"[\",function(){var e=on(!0);if(e.isCompArray)return f.option.inESNext()||K(\"W119\",f.tokens.curr,\"array comprehension\"),Ut();e.isDestAssign&&!f.option.inESNext()&&K(\"W104\",f.tokens.curr,\"destructuring assignment\");var t=f.tokens.curr.line!==f.tokens.next.line;this.first=[],t&&(N+=f.option.indent,f.tokens.next.from===N+f.option.indent&&(N+=f.option.indent));while(f.tokens.next.id!==\"(end)\"){while(f.tokens.next.id===\",\")f.option.inES5()||K(\"W070\"),rt(\",\");if(f.tokens.next.id===\"]\")break;this.first.push(ot(10));if(f.tokens.next.id!==\",\")break;lt({allowTrailing:!0});if(f.tokens.next.id===\"]\"&&!f.option.inES5(!0)){K(\"W070\",f.tokens.curr);break}}return t&&(N-=f.option.indent),rt(\"]\",this),this},160),function(e){e.nud=function(e){function c(e,t){a[e]&&r.has(a,e)?K(\"W075\",f.tokens.next,i):a[e]={},a[e].basic=!0,a[e].basictkn=t}function h(e,t){a[e]&&r.has(a,e)?(a[e].basic||a[e].setter)&&K(\"W075\",f.tokens.next,i):a[e]={},a[e].setter=!0,a[e].setterToken=t}function p(e){a[e]&&r.has(a,e)?(a[e].basic||a[e].getter)&&K(\"W075\",f.tokens.next,i):a[e]={},a[e].getter=!0,a[e].getterToken=f.tokens.curr}var t,n,i,s,o,u,a={},l=\"\";t=f.tokens.curr.line!==f.tokens.next.line,t&&(N+=f.option.indent,f.tokens.next.from===N+f.option.indent&&(N+=f.option.indent));for(;;){if(f.tokens.next.id===\"}\")break;e&&f.tokens.next.value===\"static\"&&(rt(\"static\"),l=\"static \");if(f.tokens.next.value===\"get\"&&nt().id!==\":\")rt(\"get\"),f.option.inES5(!e)||G(\"E034\"),i=zt(),!i&&!f.option.inESNext()&&G(\"E035\"),e&&i===\"constructor\"&&G(\"E049\",f.tokens.next,\"class getter method\",i),i&&p(l+i),o=f.tokens.next,n=Jt(),s=n[\"(params)\"],i&&s&&K(\"W076\",o,s[0],i);else if(f.tokens.next.value===\"set\"&&nt().id!==\":\")rt(\"set\"),f.option.inES5(!e)||G(\"E034\"),i=zt(),!i&&!f.option.inESNext()&&G(\"E035\"),e&&i===\"constructor\"&&G(\"E049\",f.tokens.next,\"class setter method\",i),i&&h(l+i,f.tokens.next),o=f.tokens.next,n=Jt(),s=n[\"(params)\"],i&&(!s||s.length!==1)&&K(\"W077\",o,i);else{u=!1,f.tokens.next.value===\"*\"&&f.tokens.next.type===\"(punctuator)\"&&(f.option.inESNext()||K(\"W104\",f.tokens.next,\"generator functions\"),rt(\"*\"),u=!0),i=zt(),c(l+i,f.tokens.next);if(typeof i!=\"string\")break;f.tokens.next.value===\"(\"?(f.option.inESNext()||K(\"W104\",f.tokens.curr,\"concise methods\"),Jt(i,undefined,u)):e||(rt(\":\"),ot(10))}e&&i===\"prototype\"&&G(\"E049\",f.tokens.next,\"class method\",i),It(i);if(e){l=\"\";continue}if(f.tokens.next.id!==\",\")break;lt({allowTrailing:!0,property:!0}),f.tokens.next.id===\",\"?K(\"W070\",f.tokens.curr):f.tokens.next.id===\"}\"&&!f.option.inES5(!0)&&K(\"W070\",f.tokens.curr)}t&&(N-=f.option.indent),rt(\"}\",this);if(f.option.inES5())for(var d in a)r.has(a,d)&&a[d].setter&&!a[d].getter&&K(\"W078\",a[d].setterToken);return this},e.fud=function(){G(\"E036\",f.tokens.curr)}}(ht(\"{\"));var en=pt(\"const\",function(e){var t,n,i;f.option.inESNext()||K(\"W104\",f.tokens.curr,\"const\"),this.first=[];for(;;){var s=[];r.contains([\"{\",\"[\"],f.tokens.next.value)?(t=Yt(),i=!1):(t=[{id:_t(),token:f.tokens.curr}],i=!0);for(var o in t)t.hasOwnProperty(o)&&(o=t[o],w[o.id]===\"const\"&&K(\"E011\",null,o.id),w[\"(global)\"]&&M[o.id]===!1&&K(\"W079\",o.token,o.id),o.id&&(et(o.id,{token:o.token,type:\"const\",unused:!0}),s.push(o.token)));if(e)break;this.first=this.first.concat(s),f.tokens.next.id!==\"=\"&&K(\"E012\",f.tokens.curr,f.tokens.curr.value),f.tokens.next.id===\"=\"&&(rt(\"=\"),f.tokens.next.id===\"undefined\"&&K(\"W080\",f.tokens.prev,f.tokens.prev.value),nt(0).id===\"=\"&&f.tokens.next.identifier&&K(\"W120\",f.tokens.next,f.tokens.next.value),n=ot(10),i?t[0].first=n:Zt(s,n));if(f.tokens.next.id!==\",\")break;lt()}return this});en.exps=!0;var tn=pt(\"var\",function(e){var t,n,i;this.first=[];for(;;){var s=[];r.contains([\"{\",\"[\"],f.tokens.next.value)?(t=Yt(),n=!1):(t=[{id:_t(),token:f.tokens.curr}],n=!0);for(var o in t)t.hasOwnProperty(o)&&(o=t[o],f.option.inESNext()&&w[o.id]===\"const\"&&K(\"E011\",null,o.id),w[\"(global)\"]&&M[o.id]===!1&&K(\"W079\",o.token,o.id),o.id&&(et(o.id,{type:\"unused\",token:o.token}),s.push(o.token)));if(e)break;this.first=this.first.concat(s),f.tokens.next.id===\"=\"&&(rt(\"=\"),f.tokens.next.id===\"undefined\"&&K(\"W080\",f.tokens.prev,f.tokens.prev.value),nt(0).id===\"=\"&&f.tokens.next.identifier&&K(\"W120\",f.tokens.next,f.tokens.next.value),i=ot(10),n?t[0].first=i:Zt(s,i));if(f.tokens.next.id!==\",\")break;lt()}return this});tn.exps=!0;var nn=pt(\"let\",function(e){var t,n,i,s;f.option.inESNext()||K(\"W104\",f.tokens.curr,\"let\"),f.tokens.next.value===\"(\"?(f.option.inMoz(!0)||K(\"W118\",f.tokens.next,\"let block\"),rt(\"(\"),w[\"(blockscope)\"].stack(),s=!0):w[\"(nolet)\"]&&G(\"E048\",f.tokens.curr),this.first=[];for(;;){var o=[];r.contains([\"{\",\"[\"],f.tokens.next.value)?(t=Yt(),n=!1):(t=[{id:_t(),token:f.tokens.curr.value}],n=!0);for(var u in t)t.hasOwnProperty(u)&&(u=t[u],f.option.inESNext()&&w[u.id]===\"const\"&&K(\"E011\",null,u.id),w[\"(global)\"]&&M[u.id]===!1&&K(\"W079\",u.token,u.id),u.id&&!w[\"(nolet)\"]&&(et(u.id,{type:\"unused\",token:u.token,islet:!0}),o.push(u.token)));if(e)break;this.first=this.first.concat(o),f.tokens.next.id===\"=\"&&(rt(\"=\"),f.tokens.next.id===\"undefined\"&&K(\"W080\",f.tokens.prev,f.tokens.prev.value),nt(0).id===\"=\"&&f.tokens.next.identifier&&K(\"W120\",f.tokens.next,f.tokens.next.value),i=ot(10),n?t[0].first=i:Zt(o,i));if(f.tokens.next.id!==\",\")break;lt()}return s&&(rt(\")\"),Ft(!0,!0),this.block=!0,w[\"(blockscope)\"].unstack()),this});nn.exps=!0,dt(\"class\",function(){return rn.call(this,!0)}),dt(\"function\",function(){var e=!1;f.tokens.next.value===\"*\"&&(rt(\"*\"),f.option.inESNext(!0)?e=!0:K(\"W119\",f.tokens.curr,\"function*\")),T&&K(\"W082\",f.tokens.curr);var t=_t();return w[t]===\"const\"&&K(\"E011\",null,t),et(t,{type:\"unction\",token:f.tokens.curr}),Jt(t,{statement:!0},e),f.tokens.next.id===\"(\"&&f.tokens.next.line===f.tokens.curr.line&&G(\"E039\"),this}),mt(\"function\",function(){var e=!1;f.tokens.next.value===\"*\"&&(f.option.inESNext()||K(\"W119\",f.tokens.curr,\"function*\"),rt(\"*\"),e=!0);var t=Mt();return Jt(t,undefined,e),!f.option.loopfunc&&w[\"(loopage)\"]&&K(\"W083\"),this}),dt(\"if\",function(){var e=f.tokens.next;return Qt(),f.condition=!0,rt(\"(\"),Gt(ot(0)),rt(\")\",e),f.condition=!1,Ft(!0,!0),f.tokens.next.id===\"else\"&&(rt(\"else\"),f.tokens.next.id===\"if\"||f.tokens.next.id===\"switch\"?Ht(!0):Ft(!0,!0)),this}),dt(\"try\",function(){function t(){var e=D,t;rt(\"catch\"),rt(\"(\"),D=Object.create(e),t=f.tokens.next.value,f.tokens.next.type!==\"(identifier)\"&&(t=null,K(\"E030\",f.tokens.next,t)),rt(),w=$t(\"(catch)\",f.tokens.next,D,{\"(context)\":w,\"(breakage)\":w[\"(breakage)\"],\"(loopage)\":w[\"(loopage)\"],\"(statement)\":!1,\"(catch)\":!0}),t&&et(t,{type:\"exception\"}),f.tokens.next.value===\"if\"&&(f.option.inMoz(!0)||K(\"W118\",f.tokens.curr,\"catch filter\"),rt(\"if\"),ot(0)),rt(\")\"),f.tokens.curr.funct=w,E.push(w),Ft(!1),D=e,w[\"(last)\"]=f.tokens.curr.line,w[\"(lastcharacter)\"]=f.tokens.curr.character,w=w[\"(context)\"]}var e;Ft(!0);while(f.tokens.next.id===\"catch\")Qt(),e&&!f.option.inMoz(!0)&&K(\"W118\",f.tokens.next,\"multiple catch blocks\"),t(),e=!0;if(f.tokens.next.id===\"finally\"){rt(\"finally\"),Ft(!0);return}return e||G(\"E021\",f.tokens.next,\"catch\",f.tokens.next.value),this}),dt(\"while\",function(){var e=f.tokens.next;return w[\"(breakage)\"]+=1,w[\"(loopage)\"]+=1,Qt(),rt(\"(\"),Gt(ot(0)),rt(\")\",e),Ft(!0,!0),w[\"(breakage)\"]-=1,w[\"(loopage)\"]-=1,this}).labelled=!0,dt(\"with\",function(){var e=f.tokens.next;return f.directive[\"use strict\"]?G(\"E010\",f.tokens.curr):f.option.withstmt||K(\"W085\",f.tokens.curr),rt(\"(\"),ot(0),rt(\")\",e),Ft(!0,!0),this}),dt(\"switch\",function(){var e=f.tokens.next,t=!1,n=!1;w[\"(breakage)\"]+=1,rt(\"(\"),Gt(ot(0)),rt(\")\",e),e=f.tokens.next,rt(\"{\"),f.tokens.next.from===N&&(n=!0),n||(N+=f.option.indent),this.cases=[];for(;;)switch(f.tokens.next.id){case\"case\":switch(w[\"(verb)\"]){case\"yield\":case\"break\":case\"case\":case\"continue\":case\"return\":case\"switch\":case\"throw\":break;default:a.fallsThrough.test(f.lines[f.tokens.next.line-2])||K(\"W086\",f.tokens.curr,\"case\")}rt(\"case\"),this.cases.push(ot(0)),Qt(),t=!0,rt(\":\"),w[\"(verb)\"]=\"case\";break;case\"default\":switch(w[\"(verb)\"]){case\"yield\":case\"break\":case\"continue\":case\"return\":case\"throw\":break;default:this.cases.length&&(a.fallsThrough.test(f.lines[f.tokens.next.line-2])||K(\"W086\",f.tokens.curr,\"default\"))}rt(\"default\"),t=!0,rt(\":\");break;case\"}\":n||(N-=f.option.indent),rt(\"}\",e),w[\"(breakage)\"]-=1,w[\"(verb)\"]=undefined;return;case\"(end)\":G(\"E023\",f.tokens.next,\"}\");return;default:N+=f.option.indent;if(t)switch(f.tokens.curr.id){case\",\":G(\"E040\");return;case\":\":t=!1,Bt();break;default:G(\"E025\",f.tokens.curr);return}else{if(f.tokens.curr.id!==\":\"){G(\"E021\",f.tokens.next,\"case\",f.tokens.next.value);return}rt(\":\"),G(\"E024\",f.tokens.curr,\":\"),Bt()}N-=f.option.indent}}).labelled=!0,pt(\"debugger\",function(){return f.option.debug||K(\"W087\",this),this}).exps=!0,function(){var e=pt(\"do\",function(){w[\"(breakage)\"]+=1,w[\"(loopage)\"]+=1,Qt(),this.first=Ft(!0,!0),rt(\"while\");var e=f.tokens.next;return rt(\"(\"),Gt(ot(0)),rt(\")\",e),w[\"(breakage)\"]-=1,w[\"(loopage)\"]-=1,this});e.labelled=!0,e.exps=!0}(),dt(\"for\",function(){var e,t=f.tokens.next,n=!1,i=null;t.value===\"each\"&&(i=t,rt(\"each\"),f.option.inMoz(!0)||K(\"W118\",f.tokens.curr,\"for each\")),w[\"(breakage)\"]+=1,w[\"(loopage)\"]+=1,Qt(),rt(\"(\");var s,o=0,u=[\"in\",\"of\"];do s=nt(o),++o;while(!r.contains(u,s.value)&&s.value!==\";\"&&s.type!==\"(end)\");if(r.contains(u,s.value)){!f.option.inESNext()&&s.value===\"of\"&&G(\"W104\",s,\"for of\");if(f.tokens.next.id===\"var\")rt(\"var\"),f.syntax[\"var\"].fud.call(f.syntax[\"var\"].fud,!0);else if(f.tokens.next.id===\"let\")rt(\"let\"),n=!0,w[\"(blockscope)\"].stack(),f.syntax.let.fud.call(f.syntax.let.fud,!0);else if(!f.tokens.next.identifier)G(\"E030\",f.tokens.next,f.tokens.next.type),rt();else{switch(w[f.tokens.next.value]){case\"unused\":w[f.tokens.next.value]=\"var\";break;case\"var\":break;default:w[\"(blockscope)\"].getlabel(f.tokens.next.value)||K(\"W088\",f.tokens.next,f.tokens.next.value)}rt()}rt(s.value),ot(20),rt(\")\",t),e=Ft(!0,!0),f.option.forin&&e&&(e.length>1||typeof e[0]!=\"object\"||e[0].value!==\"if\")&&K(\"W089\",this),w[\"(breakage)\"]-=1,w[\"(loopage)\"]-=1}else{i&&G(\"E045\",i);if(f.tokens.next.id!==\";\")if(f.tokens.next.id===\"var\")rt(\"var\"),f.syntax[\"var\"].fud.call(f.syntax[\"var\"].fud);else if(f.tokens.next.id===\"let\")rt(\"let\"),n=!0,w[\"(blockscope)\"].stack(),f.syntax.let.fud.call(f.syntax.let.fud);else for(;;){ot(0,\"for\");if(f.tokens.next.id!==\",\")break;lt()}at(f.tokens.curr),rt(\";\"),f.tokens.next.id!==\";\"&&Gt(ot(0)),at(f.tokens.curr),rt(\";\"),f.tokens.next.id===\";\"&&G(\"E021\",f.tokens.next,\")\",\";\");if(f.tokens.next.id!==\")\")for(;;){ot(0,\"for\");if(f.tokens.next.id!==\",\")break;lt()}rt(\")\",t),Ft(!0,!0),w[\"(breakage)\"]-=1,w[\"(loopage)\"]-=1}return n&&w[\"(blockscope)\"].unstack(),this}).labelled=!0,pt(\"break\",function(){var e=f.tokens.next.value;return w[\"(breakage)\"]===0&&K(\"W052\",f.tokens.next,this.value),f.option.asi||at(this),f.tokens.next.id!==\";\"&&!f.tokens.next.reach&&f.tokens.curr.line===f.tokens.next.line&&(w[e]!==\"label\"?K(\"W090\",f.tokens.next,e):D[e]!==w&&K(\"W091\",f.tokens.next,e),this.first=f.tokens.next,rt()),Dt(\"break\"),this}).exps=!0,pt(\"continue\",function(){var e=f.tokens.next.value;return w[\"(breakage)\"]===0&&K(\"W052\",f.tokens.next,this.value),f.option.asi||at(this),f.tokens.next.id!==\";\"&&!f.tokens.next.reach?f.tokens.curr.line===f.tokens.next.line&&(w[e]!==\"label\"?K(\"W090\",f.tokens.next,e):D[e]!==w&&K(\"W091\",f.tokens.next,e),this.first=f.tokens.next,rt()):w[\"(loopage)\"]||K(\"W052\",f.tokens.next,this.value),Dt(\"continue\"),this}).exps=!0,pt(\"return\",function(){return this.line===f.tokens.next.line?f.tokens.next.id!==\";\"&&!f.tokens.next.reach&&(this.first=ot(0),this.first&&this.first.type===\"(punctuator)\"&&this.first.value===\"=\"&&!this.first.paren&&!f.option.boss&&Q(\"W093\",this.first.line,this.first.character)):f.tokens.next.type===\"(punctuator)\"&&[\"[\",\"{\",\"+\",\"-\"].indexOf(f.tokens.next.value)>-1&&at(this),Dt(\"return\"),this}).exps=!0,function(e){e.exps=!0,e.lbp=25}(mt(\"yield\",function(){var e=f.tokens.prev;return f.option.inESNext(!0)&&!w[\"(generator)\"]?(\"(catch)\"!==w[\"(name)\"]||!w[\"(context)\"][\"(generator)\"])&&G(\"E046\",f.tokens.curr,\"yield\"):f.option.inESNext()||K(\"W104\",f.tokens.curr,\"yield\"),w[\"(generator)\"]=\"yielded\",this.line===f.tokens.next.line||!f.option.inMoz(!0)?(f.tokens.next.id!==\";\"&&!f.tokens.next.reach&&f.tokens.next.nud&&(ut(f.tokens.curr,f.tokens.next),this.first=ot(10),this.first.type===\"(punctuator)\"&&this.first.value===\"=\"&&!this.first.paren&&!f.option.boss&&Q(\"W093\",this.first.line,this.first.character)),f.option.inMoz(!0)&&f.tokens.next.id!==\")\"&&(e.lbp>30||!e.assign&&!st()||e.id===\"yield\")&&G(\"E050\",this)):f.option.asi||at(this),this})),pt(\"throw\",function(){return at(this),this.first=ot(20),Dt(\"throw\"),this}).exps=!0,pt(\"import\",function(){f.option.inESNext()||K(\"W119\",f.tokens.curr,\"import\");if(f.tokens.next.type===\"(string)\")return rt(\"(string)\"),this;if(f.tokens.next.identifier)this.name=_t(),et(this.name,{type:\"unused\",token:f.tokens.curr});else{rt(\"{\");for(;;){if(f.tokens.next.value===\"}\"){rt(\"}\");break}var e;f.tokens.next.type===\"default\"?(e=\"default\",rt(\"default\")):e=_t(),f.tokens.next.value===\"as\"&&(rt(\"as\"),e=_t()),et(e,{type:\"unused\",token:f.tokens.curr});if(f.tokens.next.value!==\",\"){if(f.tokens.next.value===\"}\"){rt(\"}\");break}G(\"E024\",f.tokens.next,f.tokens.next.value);break}rt(\",\")}}return rt(\"from\"),rt(\"(string)\"),this}).exps=!0,pt(\"export\",function(){f.option.inESNext()||K(\"W119\",f.tokens.curr,\"export\");if(f.tokens.next.type===\"default\"){rt(\"default\");if(f.tokens.next.id===\"function\"||f.tokens.next.id===\"class\")this.block=!0;return this.exportee=ot(10),this}if(f.tokens.next.value===\"{\"){rt(\"{\");for(;;){y[_t()]=!0;if(f.tokens.next.value!==\",\"){if(f.tokens.next.value===\"}\"){rt(\"}\");break}G(\"E024\",f.tokens.next,f.tokens.next.value);break}rt(\",\")}return this}return f.tokens.next.id===\"var\"?(rt(\"var\"),y[f.tokens.next.value]=!0,f.syntax[\"var\"].fud.call(f.syntax[\"var\"].fud)):f.tokens.next.id===\"let\"?(rt(\"let\"),y[f.tokens.next.value]=!0,f.syntax.let.fud.call(f.syntax.let.fud)):f.tokens.next.id===\"const\"?(rt(\"const\"),y[f.tokens.next.value]=!0,f.syntax[\"const\"].fud.call(f.syntax[\"const\"].fud)):f.tokens.next.id===\"function\"?(this.block=!0,rt(\"function\"),y[f.tokens.next.value]=!0,f.syntax[\"function\"].fud()):f.tokens.next.id===\"class\"?(this.block=!0,rt(\"class\"),y[f.tokens.next.value]=!0,f.syntax[\"class\"].fud()):G(\"E024\",f.tokens.next,f.tokens.next.value),this}).exps=!0,bt(\"abstract\"),bt(\"boolean\"),bt(\"byte\"),bt(\"char\"),bt(\"class\",{es5:!0,nud:rn}),bt(\"double\"),bt(\"enum\",{es5:!0}),bt(\"export\",{es5:!0}),bt(\"extends\",{es5:!0}),bt(\"final\"),bt(\"float\"),bt(\"goto\"),bt(\"implements\",{es5:!0,strictOnly:!0}),bt(\"import\",{es5:!0}),bt(\"int\"),bt(\"interface\",{es5:!0,strictOnly:!0}),bt(\"long\"),bt(\"native\"),bt(\"package\",{es5:!0,strictOnly:!0}),bt(\"private\",{es5:!0,strictOnly:!0}),bt(\"protected\",{es5:!0,strictOnly:!0}),bt(\"public\",{es5:!0,strictOnly:!0}),bt(\"short\"),bt(\"static\",{es5:!0,strictOnly:!0}),bt(\"super\",{es5:!0}),bt(\"synchronized\"),bt(\"transient\"),bt(\"volatile\");var on=function(){var e,t,n=-1,i=0,s={};r.contains([\"[\",\"{\"],f.tokens.curr.value)&&(i+=1);do{e=n===-1?f.tokens.next:nt(n),t=nt(n+1),n+=1,r.contains([\"[\",\"{\"],e.value)?i+=1:r.contains([\"]\",\"}\"],e.value)&&(i-=1);if(e.identifier&&e.value===\"for\"&&i===1){s.isCompArray=!0,s.notJson=!0;break}if(r.contains([\"}\",\"]\"],e.value)&&t.value===\"=\"&&i===0){s.isDestAssign=!0,s.notJson=!0;break}e.value===\";\"&&(s.isBlock=!0,s.notJson=!0)}while(i>0&&e.id!==\"(end)\"&&n<15);return s},an=function(){function i(e){var t=n.variables.filter(function(t){if(t.value===e)return t.undef=!1,e}).length;return t!==0}function s(e){var t=n.variables.filter(function(t){if(t.value===e&&!t.undef)return t.unused===!0&&(t.unused=!1),e}).length;return t===0}var e=function(){this.mode=\"use\",this.variables=[]},t=[],n;return{stack:function(){n=new e,t.push(n)},unstack:function(){n.variables.filter(function(e){e.unused&&K(\"W098\",e.token,e.value),e.undef&&$(e.funct,\"W117\",e.token,e.value)}),t.splice(-1,1),n=t[t.length-1]},setState:function(e){r.contains([\"use\",\"define\",\"generate\",\"filter\"],e)&&(n.mode=e)},check:function(e){if(!n)return;return n&&n.mode===\"use\"?(s(e)&&n.variables.push({funct:w,token:f.tokens.curr,value:e,undef:!0,unused:!1}),!0):n&&n.mode===\"define\"?(i(e)||n.variables.push({funct:w,token:f.tokens.curr,value:e,undef:!1,unused:!0}),!0):n&&n.mode===\"generate\"?($(w,\"W117\",f.tokens.curr,e),!0):n&&n.mode===\"filter\"?(s(e)&&$(w,\"W117\",f.tokens.curr,e),!0):!1}}},ln=function(){function n(){for(var t in e)if(e[t][\"(type)\"]===\"unused\"&&f.option.unused){var n=e[t][\"(token)\"],r=n.line,i=n.character;Q(\"W098\",r,i,t)}}var e={},t=[e];return{stack:function(){e={},t.push(e)},unstack:function(){n(),t.splice(t.length-1,1),e=r.last(t)},getlabel:function(e){for(var n=t.length-1;n>=0;--n)if(r.has(t[n],e)&&!t[n][e][\"(shadowed)\"])return t[n]},shadow:function(e){for(var n=t.length-1;n>=0;n--)r.has(t[n],e)&&(t[n][e][\"(shadowed)\"]=!0)},unshadow:function(e){for(var n=t.length-1;n>=0;n--)r.has(t[n],e)&&(t[n][e][\"(shadowed)\"]=!1)},current:{has:function(t){return r.has(e,t)},add:function(t,n,r){e[t]={\"(type)\":n,\"(token)\":r,\"(shadowed)\":!1}}}}},cn=function(e,n,i){function v(e,t){if(!e)return;!Array.isArray(e)&&typeof e==\"object\"&&(e=Object.keys(e)),e.forEach(t)}var o,a,l,h,p={},d={};n=r.clone(n),f.reset(),n&&n.scope?c.scope=n.scope:(c.errors=[],c.undefs=[],c.internals=[],c.blacklist={},c.scope=\"(main)\"),M=Object.create(null),W(M,s.ecmaIdentifiers),W(M,s.reservedVars),W(M,i||{}),g=Object.create(null),y=Object.create(null);if(n){v(n.predef||null,function(e){var t,r;e[0]===\"-\"?(t=e.slice(1),c.blacklist[t]=t):(r=Object.getOwnPropertyDescriptor(n.predef,e),M[e]=r?r.value:!1)}),v(n.exported||null,function(e){y[e]=!0}),delete n.predef,delete n.exported,h=Object.keys(n);for(l=0;l<h.length;l++)/^-W\\d{3}$/g.test(h[l])?d[h[l].slice(1)]=!0:(p[h[l]]=n[h[l]],h[l]===\"newcap\"&&n[h[l]]===!1&&(p[\"(explicitNewcap)\"]=!0))}f.option=p,f.ignored=d,f.option.indent=f.option.indent||4,f.option.maxerr=f.option.maxerr||50,N=1,S=Object.create(M),D=S,w=$t(\"(global)\",null,D,{\"(global)\":!0,\"(blockscope)\":ln(),\"(comparray)\":an(),\"(metrics)\":Kt(f.tokens.next)}),E=[w],B=[],P=null,L={},A=null,x={},T=!1,C=[],H=[];if(!q(e)&&!Array.isArray(e))return Y(\"E004\",0),!1;t={get isJSON(){return f.jsonMode},getOption:function(e){return f.option[e]||null},getCache:function(e){return f.cache[e]},setCache:function(e,t){f.cache[e]=t},warn:function(e,t){Q.apply(null,[e,t.line,t.char].concat(t.data))},on:function(e,t){e.split(\" \").forEach(function(e){F.on(e,t)}.bind(this))}},F.removeAllListeners(),(j||[]).forEach(function(e){e(t)}),f.tokens.prev=f.tokens.curr=f.tokens.next=f.syntax[\"(begin)\"],k=new u(e),k.on(\"warning\",function(e){Q.apply(null,[e.code,e.line,e.character].concat(e.data))}),k.on(\"error\",function(e){Y.apply(null,[e.code,e.line,e.character].concat(e.data))}),k.on(\"fatal\",function(e){V(\"E041\",e.line,e.from)}),k.on(\"Identifier\",function(e){F.emit(\"Identifier\",e)}),k.on(\"String\",function(e){F.emit(\"String\",e)}),k.on(\"Number\",function(e){F.emit(\"Number\",e)}),k.start();for(var m in n)r.has(n,m)&&I(m,f.tokens.curr);X(),W(M,i||{}),lt.first=!0;try{rt();switch(f.tokens.next.id){case\"{\":case\"[\":un();break;default:jt(),f.directive[\"use strict\"]&&!f.option.globalstrict&&!f.option.node&&!f.option.phantom&&K(\"W097\",f.tokens.prev),Bt()}rt(f.tokens.next&&f.tokens.next.value!==\".\"?\"(end)\":undefined),w[\"(blockscope)\"].unstack();var b=function(e,t){do{if(typeof t[e]==\"string\")return t[e]===\"unused\"?t[e]=\"var\":t[e]===\"unction\"&&(t[e]=\"closure\"),!0;t=t[\"(context)\"]}while(t);return!1},O=function(e,t){if(!x[e])return;var n=[];for(var r=0;r<x[e].length;r+=1)x[e][r]!==t&&n.push(x[e][r]);n.length===0?delete x[e]:x[e]=n},R=function(e,t,n,r){var i=t.line,s=t.character;r===undefined&&(r=f.option.unused),r===!0&&(r=\"last-param\");var o={vars:[\"var\"],\"last-param\":[\"var\",\"param\"],strict:[\"var\",\"param\",\"last-param\"]};r&&o[r]&&o[r].indexOf(n)!==-1&&Q(\"W098\",i,s,e),H.push({name:e,line:i,character:s})},U=function(e,t){var n=e[t],i=e[\"(tokens)\"][t];if(t.charAt(0)===\"(\")return;if(n!==\"unused\"&&n!==\"unction\"&&n!==\"const\")return;if(e[\"(params)\"]&&e[\"(params)\"].indexOf(t)!==-1)return;if(e[\"(global)\"]&&r.has(y,t))return;if(n===\"const\"&&!Vt(e,t,\"unused\"))return;R(t,i,\"var\")};for(o=0;o<c.undefs.length;o+=1)a=c.undefs[o].slice(0),b(a[2].value,a[0])?O(a[2].value,a[2].line):f.option.undef&&K.apply(K,a.slice(1));E.forEach(function(e){if(e[\"(unusedOption)\"]===!1)return;for(var t in e)r.has(e,t)&&U(e,t);if(!e[\"(params)\"])return;var n=e[\"(params)\"].slice(),i=n.pop(),s,o;while(i){s=e[i],o=e[\"(unusedOption)\"]||f.option.unused,o=o===!0?\"last-param\":o;if(i===\"undefined\")return;if(s===\"unused\"||s===\"unction\")R(i,e[\"(tokens)\"][i],\"param\",e[\"(unusedOption)\"]);else if(o===\"last-param\")return;i=n.pop()}});for(var z in g)r.has(g,z)&&!r.has(S,z)&&!r.has(y,z)&&R(z,g[z],\"var\")}catch($){if(!$||$.name!==\"JSHintError\")throw $;var J=f.tokens.next||{};c.errors.push({scope:\"(main)\",raw:$.raw,code:$.code,reason:$.message,line:$.line||J.line,character:$.character||J.from},null)}if(c.scope===\"(main)\"){n=n||{};for(o=0;o<c.internals.length;o+=1)a=c.internals[o],n.scope=a.elem,cn(a.value,n,i)}return c.errors.length===0};return cn.addModule=function(e){j.push(e)},cn.addModule(l.register),cn.data=function(){var e={functions:[],options:f.option},t=[],n=[],i,s,o,u,a,l;cn.errors.length&&(e.errors=cn.errors),f.jsonMode&&(e.json=!0);for(a in x)r.has(x,a)&&t.push({name:a,line:x[a]});t.length>0&&(e.implieds=t),B.length>0&&(e.urls=B),l=Object.keys(D),l.length>0&&(e.globals=l);for(o=1;o<E.length;o+=1){s=E[o],i={};for(u=0;u<b.length;u+=1)i[b[u]]=[];for(u=0;u<b.length;u+=1)i[b[u]].length===0&&delete i[b[u]];i.name=s[\"(name)\"],i.param=s[\"(params)\"],i.line=s[\"(line)\"],i.character=s[\"(character)\"],i.last=s[\"(last)\"],i.lastcharacter=s[\"(lastcharacter)\"],i.metrics={complexity:s[\"(metrics)\"].ComplexityCount,parameters:(s[\"(params)\"]||[]).length,statements:s[\"(metrics)\"].statementCount},e.functions.push(i)}H.length>0&&(e.unused=H),n=[];for(a in L)if(typeof L[a]==\"number\"){e.member=L;break}return e},cn.jshint=cn,cn}();typeof n==\"object\"&&n&&(n.JSHINT=c)},{\"./lex.js\":4,\"./messages.js\":5,\"./reg.js\":6,\"./state.js\":7,\"./style.js\":8,\"./vars.js\":9,events:10,underscore:2}],4:[function(e,t,n){\"use strict\";function c(){var e=[];return{push:function(t){e.push(t)},check:function(){for(var t=0;t<e.length;++t)e[t]();e.splice(0,e.length)}}}function h(e){var t=e;typeof t==\"string\"&&(t=t.replace(/\\r\\n/g,\"\\n\").replace(/\\r/g,\"\\n\").split(\"\\n\")),t[0]&&t[0].substr(0,2)===\"#!\"&&(t[0].indexOf(\"node\")!==-1&&(o.option.node=!0),t[0]=\"\"),this.emitter=new i.EventEmitter,this.source=e,this.setLines(t),this.prereg=!0,this.line=0,this.char=1,this.from=1,this.input=\"\",this.inComment=!1;for(var n=0;n<o.option.indent;n+=1)o.tab+=\" \"}var r=e(\"underscore\"),i=e(\"events\"),s=e(\"./reg.js\"),o=e(\"./state.js\").state,u=e(\"../data/ascii-identifier-data.js\"),a=u.asciiIdentifierStartTable,f=u.asciiIdentifierPartTable,l={Identifier:1,Punctuator:2,NumericLiteral:3,StringLiteral:4,Comment:5,Keyword:6,NullLiteral:7,BooleanLiteral:8,RegExp:9,TemplateLiteral:10};h.prototype={_lines:[],getLines:function(){return this._lines=o.lines,this._lines},setLines:function(e){this._lines=e,o.lines=this._lines},peek:function(e){return this.input.charAt(e||0)},skip:function(e){e=e||1,this.char+=e,this.input=this.input.slice(e)},on:function(e,t){e.split(\" \").forEach(function(e){this.emitter.on(e,t)}.bind(this))},trigger:function(){this.emitter.emit.apply(this.emitter,Array.prototype.slice.call(arguments))},triggerAsync:function(e,t,n,r){n.push(function(){r()&&this.trigger(e,t)}.bind(this))},scanPunctuator:function(){var e=this.peek(),t,n,r;switch(e){case\".\":if(/^[0-9]$/.test(this.peek(1)))return null;if(this.peek(1)===\".\"&&this.peek(2)===\".\")return{type:l.Punctuator,value:\"...\"};case\"(\":case\")\":case\";\":case\",\":case\"{\":case\"}\":case\"[\":case\"]\":case\":\":case\"~\":case\"?\":return{type:l.Punctuator,value:e};case\"#\":return{type:l.Punctuator,value:e};case\"\":return null}return t=this.peek(1),n=this.peek(2),r=this.peek(3),e===\">\"&&t===\">\"&&n===\">\"&&r===\"=\"?{type:l.Punctuator,value:\">>>=\"}:e===\"=\"&&t===\"=\"&&n===\"=\"?{type:l.Punctuator,value:\"===\"}:e===\"!\"&&t===\"=\"&&n===\"=\"?{type:l.Punctuator,value:\"!==\"}:e===\">\"&&t===\">\"&&n===\">\"?{type:l.Punctuator,value:\">>>\"}:e===\"<\"&&t===\"<\"&&n===\"=\"?{type:l.Punctuator,value:\"<<=\"}:e===\">\"&&t===\">\"&&n===\"=\"?{type:l.Punctuator,value:\">>=\"}:e===\"=\"&&t===\">\"?{type:l.Punctuator,value:e+t}:e===t&&\"+-<>&|\".indexOf(e)>=0?{type:l.Punctuator,value:e+t}:\"<>=!+-*%&|^\".indexOf(e)>=0?t===\"=\"?{type:l.Punctuator,value:e+t}:{type:l.Punctuator,value:e}:e===\"/\"?t===\"=\"&&/\\/=(?!(\\S*\\/[gim]?))/.test(this.input)?{type:l.Punctuator,value:\"/=\"}:{type:l.Punctuator,value:\"/\"}:null},scanComments:function(){function s(e,t,n){var r=[\"jshint\",\"jslint\",\"members\",\"member\",\"globals\",\"global\",\"exported\"],i=!1,s=e+t,o=\"plain\";return n=n||{},n.isMultiline&&(s+=\"*/\"),r.forEach(function(n){if(i)return;if(e===\"//\"&&n!==\"jshint\")return;t.substr(0,n.length)===n&&(i=!0,e+=n,t=t.substr(n.length)),!i&&t.charAt(0)===\" \"&&t.substr(1,n.length)===n&&(i=!0,e=e+\" \"+n,t=t.substr(n.length+1));if(!i)return;switch(n){case\"member\":o=\"members\";break;case\"global\":o=\"globals\";break;default:o=n}}),{type:l.Comment,commentType:o,value:s,body:t,isSpecial:i,isMultiline:n.isMultiline||!1,isMalformed:n.isMalformed||!1}}var e=this.peek(),t=this.peek(1),n=this.input.substr(2),r=this.line,i=this.char;if(e===\"*\"&&t===\"/\")return this.trigger(\"error\",{code:\"E018\",line:r,character:i}),this.skip(2),null;if(e!==\"/\"||t!==\"*\"&&t!==\"/\")return null;if(t===\"/\")return this.skip(this.input.length),s(\"//\",n);var o=\"\";if(t===\"*\"){this.inComment=!0,this.skip(2);while(this.peek()!==\"*\"||this.peek(1)!==\"/\")if(this.peek()===\"\"){o+=\"\\n\";if(!this.nextLine())return this.trigger(\"error\",{code:\"E017\",line:r,character:i}),this.inComment=!1,s(\"/*\",o,{isMultiline:!0,isMalformed:!0})}else o+=this.peek(),this.skip();return this.skip(2),this.inComment=!1,s(\"/*\",o,{isMultiline:!0})}},scanKeyword:function(){var e=/^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input),t=[\"if\",\"in\",\"do\",\"var\",\"for\",\"new\",\"try\",\"let\",\"this\",\"else\",\"case\",\"void\",\"with\",\"enum\",\"while\",\"break\",\"catch\",\"throw\",\"const\",\"yield\",\"class\",\"super\",\"return\",\"typeof\",\"delete\",\"switch\",\"export\",\"import\",\"default\",\"finally\",\"extends\",\"function\",\"continue\",\"debugger\",\"instanceof\"];return e&&t.indexOf(e[0])>=0?{type:l.Keyword,value:e[0]}:null},scanIdentifier:function(){function i(e){return e>256}function s(e){return e>256}function o(e){return/^[0-9a-fA-F]$/.test(e)}var e=\"\",t=0,n,r,u=function(){t+=1;if(this.peek(t)!==\"u\")return null;var e=this.peek(t+1),n=this.peek(t+2),r=this.peek(t+3),i=this.peek(t+4),u;return o(e)&&o(n)&&o(r)&&o(i)?(u=parseInt(e+n+r+i,16),f[u]||s(u)?(t+=5,\"\\\\u\"+e+n+r+i):null):null}.bind(this),c=function(){var e=this.peek(t),n=e.charCodeAt(0);return n===92?u():n<128?a[n]?(t+=1,e):null:i(n)?(t+=1,e):null}.bind(this),h=function(){var e=this.peek(t),n=e.charCodeAt(0);return n===92?u():n<128?f[n]?(t+=1,e):null:s(n)?(t+=1,e):null}.bind(this);r=c();if(r===null)return null;e=r;for(;;){r=h();if(r===null)break;e+=r}switch(e){case\"true\":case\"false\":n=l.BooleanLiteral;break;case\"null\":n=l.NullLiteral;break;default:n=l.Identifier}return{type:n,value:e}},scanNumericLiteral:function(){function s(e){return/^[0-9]$/.test(e)}function o(e){return/^[0-7]$/.test(e)}function u(e){return/^[0-9a-fA-F]$/.test(e)}function a(e){return e===\"$\"||e===\"_\"||e===\"\\\\\"||e>=\"a\"&&e<=\"z\"||e>=\"A\"&&e<=\"Z\"}var e=0,t=\"\",n=this.input.length,r=this.peek(e),i;if(r!==\".\"&&!s(r))return null;if(r!==\".\"){t=this.peek(e),e+=1,r=this.peek(e);if(t===\"0\"){if(r===\"x\"||r===\"X\"){e+=1,t+=r;while(e<n){r=this.peek(e);if(!u(r))break;t+=r,e+=1}if(t.length<=2)return{type:l.NumericLiteral,value:t,isMalformed:!0};if(e<n){r=this.peek(e);if(a(r))return null}return{type:l.NumericLiteral,value:t,base:16,isMalformed:!1}}if(o(r)){e+=1,t+=r,i=!1;while(e<n){r=this.peek(e);if(s(r))i=!0;else if(!o(r))break;t+=r,e+=1}if(e<n){r=this.peek(e);if(a(r))return null}return{type:l.NumericLiteral,value:t,base:8,isMalformed:!1}}s(r)&&(e+=1,t+=r)}while(e<n){r=this.peek(e);if(!s(r))break;t+=r,e+=1}}if(r===\".\"){t+=r,e+=1;while(e<n){r=this.peek(e);if(!s(r))break;t+=r,e+=1}}if(r===\"e\"||r===\"E\"){t+=r,e+=1,r=this.peek(e);if(r===\"+\"||r===\"-\")t+=this.peek(e),e+=1;r=this.peek(e);if(!s(r))return null;t+=r,e+=1;while(e<n){r=this.peek(e);if(!s(r))break;t+=r,e+=1}}if(e<n){r=this.peek(e);if(a(r))return null}return{type:l.NumericLiteral,value:t,base:10,isMalformed:!isFinite(t)}},scanTemplateLiteral:function(){if(!o.option.esnext||this.peek()!==\"`\")return null;var e=this.line,t=this.char,n=1,r=\"\";this.skip();while(this.peek()!==\"`\"){while(this.peek()===\"\"){if(!this.nextLine())return this.trigger(\"error\",{code:\"E052\",line:e,character:t}),{type:l.TemplateLiteral,value:r,isUnclosed:!0};r+=\"\\n\"}var i=this.peek();this.skip(n),r+=i}return this.skip(),{type:l.TemplateLiteral,value:r,isUnclosed:!1}},scanStringLiteral:function(e){var t=this.peek();if(t!=='\"'&&t!==\"'\")return null;this.triggerAsync(\"warning\",{code:\"W108\",line:this.line,character:this.char},e,function(){return o.jsonMode&&t!=='\"'});var n=\"\",r=this.line,i=this.char,s=!1;this.skip();e:while(this.peek()!==t){while(this.peek()===\"\"){s?(s=!1,this.triggerAsync(\"warning\",{code:\"W043\",line:this.line,character:this.char},e,function(){return!o.option.multistr}),this.triggerAsync(\"warning\",{code:\"W042\",line:this.line,character:this.char},e,function(){return o.jsonMode&&o.option.multistr})):this.trigger(\"warning\",{code:\"W112\",line:this.line,character:this.char});if(!this.nextLine())return this.trigger(\"error\",{code:\"E029\",line:r,character:i}),{type:l.StringLiteral,value:n,isUnclosed:!0,quote:t};if(this.peek()==t)break e}s=!1;var u=this.peek(),a=1;u<\" \"&&this.trigger(\"warning\",{code:\"W113\",line:this.line,character:this.char,data:[\"<non-printable>\"]});if(u===\"\\\\\"){this.skip(),u=this.peek();switch(u){case\"'\":this.triggerAsync(\"warning\",{code:\"W114\",line:this.line,character:this.char,data:[\"\\\\'\"]},e,function(){return o.jsonMode});break;case\"b\":u=\"\\\\b\";break;case\"f\":u=\"\\\\f\";break;case\"n\":u=\"\\\\n\";break;case\"r\":u=\"\\\\r\";break;case\"t\":u=\"\\\\t\";break;case\"0\":u=\"\\\\0\";var f=parseInt(this.peek(1),10);this.triggerAsync(\"warning\",{code:\"W115\",line:this.line,character:this.char},e,function(){return f>=0&&f<=7&&o.directive[\"use strict\"]});break;case\"u\":u=String.fromCharCode(parseInt(this.input.substr(1,4),16)),a=5;break;case\"v\":this.triggerAsync(\"warning\",{code:\"W114\",line:this.line,character:this.char,data:[\"\\\\v\"]},e,function(){return o.jsonMode}),u=\"\u000b\";break;case\"x\":var c=parseInt(this.input.substr(1,2),16);this.triggerAsync(\"warning\",{code:\"W114\",line:this.line,character:this.char,data:[\"\\\\x-\"]},e,function(){return o.jsonMode}),u=String.fromCharCode(c),a=3;break;case\"\\\\\":u=\"\\\\\\\\\";break;case'\"':u='\\\\\"';break;case\"/\":break;case\"\":s=!0,u=\"\";break;case\"!\":if(n.slice(n.length-2)===\"<\")break;default:this.trigger(\"warning\",{code:\"W044\",line:this.line,character:this.char})}}n+=u,this.skip(a)}return this.skip(),{type:l.StringLiteral,value:n,isUnclosed:!1,quote:t}},scanRegExp:function(){var e=0,t=this.input.length,n=this.peek(),r=n,i=\"\",s=[],o=!1,u=!1,a,f=function(){n<\" \"&&(o=!0,this.trigger(\"warning\",{code:\"W048\",line:this.line,character:this.char})),n===\"<\"&&(o=!0,this.trigger(\"warning\",{code:\"W049\",line:this.line,character:this.char,data:[n]}))}.bind(this);if(!this.prereg||n!==\"/\")return null;e+=1,a=!1;while(e<t){n=this.peek(e),r+=n,i+=n;if(u){n===\"]\"&&(this.peek(e-1)!==\"\\\\\"||this.peek(e-2)===\"\\\\\")&&(u=!1),n===\"\\\\\"&&(e+=1,n=this.peek(e),i+=n,r+=n,f()),e+=1;continue}if(n===\"\\\\\"){e+=1,n=this.peek(e),i+=n,r+=n,f();if(n===\"/\"){e+=1;continue}if(n===\"[\"){e+=1;continue}}if(n===\"[\"){u=!0,e+=1;continue}if(n===\"/\"){i=i.substr(0,i.length-1),a=!0,e+=1;break}e+=1}if(!a)return this.trigger(\"error\",{code:\"E015\",line:this.line,character:this.from}),void this.trigger(\"fatal\",{line:this.line,from:this.from});while(e<t){n=this.peek(e);if(!/[gim]/.test(n))break;s.push(n),r+=n,e+=1}try{new RegExp(i,s.join(\"\"))}catch(c){o=!0,this.trigger(\"error\",{code:\"E016\",line:this.line,character:this.char,data:[c.message]})}return{type:l.RegExp,value:r,flags:s,isMalformed:o}},scanNonBreakingSpaces:function(){return o.option.nonbsp?this.input.search(/(\\u00A0)/):-1},scanUnsafeChars:function(){return this.input.search(s.unsafeChars)},next:function(e){this.from=this.char;var t;if(/\\s/.test(this.peek())){t=this.char;while(/\\s/.test(this.peek()))this.from+=1,this.skip()}var n=this.scanComments()||this.scanStringLiteral(e)||this.scanTemplateLiteral();return n?n:(n=this.scanRegExp()||this.scanPunctuator()||this.scanKeyword()||this.scanIdentifier()||this.scanNumericLiteral(),n?(this.skip(n.value.length),n):null)},nextLine:function(){var e;if(this.line>=this.getLines().length)return!1;this.input=this.getLines()[this.line],this.line+=1,this.char=1,this.from=1;var t=this.input.trim(),n=function(){return r.some(arguments,function(e){return t.indexOf(e)===0})},i=function(){return r.some(arguments,function(e){return t.indexOf(e,t.length-e.length)!==-1})};o.ignoreLinterErrors===!0&&!n(\"/*\",\"//\")&&!i(\"*/\")&&(this.input=\"\"),e=this.scanNonBreakingSpaces(),e>=0&&this.trigger(\"warning\",{code:\"W125\",line:this.line,character:e+1}),this.input=this.input.replace(/\\t/g,o.tab),e=this.scanUnsafeChars(),e>=0&&this.trigger(\"warning\",{code:\"W100\",line:this.line,character:e});if(o.option.maxlen&&o.option.maxlen<this.input.length){var u=this.inComment||n.call(t,\"//\")||n.call(t,\"/*\"),a=!u||!s.maxlenException.test(t);a&&this.trigger(\"warning\",{code:\"W101\",line:this.line,character:this.input.length})}return!0},start:function(){this.nextLine()},token:function(){function n(e,t){if(!e.reserved)return!1;var n=e.meta;if(n&&n.isFutureReservedWord&&o.option.inES5()){if(!n.es5)return!1;if(n.strictOnly&&!o.option.strict&&!o.directive[\"use strict\"])return!1;if(t)return!1}return!0}var e=c(),t,i=function(t,i,s){var u;t!==\"(endline)\"&&t!==\"(end)\"&&(this.prereg=!1);if(t===\"(punctuator)\"){switch(i){case\".\":case\")\":case\"~\":case\"#\":case\"]\":this.prereg=!1;break;default:this.prereg=!0}u=Object.create(o.syntax[i]||o.syntax[\"(error)\"])}if(t===\"(identifier)\"){if(i===\"return\"||i===\"case\"||i===\"typeof\")this.prereg=!0;r.has(o.syntax,i)&&(u=Object.create(o.syntax[i]||o.syntax[\"(error)\"]),n(u,s&&t===\"(identifier)\")||(u=null))}return u||(u=Object.create(o.syntax[t])),u.identifier=t===\"(identifier)\",u.type=u.type||t,u.value=i,u.line=this.line,u.character=this.char,u.from=this.from,s&&u.identifier&&(u.isProperty=s),u.check=e.check,u}.bind(this);for(;;){if(!this.input.length)return i(this.nextLine()?\"(endline)\":\"(end)\",\"\");t=this.next(e);if(!t){this.input.length&&(this.trigger(\"error\",{code:\"E024\",line:this.line,character:this.char,data:[this.peek()]}),this.input=\"\");continue}switch(t.type){case l.StringLiteral:return this.triggerAsync(\"String\",{line:this.line,\"char\":this.char,from:this.from,value:t.value,quote:t.quote},e,function(){return!0}),i(\"(string)\",t.value);case l.TemplateLiteral:return this.trigger(\"Template\",{line:this.line,\"char\":this.char,from:this.from,value:t.value}),i(\"(template)\",t.value);case l.Identifier:this.trigger(\"Identifier\",{line:this.line,\"char\":this.char,from:this.form,name:t.value,isProperty:o.tokens.curr.id===\".\"});case l.Keyword:case l.NullLiteral:case l.BooleanLiteral:return i(\"(identifier)\",t.value,o.tokens.curr.id===\".\");case l.NumericLiteral:return t.isMalformed&&this.trigger(\"warning\",{code:\"W045\",line:this.line,character:this.char,data:[t.value]}),this.triggerAsync(\"warning\",{code:\"W114\",line:this.line,character:this.char,data:[\"0x-\"]},e,function(){return t.base===16&&o.jsonMode}),this.triggerAsync(\"warning\",{code:\"W115\",line:this.line,character:this.char},e,function(){return o.directive[\"use strict\"]&&t.base===8}),this.trigger(\"Number\",{line:this.line,\"char\":this.char,from:this.from,value:t.value,base:t.base,isMalformed:t.malformed}),i(\"(number)\",t.value);case l.RegExp:return i(\"(regexp)\",t.value);case l.Comment:o.tokens.curr.comment=!0;if(t.isSpecial)return{id:\"(comment)\",value:t.value,body:t.body,type:t.commentType,isSpecial:t.isSpecial,line:this.line,character:this.char,from:this.from};break;case\"\":break;default:return i(\"(punctuator)\",t.value)}}}},n.Lexer=h},{\"../data/ascii-identifier-data.js\":1,\"./reg.js\":6,\"./state.js\":7,events:10,underscore:2}],5:[function(e,t,n){\"use strict\";var r=e(\"underscore\"),i={E001:\"Bad option: '{a}'.\",E002:\"Bad option value.\",E003:\"Expected a JSON value.\",E004:\"Input is neither a string nor an array of strings.\",E005:\"Input is empty.\",E006:\"Unexpected early end of program.\",E007:'Missing \"use strict\" statement.',E008:\"Strict violation.\",E009:\"Option 'validthis' can't be used in a global scope.\",E010:\"'with' is not allowed in strict mode.\",E011:\"const '{a}' has already been declared.\",E012:\"const '{a}' is initialized to 'undefined'.\",E013:\"Attempting to override '{a}' which is a constant.\",E014:\"A regular expression literal can be confused with '/='.\",E015:\"Unclosed regular expression.\",E016:\"Invalid regular expression.\",E017:\"Unclosed comment.\",E018:\"Unbegun comment.\",E019:\"Unmatched '{a}'.\",E020:\"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.\",E021:\"Expected '{a}' and instead saw '{b}'.\",E022:\"Line breaking error '{a}'.\",E023:\"Missing '{a}'.\",E024:\"Unexpected '{a}'.\",E025:\"Missing ':' on a case clause.\",E026:\"Missing '}' to match '{' from line {a}.\",E027:\"Missing ']' to match '[' from line {a}.\",E028:\"Illegal comma.\",E029:\"Unclosed string.\",E030:\"Expected an identifier and instead saw '{a}'.\",E031:\"Bad assignment.\",E032:\"Expected a small integer or 'false' and instead saw '{a}'.\",E033:\"Expected an operator and instead saw '{a}'.\",E034:\"get/set are ES5 features.\",E035:\"Missing property name.\",E036:\"Expected to see a statement and instead saw a block.\",E037:null,E038:null,E039:\"Function declarations are not invocable. Wrap the whole function invocation in parens.\",E040:\"Each value should have its own case label.\",E041:\"Unrecoverable syntax error.\",E042:\"Stopping.\",E043:\"Too many errors.\",E044:null,E045:\"Invalid for each loop.\",E046:\"A yield statement shall be within a generator function (with syntax: `function*`)\",E047:null,E048:\"Let declaration not directly within block.\",E049:\"A {a} cannot be named '{b}'.\",E050:\"Mozilla requires the yield expression to be parenthesized here.\",E051:\"Regular parameters cannot come after default parameters.\",E052:\"Unclosed template literal.\"},s={W001:\"'hasOwnProperty' is a really bad name.\",W002:\"Value of '{a}' may be overwritten in IE 8 and earlier.\",W003:\"'{a}' was used before it was defined.\",W004:\"'{a}' is already defined.\",W005:\"A dot following a number can be confused with a decimal point.\",W006:\"Confusing minuses.\",W007:\"Confusing plusses.\",W008:\"A leading decimal point can be confused with a dot: '{a}'.\",W009:\"The array literal notation [] is preferable.\",W010:\"The object literal notation {} is preferable.\",W011:null,W012:null,W013:null,W014:\"Bad line breaking before '{a}'.\",W015:null,W016:\"Unexpected use of '{a}'.\",W017:\"Bad operand.\",W018:\"Confusing use of '{a}'.\",W019:\"Use the isNaN function to compare with NaN.\",W020:\"Read only.\",W021:\"'{a}' is a function.\",W022:\"Do not assign to the exception parameter.\",W023:\"Expected an identifier in an assignment and instead saw a function invocation.\",W024:\"Expected an identifier and instead saw '{a}' (a reserved word).\",W025:\"Missing name in function declaration.\",W026:\"Inner functions should be listed at the top of the outer function.\",W027:\"Unreachable '{a}' after '{b}'.\",W028:\"Label '{a}' on {b} statement.\",W030:\"Expected an assignment or function call and instead saw an expression.\",W031:\"Do not use 'new' for side effects.\",W032:\"Unnecessary semicolon.\",W033:\"Missing semicolon.\",W034:'Unnecessary directive \"{a}\".',W035:\"Empty block.\",W036:\"Unexpected /*member '{a}'.\",W037:\"'{a}' is a statement label.\",W038:\"'{a}' used out of scope.\",W039:\"'{a}' is not allowed.\",W040:\"Possible strict violation.\",W041:\"Use '{a}' to compare with '{b}'.\",W042:\"Avoid EOL escaping.\",W043:\"Bad escaping of EOL. Use option multistr if needed.\",W044:\"Bad or unnecessary escaping.\",W045:\"Bad number '{a}'.\",W046:\"Don't use extra leading zeros '{a}'.\",W047:\"A trailing decimal point can be confused with a dot: '{a}'.\",W048:\"Unexpected control character in regular expression.\",W049:\"Unexpected escaped character '{a}' in regular expression.\",W050:\"JavaScript URL.\",W051:\"Variables should not be deleted.\",W052:\"Unexpected '{a}'.\",W053:\"Do not use {a} as a constructor.\",W054:\"The Function constructor is a form of eval.\",W055:\"A constructor name should start with an uppercase letter.\",W056:\"Bad constructor.\",W057:\"Weird construction. Is 'new' necessary?\",W058:\"Missing '()' invoking a constructor.\",W059:\"Avoid arguments.{a}.\",W060:\"document.write can be a form of eval.\",W061:\"eval can be harmful.\",W062:\"Wrap an immediate function invocation in parens to assist the reader in understanding that the expression is the result of a function, and not the function itself.\",W063:\"Math is not a function.\",W064:\"Missing 'new' prefix when invoking a constructor.\",W065:\"Missing radix parameter.\",W066:\"Implied eval. Consider passing a function instead of a string.\",W067:\"Bad invocation.\",W068:\"Wrapping non-IIFE function literals in parens is unnecessary.\",W069:\"['{a}'] is better written in dot notation.\",W070:\"Extra comma. (it breaks older versions of IE)\",W071:\"This function has too many statements. ({a})\",W072:\"This function has too many parameters. ({a})\",W073:\"Blocks are nested too deeply. ({a})\",W074:\"This function's cyclomatic complexity is too high. ({a})\",W075:\"Duplicate key '{a}'.\",W076:\"Unexpected parameter '{a}' in get {b} function.\",W077:\"Expected a single parameter in set {a} function.\",W078:\"Setter is defined without getter.\",W079:\"Redefinition of '{a}'.\",W080:\"It's not necessary to initialize '{a}' to 'undefined'.\",W081:null,W082:\"Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.\",W083:\"Don't make functions within a loop.\",W084:\"Assignment in conditional expression\",W085:\"Don't use 'with'.\",W086:\"Expected a 'break' statement before '{a}'.\",W087:\"Forgotten 'debugger' statement?\",W088:\"Creating global 'for' variable. Should be 'for (var {a} ...'.\",W089:\"The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.\",W090:\"'{a}' is not a statement label.\",W091:\"'{a}' is out of scope.\",W093:\"Did you mean to return a conditional instead of an assignment?\",W094:\"Unexpected comma.\",W095:\"Expected a string and instead saw {a}.\",W096:\"The '{a}' key may produce unexpected results.\",W097:'Use the function form of \"use strict\".',W098:\"'{a}' is defined but never used.\",W099:null,W100:\"This character may get silently deleted by one or more browsers.\",W101:\"Line is too long.\",W102:null,W103:\"The '{a}' property is deprecated.\",W104:\"'{a}' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).\",W105:\"Unexpected {a} in '{b}'.\",W106:\"Identifier '{a}' is not in camel case.\",W107:\"Script URL.\",W108:\"Strings must use doublequote.\",W109:\"Strings must use singlequote.\",W110:\"Mixed double and single quotes.\",W112:\"Unclosed string.\",W113:\"Control character in string: {a}.\",W114:\"Avoid {a}.\",W115:\"Octal literals are not allowed in strict mode.\",W116:\"Expected '{a}' and instead saw '{b}'.\",W117:\"'{a}' is not defined.\",W118:\"'{a}' is only available in Mozilla JavaScript extensions (use moz option).\",W119:\"'{a}' is only available in ES6 (use esnext option).\",W120:\"You might be leaking a variable ({a}) here.\",W121:\"Extending prototype of native object: '{a}'.\",W122:\"Invalid typeof value '{a}'\",W123:\"'{a}' is already defined in outer scope.\",W124:\"A generator function shall contain a yield statement.\",W125:\"This line contains non-breaking spaces: http://jshint.com/doc/options/#nonbsp\"},o={I001:\"Comma warnings can be turned off with 'laxcomma'.\",I002:null,I003:\"ES5 option is now set per default\"};n.errors={},n.warnings={},n.info={},r.each(i,function(e,t){n.errors[t]={code:t,desc:e}}),r.each(s,function(e,t){n.warnings[t]={code:t,desc:e}}),r.each(o,function(e,t){n.info[t]={code:t,desc:e}})},{underscore:2}],6:[function(e,t,n){\"use string\";n.unsafeString=/@cc|<\\/?|script|\\]\\s*\\]|<\\s*!|&lt/i,n.unsafeChars=/[\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/,n.needEsc=/[\\u0000-\\u001f&<\"\\/\\\\\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/,n.needEscGlobal=/[\\u0000-\\u001f&<\"\\/\\\\\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,n.starSlash=/\\*\\//,n.identifier=/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,n.javascriptURL=/^(?:javascript|jscript|ecmascript|vbscript|livescript)\\s*:/i,n.fallsThrough=/^\\s*\\/\\*\\s*falls?\\sthrough\\s*\\*\\/\\s*$/,n.maxlenException=/^(?:(?:\\/\\/|\\/\\*|\\*) ?)?[^ ]+$/},{}],7:[function(e,t,n){\"use strict\";var r={syntax:{},reset:function(){this.tokens={prev:null,next:null,curr:null},this.option={},this.ignored={},this.directive={},this.jsonMode=!1,this.jsonWarnings=[],this.lines=[],this.tab=\"\",this.cache={},this.ignoredLines={},this.ignoreLinterErrors=!1}};n.state=r},{}],8:[function(e,t,n){\"use strict\";n.register=function(e){e.on(\"Identifier\",function(n){if(e.getOption(\"proto\"))return;n.name===\"__proto__\"&&e.warn(\"W103\",{line:n.line,\"char\":n.char,data:[n.name]})}),e.on(\"Identifier\",function(n){if(e.getOption(\"iterator\"))return;n.name===\"__iterator__\"&&e.warn(\"W104\",{line:n.line,\"char\":n.char,data:[n.name]})}),e.on(\"Identifier\",function(n){if(!e.getOption(\"camelcase\"))return;n.name.replace(/^_+|_+$/g,\"\").indexOf(\"_\")>-1&&!n.name.match(/^[A-Z0-9_]*$/)&&e.warn(\"W106\",{line:n.line,\"char\":n.from,data:[n.name]})}),e.on(\"String\",function(n){var r=e.getOption(\"quotmark\"),i;if(!r)return;r===\"single\"&&n.quote!==\"'\"&&(i=\"W109\"),r===\"double\"&&n.quote!=='\"'&&(i=\"W108\"),r===!0&&(e.getCache(\"quotmark\")||e.setCache(\"quotmark\",n.quote),e.getCache(\"quotmark\")!==n.quote&&(i=\"W110\")),i&&e.warn(i,{line:n.line,\"char\":n.char})}),e.on(\"Number\",function(n){n.value.charAt(0)===\".\"&&e.warn(\"W008\",{line:n.line,\"char\":n.char,data:[n.value]}),n.value.substr(n.value.length-1)===\".\"&&e.warn(\"W047\",{line:n.line,\"char\":n.char,data:[n.value]}),/^00+/.test(n.value)&&e.warn(\"W046\",{line:n.line,\"char\":n.char,data:[n.value]})}),e.on(\"String\",function(n){var r=/^(?:javascript|jscript|ecmascript|vbscript|livescript)\\s*:/i;if(e.getOption(\"scripturl\"))return;r.test(n.value)&&e.warn(\"W107\",{line:n.line,\"char\":n.char})})}},{}],9:[function(e,t,n){\"use strict\";n.reservedVars={arguments:!1,NaN:!1},n.ecmaIdentifiers={Array:!1,Boolean:!1,Date:!1,decodeURI:!1,decodeURIComponent:!1,encodeURI:!1,encodeURIComponent:!1,Error:!1,eval:!1,EvalError:!1,Function:!1,hasOwnProperty:!1,isFinite:!1,isNaN:!1,JSON:!1,Math:!1,Number:!1,Object:!1,parseInt:!1,parseFloat:!1,RangeError:!1,ReferenceError:!1,RegExp:!1,String:!1,SyntaxError:!1,TypeError:!1,URIError:!1},n.newEcmaIdentifiers={Set:!1,Map:!1,WeakMap:!1,WeakSet:!1,Proxy:!1,Promise:!1},n.browser={Audio:!1,Blob:!1,addEventListener:!1,applicationCache:!1,atob:!1,blur:!1,btoa:!1,CanvasGradient:!1,CanvasPattern:!1,CanvasRenderingContext2D:!1,clearInterval:!1,clearTimeout:!1,close:!1,closed:!1,CustomEvent:!1,DOMParser:!1,defaultStatus:!1,document:!1,Element:!1,ElementTimeControl:!1,event:!1,FileReader:!1,FormData:!1,focus:!1,frames:!1,getComputedStyle:!1,HTMLElement:!1,HTMLAnchorElement:!1,HTMLBaseElement:!1,HTMLBlockquoteElement:!1,HTMLBodyElement:!1,HTMLBRElement:!1,HTMLButtonElement:!1,HTMLCanvasElement:!1,HTMLDirectoryElement:!1,HTMLDivElement:!1,HTMLDListElement:!1,HTMLFieldSetElement:!1,HTMLFontElement:!1,HTMLFormElement:!1,HTMLFrameElement:!1,HTMLFrameSetElement:!1,HTMLHeadElement:!1,HTMLHeadingElement:!1,HTMLHRElement:!1,HTMLHtmlElement:!1,HTMLIFrameElement:!1,HTMLImageElement:!1,HTMLInputElement:!1,HTMLIsIndexElement:!1,HTMLLabelElement:!1,HTMLLayerElement:!1,HTMLLegendElement:!1,HTMLLIElement:!1,HTMLLinkElement:!1,HTMLMapElement:!1,HTMLMenuElement:!1,HTMLMetaElement:!1,HTMLModElement:!1,HTMLObjectElement:!1,HTMLOListElement:!1,HTMLOptGroupElement:!1,HTMLOptionElement:!1,HTMLParagraphElement:!1,HTMLParamElement:!1,HTMLPreElement:!1,HTMLQuoteElement:!1,HTMLScriptElement:!1,HTMLSelectElement:!1,HTMLStyleElement:!1,HTMLTableCaptionElement:!1,HTMLTableCellElement:!1,HTMLTableColElement:!1,HTMLTableElement:!1,HTMLTableRowElement:!1,HTMLTableSectionElement:!1,HTMLTextAreaElement:!1,HTMLTitleElement:!1,HTMLUListElement:!1,HTMLVideoElement:!1,history:!1,Image:!1,length:!1,localStorage:!1,location:!1,matchMedia:!1,MessageChannel:!1,MessageEvent:!1,MessagePort:!1,MouseEvent:!1,moveBy:!1,moveTo:!1,MutationObserver:!1,name:!1,Node:!1,NodeFilter:!1,NodeList:!1,navigator:!1,onbeforeunload:!0,onblur:!0,onerror:!0,onfocus:!0,onload:!0,onresize:!0,onunload:!0,open:!1,openDatabase:!1,opener:!1,Option:!1,parent:!1,print:!1,removeEventListener:!1,resizeBy:!1,resizeTo:!1,screen:!1,scroll:!1,scrollBy:!1,scrollTo:!1,sessionStorage:!1,setInterval:!1,setTimeout:!1,SharedWorker:!1,status:!1,SVGAElement:!1,SVGAltGlyphDefElement:!1,SVGAltGlyphElement:!1,SVGAltGlyphItemElement:!1,SVGAngle:!1,SVGAnimateColorElement:!1,SVGAnimateElement:!1,SVGAnimateMotionElement:!1,SVGAnimateTransformElement:!1,SVGAnimatedAngle:!1,SVGAnimatedBoolean:!1,SVGAnimatedEnumeration:!1,SVGAnimatedInteger:!1,SVGAnimatedLength:!1,SVGAnimatedLengthList:!1,SVGAnimatedNumber:!1,SVGAnimatedNumberList:!1,SVGAnimatedPathData:!1,SVGAnimatedPoints:!1,SVGAnimatedPreserveAspectRatio:!1,SVGAnimatedRect:!1,SVGAnimatedString:!1,SVGAnimatedTransformList:!1,SVGAnimationElement:!1,SVGCSSRule:!1,SVGCircleElement:!1,SVGClipPathElement:!1,SVGColor:!1,SVGColorProfileElement:!1,SVGColorProfileRule:!1,SVGComponentTransferFunctionElement:!1,SVGCursorElement:!1,SVGDefsElement:!1,SVGDescElement:!1,SVGDocument:!1,SVGElement:!1,SVGElementInstance:!1,SVGElementInstanceList:!1,SVGEllipseElement:!1,SVGExternalResourcesRequired:!1,SVGFEBlendElement:!1,SVGFEColorMatrixElement:!1,SVGFEComponentTransferElement:!1,SVGFECompositeElement:!1,SVGFEConvolveMatrixElement:!1,SVGFEDiffuseLightingElement:!1,SVGFEDisplacementMapElement:!1,SVGFEDistantLightElement:!1,SVGFEFloodElement:!1,SVGFEFuncAElement:!1,SVGFEFuncBElement:!1,SVGFEFuncGElement:!1,SVGFEFuncRElement:!1,SVGFEGaussianBlurElement:!1,SVGFEImageElement:!1,SVGFEMergeElement:!1,SVGFEMergeNodeElement:!1,SVGFEMorphologyElement:!1,SVGFEOffsetElement:!1,SVGFEPointLightElement:!1,SVGFESpecularLightingElement:!1,SVGFESpotLightElement:!1,SVGFETileElement:!1,SVGFETurbulenceElement:!1,SVGFilterElement:!1,SVGFilterPrimitiveStandardAttributes:!1,SVGFitToViewBox:!1,SVGFontElement:!1,SVGFontFaceElement:!1,SVGFontFaceFormatElement:!1,SVGFontFaceNameElement:!1,SVGFontFaceSrcElement:!1,SVGFontFaceUriElement:!1,SVGForeignObjectElement:!1,SVGGElement:!1,SVGGlyphElement:!1,SVGGlyphRefElement:!1,SVGGradientElement:!1,SVGHKernElement:!1,SVGICCColor:!1,SVGImageElement:!1,SVGLangSpace:!1,SVGLength:!1,SVGLengthList:!1,SVGLineElement:!1,SVGLinearGradientElement:!1,SVGLocatable:!1,SVGMPathElement:!1,SVGMarkerElement:!1,SVGMaskElement:!1,SVGMatrix:!1,SVGMetadataElement:!1,SVGMissingGlyphElement:!1,SVGNumber:!1,SVGNumberList:!1,SVGPaint:!1,SVGPathElement:!1,SVGPathSeg:!1,SVGPathSegArcAbs:!1,SVGPathSegArcRel:!1,SVGPathSegClosePath:!1,SVGPathSegCurvetoCubicAbs:!1,SVGPathSegCurvetoCubicRel:!1,SVGPathSegCurvetoCubicSmoothAbs:!1,SVGPathSegCurvetoCubicSmoothRel:!1,SVGPathSegCurvetoQuadraticAbs:!1,SVGPathSegCurvetoQuadraticRel:!1,SVGPathSegCurvetoQuadraticSmoothAbs:!1,SVGPathSegCurvetoQuadraticSmoothRel:!1,SVGPathSegLinetoAbs:!1,SVGPathSegLinetoHorizontalAbs:!1,SVGPathSegLinetoHorizontalRel:!1,SVGPathSegLinetoRel:!1,SVGPathSegLinetoVerticalAbs:!1,SVGPathSegLinetoVerticalRel:!1,SVGPathSegList:!1,SVGPathSegMovetoAbs:!1,SVGPathSegMovetoRel:!1,SVGPatternElement:!1,SVGPoint:!1,SVGPointList:!1,SVGPolygonElement:!1,SVGPolylineElement:!1,SVGPreserveAspectRatio:!1,SVGRadialGradientElement:!1,SVGRect:!1,SVGRectElement:!1,SVGRenderingIntent:!1,SVGSVGElement:!1,SVGScriptElement:!1,SVGSetElement:!1,SVGStopElement:!1,SVGStringList:!1,SVGStylable:!1,SVGStyleElement:!1,SVGSwitchElement:!1,SVGSymbolElement:!1,SVGTRefElement:!1,SVGTSpanElement:!1,SVGTests:!1,SVGTextContentElement:!1,SVGTextElement:!1,SVGTextPathElement:!1,SVGTextPositioningElement:!1,SVGTitleElement:!1,SVGTransform:!1,SVGTransformList:!1,SVGTransformable:!1,SVGURIReference:!1,SVGUnitTypes:!1,SVGUseElement:!1,SVGVKernElement:!1,SVGViewElement:!1,SVGViewSpec:!1,SVGZoomAndPan:!1,TimeEvent:!1,top:!1,URL:!1,WebSocket:!1,window:!1,Worker:!1,XMLHttpRequest:!1,XMLSerializer:!1,XPathEvaluator:!1,XPathException:!1,XPathExpression:!1,XPathNamespace:!1,XPathNSResolver:!1,XPathResult:!1},n.devel={alert:!1,confirm:!1,console:!1,Debug:!1,opera:!1,prompt:!1},n.worker={importScripts:!0,postMessage:!0,self:!0},n.nonstandard={escape:!1,unescape:!1},n.couch={require:!1,respond:!1,getRow:!1,emit:!1,send:!1,start:!1,sum:!1,log:!1,exports:!1,module:!1,provides:!1},n.node={__filename:!1,__dirname:!1,GLOBAL:!1,global:!1,module:!1,require:!1,Buffer:!0,console:!0,exports:!0,process:!0,setTimeout:!0,clearTimeout:!0,setInterval:!0,clearInterval:!0,setImmediate:!0,clearImmediate:!0},n.phantom={phantom:!0,require:!0,WebPage:!0,console:!0,exports:!0},n.qunit={asyncTest:!1,deepEqual:!1,equal:!1,expect:!1,module:!1,notDeepEqual:!1,notEqual:!1,notPropEqual:!1,notStrictEqual:!1,ok:!1,propEqual:!1,QUnit:!1,raises:!1,start:!1,stop:!1,strictEqual:!1,test:!1,\"throws\":!1},n.rhino={defineClass:!1,deserialize:!1,gc:!1,help:!1,importClass:!1,importPackage:!1,java:!1,load:!1,loadClass:!1,Packages:!1,print:!1,quit:!1,readFile:!1,readUrl:!1,runCommand:!1,seal:!1,serialize:!1,spawn:!1,sync:!1,toint32:!1,version:!1},n.shelljs={target:!1,echo:!1,exit:!1,cd:!1,pwd:!1,ls:!1,find:!1,cp:!1,rm:!1,mv:!1,mkdir:!1,test:!1,cat:!1,sed:!1,grep:!1,which:!1,dirs:!1,pushd:!1,popd:!1,env:!1,exec:!1,chmod:!1,config:!1,error:!1,tempdir:!1},n.typed={ArrayBuffer:!1,ArrayBufferView:!1,DataView:!1,Float32Array:!1,Float64Array:!1,Int16Array:!1,Int32Array:!1,Int8Array:!1,Uint16Array:!1,Uint32Array:!1,Uint8Array:!1,Uint8ClampedArray:!1},n.wsh={ActiveXObject:!0,Enumerator:!0,GetObject:!0,ScriptEngine:!0,ScriptEngineBuildVersion:!0,ScriptEngineMajorVersion:!0,ScriptEngineMinorVersion:!0,VBArray:!0,WSH:!0,WScript:!0,XDomainRequest:!0},n.dojo={dojo:!1,dijit:!1,dojox:!1,define:!1,require:!1},n.jquery={$:!1,jQuery:!1},n.mootools={$:!1,$$:!1,Asset:!1,Browser:!1,Chain:!1,Class:!1,Color:!1,Cookie:!1,Core:!1,Document:!1,DomReady:!1,DOMEvent:!1,DOMReady:!1,Drag:!1,Element:!1,Elements:!1,Event:!1,Events:!1,Fx:!1,Group:!1,Hash:!1,HtmlTable:!1,IFrame:!1,IframeShim:!1,InputValidator:!1,instanceOf:!1,Keyboard:!1,Locale:!1,Mask:!1,MooTools:!1,Native:!1,Options:!1,OverText:!1,Request:!1,Scroller:!1,Slick:!1,Slider:!1,Sortables:!1,Spinner:!1,Swiff:!1,Tips:!1,Type:!1,typeOf:!1,URI:!1,Window:!1},n.prototypejs={$:!1,$$:!1,$A:!1,$F:!1,$H:!1,$R:!1,$break:!1,$continue:!1,$w:!1,Abstract:!1,Ajax:!1,Class:!1,Enumerable:!1,Element:!1,Event:!1,Field:!1,Form:!1,Hash:!1,Insertion:!1,ObjectRange:!1,PeriodicalExecuter:!1,Position:!1,Prototype:!1,Selector:!1,Template:!1,Toggle:!1,Try:!1,Autocompleter:!1,Builder:!1,Control:!1,Draggable:!1,Draggables:!1,Droppables:!1,Effect:!1,Sortable:!1,SortableObserver:!1,Sound:!1,Scriptaculous:!1},n.yui={YUI:!1,Y:!1,YUI_config:!1},n.mocha={describe:!1,it:!1,before:!1,after:!1,beforeEach:!1,afterEach:!1,suite:!1,test:!1,setup:!1,teardown:!1},n.jasmine={jasmine:!1,describe:!1,it:!1,xit:!1,beforeEach:!1,afterEach:!1,setFixtures:!1,loadFixtures:!1,spyOn:!1,expect:!1,runs:!1,waitsFor:!1,waits:!1}},{}],10:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||undefined}function i(e){return typeof e==\"function\"}function s(e){return typeof e==\"number\"}function o(e){return typeof e==\"object\"&&e!==null}function u(e){return e===void 0}t.exports=r,r.EventEmitter=r,r.prototype._events=undefined,r.prototype._maxListeners=undefined,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!s(e)||e<0||isNaN(e))throw TypeError(\"n must be a positive number\");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,s,a,f;this._events||(this._events={});if(e===\"error\")if(!this._events.error||o(this._events.error)&&!this._events.error.length)throw t=arguments[1],t instanceof Error?t:TypeError('Uncaught, unspecified \"error\" event.');n=this._events[e];if(u(n))return!1;if(i(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:r=arguments.length,s=new Array(r-1);for(a=1;a<r;a++)s[a-1]=arguments[a];n.apply(this,s)}else if(o(n)){r=arguments.length,s=new Array(r-1);for(a=1;a<r;a++)s[a-1]=arguments[a];f=n.slice(),r=f.length;for(a=0;a<r;a++)f[a].apply(this,s)}return!0},r.prototype.addListener=function(e,t){var n;if(!i(t))throw TypeError(\"listener must be a function\");this._events||(this._events={}),this._events.newListener&&this.emit(\"newListener\",e,i(t.listener)?t.listener:t),this._events[e]?o(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t;if(o(this._events[e])&&!this._events[e].warned){var n;u(this._maxListeners)?n=r.defaultMaxListeners:n=this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error(\"(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.\",this._events[e].length),console.trace())}return this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}if(!i(t))throw TypeError(\"listener must be a function\");var n=!1;return r.listener=t,this.on(e,r),this},r.prototype.removeListener=function(e,t){var n,r,s,u;if(!i(t))throw TypeError(\"listener must be a function\");if(!this._events||!this._events[e])return this;n=this._events[e],s=n.length,r=-1;if(n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit(\"removeListener\",e,t);else if(o(n)){for(u=s;u-->0;)if(n[u]===t||n[u].listener&&n[u].listener===t){r=u;break}if(r<0)return this;n.length===1?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit(\"removeListener\",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return arguments.length===0?this._events={}:this._events[e]&&delete this._events[e],this;if(arguments.length===0){for(t in this._events){if(t===\"removeListener\")continue;this.removeAllListeners(t)}return this.removeAllListeners(\"removeListener\"),this._events={},this}n=this._events[e];if(i(n))this.removeListener(e,n);else while(n.length)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return!this._events||!this._events[e]?t=[]:i(this._events[e])?t=[this._events[e]]:t=this._events[e].slice(),t},r.listenerCount=function(e,t){var n;return!e._events||!e._events[t]?n=0:i(e._events[t])?n=1:n=e._events[t].length,n}},{}]},{},[3])(3)}),ace.define(\"ace/mode/javascript_worker\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/worker/mirror\",\"ace/mode/javascript/jshint\"],function(require,exports,module){\"use strict\";function startRegex(e){return RegExp(\"^(\"+e.join(\"|\")+\")\")}var oop=require(\"../lib/oop\"),Mirror=require(\"../worker/mirror\").Mirror,lint=require(\"./javascript/jshint\").JSHINT,disabledWarningsRe=startRegex([\"Bad for in variable '(.+)'.\",'Missing \"use strict\"']),errorsRe=startRegex([\"Unexpected\",\"Expected \",\"Confusing (plus|minus)\",\"\\\\{a\\\\} unterminated regular expression\",\"Unclosed \",\"Unmatched \",\"Unbegun comment\",\"Bad invocation\",\"Missing space after\",\"Missing operator at\"]),infoRe=startRegex([\"Expected an assignment\",\"Bad escapement of EOL\",\"Unexpected comma\",\"Unexpected space\",\"Missing radix parameter.\",\"A leading decimal point can\",\"\\\\['{a}'\\\\] is better written in dot notation.\",\"'{a}' used out of scope\"]),JavaScriptWorker=exports.JavaScriptWorker=function(e){Mirror.call(this,e),this.setTimeout(500),this.setOptions()};oop.inherits(JavaScriptWorker,Mirror),function(){this.setOptions=function(e){this.options=e||{esnext:!0,moz:!0,devel:!0,browser:!0,node:!0,laxcomma:!0,laxbreak:!0,lastsemic:!0,onevar:!1,passfail:!1,maxerr:100,expr:!0,multistr:!0,globalstrict:!0},this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.changeOptions=function(e){oop.mixin(this.options,e),this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.isValidJS=function(str){try{eval(\"throw 0;\"+str)}catch(e){if(e===0)return!0}return!1},this.onUpdate=function(){var e=this.doc.getValue();e=e.replace(/^#!.*\\n/,\"\\n\");if(!e){this.sender.emit(\"jslint\",[]);return}var t=[],n=this.isValidJS(e)?\"warning\":\"error\";lint(e,this.options);var r=lint.errors,i=!1;for(var s=0;s<r.length;s++){var o=r[s];if(!o)continue;var u=o.raw,a=\"warning\";if(u==\"Missing semicolon.\"){var f=o.evidence.substr(o.character);f=f.charAt(f.search(/\\S/)),n==\"error\"&&f&&/[\\w\\d{(['\"]/.test(f)?(o.reason='Missing \";\" before statement',a=\"error\"):a=\"info\"}else{if(disabledWarningsRe.test(u))continue;infoRe.test(u)?a=\"info\":errorsRe.test(u)?(i=!0,a=n):u==\"'{a}' is not defined.\"?a=\"warning\":u==\"'{a}' is defined but never used.\"&&(a=\"info\")}t.push({row:o.line-1,column:o.character-1,text:o.reason,type:a,raw:u}),i}this.sender.emit(\"jslint\",t)}}.call(JavaScriptWorker.prototype)}),ace.define(\"ace/lib/es5-shim\",[\"require\",\"exports\",\"module\"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,\"sentinel\",{}),\"sentinel\"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t===\"undefined\"||t===\"boolean\"||t===\"number\"||t===\"string\"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n==\"function\"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r==\"function\"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!=\"function\")throw new TypeError(\"Function.prototype.bind called on incompatible \"+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,\"__defineGetter__\"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,\"XXX\"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)==\"[object Array]\"});var m=Object(\"a\"),g=m[0]!=\"a\"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!=\"[object Function]\")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0,s=arguments[1];if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0;if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");if(!i&&arguments.length==1)throw new TypeError(\"reduce of empty array with no initial value\");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError(\"reduce of empty array with no initial value\")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)==\"[object String]\"?this.split(\"\"):n,i=r.length>>>0;if(a(t)!=\"[object Function]\")throw new TypeError(t+\" is not a function\");if(!i&&arguments.length==1)throw new TypeError(\"reduceRight of empty array with no initial value\");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError(\"reduceRight of empty array with no initial value\")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)==\"[object String]\"?this.split(\"\"):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)==\"[object String]\"?this.split(\"\"):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y=\"Object.getOwnPropertyDescriptor called on a non-object: \";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!=\"object\"&&typeof t!=\"function\"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!=\"object\")throw new TypeError(\"typeof prototype[\"+typeof t+\"] != 'object'\");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document==\"undefined\"||w(document.createElement(\"div\"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T=\"Property description must be an object: \",N=\"Object.defineProperty called on non-object: \",C=\"getters & setters can not be defined on this javascript engine\";Object.defineProperty=function(t,n,r){if(typeof t!=\"object\"&&typeof t!=\"function\"||t===null)throw new TypeError(N+t);if(typeof r!=\"object\"&&typeof r!=\"function\"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,\"value\"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,\"get\")&&l(t,n,r.get),f(r,\"set\")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n==\"function\"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n=\"\";while(f(t,n))n+=\"?\";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=[\"toString\",\"toLocaleString\",\"valueOf\",\"hasOwnProperty\",\"isPrototypeOf\",\"propertyIsEnumerable\",\"constructor\"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!=\"object\"&&typeof e!=\"function\"||e===null)throw new TypeError(\"Object.keys called on a non-object\");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _=\" \\n\u000b\\f\\r \\u00a0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029\\ufeff\";if(!String.prototype.trim||_.trim()){_=\"[\"+_+\"]\";var D=new RegExp(\"^\"+_+_+\"*\"),P=new RegExp(_+_+\"*$\");String.prototype.trim=function(){return String(this).replace(D,\"\").replace(P,\"\")}}var F=function(e){if(e==null)throw new TypeError(\"can't convert \"+e+\" to object\");return Object(e)}})\n"
  },
  {
    "path": "docs/js/c3.esm.js",
    "content": "/* @license C3.js v0.7.18 | (c) C3 Team and other contributors | http://c3js.org/ */\nimport * as d3 from 'd3';\n\nfunction ChartInternal(api) {\n  var $$ = this;\n  // Note: This part will be replaced by rollup-plugin-modify\n  // When bundling esm output. Beware of changing this line.\n  // TODO: Maybe we should check that the modification by rollup-plugin-modify\n  // is valid during unit tests.\n  $$.d3 = window.d3\n    ? window.d3\n    : typeof require !== 'undefined'\n    ? require('d3')\n    : undefined;\n  $$.api = api;\n  $$.config = $$.getDefaultConfig();\n  $$.data = {};\n  $$.cache = {};\n  $$.axes = {};\n}\n\n/**\n * The Chart class\n *\n * The methods of this class is the public APIs of the chart object.\n */\nfunction Chart(config) {\n  this.internal = new ChartInternal(this);\n  this.internal.loadConfig(config);\n\n  this.internal.beforeInit(config);\n  this.internal.init();\n  this.internal.afterInit(config)\n\n  // bind \"this\" to nested API\n  ;(function bindThis(fn, target, argThis) {\n    Object.keys(fn).forEach(function(key) {\n      target[key] = fn[key].bind(argThis);\n      if (Object.keys(fn[key]).length > 0) {\n        bindThis(fn[key], target[key], argThis);\n      }\n    });\n  })(Chart.prototype, this, this);\n}\n\nvar asHalfPixel = function(n) {\n  return Math.ceil(n) + 0.5\n};\nvar ceil10 = function(v) {\n  return Math.ceil(v / 10) * 10\n};\nvar diffDomain = function(d) {\n  return d[1] - d[0]\n};\nvar getOption = function(options, key, defaultValue) {\n  return isDefined(options[key]) ? options[key] : defaultValue\n};\nvar getPathBox = function(path) {\n  var box = getBBox(path),\n    items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)],\n    minX = items[0].x,\n    minY = Math.min(items[0].y, items[1].y);\n  return { x: minX, y: minY, width: box.width, height: box.height }\n};\nvar getBBox = function(element) {\n  try {\n    return element.getBBox()\n  } catch (ignore) {\n    // Firefox will throw an exception if getBBox() is called whereas the\n    // element is rendered with display:none\n    // See https://github.com/c3js/c3/issues/2692\n\n    // The previous code was using `getBoundingClientRect` which was returning\n    // everything at 0 in this case so let's reproduce this behavior here.\n\n    return { x: 0, y: 0, width: 0, height: 0 }\n  }\n};\nvar hasValue = function(dict, value) {\n  var found = false;\n  Object.keys(dict).forEach(function(key) {\n    if (dict[key] === value) {\n      found = true;\n    }\n  });\n  return found\n};\nvar isArray = function(o) {\n  return Array.isArray(o)\n};\nvar isDefined = function(v) {\n  return typeof v !== 'undefined'\n};\nvar isEmpty = function(o) {\n  return (\n    typeof o === 'undefined' ||\n    o === null ||\n    (isString(o) && o.length === 0) ||\n    (typeof o === 'object' && Object.keys(o).length === 0)\n  )\n};\nvar isFunction = function(o) {\n  return typeof o === 'function'\n};\nvar isNumber = function(o) {\n  return typeof o === 'number'\n};\nvar isString = function(o) {\n  return typeof o === 'string'\n};\nvar isUndefined = function(v) {\n  return typeof v === 'undefined'\n};\nvar isValue = function(v) {\n  return v || v === 0\n};\nvar notEmpty = function(o) {\n  return !isEmpty(o)\n};\nvar sanitise = function(str) {\n  return typeof str === 'string'\n    ? str.replace(/</g, '&lt;').replace(/>/g, '&gt;')\n    : str\n};\nvar flattenArray = function(arr) {\n  return Array.isArray(arr) ? [].concat(...arr) : []\n};\n/**\n * Returns whether the point is within the given box.\n *\n * @param {Array} point An [x,y] coordinate\n * @param {Object} box An object with {x, y, width, height} keys\n * @param {Number} sensitivity An offset to ease check on very small boxes\n */\nvar isWithinBox = function(point, box, sensitivity = 0) {\n  const xStart = box.x - sensitivity;\n  const xEnd = box.x + box.width + sensitivity;\n  const yStart = box.y + box.height + sensitivity;\n  const yEnd = box.y - sensitivity;\n\n  return (\n    xStart < point[0] && point[0] < xEnd && yEnd < point[1] && point[1] < yStart\n  )\n};\n\n/**\n * Returns Internet Explorer version number (or false if no Internet Explorer used).\n *\n * @param string agent Optional parameter to specify user agent\n */\nvar getIEVersion = function(agent) {\n  // https://stackoverflow.com/questions/19999388/check-if-user-is-using-ie\n  if (typeof agent === 'undefined') {\n    agent = window.navigator.userAgent;\n  }\n\n  let pos = agent.indexOf('MSIE '); // up to IE10\n  if (pos > 0) {\n    return parseInt(agent.substring(pos + 5, agent.indexOf('.', pos)), 10)\n  }\n\n  pos = agent.indexOf('Trident/'); // IE11\n  if (pos > 0) {\n    pos = agent.indexOf('rv:');\n    return parseInt(agent.substring(pos + 3, agent.indexOf('.', pos)), 10)\n  }\n\n  return false\n};\n\n/**\n * Returns whether the used browser is Internet Explorer.\n *\n * @param {Number} version Optional parameter to specify IE version\n */\nvar isIE = function(version) {\n  const ver = getIEVersion();\n\n  if (typeof version === 'undefined') {\n    return !!ver\n  }\n\n  return version === ver\n};\n\nfunction AxisInternal(component, params) {\n  var internal = this;\n  internal.component = component;\n  internal.params = params || {};\n\n  internal.d3 = component.d3;\n  internal.scale = internal.d3.scaleLinear();\n  internal.range;\n  internal.orient = 'bottom';\n  internal.innerTickSize = 6;\n  internal.outerTickSize = this.params.withOuterTick ? 6 : 0;\n  internal.tickPadding = 3;\n  internal.tickValues = null;\n  internal.tickFormat;\n  internal.tickArguments;\n\n  internal.tickOffset = 0;\n  internal.tickCulling = true;\n  internal.tickCentered;\n  internal.tickTextCharSize;\n  internal.tickTextRotate = internal.params.tickTextRotate;\n  internal.tickLength;\n\n  internal.axis = internal.generateAxis();\n}\n\nAxisInternal.prototype.axisX = function(selection, x, tickOffset) {\n  selection.attr('transform', function(d) {\n    return 'translate(' + Math.ceil(x(d) + tickOffset) + ', 0)'\n  });\n};\nAxisInternal.prototype.axisY = function(selection, y) {\n  selection.attr('transform', function(d) {\n    return 'translate(0,' + Math.ceil(y(d)) + ')'\n  });\n};\nAxisInternal.prototype.scaleExtent = function(domain) {\n  var start = domain[0],\n    stop = domain[domain.length - 1];\n  return start < stop ? [start, stop] : [stop, start]\n};\nAxisInternal.prototype.generateTicks = function(scale) {\n  var internal = this;\n  var i,\n    domain,\n    ticks = [];\n  if (scale.ticks) {\n    return scale.ticks.apply(scale, internal.tickArguments)\n  }\n  domain = scale.domain();\n  for (i = Math.ceil(domain[0]); i < domain[1]; i++) {\n    ticks.push(i);\n  }\n  if (ticks.length > 0 && ticks[0] > 0) {\n    ticks.unshift(ticks[0] - (ticks[1] - ticks[0]));\n  }\n  return ticks\n};\nAxisInternal.prototype.copyScale = function() {\n  var internal = this;\n  var newScale = internal.scale.copy(),\n    domain;\n  if (internal.params.isCategory) {\n    domain = internal.scale.domain();\n    newScale.domain([domain[0], domain[1] - 1]);\n  }\n  return newScale\n};\nAxisInternal.prototype.textFormatted = function(v) {\n  var internal = this,\n    formatted = internal.tickFormat ? internal.tickFormat(v) : v;\n  return typeof formatted !== 'undefined' ? formatted : ''\n};\nAxisInternal.prototype.updateRange = function() {\n  var internal = this;\n  internal.range = internal.scale.rangeExtent\n    ? internal.scale.rangeExtent()\n    : internal.scaleExtent(internal.scale.range());\n  return internal.range\n};\nAxisInternal.prototype.updateTickTextCharSize = function(tick) {\n  var internal = this;\n  if (internal.tickTextCharSize) {\n    return internal.tickTextCharSize\n  }\n  var size = {\n    h: 11.5,\n    w: 5.5\n  };\n  tick\n    .select('text')\n    .text(function(d) {\n      return internal.textFormatted(d)\n    })\n    .each(function(d) {\n      var box = getBBox(this),\n        text = internal.textFormatted(d),\n        h = box.height,\n        w = text ? box.width / text.length : undefined;\n      if (h && w) {\n        size.h = h;\n        size.w = w;\n      }\n    })\n    .text('');\n  internal.tickTextCharSize = size;\n  return size\n};\nAxisInternal.prototype.isVertical = function() {\n  return this.orient === 'left' || this.orient === 'right'\n};\nAxisInternal.prototype.tspanData = function(d, i, scale) {\n  var internal = this;\n  var splitted = internal.params.tickMultiline\n    ? internal.splitTickText(d, scale)\n    : [].concat(internal.textFormatted(d));\n\n  if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) {\n    splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax);\n  }\n\n  return splitted.map(function(s) {\n    return { index: i, splitted: s, length: splitted.length }\n  })\n};\nAxisInternal.prototype.splitTickText = function(d, scale) {\n  var internal = this,\n    tickText = internal.textFormatted(d),\n    maxWidth = internal.params.tickWidth,\n    subtext,\n    spaceIndex,\n    textWidth,\n    splitted = [];\n\n  if (Object.prototype.toString.call(tickText) === '[object Array]') {\n    return tickText\n  }\n\n  if (!maxWidth || maxWidth <= 0) {\n    maxWidth = internal.isVertical()\n      ? 95\n      : internal.params.isCategory\n      ? Math.ceil(scale(1) - scale(0)) - 12\n      : 110;\n  }\n\n  function split(splitted, text) {\n    spaceIndex = undefined;\n    for (var i = 1; i < text.length; i++) {\n      if (text.charAt(i) === ' ') {\n        spaceIndex = i;\n      }\n      subtext = text.substr(0, i + 1);\n      textWidth = internal.tickTextCharSize.w * subtext.length;\n      // if text width gets over tick width, split by space index or crrent index\n      if (maxWidth < textWidth) {\n        return split(\n          splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)),\n          text.slice(spaceIndex ? spaceIndex + 1 : i)\n        )\n      }\n    }\n    return splitted.concat(text)\n  }\n\n  return split(splitted, tickText + '')\n};\nAxisInternal.prototype.ellipsify = function(splitted, max) {\n  if (splitted.length <= max) {\n    return splitted\n  }\n\n  var ellipsified = splitted.slice(0, max);\n  var remaining = 3;\n  for (var i = max - 1; i >= 0; i--) {\n    var available = ellipsified[i].length;\n\n    ellipsified[i] = ellipsified[i]\n      .substr(0, available - remaining)\n      .padEnd(available, '.');\n\n    remaining -= available;\n\n    if (remaining <= 0) {\n      break\n    }\n  }\n\n  return ellipsified\n};\nAxisInternal.prototype.updateTickLength = function() {\n  var internal = this;\n  internal.tickLength =\n    Math.max(internal.innerTickSize, 0) + internal.tickPadding;\n};\nAxisInternal.prototype.lineY2 = function(d) {\n  var internal = this,\n    tickPosition =\n      internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset);\n  return internal.range[0] < tickPosition && tickPosition < internal.range[1]\n    ? internal.innerTickSize\n    : 0\n};\nAxisInternal.prototype.textY = function() {\n  var internal = this,\n    rotate = internal.tickTextRotate;\n  return rotate\n    ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1)\n    : internal.tickLength\n};\nAxisInternal.prototype.textTransform = function() {\n  var internal = this,\n    rotate = internal.tickTextRotate;\n  return rotate ? 'rotate(' + rotate + ')' : ''\n};\nAxisInternal.prototype.textTextAnchor = function() {\n  var internal = this,\n    rotate = internal.tickTextRotate;\n  return rotate ? (rotate > 0 ? 'start' : 'end') : 'middle'\n};\nAxisInternal.prototype.tspanDx = function() {\n  var internal = this,\n    rotate = internal.tickTextRotate;\n  return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0\n};\nAxisInternal.prototype.tspanDy = function(d, i) {\n  var internal = this,\n    dy = internal.tickTextCharSize.h;\n  if (i === 0) {\n    if (internal.isVertical()) {\n      dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3);\n    } else {\n      dy = '.71em';\n    }\n  }\n  return dy\n};\n\nAxisInternal.prototype.generateAxis = function() {\n  var internal = this,\n    d3 = internal.d3,\n    params = internal.params;\n  function axis(g, transition) {\n    var self;\n    g.each(function() {\n      var g = (axis.g = d3.select(this));\n\n      var scale0 = this.__chart__ || internal.scale,\n        scale1 = (this.__chart__ = internal.copyScale());\n\n      var ticksValues = internal.tickValues\n          ? internal.tickValues\n          : internal.generateTicks(scale1),\n        ticks = g.selectAll('.tick').data(ticksValues, scale1),\n        tickEnter = ticks\n          .enter()\n          .insert('g', '.domain')\n          .attr('class', 'tick')\n          .style('opacity', 1e-6),\n        // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks.\n        tickExit = ticks.exit().remove(),\n        tickUpdate = ticks.merge(tickEnter),\n        tickTransform,\n        tickX,\n        tickY;\n\n      if (params.isCategory) {\n        internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);\n        tickX = internal.tickCentered ? 0 : internal.tickOffset;\n        tickY = internal.tickCentered ? internal.tickOffset : 0;\n      } else {\n        internal.tickOffset = tickX = 0;\n      }\n\n      internal.updateRange();\n      internal.updateTickLength();\n      internal.updateTickTextCharSize(g.select('.tick'));\n\n      var lineUpdate = tickUpdate\n          .select('line')\n          .merge(tickEnter.append('line')),\n        textUpdate = tickUpdate.select('text').merge(tickEnter.append('text'));\n\n      var tspans = tickUpdate\n          .selectAll('text')\n          .selectAll('tspan')\n          .data(function(d, i) {\n            return internal.tspanData(d, i, scale1)\n          }),\n        tspanEnter = tspans.enter().append('tspan'),\n        tspanUpdate = tspanEnter.merge(tspans).text(function(d) {\n          return d.splitted\n        });\n      tspans.exit().remove();\n\n      var path = g.selectAll('.domain').data([0]),\n        pathUpdate = path\n          .enter()\n          .append('path')\n          .merge(path)\n          .attr('class', 'domain');\n\n      // TODO: each attr should be one function and change its behavior by internal.orient, probably\n      switch (internal.orient) {\n        case 'bottom': {\n          tickTransform = internal.axisX;\n          lineUpdate\n            .attr('x1', tickX)\n            .attr('x2', tickX)\n            .attr('y2', function(d, i) {\n              return internal.lineY2(d, i)\n            });\n          textUpdate\n            .attr('x', 0)\n            .attr('y', function(d, i) {\n              return internal.textY(d, i)\n            })\n            .attr('transform', function(d, i) {\n              return internal.textTransform(d, i)\n            })\n            .style('text-anchor', function(d, i) {\n              return internal.textTextAnchor(d, i)\n            });\n          tspanUpdate\n            .attr('x', 0)\n            .attr('dy', function(d, i) {\n              return internal.tspanDy(d, i)\n            })\n            .attr('dx', function(d, i) {\n              return internal.tspanDx(d, i)\n            });\n          pathUpdate.attr(\n            'd',\n            'M' +\n              internal.range[0] +\n              ',' +\n              internal.outerTickSize +\n              'V0H' +\n              internal.range[1] +\n              'V' +\n              internal.outerTickSize\n          );\n          break\n        }\n        case 'top': {\n          // TODO: rotated tick text\n          tickTransform = internal.axisX;\n          lineUpdate\n            .attr('x1', tickX)\n            .attr('x2', tickX)\n            .attr('y2', function(d, i) {\n              return -1 * internal.lineY2(d, i)\n            });\n          textUpdate\n            .attr('x', 0)\n            .attr('y', function(d, i) {\n              return (\n                -1 * internal.textY(d, i) -\n                (params.isCategory ? 2 : internal.tickLength - 2)\n              )\n            })\n            .attr('transform', function(d, i) {\n              return internal.textTransform(d, i)\n            })\n            .style('text-anchor', function(d, i) {\n              return internal.textTextAnchor(d, i)\n            });\n          tspanUpdate\n            .attr('x', 0)\n            .attr('dy', function(d, i) {\n              return internal.tspanDy(d, i)\n            })\n            .attr('dx', function(d, i) {\n              return internal.tspanDx(d, i)\n            });\n          pathUpdate.attr(\n            'd',\n            'M' +\n              internal.range[0] +\n              ',' +\n              -internal.outerTickSize +\n              'V0H' +\n              internal.range[1] +\n              'V' +\n              -internal.outerTickSize\n          );\n          break\n        }\n        case 'left': {\n          tickTransform = internal.axisY;\n          lineUpdate\n            .attr('x2', -internal.innerTickSize)\n            .attr('y1', tickY)\n            .attr('y2', tickY);\n          textUpdate\n            .attr('x', -internal.tickLength)\n            .attr('y', internal.tickOffset)\n            .style('text-anchor', 'end');\n          tspanUpdate\n            .attr('x', -internal.tickLength)\n            .attr('dy', function(d, i) {\n              return internal.tspanDy(d, i)\n            });\n          pathUpdate.attr(\n            'd',\n            'M' +\n              -internal.outerTickSize +\n              ',' +\n              internal.range[0] +\n              'H0V' +\n              internal.range[1] +\n              'H' +\n              -internal.outerTickSize\n          );\n          break\n        }\n        case 'right': {\n          tickTransform = internal.axisY;\n          lineUpdate\n            .attr('x2', internal.innerTickSize)\n            .attr('y1', tickY)\n            .attr('y2', tickY);\n          textUpdate\n            .attr('x', internal.tickLength)\n            .attr('y', internal.tickOffset)\n            .style('text-anchor', 'start');\n          tspanUpdate.attr('x', internal.tickLength).attr('dy', function(d, i) {\n            return internal.tspanDy(d, i)\n          });\n          pathUpdate.attr(\n            'd',\n            'M' +\n              internal.outerTickSize +\n              ',' +\n              internal.range[0] +\n              'H0V' +\n              internal.range[1] +\n              'H' +\n              internal.outerTickSize\n          );\n          break\n        }\n      }\n      if (scale1.rangeBand) {\n        var x = scale1,\n          dx = x.rangeBand() / 2;\n        scale0 = scale1 = function(d) {\n          return x(d) + dx\n        };\n      } else if (scale0.rangeBand) {\n        scale0 = scale1;\n      } else {\n        tickExit.call(tickTransform, scale1, internal.tickOffset);\n      }\n      tickEnter.call(tickTransform, scale0, internal.tickOffset);\n      self = (transition ? tickUpdate.transition(transition) : tickUpdate)\n        .style('opacity', 1)\n        .call(tickTransform, scale1, internal.tickOffset);\n    });\n    return self\n  }\n  axis.scale = function(x) {\n    if (!arguments.length) {\n      return internal.scale\n    }\n    internal.scale = x;\n    return axis\n  };\n  axis.orient = function(x) {\n    if (!arguments.length) {\n      return internal.orient\n    }\n    internal.orient =\n      x in { top: 1, right: 1, bottom: 1, left: 1 } ? x + '' : 'bottom';\n    return axis\n  };\n  axis.tickFormat = function(format) {\n    if (!arguments.length) {\n      return internal.tickFormat\n    }\n    internal.tickFormat = format;\n    return axis\n  };\n  axis.tickCentered = function(isCentered) {\n    if (!arguments.length) {\n      return internal.tickCentered\n    }\n    internal.tickCentered = isCentered;\n    return axis\n  };\n  axis.tickOffset = function() {\n    return internal.tickOffset\n  };\n  axis.tickInterval = function() {\n    var interval, length;\n    if (params.isCategory) {\n      interval = internal.tickOffset * 2;\n    } else {\n      length =\n        axis.g\n          .select('path.domain')\n          .node()\n          .getTotalLength() -\n        internal.outerTickSize * 2;\n      interval = length / axis.g.selectAll('line').size();\n    }\n    return interval === Infinity ? 0 : interval\n  };\n  axis.ticks = function() {\n    if (!arguments.length) {\n      return internal.tickArguments\n    }\n    internal.tickArguments = arguments;\n    return axis\n  };\n  axis.tickCulling = function(culling) {\n    if (!arguments.length) {\n      return internal.tickCulling\n    }\n    internal.tickCulling = culling;\n    return axis\n  };\n  axis.tickValues = function(x) {\n    if (typeof x === 'function') {\n      internal.tickValues = function() {\n        return x(internal.scale.domain())\n      };\n    } else {\n      if (!arguments.length) {\n        return internal.tickValues\n      }\n      internal.tickValues = x;\n    }\n    return axis\n  };\n  return axis\n};\n\nvar CLASS = {\n  target: 'c3-target',\n  chart: 'c3-chart',\n  chartLine: 'c3-chart-line',\n  chartLines: 'c3-chart-lines',\n  chartBar: 'c3-chart-bar',\n  chartBars: 'c3-chart-bars',\n  chartText: 'c3-chart-text',\n  chartTexts: 'c3-chart-texts',\n  chartArc: 'c3-chart-arc',\n  chartArcs: 'c3-chart-arcs',\n  chartArcsTitle: 'c3-chart-arcs-title',\n  chartArcsBackground: 'c3-chart-arcs-background',\n  chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit',\n  chartArcsGaugeMax: 'c3-chart-arcs-gauge-max',\n  chartArcsGaugeMin: 'c3-chart-arcs-gauge-min',\n  selectedCircle: 'c3-selected-circle',\n  selectedCircles: 'c3-selected-circles',\n  eventRect: 'c3-event-rect',\n  eventRects: 'c3-event-rects',\n  eventRectsSingle: 'c3-event-rects-single',\n  eventRectsMultiple: 'c3-event-rects-multiple',\n  zoomRect: 'c3-zoom-rect',\n  brush: 'c3-brush',\n  dragZoom: 'c3-drag-zoom',\n  focused: 'c3-focused',\n  defocused: 'c3-defocused',\n  region: 'c3-region',\n  regions: 'c3-regions',\n  title: 'c3-title',\n  tooltipContainer: 'c3-tooltip-container',\n  tooltip: 'c3-tooltip',\n  tooltipName: 'c3-tooltip-name',\n  shape: 'c3-shape',\n  shapes: 'c3-shapes',\n  line: 'c3-line',\n  lines: 'c3-lines',\n  bar: 'c3-bar',\n  bars: 'c3-bars',\n  circle: 'c3-circle',\n  circles: 'c3-circles',\n  arc: 'c3-arc',\n  arcLabelLine: 'c3-arc-label-line',\n  arcs: 'c3-arcs',\n  area: 'c3-area',\n  areas: 'c3-areas',\n  empty: 'c3-empty',\n  text: 'c3-text',\n  texts: 'c3-texts',\n  gaugeValue: 'c3-gauge-value',\n  grid: 'c3-grid',\n  gridLines: 'c3-grid-lines',\n  xgrid: 'c3-xgrid',\n  xgrids: 'c3-xgrids',\n  xgridLine: 'c3-xgrid-line',\n  xgridLines: 'c3-xgrid-lines',\n  xgridFocus: 'c3-xgrid-focus',\n  ygrid: 'c3-ygrid',\n  ygrids: 'c3-ygrids',\n  ygridLine: 'c3-ygrid-line',\n  ygridLines: 'c3-ygrid-lines',\n  colorScale: 'c3-colorscale',\n  stanfordElements: 'c3-stanford-elements',\n  stanfordLine: 'c3-stanford-line',\n  stanfordLines: 'c3-stanford-lines',\n  stanfordRegion: 'c3-stanford-region',\n  stanfordRegions: 'c3-stanford-regions',\n  stanfordText: 'c3-stanford-text',\n  stanfordTexts: 'c3-stanford-texts',\n  axis: 'c3-axis',\n  axisX: 'c3-axis-x',\n  axisXLabel: 'c3-axis-x-label',\n  axisY: 'c3-axis-y',\n  axisYLabel: 'c3-axis-y-label',\n  axisY2: 'c3-axis-y2',\n  axisY2Label: 'c3-axis-y2-label',\n  legendBackground: 'c3-legend-background',\n  legendItem: 'c3-legend-item',\n  legendItemEvent: 'c3-legend-item-event',\n  legendItemTile: 'c3-legend-item-tile',\n  legendItemHidden: 'c3-legend-item-hidden',\n  legendItemFocused: 'c3-legend-item-focused',\n  dragarea: 'c3-dragarea',\n  EXPANDED: '_expanded_',\n  SELECTED: '_selected_',\n  INCLUDED: '_included_'\n};\n\nclass Axis {\n  constructor(owner) {\n    this.owner = owner;\n    this.d3 = owner.d3;\n    this.internal = AxisInternal;\n  }\n}\nAxis.prototype.init = function init() {\n  var $$ = this.owner,\n    config = $$.config,\n    main = $$.main;\n  $$.axes.x = main\n    .append('g')\n    .attr('class', CLASS.axis + ' ' + CLASS.axisX)\n    .attr('clip-path', config.axis_x_inner ? '' : $$.clipPathForXAxis)\n    .attr('transform', $$.getTranslate('x'))\n    .style('visibility', config.axis_x_show ? 'visible' : 'hidden');\n  $$.axes.x\n    .append('text')\n    .attr('class', CLASS.axisXLabel)\n    .attr('transform', config.axis_rotated ? 'rotate(-90)' : '')\n    .style('text-anchor', this.textAnchorForXAxisLabel.bind(this));\n  $$.axes.y = main\n    .append('g')\n    .attr('class', CLASS.axis + ' ' + CLASS.axisY)\n    .attr('clip-path', config.axis_y_inner ? '' : $$.clipPathForYAxis)\n    .attr('transform', $$.getTranslate('y'))\n    .style('visibility', config.axis_y_show ? 'visible' : 'hidden');\n  $$.axes.y\n    .append('text')\n    .attr('class', CLASS.axisYLabel)\n    .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\n    .style('text-anchor', this.textAnchorForYAxisLabel.bind(this));\n\n  $$.axes.y2 = main\n    .append('g')\n    .attr('class', CLASS.axis + ' ' + CLASS.axisY2)\n    // clip-path?\n    .attr('transform', $$.getTranslate('y2'))\n    .style('visibility', config.axis_y2_show ? 'visible' : 'hidden');\n  $$.axes.y2\n    .append('text')\n    .attr('class', CLASS.axisY2Label)\n    .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\n    .style('text-anchor', this.textAnchorForY2AxisLabel.bind(this));\n};\nAxis.prototype.getXAxis = function getXAxis(\n  scale,\n  orient,\n  tickFormat,\n  tickValues,\n  withOuterTick,\n  withoutTransition,\n  withoutRotateTickText\n) {\n  var $$ = this.owner,\n    config = $$.config,\n    axisParams = {\n      isCategory: $$.isCategorized(),\n      withOuterTick: withOuterTick,\n      tickMultiline: config.axis_x_tick_multiline,\n      tickMultilineMax: config.axis_x_tick_multiline\n        ? Number(config.axis_x_tick_multilineMax)\n        : 0,\n      tickWidth: config.axis_x_tick_width,\n      tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate,\n      withoutTransition: withoutTransition\n    },\n    axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient);\n\n  if ($$.isTimeSeries() && tickValues && typeof tickValues !== 'function') {\n    tickValues = tickValues.map(function(v) {\n      return $$.parseDate(v)\n    });\n  }\n\n  // Set tick\n  axis.tickFormat(tickFormat).tickValues(tickValues);\n  if ($$.isCategorized()) {\n    axis.tickCentered(config.axis_x_tick_centered);\n    if (isEmpty(config.axis_x_tick_culling)) {\n      config.axis_x_tick_culling = false;\n    }\n  }\n\n  return axis\n};\nAxis.prototype.updateXAxisTickValues = function updateXAxisTickValues(\n  targets,\n  axis\n) {\n  var $$ = this.owner,\n    config = $$.config,\n    tickValues;\n  if (config.axis_x_tick_fit || config.axis_x_tick_count) {\n    tickValues = this.generateTickValues(\n      $$.mapTargetsToUniqueXs(targets),\n      config.axis_x_tick_count,\n      $$.isTimeSeries()\n    );\n  }\n  if (axis) {\n    axis.tickValues(tickValues);\n  } else {\n    $$.xAxis.tickValues(tickValues);\n    $$.subXAxis.tickValues(tickValues);\n  }\n  return tickValues\n};\nAxis.prototype.getYAxis = function getYAxis(\n  axisId,\n  scale,\n  orient,\n  tickValues,\n  withOuterTick,\n  withoutTransition,\n  withoutRotateTickText\n) {\n  const $$ = this.owner;\n  const config = $$.config;\n\n  let tickFormat = config[`axis_${axisId}_tick_format`];\n  if (!tickFormat && $$.isAxisNormalized(axisId)) {\n    tickFormat = x => `${x}%`;\n  }\n\n  const axis = new this.internal(this, {\n    withOuterTick: withOuterTick,\n    withoutTransition: withoutTransition,\n    tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate\n  }).axis\n    .scale(scale)\n    .orient(orient);\n\n  if (tickFormat) {\n    axis.tickFormat(tickFormat);\n  }\n\n  if ($$.isTimeSeriesY()) {\n    axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval);\n  } else {\n    axis.tickValues(tickValues);\n  }\n  return axis\n};\nAxis.prototype.getId = function getId(id) {\n  var config = this.owner.config;\n  return id in config.data_axes ? config.data_axes[id] : 'y'\n};\nAxis.prototype.getXAxisTickFormat = function getXAxisTickFormat() {\n  // #2251 previously set any negative values to a whole number,\n  // however both should be truncated according to the users format specification\n  var $$ = this.owner,\n    config = $$.config;\n  let format = $$.isTimeSeries()\n    ? $$.defaultAxisTimeFormat\n    : $$.isCategorized()\n    ? $$.categoryName\n    : function(v) {\n        return v\n      };\n\n  if (config.axis_x_tick_format) {\n    if (isFunction(config.axis_x_tick_format)) {\n      format = config.axis_x_tick_format;\n    } else if ($$.isTimeSeries()) {\n      format = function(date) {\n        return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : ''\n      };\n    }\n  }\n  return isFunction(format)\n    ? function(v) {\n        return format.call($$, v)\n      }\n    : format\n};\nAxis.prototype.getTickValues = function getTickValues(tickValues, axis) {\n  return tickValues ? tickValues : axis ? axis.tickValues() : undefined\n};\nAxis.prototype.getXAxisTickValues = function getXAxisTickValues() {\n  return this.getTickValues(\n    this.owner.config.axis_x_tick_values,\n    this.owner.xAxis\n  )\n};\nAxis.prototype.getYAxisTickValues = function getYAxisTickValues() {\n  return this.getTickValues(\n    this.owner.config.axis_y_tick_values,\n    this.owner.yAxis\n  )\n};\nAxis.prototype.getY2AxisTickValues = function getY2AxisTickValues() {\n  return this.getTickValues(\n    this.owner.config.axis_y2_tick_values,\n    this.owner.y2Axis\n  )\n};\nAxis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(\n  axisId\n) {\n  var $$ = this.owner,\n    config = $$.config,\n    option;\n  if (axisId === 'y') {\n    option = config.axis_y_label;\n  } else if (axisId === 'y2') {\n    option = config.axis_y2_label;\n  } else if (axisId === 'x') {\n    option = config.axis_x_label;\n  }\n  return option\n};\nAxis.prototype.getLabelText = function getLabelText(axisId) {\n  var option = this.getLabelOptionByAxisId(axisId);\n  return isString(option) ? option : option ? option.text : null\n};\nAxis.prototype.setLabelText = function setLabelText(axisId, text) {\n  var $$ = this.owner,\n    config = $$.config,\n    option = this.getLabelOptionByAxisId(axisId);\n  if (isString(option)) {\n    if (axisId === 'y') {\n      config.axis_y_label = text;\n    } else if (axisId === 'y2') {\n      config.axis_y2_label = text;\n    } else if (axisId === 'x') {\n      config.axis_x_label = text;\n    }\n  } else if (option) {\n    option.text = text;\n  }\n};\nAxis.prototype.getLabelPosition = function getLabelPosition(\n  axisId,\n  defaultPosition\n) {\n  var option = this.getLabelOptionByAxisId(axisId),\n    position =\n      option && typeof option === 'object' && option.position\n        ? option.position\n        : defaultPosition;\n  return {\n    isInner: position.indexOf('inner') >= 0,\n    isOuter: position.indexOf('outer') >= 0,\n    isLeft: position.indexOf('left') >= 0,\n    isCenter: position.indexOf('center') >= 0,\n    isRight: position.indexOf('right') >= 0,\n    isTop: position.indexOf('top') >= 0,\n    isMiddle: position.indexOf('middle') >= 0,\n    isBottom: position.indexOf('bottom') >= 0\n  }\n};\nAxis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() {\n  return this.getLabelPosition(\n    'x',\n    this.owner.config.axis_rotated ? 'inner-top' : 'inner-right'\n  )\n};\nAxis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() {\n  return this.getLabelPosition(\n    'y',\n    this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'\n  )\n};\nAxis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() {\n  return this.getLabelPosition(\n    'y2',\n    this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'\n  )\n};\nAxis.prototype.getLabelPositionById = function getLabelPositionById(id) {\n  return id === 'y2'\n    ? this.getY2AxisLabelPosition()\n    : id === 'y'\n    ? this.getYAxisLabelPosition()\n    : this.getXAxisLabelPosition()\n};\nAxis.prototype.textForXAxisLabel = function textForXAxisLabel() {\n  return this.getLabelText('x')\n};\nAxis.prototype.textForYAxisLabel = function textForYAxisLabel() {\n  return this.getLabelText('y')\n};\nAxis.prototype.textForY2AxisLabel = function textForY2AxisLabel() {\n  return this.getLabelText('y2')\n};\nAxis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) {\n  var $$ = this.owner;\n  if (forHorizontal) {\n    return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width\n  } else {\n    return position.isBottom\n      ? -$$.height\n      : position.isMiddle\n      ? -$$.height / 2\n      : 0\n  }\n};\nAxis.prototype.dxForAxisLabel = function dxForAxisLabel(\n  forHorizontal,\n  position\n) {\n  if (forHorizontal) {\n    return position.isLeft ? '0.5em' : position.isRight ? '-0.5em' : '0'\n  } else {\n    return position.isTop ? '-0.5em' : position.isBottom ? '0.5em' : '0'\n  }\n};\nAxis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(\n  forHorizontal,\n  position\n) {\n  if (forHorizontal) {\n    return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end'\n  } else {\n    return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end'\n  }\n};\nAxis.prototype.xForXAxisLabel = function xForXAxisLabel() {\n  return this.xForAxisLabel(\n    !this.owner.config.axis_rotated,\n    this.getXAxisLabelPosition()\n  )\n};\nAxis.prototype.xForYAxisLabel = function xForYAxisLabel() {\n  return this.xForAxisLabel(\n    this.owner.config.axis_rotated,\n    this.getYAxisLabelPosition()\n  )\n};\nAxis.prototype.xForY2AxisLabel = function xForY2AxisLabel() {\n  return this.xForAxisLabel(\n    this.owner.config.axis_rotated,\n    this.getY2AxisLabelPosition()\n  )\n};\nAxis.prototype.dxForXAxisLabel = function dxForXAxisLabel() {\n  return this.dxForAxisLabel(\n    !this.owner.config.axis_rotated,\n    this.getXAxisLabelPosition()\n  )\n};\nAxis.prototype.dxForYAxisLabel = function dxForYAxisLabel() {\n  return this.dxForAxisLabel(\n    this.owner.config.axis_rotated,\n    this.getYAxisLabelPosition()\n  )\n};\nAxis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() {\n  return this.dxForAxisLabel(\n    this.owner.config.axis_rotated,\n    this.getY2AxisLabelPosition()\n  )\n};\nAxis.prototype.dyForXAxisLabel = function dyForXAxisLabel() {\n  var $$ = this.owner,\n    config = $$.config,\n    position = this.getXAxisLabelPosition();\n  if (config.axis_rotated) {\n    return position.isInner\n      ? '1.2em'\n      : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x'))\n  } else {\n    return position.isInner ? '-0.5em' : $$.getHorizontalAxisHeight('x') - 10\n  }\n};\nAxis.prototype.dyForYAxisLabel = function dyForYAxisLabel() {\n  var $$ = this.owner,\n    position = this.getYAxisLabelPosition();\n  if ($$.config.axis_rotated) {\n    return position.isInner ? '-0.5em' : '3em'\n  } else {\n    return position.isInner\n      ? '1.2em'\n      : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10)\n  }\n};\nAxis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() {\n  var $$ = this.owner,\n    position = this.getY2AxisLabelPosition();\n  if ($$.config.axis_rotated) {\n    return position.isInner ? '1.2em' : '-2.2em'\n  } else {\n    return position.isInner\n      ? '-0.5em'\n      : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15)\n  }\n};\nAxis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() {\n  var $$ = this.owner;\n  return this.textAnchorForAxisLabel(\n    !$$.config.axis_rotated,\n    this.getXAxisLabelPosition()\n  )\n};\nAxis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() {\n  var $$ = this.owner;\n  return this.textAnchorForAxisLabel(\n    $$.config.axis_rotated,\n    this.getYAxisLabelPosition()\n  )\n};\nAxis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() {\n  var $$ = this.owner;\n  return this.textAnchorForAxisLabel(\n    $$.config.axis_rotated,\n    this.getY2AxisLabelPosition()\n  )\n};\nAxis.prototype.getMaxTickWidth = function getMaxTickWidth(\n  id,\n  withoutRecompute\n) {\n  var $$ = this.owner,\n    maxWidth = 0,\n    targetsToShow,\n    scale,\n    axis,\n    dummy,\n    svg;\n  if (withoutRecompute && $$.currentMaxTickWidths[id]) {\n    return $$.currentMaxTickWidths[id]\n  }\n  if ($$.svg) {\n    targetsToShow = $$.filterTargetsToShow($$.data.targets);\n    if (id === 'y') {\n      scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));\n      axis = this.getYAxis(\n        id,\n        scale,\n        $$.yOrient,\n        $$.yAxisTickValues,\n        false,\n        true,\n        true\n      );\n    } else if (id === 'y2') {\n      scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));\n      axis = this.getYAxis(\n        id,\n        scale,\n        $$.y2Orient,\n        $$.y2AxisTickValues,\n        false,\n        true,\n        true\n      );\n    } else {\n      scale = $$.x.copy().domain($$.getXDomain(targetsToShow));\n      axis = this.getXAxis(\n        scale,\n        $$.xOrient,\n        $$.xAxisTickFormat,\n        $$.xAxisTickValues,\n        false,\n        true,\n        true\n      );\n      this.updateXAxisTickValues(targetsToShow, axis);\n    }\n    dummy = $$.d3\n      .select('body')\n      .append('div')\n      .classed('c3', true)\n    ;(svg = dummy\n      .append('svg')\n      .style('visibility', 'hidden')\n      .style('position', 'fixed')\n      .style('top', 0)\n      .style('left', 0)),\n      svg\n        .append('g')\n        .call(axis)\n        .each(function() {\n          $$.d3\n            .select(this)\n            .selectAll('text')\n            .each(function() {\n              var box = getBBox(this);\n              if (maxWidth < box.width) {\n                maxWidth = box.width;\n              }\n            });\n          dummy.remove();\n        });\n  }\n  $$.currentMaxTickWidths[id] =\n    maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth;\n  return $$.currentMaxTickWidths[id]\n};\n\nAxis.prototype.updateLabels = function updateLabels(withTransition) {\n  var $$ = this.owner;\n  var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel),\n    axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel),\n    axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label)\n  ;(withTransition ? axisXLabel.transition() : axisXLabel)\n    .attr('x', this.xForXAxisLabel.bind(this))\n    .attr('dx', this.dxForXAxisLabel.bind(this))\n    .attr('dy', this.dyForXAxisLabel.bind(this))\n    .text(this.textForXAxisLabel.bind(this))\n  ;(withTransition ? axisYLabel.transition() : axisYLabel)\n    .attr('x', this.xForYAxisLabel.bind(this))\n    .attr('dx', this.dxForYAxisLabel.bind(this))\n    .attr('dy', this.dyForYAxisLabel.bind(this))\n    .text(this.textForYAxisLabel.bind(this))\n  ;(withTransition ? axisY2Label.transition() : axisY2Label)\n    .attr('x', this.xForY2AxisLabel.bind(this))\n    .attr('dx', this.dxForY2AxisLabel.bind(this))\n    .attr('dy', this.dyForY2AxisLabel.bind(this))\n    .text(this.textForY2AxisLabel.bind(this));\n};\nAxis.prototype.getPadding = function getPadding(\n  padding,\n  key,\n  defaultValue,\n  domainLength\n) {\n  var p = typeof padding === 'number' ? padding : padding[key];\n  if (!isValue(p)) {\n    return defaultValue\n  }\n  if (padding.unit === 'ratio') {\n    return padding[key] * domainLength\n  }\n  // assume padding is pixels if unit is not specified\n  return this.convertPixelsToAxisPadding(p, domainLength)\n};\nAxis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(\n  pixels,\n  domainLength\n) {\n  var $$ = this.owner,\n    length = $$.config.axis_rotated ? $$.width : $$.height;\n  return domainLength * (pixels / length)\n};\nAxis.prototype.generateTickValues = function generateTickValues(\n  values,\n  tickCount,\n  forTimeSeries\n) {\n  var tickValues = values,\n    targetCount,\n    start,\n    end,\n    count,\n    interval,\n    i,\n    tickValue;\n  if (tickCount) {\n    targetCount = isFunction(tickCount) ? tickCount() : tickCount;\n    // compute ticks according to tickCount\n    if (targetCount === 1) {\n      tickValues = [values[0]];\n    } else if (targetCount === 2) {\n      tickValues = [values[0], values[values.length - 1]];\n    } else if (targetCount > 2) {\n      count = targetCount - 2;\n      start = values[0];\n      end = values[values.length - 1];\n      interval = (end - start) / (count + 1);\n      // re-construct unique values\n      tickValues = [start];\n      for (i = 0; i < count; i++) {\n        tickValue = +start + interval * (i + 1);\n        tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue);\n      }\n      tickValues.push(end);\n    }\n  }\n  if (!forTimeSeries) {\n    tickValues = tickValues.sort(function(a, b) {\n      return a - b\n    });\n  }\n  return tickValues\n};\nAxis.prototype.generateTransitions = function generateTransitions(duration) {\n  var $$ = this.owner,\n    axes = $$.axes;\n  return {\n    axisX: duration ? axes.x.transition().duration(duration) : axes.x,\n    axisY: duration ? axes.y.transition().duration(duration) : axes.y,\n    axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2,\n    axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx\n  }\n};\nAxis.prototype.redraw = function redraw(duration, isHidden) {\n  var $$ = this.owner,\n    transition = duration ? $$.d3.transition().duration(duration) : null;\n  $$.axes.x.style('opacity', isHidden ? 0 : 1).call($$.xAxis, transition);\n  $$.axes.y.style('opacity', isHidden ? 0 : 1).call($$.yAxis, transition);\n  $$.axes.y2.style('opacity', isHidden ? 0 : 1).call($$.y2Axis, transition);\n  $$.axes.subx.style('opacity', isHidden ? 0 : 1).call($$.subXAxis, transition);\n};\n\nvar c3 = {\n  version: '0.7.18',\n  chart: {\n    fn: Chart.prototype,\n    internal: {\n      fn: ChartInternal.prototype,\n      axis: {\n        fn: Axis.prototype,\n        internal: {\n          fn: AxisInternal.prototype\n        }\n      }\n    }\n  },\n  generate: function(config) {\n    return new Chart(config)\n  }\n};\n\nChartInternal.prototype.beforeInit = function() {\n  // can do something\n};\nChartInternal.prototype.afterInit = function() {\n  // can do something\n};\nChartInternal.prototype.init = function() {\n  var $$ = this,\n    config = $$.config;\n\n  $$.initParams();\n\n  if (config.data_url) {\n    $$.convertUrlToData(\n      config.data_url,\n      config.data_mimeType,\n      config.data_headers,\n      config.data_keys,\n      $$.initWithData\n    );\n  } else if (config.data_json) {\n    $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));\n  } else if (config.data_rows) {\n    $$.initWithData($$.convertRowsToData(config.data_rows));\n  } else if (config.data_columns) {\n    $$.initWithData($$.convertColumnsToData(config.data_columns));\n  } else {\n    throw Error('url or json or rows or columns is required.')\n  }\n};\n\nChartInternal.prototype.initParams = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config;\n\n  // MEMO: clipId needs to be unique because it conflicts when multiple charts exist\n  $$.clipId = 'c3-' + new Date().valueOf() + '-clip';\n  $$.clipIdForXAxis = $$.clipId + '-xaxis';\n  $$.clipIdForYAxis = $$.clipId + '-yaxis';\n  $$.clipIdForGrid = $$.clipId + '-grid';\n  $$.clipIdForSubchart = $$.clipId + '-subchart';\n  $$.clipPath = $$.getClipPath($$.clipId);\n  $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis);\n  $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis);\n  $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid);\n  $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart);\n\n  $$.dragStart = null;\n  $$.dragging = false;\n  $$.flowing = false;\n  $$.cancelClick = false;\n  $$.mouseover = undefined;\n  $$.transiting = false;\n\n  $$.color = $$.generateColor();\n  $$.levelColor = $$.generateLevelColor();\n\n  $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)(\n    $$.config.data_xFormat\n  );\n  $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat;\n  $$.defaultAxisTimeFormat = function(date) {\n    if (date.getMilliseconds()) {\n      return d3.timeFormat('.%L')(date)\n    }\n    if (date.getSeconds()) {\n      return d3.timeFormat(':%S')(date)\n    }\n    if (date.getMinutes()) {\n      return d3.timeFormat('%I:%M')(date)\n    }\n    if (date.getHours()) {\n      return d3.timeFormat('%I %p')(date)\n    }\n    if (date.getDay() && date.getDate() !== 1) {\n      return d3.timeFormat('%-m/%-d')(date)\n    }\n    if (date.getDate() !== 1) {\n      return d3.timeFormat('%-m/%-d')(date)\n    }\n    if (date.getMonth()) {\n      return d3.timeFormat('%-m/%-d')(date)\n    }\n    return d3.timeFormat('%Y/%-m/%-d')(date)\n  };\n  $$.hiddenTargetIds = [];\n  $$.hiddenLegendIds = [];\n  $$.focusedTargetIds = [];\n  $$.defocusedTargetIds = [];\n\n  $$.xOrient = config.axis_rotated\n    ? config.axis_x_inner\n      ? 'right'\n      : 'left'\n    : config.axis_x_inner\n    ? 'top'\n    : 'bottom';\n  $$.yOrient = config.axis_rotated\n    ? config.axis_y_inner\n      ? 'top'\n      : 'bottom'\n    : config.axis_y_inner\n    ? 'right'\n    : 'left';\n  $$.y2Orient = config.axis_rotated\n    ? config.axis_y2_inner\n      ? 'bottom'\n      : 'top'\n    : config.axis_y2_inner\n    ? 'left'\n    : 'right';\n  $$.subXOrient = config.axis_rotated ? 'left' : 'bottom';\n\n  $$.isLegendRight = config.legend_position === 'right';\n  $$.isLegendInset = config.legend_position === 'inset';\n  $$.isLegendTop =\n    config.legend_inset_anchor === 'top-left' ||\n    config.legend_inset_anchor === 'top-right';\n  $$.isLegendLeft =\n    config.legend_inset_anchor === 'top-left' ||\n    config.legend_inset_anchor === 'bottom-left';\n  $$.legendStep = 0;\n  $$.legendItemWidth = 0;\n  $$.legendItemHeight = 0;\n\n  $$.currentMaxTickWidths = {\n    x: 0,\n    y: 0,\n    y2: 0\n  };\n\n  $$.rotated_padding_left = 30;\n  $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30;\n  $$.rotated_padding_top = 5;\n\n  $$.withoutFadeIn = {};\n\n  $$.intervalForObserveInserted = undefined;\n\n  $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js\n};\n\nChartInternal.prototype.initChartElements = function() {\n  if (this.initBar) {\n    this.initBar();\n  }\n  if (this.initLine) {\n    this.initLine();\n  }\n  if (this.initArc) {\n    this.initArc();\n  }\n  if (this.initGauge) {\n    this.initGauge();\n  }\n  if (this.initText) {\n    this.initText();\n  }\n};\n\nChartInternal.prototype.initWithData = function(data) {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config;\n  var defs,\n    main,\n    binding = true;\n\n  $$.axis = new Axis($$);\n\n  if (!config.bindto) {\n    $$.selectChart = d3.selectAll([]);\n  } else if (typeof config.bindto.node === 'function') {\n    $$.selectChart = config.bindto;\n  } else {\n    $$.selectChart = d3.select(config.bindto);\n  }\n  if ($$.selectChart.empty()) {\n    $$.selectChart = d3\n      .select(document.createElement('div'))\n      .style('opacity', 0);\n    $$.observeInserted($$.selectChart);\n    binding = false;\n  }\n  $$.selectChart.html('').classed('c3', true);\n\n  // Init data as targets\n  $$.data.xs = {};\n  $$.data.targets = $$.convertDataToTargets(data);\n\n  if (config.data_filter) {\n    $$.data.targets = $$.data.targets.filter(config.data_filter);\n  }\n\n  // Set targets to hide if needed\n  if (config.data_hide) {\n    $$.addHiddenTargetIds(\n      config.data_hide === true\n        ? $$.mapToIds($$.data.targets)\n        : config.data_hide\n    );\n  }\n  if (config.legend_hide) {\n    $$.addHiddenLegendIds(\n      config.legend_hide === true\n        ? $$.mapToIds($$.data.targets)\n        : config.legend_hide\n    );\n  }\n\n  if ($$.isStanfordGraphType()) {\n    $$.initStanfordData();\n  }\n\n  // Init sizes and scales\n  $$.updateSizes();\n  $$.updateScales();\n\n  // Set domains for each scale\n  $$.x.domain(d3.extent($$.getXDomain($$.data.targets)));\n  $$.y.domain($$.getYDomain($$.data.targets, 'y'));\n  $$.y2.domain($$.getYDomain($$.data.targets, 'y2'));\n  $$.subX.domain($$.x.domain());\n  $$.subY.domain($$.y.domain());\n  $$.subY2.domain($$.y2.domain());\n\n  // Save original x domain for zoom update\n  $$.orgXDomain = $$.x.domain();\n\n  /*-- Basic Elements --*/\n\n  // Define svgs\n  $$.svg = $$.selectChart\n    .append('svg')\n    .style('overflow', 'hidden')\n    .on('mouseenter', function() {\n      return config.onmouseover.call($$)\n    })\n    .on('mouseleave', function() {\n      return config.onmouseout.call($$)\n    });\n\n  if ($$.config.svg_classname) {\n    $$.svg.attr('class', $$.config.svg_classname);\n  }\n\n  // Define defs\n  defs = $$.svg.append('defs');\n  $$.clipChart = $$.appendClip(defs, $$.clipId);\n  $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis);\n  $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis);\n  $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid);\n  $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart);\n  $$.updateSvgSize();\n\n  // Define regions\n  main = $$.main = $$.svg.append('g').attr('transform', $$.getTranslate('main'));\n\n  if ($$.initPie) {\n    $$.initPie();\n  }\n  if ($$.initDragZoom) {\n    $$.initDragZoom();\n  }\n  if (config.subchart_show && $$.initSubchart) {\n    $$.initSubchart();\n  }\n  if ($$.initTooltip) {\n    $$.initTooltip();\n  }\n  if ($$.initLegend) {\n    $$.initLegend();\n  }\n  if ($$.initTitle) {\n    $$.initTitle();\n  }\n  if ($$.initZoom) {\n    $$.initZoom();\n  }\n  if ($$.isStanfordGraphType()) {\n    $$.drawColorScale();\n  }\n\n  // Update selection based on size and scale\n  // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart.\n  if (config.subchart_show && $$.initSubchartBrush) {\n    $$.initSubchartBrush();\n  }\n\n  /*-- Main Region --*/\n\n  // text when empty\n  main\n    .append('text')\n    .attr('class', CLASS.text + ' ' + CLASS.empty)\n    .attr('text-anchor', 'middle') // horizontal centering of text at x position in all browsers.\n    .attr('dominant-baseline', 'middle'); // vertical centering of text at y position in all browsers, except IE.\n\n  // Regions\n  $$.initRegion();\n\n  // Grids\n  $$.initGrid();\n\n  // Define g for chart area\n  main\n    .append('g')\n    .attr('clip-path', $$.clipPath)\n    .attr('class', CLASS.chart);\n\n  // Grid lines\n  if (config.grid_lines_front) {\n    $$.initGridLines();\n  }\n\n  $$.initStanfordElements();\n\n  // Cover whole with rects for events\n  $$.initEventRect();\n\n  // Define g for chart\n  $$.initChartElements();\n\n  // Add Axis\n  $$.axis.init();\n\n  // Set targets\n  $$.updateTargets($$.data.targets);\n\n  // Set default extent if defined\n  if (config.axis_x_selection) {\n    $$.brush.selectionAsValue($$.getDefaultSelection());\n  }\n\n  // Draw with targets\n  if (binding) {\n    $$.updateDimension();\n    $$.config.oninit.call($$);\n    $$.redraw({\n      withTransition: false,\n      withTransform: true,\n      withUpdateXDomain: true,\n      withUpdateOrgXDomain: true,\n      withTransitionForAxis: false\n    });\n  }\n\n  // Bind to resize event\n  $$.bindResize();\n\n  // Bind to window focus event\n  $$.bindWindowFocus();\n\n  // export element of the chart\n  $$.api.element = $$.selectChart.node();\n};\n\nChartInternal.prototype.smoothLines = function(el, type) {\n  var $$ = this;\n  if (type === 'grid') {\n    el.each(function() {\n      var g = $$.d3.select(this),\n        x1 = g.attr('x1'),\n        x2 = g.attr('x2'),\n        y1 = g.attr('y1'),\n        y2 = g.attr('y2');\n      g.attr({\n        x1: Math.ceil(x1),\n        x2: Math.ceil(x2),\n        y1: Math.ceil(y1),\n        y2: Math.ceil(y2)\n      });\n    });\n  }\n};\n\nChartInternal.prototype.updateSizes = function() {\n  var $$ = this,\n    config = $$.config;\n  var legendHeight = $$.legend ? $$.getLegendHeight() : 0,\n    legendWidth = $$.legend ? $$.getLegendWidth() : 0,\n    legendHeightForBottom =\n      $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight,\n    hasArc = $$.hasArcType(),\n    xAxisHeight =\n      config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'),\n    subchartHeight =\n      config.subchart_show && !hasArc\n        ? config.subchart_size_height + xAxisHeight\n        : 0;\n\n  $$.currentWidth = $$.getCurrentWidth();\n  $$.currentHeight = $$.getCurrentHeight();\n\n  // for main\n  $$.margin = config.axis_rotated\n    ? {\n        top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(),\n        right: hasArc ? 0 : $$.getCurrentPaddingRight(),\n        bottom:\n          $$.getHorizontalAxisHeight('y') +\n          legendHeightForBottom +\n          $$.getCurrentPaddingBottom(),\n        left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft())\n      }\n    : {\n        top: 4 + $$.getCurrentPaddingTop(), // for top tick text\n        right: hasArc ? 0 : $$.getCurrentPaddingRight(),\n        bottom:\n          xAxisHeight +\n          subchartHeight +\n          legendHeightForBottom +\n          $$.getCurrentPaddingBottom(),\n        left: hasArc ? 0 : $$.getCurrentPaddingLeft()\n      };\n\n  // for subchart\n  $$.margin2 = config.axis_rotated\n    ? {\n        top: $$.margin.top,\n        right: NaN,\n        bottom: 20 + legendHeightForBottom,\n        left: $$.rotated_padding_left\n      }\n    : {\n        top: $$.currentHeight - subchartHeight - legendHeightForBottom,\n        right: NaN,\n        bottom: xAxisHeight + legendHeightForBottom,\n        left: $$.margin.left\n      };\n\n  // for legend\n  $$.margin3 = {\n    top: 0,\n    right: NaN,\n    bottom: 0,\n    left: 0\n  };\n  if ($$.updateSizeForLegend) {\n    $$.updateSizeForLegend(legendHeight, legendWidth);\n  }\n\n  $$.width = $$.currentWidth - $$.margin.left - $$.margin.right;\n  $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom;\n  if ($$.width < 0) {\n    $$.width = 0;\n  }\n  if ($$.height < 0) {\n    $$.height = 0;\n  }\n\n  $$.width2 = config.axis_rotated\n    ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right\n    : $$.width;\n  $$.height2 = config.axis_rotated\n    ? $$.height\n    : $$.currentHeight - $$.margin2.top - $$.margin2.bottom;\n  if ($$.width2 < 0) {\n    $$.width2 = 0;\n  }\n  if ($$.height2 < 0) {\n    $$.height2 = 0;\n  }\n\n  // for arc\n  $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0);\n  $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10);\n  if ($$.hasType('gauge') && !config.gauge_fullCircle) {\n    $$.arcHeight += $$.height - $$.getGaugeLabelHeight();\n  }\n  if ($$.updateRadius) {\n    $$.updateRadius();\n  }\n\n  if ($$.isLegendRight && hasArc) {\n    $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1;\n  }\n};\n\nChartInternal.prototype.updateTargets = function(targets) {\n  var $$ = this,\n    config = $$.config;\n\n  /*-- Main --*/\n\n  //-- Text --//\n  $$.updateTargetsForText(targets);\n\n  //-- Bar --//\n  $$.updateTargetsForBar(targets);\n\n  //-- Line --//\n  $$.updateTargetsForLine(targets);\n\n  //-- Arc --//\n  if ($$.hasArcType() && $$.updateTargetsForArc) {\n    $$.updateTargetsForArc(targets);\n  }\n\n  /*-- Sub --*/\n\n  if (config.subchart_show && $$.updateTargetsForSubchart) {\n    $$.updateTargetsForSubchart(targets);\n  }\n\n  // Fade-in each chart\n  $$.showTargets();\n};\nChartInternal.prototype.showTargets = function() {\n  var $$ = this;\n  $$.svg\n    .selectAll('.' + CLASS.target)\n    .filter(function(d) {\n      return $$.isTargetToShow(d.id)\n    })\n    .transition()\n    .duration($$.config.transition_duration)\n    .style('opacity', 1);\n};\n\nChartInternal.prototype.redraw = function(options, transitions) {\n  var $$ = this,\n    main = $$.main,\n    d3 = $$.d3,\n    config = $$.config;\n  var areaIndices = $$.getShapeIndices($$.isAreaType),\n    barIndices = $$.getShapeIndices($$.isBarType),\n    lineIndices = $$.getShapeIndices($$.isLineType);\n  var withY,\n    withSubchart,\n    withTransition,\n    withTransitionForExit,\n    withTransitionForAxis,\n    withTransform,\n    withUpdateXDomain,\n    withUpdateOrgXDomain,\n    withTrimXDomain,\n    withLegend,\n    withEventRect,\n    withDimension,\n    withUpdateXAxis;\n  var hideAxis = $$.hasArcType();\n  var drawArea, drawBar, drawLine, xForText, yForText;\n  var duration, durationForExit, durationForAxis;\n  var transitionsToWait, waitForDraw, flow, transition;\n  var targetsToShow = $$.filterTargetsToShow($$.data.targets),\n    tickValues,\n    i,\n    intervalForCulling,\n    xDomainForZoom;\n  var xv = $$.xv.bind($$),\n    cx,\n    cy;\n\n  options = options || {};\n  withY = getOption(options, 'withY', true);\n  withSubchart = getOption(options, 'withSubchart', true);\n  withTransition = getOption(options, 'withTransition', true);\n  withTransform = getOption(options, 'withTransform', false);\n  withUpdateXDomain = getOption(options, 'withUpdateXDomain', false);\n  withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', false);\n  withTrimXDomain = getOption(options, 'withTrimXDomain', true);\n  withUpdateXAxis = getOption(options, 'withUpdateXAxis', withUpdateXDomain);\n  withLegend = getOption(options, 'withLegend', false);\n  withEventRect = getOption(options, 'withEventRect', true);\n  withDimension = getOption(options, 'withDimension', true);\n  withTransitionForExit = getOption(\n    options,\n    'withTransitionForExit',\n    withTransition\n  );\n  withTransitionForAxis = getOption(\n    options,\n    'withTransitionForAxis',\n    withTransition\n  );\n\n  duration = withTransition ? config.transition_duration : 0;\n  durationForExit = withTransitionForExit ? duration : 0;\n  durationForAxis = withTransitionForAxis ? duration : 0;\n\n  transitions = transitions || $$.axis.generateTransitions(durationForAxis);\n\n  // update legend and transform each g\n  if (withLegend && config.legend_show) {\n    $$.updateLegend($$.mapToIds($$.data.targets), options, transitions);\n  } else if (withDimension) {\n    // need to update dimension (e.g. axis.y.tick.values) because y tick values should change\n    // no need to update axis in it because they will be updated in redraw()\n    $$.updateDimension(true);\n  }\n\n  // MEMO: needed for grids calculation\n  if ($$.isCategorized() && targetsToShow.length === 0) {\n    $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]);\n  }\n\n  if (targetsToShow.length) {\n    $$.updateXDomain(\n      targetsToShow,\n      withUpdateXDomain,\n      withUpdateOrgXDomain,\n      withTrimXDomain\n    );\n    if (!config.axis_x_tick_values) {\n      tickValues = $$.axis.updateXAxisTickValues(targetsToShow);\n    }\n  } else {\n    $$.xAxis.tickValues([]);\n    $$.subXAxis.tickValues([]);\n  }\n\n  if (config.zoom_rescale && !options.flow) {\n    xDomainForZoom = $$.x.orgDomain();\n  }\n\n  $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom));\n  $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom));\n\n  if (!config.axis_y_tick_values && config.axis_y_tick_count) {\n    $$.yAxis.tickValues(\n      $$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count)\n    );\n  }\n  if (!config.axis_y2_tick_values && config.axis_y2_tick_count) {\n    $$.y2Axis.tickValues(\n      $$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count)\n    );\n  }\n\n  // axes\n  $$.axis.redraw(durationForAxis, hideAxis);\n\n  // Update axis label\n  $$.axis.updateLabels(withTransition);\n\n  // show/hide if manual culling needed\n  if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) {\n    if (config.axis_x_tick_culling && tickValues) {\n      for (i = 1; i < tickValues.length; i++) {\n        if (tickValues.length / i < config.axis_x_tick_culling_max) {\n          intervalForCulling = i;\n          break\n        }\n      }\n      $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function(e) {\n        var index = tickValues.indexOf(e);\n        if (index >= 0) {\n          d3.select(this).style(\n            'display',\n            index % intervalForCulling ? 'none' : 'block'\n          );\n        }\n      });\n    } else {\n      $$.svg\n        .selectAll('.' + CLASS.axisX + ' .tick text')\n        .style('display', 'block');\n    }\n  }\n\n  // setup drawer - MEMO: these must be called after axis updated\n  drawArea = $$.generateDrawArea\n    ? $$.generateDrawArea(areaIndices, false)\n    : undefined;\n  drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined;\n  drawLine = $$.generateDrawLine\n    ? $$.generateDrawLine(lineIndices, false)\n    : undefined;\n  xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true);\n  yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false);\n\n  // update circleY based on updated parameters\n  $$.updateCircleY();\n  // generate circle x/y functions depending on updated params\n  cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$);\n  cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$);\n\n  // Update sub domain\n  if (withY) {\n    $$.subY.domain($$.getYDomain(targetsToShow, 'y'));\n    $$.subY2.domain($$.getYDomain(targetsToShow, 'y2'));\n  }\n\n  // xgrid focus\n  $$.updateXgridFocus();\n\n  // Data empty label positioning and text.\n  main\n    .select('text.' + CLASS.text + '.' + CLASS.empty)\n    .attr('x', $$.width / 2)\n    .attr('y', $$.height / 2)\n    .text(config.data_empty_label_text)\n    .transition()\n    .style('opacity', targetsToShow.length ? 0 : 1);\n\n  // event rect\n  if (withEventRect) {\n    $$.redrawEventRect();\n  }\n\n  // grid\n  $$.updateGrid(duration);\n\n  $$.updateStanfordElements(duration);\n\n  // rect for regions\n  $$.updateRegion(duration);\n\n  // bars\n  $$.updateBar(durationForExit);\n\n  // lines, areas and circles\n  $$.updateLine(durationForExit);\n  $$.updateArea(durationForExit);\n  $$.updateCircle(cx, cy);\n\n  // text\n  if ($$.hasDataLabel()) {\n    $$.updateText(xForText, yForText, durationForExit);\n  }\n\n  // title\n  if ($$.redrawTitle) {\n    $$.redrawTitle();\n  }\n\n  // arc\n  if ($$.redrawArc) {\n    $$.redrawArc(duration, durationForExit, withTransform);\n  }\n\n  // subchart\n  if (config.subchart_show && $$.redrawSubchart) {\n    $$.redrawSubchart(\n      withSubchart,\n      transitions,\n      duration,\n      durationForExit,\n      areaIndices,\n      barIndices,\n      lineIndices\n    );\n  }\n\n  if ($$.isStanfordGraphType()) {\n    $$.drawColorScale();\n  }\n\n  // circles for select\n  main\n    .selectAll('.' + CLASS.selectedCircles)\n    .filter($$.isBarType.bind($$))\n    .selectAll('circle')\n    .remove();\n\n  if (options.flow) {\n    flow = $$.generateFlow({\n      targets: targetsToShow,\n      flow: options.flow,\n      duration: options.flow.duration,\n      drawBar: drawBar,\n      drawLine: drawLine,\n      drawArea: drawArea,\n      cx: cx,\n      cy: cy,\n      xv: xv,\n      xForText: xForText,\n      yForText: yForText\n    });\n  }\n\n  if (duration && $$.isTabVisible()) {\n    // Only use transition if tab visible. See #938.\n    // transition should be derived from one transition\n    transition = d3.transition().duration(duration);\n    transitionsToWait = []\n    ;[\n      $$.redrawBar(drawBar, true, transition),\n      $$.redrawLine(drawLine, true, transition),\n      $$.redrawArea(drawArea, true, transition),\n      $$.redrawCircle(cx, cy, true, transition),\n      $$.redrawText(xForText, yForText, options.flow, true, transition),\n      $$.redrawRegion(true, transition),\n      $$.redrawGrid(true, transition)\n    ].forEach(function(transitions) {\n      transitions.forEach(function(transition) {\n        transitionsToWait.push(transition);\n      });\n    });\n    // Wait for end of transitions to call flow and onrendered callback\n    waitForDraw = $$.generateWait();\n    transitionsToWait.forEach(function(t) {\n      waitForDraw.add(t);\n    });\n    waitForDraw(function() {\n      if (flow) {\n        flow();\n      }\n      if (config.onrendered) {\n        config.onrendered.call($$);\n      }\n    });\n  } else {\n    $$.redrawBar(drawBar);\n    $$.redrawLine(drawLine);\n    $$.redrawArea(drawArea);\n    $$.redrawCircle(cx, cy);\n    $$.redrawText(xForText, yForText, options.flow);\n    $$.redrawRegion();\n    $$.redrawGrid();\n    if (flow) {\n      flow();\n    }\n    if (config.onrendered) {\n      config.onrendered.call($$);\n    }\n  }\n\n  // update fadein condition\n  $$.mapToIds($$.data.targets).forEach(function(id) {\n    $$.withoutFadeIn[id] = true;\n  });\n};\n\nChartInternal.prototype.updateAndRedraw = function(options) {\n  var $$ = this,\n    config = $$.config,\n    transitions;\n  options = options || {};\n  // same with redraw\n  options.withTransition = getOption(options, 'withTransition', true);\n  options.withTransform = getOption(options, 'withTransform', false);\n  options.withLegend = getOption(options, 'withLegend', false);\n  // NOT same with redraw\n  options.withUpdateXDomain = getOption(options, 'withUpdateXDomain', true);\n  options.withUpdateOrgXDomain = getOption(\n    options,\n    'withUpdateOrgXDomain',\n    true\n  );\n  options.withTransitionForExit = false;\n  options.withTransitionForTransform = getOption(\n    options,\n    'withTransitionForTransform',\n    options.withTransition\n  );\n  // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called)\n  $$.updateSizes();\n  // MEMO: called in updateLegend in redraw if withLegend\n  if (!(options.withLegend && config.legend_show)) {\n    transitions = $$.axis.generateTransitions(\n      options.withTransitionForAxis ? config.transition_duration : 0\n    );\n    // Update scales\n    $$.updateScales();\n    $$.updateSvgSize();\n    // Update g positions\n    $$.transformAll(options.withTransitionForTransform, transitions);\n  }\n  // Draw with new sizes & scales\n  $$.redraw(options, transitions);\n};\nChartInternal.prototype.redrawWithoutRescale = function() {\n  this.redraw({\n    withY: false,\n    withSubchart: false,\n    withEventRect: false,\n    withTransitionForAxis: false\n  });\n};\n\nChartInternal.prototype.isTimeSeries = function() {\n  return this.config.axis_x_type === 'timeseries'\n};\nChartInternal.prototype.isCategorized = function() {\n  return this.config.axis_x_type.indexOf('categor') >= 0\n};\nChartInternal.prototype.isCustomX = function() {\n  var $$ = this,\n    config = $$.config;\n  return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs))\n};\n\nChartInternal.prototype.isTimeSeriesY = function() {\n  return this.config.axis_y_type === 'timeseries'\n};\n\nChartInternal.prototype.getTranslate = function(target) {\n  var $$ = this,\n    config = $$.config,\n    x,\n    y;\n  if (target === 'main') {\n    x = asHalfPixel($$.margin.left);\n    y = asHalfPixel($$.margin.top);\n  } else if (target === 'context') {\n    x = asHalfPixel($$.margin2.left);\n    y = asHalfPixel($$.margin2.top);\n  } else if (target === 'legend') {\n    x = $$.margin3.left;\n    y = $$.margin3.top;\n  } else if (target === 'x') {\n    x = 0;\n    y = config.axis_rotated ? 0 : $$.height;\n  } else if (target === 'y') {\n    x = 0;\n    y = config.axis_rotated ? $$.height : 0;\n  } else if (target === 'y2') {\n    x = config.axis_rotated ? 0 : $$.width;\n    y = config.axis_rotated ? 1 : 0;\n  } else if (target === 'subx') {\n    x = 0;\n    y = config.axis_rotated ? 0 : $$.height2;\n  } else if (target === 'arc') {\n    x = $$.arcWidth / 2;\n    y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label\n  }\n  return 'translate(' + x + ',' + y + ')'\n};\nChartInternal.prototype.initialOpacity = function(d) {\n  return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0\n};\nChartInternal.prototype.initialOpacityForCircle = function(d) {\n  return d.value !== null && this.withoutFadeIn[d.id]\n    ? this.opacityForCircle(d)\n    : 0\n};\nChartInternal.prototype.opacityForCircle = function(d) {\n  var isPointShouldBeShown = isFunction(this.config.point_show)\n    ? this.config.point_show(d)\n    : this.config.point_show;\n  var opacity = isPointShouldBeShown || this.isStanfordType(d) ? 1 : 0;\n  return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0\n};\nChartInternal.prototype.opacityForText = function() {\n  return this.hasDataLabel() ? 1 : 0\n};\nChartInternal.prototype.xx = function(d) {\n  return d ? this.x(d.x) : null\n};\nChartInternal.prototype.xvCustom = function(d, xyValue) {\n  var $$ = this,\n    value = xyValue ? d[xyValue] : d.value;\n  if ($$.isTimeSeries()) {\n    value = $$.parseDate(d.value);\n  } else if ($$.isCategorized() && typeof d.value === 'string') {\n    value = $$.config.axis_x_categories.indexOf(d.value);\n  }\n  return Math.ceil($$.x(value))\n};\nChartInternal.prototype.yvCustom = function(d, xyValue) {\n  var $$ = this,\n    yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y,\n    value = xyValue ? d[xyValue] : d.value;\n  return Math.ceil(yScale(value))\n};\nChartInternal.prototype.xv = function(d) {\n  var $$ = this,\n    value = d.value;\n  if ($$.isTimeSeries()) {\n    value = $$.parseDate(d.value);\n  } else if ($$.isCategorized() && typeof d.value === 'string') {\n    value = $$.config.axis_x_categories.indexOf(d.value);\n  }\n  return Math.ceil($$.x(value))\n};\nChartInternal.prototype.yv = function(d) {\n  var $$ = this,\n    yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y;\n  return Math.ceil(yScale(d.value))\n};\nChartInternal.prototype.subxx = function(d) {\n  return d ? this.subX(d.x) : null\n};\n\nChartInternal.prototype.transformMain = function(withTransition, transitions) {\n  var $$ = this,\n    xAxis,\n    yAxis,\n    y2Axis;\n  if (transitions && transitions.axisX) {\n    xAxis = transitions.axisX;\n  } else {\n    xAxis = $$.main.select('.' + CLASS.axisX);\n    if (withTransition) {\n      xAxis = xAxis.transition();\n    }\n  }\n  if (transitions && transitions.axisY) {\n    yAxis = transitions.axisY;\n  } else {\n    yAxis = $$.main.select('.' + CLASS.axisY);\n    if (withTransition) {\n      yAxis = yAxis.transition();\n    }\n  }\n  if (transitions && transitions.axisY2) {\n    y2Axis = transitions.axisY2;\n  } else {\n    y2Axis = $$.main.select('.' + CLASS.axisY2);\n    if (withTransition) {\n      y2Axis = y2Axis.transition();\n    }\n  }\n(withTransition ? $$.main.transition() : $$.main).attr(\n    'transform',\n    $$.getTranslate('main')\n  );\n  xAxis.attr('transform', $$.getTranslate('x'));\n  yAxis.attr('transform', $$.getTranslate('y'));\n  y2Axis.attr('transform', $$.getTranslate('y2'));\n  $$.main\n    .select('.' + CLASS.chartArcs)\n    .attr('transform', $$.getTranslate('arc'));\n};\nChartInternal.prototype.transformAll = function(withTransition, transitions) {\n  var $$ = this;\n  $$.transformMain(withTransition, transitions);\n  if ($$.config.subchart_show) {\n    $$.transformContext(withTransition, transitions);\n  }\n  if ($$.legend) {\n    $$.transformLegend(withTransition);\n  }\n};\n\nChartInternal.prototype.updateSvgSize = function() {\n  var $$ = this,\n    brush = $$.svg.select(`.${CLASS.brush} .overlay`);\n  $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight);\n  $$.svg\n    .selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid])\n    .select('rect')\n    .attr('width', $$.width)\n    .attr('height', $$.height);\n  $$.svg\n    .select('#' + $$.clipIdForXAxis)\n    .select('rect')\n    .attr('x', $$.getXAxisClipX.bind($$))\n    .attr('y', $$.getXAxisClipY.bind($$))\n    .attr('width', $$.getXAxisClipWidth.bind($$))\n    .attr('height', $$.getXAxisClipHeight.bind($$));\n  $$.svg\n    .select('#' + $$.clipIdForYAxis)\n    .select('rect')\n    .attr('x', $$.getYAxisClipX.bind($$))\n    .attr('y', $$.getYAxisClipY.bind($$))\n    .attr('width', $$.getYAxisClipWidth.bind($$))\n    .attr('height', $$.getYAxisClipHeight.bind($$));\n  $$.svg\n    .select('#' + $$.clipIdForSubchart)\n    .select('rect')\n    .attr('width', $$.width)\n    .attr('height', (brush.size() && brush.attr('height')) || 0);\n  // MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>\n  $$.selectChart.style('max-height', $$.currentHeight + 'px');\n};\n\nChartInternal.prototype.updateDimension = function(withoutAxis) {\n  var $$ = this;\n  if (!withoutAxis) {\n    if ($$.config.axis_rotated) {\n      $$.axes.x.call($$.xAxis);\n      $$.axes.subx.call($$.subXAxis);\n    } else {\n      $$.axes.y.call($$.yAxis);\n      $$.axes.y2.call($$.y2Axis);\n    }\n  }\n  $$.updateSizes();\n  $$.updateScales();\n  $$.updateSvgSize();\n  $$.transformAll(false);\n};\n\nChartInternal.prototype.observeInserted = function(selection) {\n  var $$ = this,\n    observer;\n  if (typeof MutationObserver === 'undefined') {\n    window.console.error('MutationObserver not defined.');\n    return\n  }\n  observer = new MutationObserver(function(mutations) {\n    mutations.forEach(function(mutation) {\n      if (mutation.type === 'childList' && mutation.previousSibling) {\n        observer.disconnect();\n        // need to wait for completion of load because size calculation requires the actual sizes determined after that completion\n        $$.intervalForObserveInserted = window.setInterval(function() {\n          // parentNode will NOT be null when completed\n          if (selection.node().parentNode) {\n            window.clearInterval($$.intervalForObserveInserted);\n            $$.updateDimension();\n            if ($$.brush) {\n              $$.brush.update();\n            }\n            $$.config.oninit.call($$);\n            $$.redraw({\n              withTransform: true,\n              withUpdateXDomain: true,\n              withUpdateOrgXDomain: true,\n              withTransition: false,\n              withTransitionForTransform: false,\n              withLegend: true\n            });\n            selection.transition().style('opacity', 1);\n          }\n        }, 10);\n      }\n    });\n  });\n  observer.observe(selection.node(), {\n    attributes: true,\n    childList: true,\n    characterData: true\n  });\n};\n\n/**\n * Binds handlers to the window resize event.\n */\nChartInternal.prototype.bindResize = function() {\n  var $$ = this,\n    config = $$.config;\n\n  $$.resizeFunction = $$.generateResize(); // need to call .remove\n\n  $$.resizeFunction.add(function() {\n    config.onresize.call($$);\n  });\n  if (config.resize_auto) {\n    $$.resizeFunction.add(function() {\n      if ($$.resizeTimeout !== undefined) {\n        window.clearTimeout($$.resizeTimeout);\n      }\n      $$.resizeTimeout = window.setTimeout(function() {\n        delete $$.resizeTimeout;\n        $$.updateAndRedraw({\n          withUpdateXDomain: false,\n          withUpdateOrgXDomain: false,\n          withTransition: false,\n          withTransitionForTransform: false,\n          withLegend: true\n        });\n        if ($$.brush) {\n          $$.brush.update();\n        }\n      }, 100);\n    });\n  }\n  $$.resizeFunction.add(function() {\n    config.onresized.call($$);\n  });\n\n  $$.resizeIfElementDisplayed = function() {\n    // if element not displayed skip it\n    if ($$.api == null || !$$.api.element.offsetParent) {\n      return\n    }\n\n    $$.resizeFunction();\n  };\n\n  if (window.attachEvent) {\n    window.attachEvent('onresize', $$.resizeIfElementDisplayed);\n  } else if (window.addEventListener) {\n    window.addEventListener('resize', $$.resizeIfElementDisplayed, false);\n  } else {\n    // fallback to this, if this is a very old browser\n    var wrapper = window.onresize;\n    if (!wrapper) {\n      // create a wrapper that will call all charts\n      wrapper = $$.generateResize();\n    } else if (!wrapper.add || !wrapper.remove) {\n      // there is already a handler registered, make sure we call it too\n      wrapper = $$.generateResize();\n      wrapper.add(window.onresize);\n    }\n    // add this graph to the wrapper, we will be removed if the user calls destroy\n    wrapper.add($$.resizeFunction);\n    window.onresize = function() {\n      // if element not displayed skip it\n      if (!$$.api.element.offsetParent) {\n        return\n      }\n\n      wrapper();\n    };\n  }\n};\n\n/**\n * Binds handlers to the window focus event.\n */\nChartInternal.prototype.bindWindowFocus = function() {\n  if (this.windowFocusHandler) {\n    // The handler is already set\n    return\n  }\n\n  this.windowFocusHandler = () => {\n    this.redraw();\n  };\n\n  window.addEventListener('focus', this.windowFocusHandler);\n};\n\n/**\n * Unbinds from the window focus event.\n */\nChartInternal.prototype.unbindWindowFocus = function() {\n  window.removeEventListener('focus', this.windowFocusHandler);\n  delete this.windowFocusHandler;\n};\n\nChartInternal.prototype.generateResize = function() {\n  var resizeFunctions = [];\n\n  function callResizeFunctions() {\n    resizeFunctions.forEach(function(f) {\n      f();\n    });\n  }\n  callResizeFunctions.add = function(f) {\n    resizeFunctions.push(f);\n  };\n  callResizeFunctions.remove = function(f) {\n    for (var i = 0; i < resizeFunctions.length; i++) {\n      if (resizeFunctions[i] === f) {\n        resizeFunctions.splice(i, 1);\n        break\n      }\n    }\n  };\n  return callResizeFunctions\n};\n\nChartInternal.prototype.endall = function(transition, callback) {\n  var n = 0;\n  transition\n    .each(function() {\n      ++n;\n    })\n    .on('end', function() {\n      if (!--n) {\n        callback.apply(this, arguments);\n      }\n    });\n};\nChartInternal.prototype.generateWait = function() {\n  var $$ = this;\n  var transitionsToWait = [],\n    f = function(callback) {\n      var timer = setInterval(function() {\n        if (!$$.isTabVisible()) {\n          return\n        }\n\n        var done = 0;\n        transitionsToWait.forEach(function(t) {\n          if (t.empty()) {\n            done += 1;\n            return\n          }\n          try {\n            t.transition();\n          } catch (e) {\n            done += 1;\n          }\n        });\n        if (done === transitionsToWait.length) {\n          clearInterval(timer);\n          if (callback) {\n            callback();\n          }\n        }\n      }, 50);\n    };\n  f.add = function(transition) {\n    transitionsToWait.push(transition);\n  };\n  return f\n};\n\nChartInternal.prototype.parseDate = function(date) {\n  var $$ = this,\n    parsedDate;\n  if (date instanceof Date) {\n    parsedDate = date;\n  } else if (typeof date === 'string') {\n    parsedDate = $$.dataTimeParse(date);\n  } else if (typeof date === 'object') {\n    parsedDate = new Date(+date);\n  } else if (typeof date === 'number' && !isNaN(date)) {\n    parsedDate = new Date(+date);\n  }\n  if (!parsedDate || isNaN(+parsedDate)) {\n    window.console.error(\"Failed to parse x '\" + date + \"' to Date object\");\n  }\n  return parsedDate\n};\n\nChartInternal.prototype.isTabVisible = function() {\n  return !document.hidden\n};\n\nChartInternal.prototype.getPathBox = getPathBox;\nChartInternal.prototype.CLASS = CLASS;\n\n/* jshint ignore:start */\n(function() {\n  if (!('SVGPathSeg' in window)) {\n    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg\n    window.SVGPathSeg = function(type, typeAsLetter, owningPathSegList) {\n      this.pathSegType = type;\n      this.pathSegTypeAsLetter = typeAsLetter;\n      this._owningPathSegList = owningPathSegList;\n    };\n\n    window.SVGPathSeg.prototype.classname = 'SVGPathSeg';\n\n    window.SVGPathSeg.PATHSEG_UNKNOWN = 0;\n    window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;\n    window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;\n    window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;\n    window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;\n    window.SVGPathSeg.PATHSEG_LINETO_REL = 5;\n    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;\n    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;\n    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;\n    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;\n    window.SVGPathSeg.PATHSEG_ARC_ABS = 10;\n    window.SVGPathSeg.PATHSEG_ARC_REL = 11;\n    window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;\n    window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;\n    window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;\n    window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;\n    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;\n    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;\n    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;\n    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;\n\n    // Notify owning PathSegList on any changes so they can be synchronized back to the path element.\n    window.SVGPathSeg.prototype._segmentChanged = function() {\n      if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this);\n    };\n\n    window.SVGPathSegClosePath = function(owningPathSegList) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CLOSEPATH,\n        'z',\n        owningPathSegList\n      );\n    };\n    window.SVGPathSegClosePath.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegClosePath.prototype.toString = function() {\n      return '[object SVGPathSegClosePath]'\n    };\n    window.SVGPathSegClosePath.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter\n    };\n    window.SVGPathSegClosePath.prototype.clone = function() {\n      return new window.SVGPathSegClosePath(undefined)\n    };\n\n    window.SVGPathSegMovetoAbs = function(owningPathSegList, x, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_MOVETO_ABS,\n        'M',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n    };\n    window.SVGPathSegMovetoAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegMovetoAbs.prototype.toString = function() {\n      return '[object SVGPathSegMovetoAbs]'\n    };\n    window.SVGPathSegMovetoAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    };\n    window.SVGPathSegMovetoAbs.prototype.clone = function() {\n      return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y)\n    };\n    Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegMovetoRel = function(owningPathSegList, x, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_MOVETO_REL,\n        'm',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n    };\n    window.SVGPathSegMovetoRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegMovetoRel.prototype.toString = function() {\n      return '[object SVGPathSegMovetoRel]'\n    };\n    window.SVGPathSegMovetoRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    };\n    window.SVGPathSegMovetoRel.prototype.clone = function() {\n      return new window.SVGPathSegMovetoRel(undefined, this._x, this._y)\n    };\n    Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegLinetoAbs = function(owningPathSegList, x, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_ABS,\n        'L',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n    };\n    window.SVGPathSegLinetoAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegLinetoAbs.prototype.toString = function() {\n      return '[object SVGPathSegLinetoAbs]'\n    };\n    window.SVGPathSegLinetoAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    };\n    window.SVGPathSegLinetoAbs.prototype.clone = function() {\n      return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y)\n    };\n    Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegLinetoRel = function(owningPathSegList, x, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_REL,\n        'l',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n    };\n    window.SVGPathSegLinetoRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegLinetoRel.prototype.toString = function() {\n      return '[object SVGPathSegLinetoRel]'\n    };\n    window.SVGPathSegLinetoRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    };\n    window.SVGPathSegLinetoRel.prototype.clone = function() {\n      return new window.SVGPathSegLinetoRel(undefined, this._x, this._y)\n    };\n    Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegCurvetoCubicAbs = function(\n      owningPathSegList,\n      x,\n      y,\n      x1,\n      y1,\n      x2,\n      y2\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS,\n        'C',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._x1 = x1;\n      this._y1 = y1;\n      this._x2 = x2;\n      this._y2 = y2;\n    };\n    window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoCubicAbs.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoCubicAbs]'\n    };\n    window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x1 +\n        ' ' +\n        this._y1 +\n        ' ' +\n        this._x2 +\n        ' ' +\n        this._y2 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegCurvetoCubicAbs.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoCubicAbs(\n        undefined,\n        this._x,\n        this._y,\n        this._x1,\n        this._y1,\n        this._x2,\n        this._y2\n      )\n    };\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x1', {\n      get: function() {\n        return this._x1\n      },\n      set: function(x1) {\n        this._x1 = x1;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y1', {\n      get: function() {\n        return this._y1\n      },\n      set: function(y1) {\n        this._y1 = y1;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x2', {\n      get: function() {\n        return this._x2\n      },\n      set: function(x2) {\n        this._x2 = x2;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y2', {\n      get: function() {\n        return this._y2\n      },\n      set: function(y2) {\n        this._y2 = y2;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegCurvetoCubicRel = function(\n      owningPathSegList,\n      x,\n      y,\n      x1,\n      y1,\n      x2,\n      y2\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL,\n        'c',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._x1 = x1;\n      this._y1 = y1;\n      this._x2 = x2;\n      this._y2 = y2;\n    };\n    window.SVGPathSegCurvetoCubicRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoCubicRel.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoCubicRel]'\n    };\n    window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x1 +\n        ' ' +\n        this._y1 +\n        ' ' +\n        this._x2 +\n        ' ' +\n        this._y2 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegCurvetoCubicRel.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoCubicRel(\n        undefined,\n        this._x,\n        this._y,\n        this._x1,\n        this._y1,\n        this._x2,\n        this._y2\n      )\n    };\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x1', {\n      get: function() {\n        return this._x1\n      },\n      set: function(x1) {\n        this._x1 = x1;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y1', {\n      get: function() {\n        return this._y1\n      },\n      set: function(y1) {\n        this._y1 = y1;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x2', {\n      get: function() {\n        return this._x2\n      },\n      set: function(x2) {\n        this._x2 = x2;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y2', {\n      get: function() {\n        return this._y2\n      },\n      set: function(y2) {\n        this._y2 = y2;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegCurvetoQuadraticAbs = function(\n      owningPathSegList,\n      x,\n      y,\n      x1,\n      y1\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS,\n        'Q',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._x1 = x1;\n      this._y1 = y1;\n    };\n    window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoQuadraticAbs]'\n    };\n    window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x1 +\n        ' ' +\n        this._y1 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoQuadraticAbs(\n        undefined,\n        this._x,\n        this._y,\n        this._x1,\n        this._y1\n      )\n    };\n    Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticAbs.prototype,\n      'x1',\n      {\n        get: function() {\n          return this._x1\n        },\n        set: function(x1) {\n          this._x1 = x1;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticAbs.prototype,\n      'y1',\n      {\n        get: function() {\n          return this._y1\n        },\n        set: function(y1) {\n          this._y1 = y1;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n\n    window.SVGPathSegCurvetoQuadraticRel = function(\n      owningPathSegList,\n      x,\n      y,\n      x1,\n      y1\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL,\n        'q',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._x1 = x1;\n      this._y1 = y1;\n    };\n    window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoQuadraticRel]'\n    };\n    window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x1 +\n        ' ' +\n        this._y1 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoQuadraticRel(\n        undefined,\n        this._x,\n        this._y,\n        this._x1,\n        this._y1\n      )\n    };\n    Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticRel.prototype,\n      'x1',\n      {\n        get: function() {\n          return this._x1\n        },\n        set: function(x1) {\n          this._x1 = x1;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticRel.prototype,\n      'y1',\n      {\n        get: function() {\n          return this._y1\n        },\n        set: function(y1) {\n          this._y1 = y1;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n\n    window.SVGPathSegArcAbs = function(\n      owningPathSegList,\n      x,\n      y,\n      r1,\n      r2,\n      angle,\n      largeArcFlag,\n      sweepFlag\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_ARC_ABS,\n        'A',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._r1 = r1;\n      this._r2 = r2;\n      this._angle = angle;\n      this._largeArcFlag = largeArcFlag;\n      this._sweepFlag = sweepFlag;\n    };\n    window.SVGPathSegArcAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegArcAbs.prototype.toString = function() {\n      return '[object SVGPathSegArcAbs]'\n    };\n    window.SVGPathSegArcAbs.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._r1 +\n        ' ' +\n        this._r2 +\n        ' ' +\n        this._angle +\n        ' ' +\n        (this._largeArcFlag ? '1' : '0') +\n        ' ' +\n        (this._sweepFlag ? '1' : '0') +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegArcAbs.prototype.clone = function() {\n      return new window.SVGPathSegArcAbs(\n        undefined,\n        this._x,\n        this._y,\n        this._r1,\n        this._r2,\n        this._angle,\n        this._largeArcFlag,\n        this._sweepFlag\n      )\n    };\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r1', {\n      get: function() {\n        return this._r1\n      },\n      set: function(r1) {\n        this._r1 = r1;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r2', {\n      get: function() {\n        return this._r2\n      },\n      set: function(r2) {\n        this._r2 = r2;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'angle', {\n      get: function() {\n        return this._angle\n      },\n      set: function(angle) {\n        this._angle = angle;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'largeArcFlag', {\n      get: function() {\n        return this._largeArcFlag\n      },\n      set: function(largeArcFlag) {\n        this._largeArcFlag = largeArcFlag;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'sweepFlag', {\n      get: function() {\n        return this._sweepFlag\n      },\n      set: function(sweepFlag) {\n        this._sweepFlag = sweepFlag;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegArcRel = function(\n      owningPathSegList,\n      x,\n      y,\n      r1,\n      r2,\n      angle,\n      largeArcFlag,\n      sweepFlag\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_ARC_REL,\n        'a',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._r1 = r1;\n      this._r2 = r2;\n      this._angle = angle;\n      this._largeArcFlag = largeArcFlag;\n      this._sweepFlag = sweepFlag;\n    };\n    window.SVGPathSegArcRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegArcRel.prototype.toString = function() {\n      return '[object SVGPathSegArcRel]'\n    };\n    window.SVGPathSegArcRel.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._r1 +\n        ' ' +\n        this._r2 +\n        ' ' +\n        this._angle +\n        ' ' +\n        (this._largeArcFlag ? '1' : '0') +\n        ' ' +\n        (this._sweepFlag ? '1' : '0') +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegArcRel.prototype.clone = function() {\n      return new window.SVGPathSegArcRel(\n        undefined,\n        this._x,\n        this._y,\n        this._r1,\n        this._r2,\n        this._angle,\n        this._largeArcFlag,\n        this._sweepFlag\n      )\n    };\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r1', {\n      get: function() {\n        return this._r1\n      },\n      set: function(r1) {\n        this._r1 = r1;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r2', {\n      get: function() {\n        return this._r2\n      },\n      set: function(r2) {\n        this._r2 = r2;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'angle', {\n      get: function() {\n        return this._angle\n      },\n      set: function(angle) {\n        this._angle = angle;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'largeArcFlag', {\n      get: function() {\n        return this._largeArcFlag\n      },\n      set: function(largeArcFlag) {\n        this._largeArcFlag = largeArcFlag;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'sweepFlag', {\n      get: function() {\n        return this._sweepFlag\n      },\n      set: function(sweepFlag) {\n        this._sweepFlag = sweepFlag;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegLinetoHorizontalAbs = function(owningPathSegList, x) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS,\n        'H',\n        owningPathSegList\n      );\n      this._x = x;\n    };\n    window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function() {\n      return '[object SVGPathSegLinetoHorizontalAbs]'\n    };\n    window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x\n    };\n    window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function() {\n      return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x)\n    };\n    Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegLinetoHorizontalRel = function(owningPathSegList, x) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL,\n        'h',\n        owningPathSegList\n      );\n      this._x = x;\n    };\n    window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegLinetoHorizontalRel.prototype.toString = function() {\n      return '[object SVGPathSegLinetoHorizontalRel]'\n    };\n    window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x\n    };\n    window.SVGPathSegLinetoHorizontalRel.prototype.clone = function() {\n      return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x)\n    };\n    Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegLinetoVerticalAbs = function(owningPathSegList, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS,\n        'V',\n        owningPathSegList\n      );\n      this._y = y;\n    };\n    window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegLinetoVerticalAbs.prototype.toString = function() {\n      return '[object SVGPathSegLinetoVerticalAbs]'\n    };\n    window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._y\n    };\n    window.SVGPathSegLinetoVerticalAbs.prototype.clone = function() {\n      return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y)\n    };\n    Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegLinetoVerticalRel = function(owningPathSegList, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL,\n        'v',\n        owningPathSegList\n      );\n      this._y = y;\n    };\n    window.SVGPathSegLinetoVerticalRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegLinetoVerticalRel.prototype.toString = function() {\n      return '[object SVGPathSegLinetoVerticalRel]'\n    };\n    window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._y\n    };\n    window.SVGPathSegLinetoVerticalRel.prototype.clone = function() {\n      return new window.SVGPathSegLinetoVerticalRel(undefined, this._y)\n    };\n    Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y;\n        this._segmentChanged();\n      },\n      enumerable: true\n    });\n\n    window.SVGPathSegCurvetoCubicSmoothAbs = function(\n      owningPathSegList,\n      x,\n      y,\n      x2,\n      y2\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS,\n        'S',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._x2 = x2;\n      this._y2 = y2;\n    };\n    window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoCubicSmoothAbs]'\n    };\n    window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x2 +\n        ' ' +\n        this._y2 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoCubicSmoothAbs(\n        undefined,\n        this._x,\n        this._y,\n        this._x2,\n        this._y2\n      )\n    };\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,\n      'x',\n      {\n        get: function() {\n          return this._x\n        },\n        set: function(x) {\n          this._x = x;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,\n      'y',\n      {\n        get: function() {\n          return this._y\n        },\n        set: function(y) {\n          this._y = y;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,\n      'x2',\n      {\n        get: function() {\n          return this._x2\n        },\n        set: function(x2) {\n          this._x2 = x2;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,\n      'y2',\n      {\n        get: function() {\n          return this._y2\n        },\n        set: function(y2) {\n          this._y2 = y2;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n\n    window.SVGPathSegCurvetoCubicSmoothRel = function(\n      owningPathSegList,\n      x,\n      y,\n      x2,\n      y2\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL,\n        's',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n      this._x2 = x2;\n      this._y2 = y2;\n    };\n    window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoCubicSmoothRel]'\n    };\n    window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x2 +\n        ' ' +\n        this._y2 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    };\n    window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoCubicSmoothRel(\n        undefined,\n        this._x,\n        this._y,\n        this._x2,\n        this._y2\n      )\n    };\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothRel.prototype,\n      'x',\n      {\n        get: function() {\n          return this._x\n        },\n        set: function(x) {\n          this._x = x;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothRel.prototype,\n      'y',\n      {\n        get: function() {\n          return this._y\n        },\n        set: function(y) {\n          this._y = y;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothRel.prototype,\n      'x2',\n      {\n        get: function() {\n          return this._x2\n        },\n        set: function(x2) {\n          this._x2 = x2;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothRel.prototype,\n      'y2',\n      {\n        get: function() {\n          return this._y2\n        },\n        set: function(y2) {\n          this._y2 = y2;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n\n    window.SVGPathSegCurvetoQuadraticSmoothAbs = function(\n      owningPathSegList,\n      x,\n      y\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS,\n        'T',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n    };\n    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoQuadraticSmoothAbs]'\n    };\n    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    };\n    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoQuadraticSmoothAbs(\n        undefined,\n        this._x,\n        this._y\n      )\n    };\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype,\n      'x',\n      {\n        get: function() {\n          return this._x\n        },\n        set: function(x) {\n          this._x = x;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype,\n      'y',\n      {\n        get: function() {\n          return this._y\n        },\n        set: function(y) {\n          this._y = y;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n\n    window.SVGPathSegCurvetoQuadraticSmoothRel = function(\n      owningPathSegList,\n      x,\n      y\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL,\n        't',\n        owningPathSegList\n      );\n      this._x = x;\n      this._y = y;\n    };\n    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    );\n    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoQuadraticSmoothRel]'\n    };\n    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    };\n    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoQuadraticSmoothRel(\n        undefined,\n        this._x,\n        this._y\n      )\n    };\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticSmoothRel.prototype,\n      'x',\n      {\n        get: function() {\n          return this._x\n        },\n        set: function(x) {\n          this._x = x;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticSmoothRel.prototype,\n      'y',\n      {\n        get: function() {\n          return this._y\n        },\n        set: function(y) {\n          this._y = y;\n          this._segmentChanged();\n        },\n        enumerable: true\n      }\n    );\n\n    // Add createSVGPathSeg* functions to window.SVGPathElement.\n    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.\n    window.SVGPathElement.prototype.createSVGPathSegClosePath = function() {\n      return new window.SVGPathSegClosePath(undefined)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function(x, y) {\n      return new window.SVGPathSegMovetoAbs(undefined, x, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function(x, y) {\n      return new window.SVGPathSegMovetoRel(undefined, x, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function(x, y) {\n      return new window.SVGPathSegLinetoAbs(undefined, x, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function(x, y) {\n      return new window.SVGPathSegLinetoRel(undefined, x, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function(\n      x,\n      y,\n      x1,\n      y1,\n      x2,\n      y2\n    ) {\n      return new window.SVGPathSegCurvetoCubicAbs(\n        undefined,\n        x,\n        y,\n        x1,\n        y1,\n        x2,\n        y2\n      )\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function(\n      x,\n      y,\n      x1,\n      y1,\n      x2,\n      y2\n    ) {\n      return new window.SVGPathSegCurvetoCubicRel(\n        undefined,\n        x,\n        y,\n        x1,\n        y1,\n        x2,\n        y2\n      )\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function(\n      x,\n      y,\n      x1,\n      y1\n    ) {\n      return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function(\n      x,\n      y,\n      x1,\n      y1\n    ) {\n      return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegArcAbs = function(\n      x,\n      y,\n      r1,\n      r2,\n      angle,\n      largeArcFlag,\n      sweepFlag\n    ) {\n      return new window.SVGPathSegArcAbs(\n        undefined,\n        x,\n        y,\n        r1,\n        r2,\n        angle,\n        largeArcFlag,\n        sweepFlag\n      )\n    };\n    window.SVGPathElement.prototype.createSVGPathSegArcRel = function(\n      x,\n      y,\n      r1,\n      r2,\n      angle,\n      largeArcFlag,\n      sweepFlag\n    ) {\n      return new window.SVGPathSegArcRel(\n        undefined,\n        x,\n        y,\n        r1,\n        r2,\n        angle,\n        largeArcFlag,\n        sweepFlag\n      )\n    };\n    window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function(\n      x\n    ) {\n      return new window.SVGPathSegLinetoHorizontalAbs(undefined, x)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function(\n      x\n    ) {\n      return new window.SVGPathSegLinetoHorizontalRel(undefined, x)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function(\n      y\n    ) {\n      return new window.SVGPathSegLinetoVerticalAbs(undefined, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function(\n      y\n    ) {\n      return new window.SVGPathSegLinetoVerticalRel(undefined, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function(\n      x,\n      y,\n      x2,\n      y2\n    ) {\n      return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function(\n      x,\n      y,\n      x2,\n      y2\n    ) {\n      return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function(\n      x,\n      y\n    ) {\n      return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y)\n    };\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function(\n      x,\n      y\n    ) {\n      return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y)\n    };\n\n    if (!('getPathSegAtLength' in window.SVGPathElement.prototype)) {\n      // Add getPathSegAtLength to SVGPathElement.\n      // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength\n      // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.\n      window.SVGPathElement.prototype.getPathSegAtLength = function(distance) {\n        if (distance === undefined || !isFinite(distance))\n          throw 'Invalid arguments.'\n\n        var measurementElement = document.createElementNS(\n          'http://www.w3.org/2000/svg',\n          'path'\n        );\n        measurementElement.setAttribute('d', this.getAttribute('d'));\n        var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1;\n\n        // If the path is empty, return 0.\n        if (lastPathSegment <= 0) return 0\n\n        do {\n          measurementElement.pathSegList.removeItem(lastPathSegment);\n          if (distance > measurementElement.getTotalLength()) break\n          lastPathSegment--;\n        } while (lastPathSegment > 0)\n        return lastPathSegment\n      };\n    }\n  }\n\n  if (!('SVGPathSegList' in window)) {\n    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList\n    window.SVGPathSegList = function(pathElement) {\n      this._pathElement = pathElement;\n      this._list = this._parsePath(this._pathElement.getAttribute('d'));\n\n      // Use a MutationObserver to catch changes to the path's \"d\" attribute.\n      this._mutationObserverConfig = {\n        attributes: true,\n        attributeFilter: ['d']\n      };\n      this._pathElementMutationObserver = new MutationObserver(\n        this._updateListFromPathMutations.bind(this)\n      );\n      this._pathElementMutationObserver.observe(\n        this._pathElement,\n        this._mutationObserverConfig\n      );\n    };\n\n    window.SVGPathSegList.prototype.classname = 'SVGPathSegList';\n\n    Object.defineProperty(window.SVGPathSegList.prototype, 'numberOfItems', {\n      get: function() {\n        this._checkPathSynchronizedToList();\n        return this._list.length\n      },\n      enumerable: true\n    });\n\n    // Add the pathSegList accessors to window.SVGPathElement.\n    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData\n    Object.defineProperty(window.SVGPathElement.prototype, 'pathSegList', {\n      get: function() {\n        if (!this._pathSegList)\n          this._pathSegList = new window.SVGPathSegList(this);\n        return this._pathSegList\n      },\n      enumerable: true\n    });\n    // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.\n    Object.defineProperty(\n      window.SVGPathElement.prototype,\n      'normalizedPathSegList',\n      {\n        get: function() {\n          return this.pathSegList\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathElement.prototype,\n      'animatedPathSegList',\n      {\n        get: function() {\n          return this.pathSegList\n        },\n        enumerable: true\n      }\n    );\n    Object.defineProperty(\n      window.SVGPathElement.prototype,\n      'animatedNormalizedPathSegList',\n      {\n        get: function() {\n          return this.pathSegList\n        },\n        enumerable: true\n      }\n    );\n\n    // Process any pending mutations to the path element and update the list as needed.\n    // This should be the first call of all public functions and is needed because\n    // MutationObservers are not synchronous so we can have pending asynchronous mutations.\n    window.SVGPathSegList.prototype._checkPathSynchronizedToList = function() {\n      this._updateListFromPathMutations(\n        this._pathElementMutationObserver.takeRecords()\n      );\n    };\n\n    window.SVGPathSegList.prototype._updateListFromPathMutations = function(\n      mutationRecords\n    ) {\n      if (!this._pathElement) return\n      var hasPathMutations = false;\n      mutationRecords.forEach(function(record) {\n        if (record.attributeName == 'd') hasPathMutations = true;\n      });\n      if (hasPathMutations)\n        this._list = this._parsePath(this._pathElement.getAttribute('d'));\n    };\n\n    // Serialize the list and update the path's 'd' attribute.\n    window.SVGPathSegList.prototype._writeListToPath = function() {\n      this._pathElementMutationObserver.disconnect();\n      this._pathElement.setAttribute(\n        'd',\n        window.SVGPathSegList._pathSegArrayAsString(this._list)\n      );\n      this._pathElementMutationObserver.observe(\n        this._pathElement,\n        this._mutationObserverConfig\n      );\n    };\n\n    // When a path segment changes the list needs to be synchronized back to the path element.\n    window.SVGPathSegList.prototype.segmentChanged = function(pathSeg) {\n      this._writeListToPath();\n    };\n\n    window.SVGPathSegList.prototype.clear = function() {\n      this._checkPathSynchronizedToList();\n\n      this._list.forEach(function(pathSeg) {\n        pathSeg._owningPathSegList = null;\n      });\n      this._list = [];\n      this._writeListToPath();\n    };\n\n    window.SVGPathSegList.prototype.initialize = function(newItem) {\n      this._checkPathSynchronizedToList();\n\n      this._list = [newItem];\n      newItem._owningPathSegList = this;\n      this._writeListToPath();\n      return newItem\n    };\n\n    window.SVGPathSegList.prototype._checkValidIndex = function(index) {\n      if (isNaN(index) || index < 0 || index >= this.numberOfItems)\n        throw 'INDEX_SIZE_ERR'\n    };\n\n    window.SVGPathSegList.prototype.getItem = function(index) {\n      this._checkPathSynchronizedToList();\n\n      this._checkValidIndex(index);\n      return this._list[index]\n    };\n\n    window.SVGPathSegList.prototype.insertItemBefore = function(\n      newItem,\n      index\n    ) {\n      this._checkPathSynchronizedToList();\n\n      // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.\n      if (index > this.numberOfItems) index = this.numberOfItems;\n      if (newItem._owningPathSegList) {\n        // SVG2 spec says to make a copy.\n        newItem = newItem.clone();\n      }\n      this._list.splice(index, 0, newItem);\n      newItem._owningPathSegList = this;\n      this._writeListToPath();\n      return newItem\n    };\n\n    window.SVGPathSegList.prototype.replaceItem = function(newItem, index) {\n      this._checkPathSynchronizedToList();\n\n      if (newItem._owningPathSegList) {\n        // SVG2 spec says to make a copy.\n        newItem = newItem.clone();\n      }\n      this._checkValidIndex(index);\n      this._list[index] = newItem;\n      newItem._owningPathSegList = this;\n      this._writeListToPath();\n      return newItem\n    };\n\n    window.SVGPathSegList.prototype.removeItem = function(index) {\n      this._checkPathSynchronizedToList();\n\n      this._checkValidIndex(index);\n      var item = this._list[index];\n      this._list.splice(index, 1);\n      this._writeListToPath();\n      return item\n    };\n\n    window.SVGPathSegList.prototype.appendItem = function(newItem) {\n      this._checkPathSynchronizedToList();\n\n      if (newItem._owningPathSegList) {\n        // SVG2 spec says to make a copy.\n        newItem = newItem.clone();\n      }\n      this._list.push(newItem);\n      newItem._owningPathSegList = this;\n      // TODO: Optimize this to just append to the existing attribute.\n      this._writeListToPath();\n      return newItem\n    };\n\n    window.SVGPathSegList._pathSegArrayAsString = function(pathSegArray) {\n      var string = '';\n      var first = true;\n      pathSegArray.forEach(function(pathSeg) {\n        if (first) {\n          first = false;\n          string += pathSeg._asPathString();\n        } else {\n          string += ' ' + pathSeg._asPathString();\n        }\n      });\n      return string\n    };\n\n    // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.\n    window.SVGPathSegList.prototype._parsePath = function(string) {\n      if (!string || string.length == 0) return []\n\n      var owningPathSegList = this;\n\n      var Builder = function() {\n        this.pathSegList = [];\n      };\n\n      Builder.prototype.appendSegment = function(pathSeg) {\n        this.pathSegList.push(pathSeg);\n      };\n\n      var Source = function(string) {\n        this._string = string;\n        this._currentIndex = 0;\n        this._endIndex = this._string.length;\n        this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;\n\n        this._skipOptionalSpaces();\n      };\n\n      Source.prototype._isCurrentSpace = function() {\n        var character = this._string[this._currentIndex];\n        return (\n          character <= ' ' &&\n          (character == ' ' ||\n            character == '\\n' ||\n            character == '\\t' ||\n            character == '\\r' ||\n            character == '\\f')\n        )\n      };\n\n      Source.prototype._skipOptionalSpaces = function() {\n        while (this._currentIndex < this._endIndex && this._isCurrentSpace())\n          this._currentIndex++;\n        return this._currentIndex < this._endIndex\n      };\n\n      Source.prototype._skipOptionalSpacesOrDelimiter = function() {\n        if (\n          this._currentIndex < this._endIndex &&\n          !this._isCurrentSpace() &&\n          this._string.charAt(this._currentIndex) != ','\n        )\n          return false\n        if (this._skipOptionalSpaces()) {\n          if (\n            this._currentIndex < this._endIndex &&\n            this._string.charAt(this._currentIndex) == ','\n          ) {\n            this._currentIndex++;\n            this._skipOptionalSpaces();\n          }\n        }\n        return this._currentIndex < this._endIndex\n      };\n\n      Source.prototype.hasMoreData = function() {\n        return this._currentIndex < this._endIndex\n      };\n\n      Source.prototype.peekSegmentType = function() {\n        var lookahead = this._string[this._currentIndex];\n        return this._pathSegTypeFromChar(lookahead)\n      };\n\n      Source.prototype._pathSegTypeFromChar = function(lookahead) {\n        switch (lookahead) {\n          case 'Z':\n          case 'z':\n            return window.SVGPathSeg.PATHSEG_CLOSEPATH\n          case 'M':\n            return window.SVGPathSeg.PATHSEG_MOVETO_ABS\n          case 'm':\n            return window.SVGPathSeg.PATHSEG_MOVETO_REL\n          case 'L':\n            return window.SVGPathSeg.PATHSEG_LINETO_ABS\n          case 'l':\n            return window.SVGPathSeg.PATHSEG_LINETO_REL\n          case 'C':\n            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS\n          case 'c':\n            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL\n          case 'Q':\n            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS\n          case 'q':\n            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL\n          case 'A':\n            return window.SVGPathSeg.PATHSEG_ARC_ABS\n          case 'a':\n            return window.SVGPathSeg.PATHSEG_ARC_REL\n          case 'H':\n            return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS\n          case 'h':\n            return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL\n          case 'V':\n            return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS\n          case 'v':\n            return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL\n          case 'S':\n            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS\n          case 's':\n            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL\n          case 'T':\n            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS\n          case 't':\n            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL\n          default:\n            return window.SVGPathSeg.PATHSEG_UNKNOWN\n        }\n      };\n\n      Source.prototype._nextCommandHelper = function(\n        lookahead,\n        previousCommand\n      ) {\n        // Check for remaining coordinates in the current command.\n        if (\n          (lookahead == '+' ||\n            lookahead == '-' ||\n            lookahead == '.' ||\n            (lookahead >= '0' && lookahead <= '9')) &&\n          previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH\n        ) {\n          if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS)\n            return window.SVGPathSeg.PATHSEG_LINETO_ABS\n          if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL)\n            return window.SVGPathSeg.PATHSEG_LINETO_REL\n          return previousCommand\n        }\n        return window.SVGPathSeg.PATHSEG_UNKNOWN\n      };\n\n      Source.prototype.initialCommandIsMoveTo = function() {\n        // If the path is empty it is still valid, so return true.\n        if (!this.hasMoreData()) return true\n        var command = this.peekSegmentType();\n        // Path must start with moveTo.\n        return (\n          command == window.SVGPathSeg.PATHSEG_MOVETO_ABS ||\n          command == window.SVGPathSeg.PATHSEG_MOVETO_REL\n        )\n      };\n\n      // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.\n      // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF\n      Source.prototype._parseNumber = function() {\n        var exponent = 0;\n        var integer = 0;\n        var frac = 1;\n        var decimal = 0;\n        var sign = 1;\n        var expsign = 1;\n\n        var startIndex = this._currentIndex;\n\n        this._skipOptionalSpaces();\n\n        // Read the sign.\n        if (\n          this._currentIndex < this._endIndex &&\n          this._string.charAt(this._currentIndex) == '+'\n        )\n          this._currentIndex++;\n        else if (\n          this._currentIndex < this._endIndex &&\n          this._string.charAt(this._currentIndex) == '-'\n        ) {\n          this._currentIndex++;\n          sign = -1;\n        }\n\n        if (\n          this._currentIndex == this._endIndex ||\n          ((this._string.charAt(this._currentIndex) < '0' ||\n            this._string.charAt(this._currentIndex) > '9') &&\n            this._string.charAt(this._currentIndex) != '.')\n        )\n          // The first character of a number must be one of [0-9+-.].\n          return undefined\n\n        // Read the integer part, build right-to-left.\n        var startIntPartIndex = this._currentIndex;\n        while (\n          this._currentIndex < this._endIndex &&\n          this._string.charAt(this._currentIndex) >= '0' &&\n          this._string.charAt(this._currentIndex) <= '9'\n        )\n          this._currentIndex++; // Advance to first non-digit.\n\n        if (this._currentIndex != startIntPartIndex) {\n          var scanIntPartIndex = this._currentIndex - 1;\n          var multiplier = 1;\n          while (scanIntPartIndex >= startIntPartIndex) {\n            integer +=\n              multiplier * (this._string.charAt(scanIntPartIndex--) - '0');\n            multiplier *= 10;\n          }\n        }\n\n        // Read the decimals.\n        if (\n          this._currentIndex < this._endIndex &&\n          this._string.charAt(this._currentIndex) == '.'\n        ) {\n          this._currentIndex++;\n\n          // There must be a least one digit following the .\n          if (\n            this._currentIndex >= this._endIndex ||\n            this._string.charAt(this._currentIndex) < '0' ||\n            this._string.charAt(this._currentIndex) > '9'\n          )\n            return undefined\n          while (\n            this._currentIndex < this._endIndex &&\n            this._string.charAt(this._currentIndex) >= '0' &&\n            this._string.charAt(this._currentIndex) <= '9'\n          ) {\n            frac *= 10;\n            decimal += (this._string.charAt(this._currentIndex) - '0') / frac;\n            this._currentIndex += 1;\n          }\n        }\n\n        // Read the exponent part.\n        if (\n          this._currentIndex != startIndex &&\n          this._currentIndex + 1 < this._endIndex &&\n          (this._string.charAt(this._currentIndex) == 'e' ||\n            this._string.charAt(this._currentIndex) == 'E') &&\n          this._string.charAt(this._currentIndex + 1) != 'x' &&\n          this._string.charAt(this._currentIndex + 1) != 'm'\n        ) {\n          this._currentIndex++;\n\n          // Read the sign of the exponent.\n          if (this._string.charAt(this._currentIndex) == '+') {\n            this._currentIndex++;\n          } else if (this._string.charAt(this._currentIndex) == '-') {\n            this._currentIndex++;\n            expsign = -1;\n          }\n\n          // There must be an exponent.\n          if (\n            this._currentIndex >= this._endIndex ||\n            this._string.charAt(this._currentIndex) < '0' ||\n            this._string.charAt(this._currentIndex) > '9'\n          )\n            return undefined\n\n          while (\n            this._currentIndex < this._endIndex &&\n            this._string.charAt(this._currentIndex) >= '0' &&\n            this._string.charAt(this._currentIndex) <= '9'\n          ) {\n            exponent *= 10;\n            exponent += this._string.charAt(this._currentIndex) - '0';\n            this._currentIndex++;\n          }\n        }\n\n        var number = integer + decimal;\n        number *= sign;\n\n        if (exponent) number *= Math.pow(10, expsign * exponent);\n\n        if (startIndex == this._currentIndex) return undefined\n\n        this._skipOptionalSpacesOrDelimiter();\n\n        return number\n      };\n\n      Source.prototype._parseArcFlag = function() {\n        if (this._currentIndex >= this._endIndex) return undefined\n        var flag = false;\n        var flagChar = this._string.charAt(this._currentIndex++);\n        if (flagChar == '0') flag = false;\n        else if (flagChar == '1') flag = true;\n        else return undefined\n\n        this._skipOptionalSpacesOrDelimiter();\n        return flag\n      };\n\n      Source.prototype.parseSegment = function() {\n        var lookahead = this._string[this._currentIndex];\n        var command = this._pathSegTypeFromChar(lookahead);\n        if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {\n          // Possibly an implicit command. Not allowed if this is the first command.\n          if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN)\n            return null\n          command = this._nextCommandHelper(lookahead, this._previousCommand);\n          if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null\n        } else {\n          this._currentIndex++;\n        }\n\n        this._previousCommand = command;\n\n        switch (command) {\n          case window.SVGPathSeg.PATHSEG_MOVETO_REL:\n            return new window.SVGPathSegMovetoRel(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_MOVETO_ABS:\n            return new window.SVGPathSegMovetoAbs(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_REL:\n            return new window.SVGPathSegLinetoRel(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_ABS:\n            return new window.SVGPathSegLinetoAbs(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:\n            return new window.SVGPathSegLinetoHorizontalRel(\n              owningPathSegList,\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:\n            return new window.SVGPathSegLinetoHorizontalAbs(\n              owningPathSegList,\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:\n            return new window.SVGPathSegLinetoVerticalRel(\n              owningPathSegList,\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:\n            return new window.SVGPathSegLinetoVerticalAbs(\n              owningPathSegList,\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_CLOSEPATH:\n            this._skipOptionalSpaces();\n            return new window.SVGPathSegClosePath(owningPathSegList)\n          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              x2: this._parseNumber(),\n              y2: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegCurvetoCubicRel(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1,\n              points.x2,\n              points.y2\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              x2: this._parseNumber(),\n              y2: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegCurvetoCubicAbs(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1,\n              points.x2,\n              points.y2\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:\n            var points = {\n              x2: this._parseNumber(),\n              y2: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegCurvetoCubicSmoothRel(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x2,\n              points.y2\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:\n            var points = {\n              x2: this._parseNumber(),\n              y2: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegCurvetoCubicSmoothAbs(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x2,\n              points.y2\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegCurvetoQuadraticRel(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegCurvetoQuadraticAbs(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:\n            return new window.SVGPathSegCurvetoQuadraticSmoothRel(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:\n            return new window.SVGPathSegCurvetoQuadraticSmoothAbs(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_ARC_REL:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              arcAngle: this._parseNumber(),\n              arcLarge: this._parseArcFlag(),\n              arcSweep: this._parseArcFlag(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegArcRel(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1,\n              points.arcAngle,\n              points.arcLarge,\n              points.arcSweep\n            )\n          case window.SVGPathSeg.PATHSEG_ARC_ABS:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              arcAngle: this._parseNumber(),\n              arcLarge: this._parseArcFlag(),\n              arcSweep: this._parseArcFlag(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            };\n            return new window.SVGPathSegArcAbs(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1,\n              points.arcAngle,\n              points.arcLarge,\n              points.arcSweep\n            )\n          default:\n            throw 'Unknown path seg type.'\n        }\n      };\n\n      var builder = new Builder();\n      var source = new Source(string);\n\n      if (!source.initialCommandIsMoveTo()) return []\n      while (source.hasMoreData()) {\n        var pathSeg = source.parseSegment();\n        if (!pathSeg) return []\n        builder.appendSegment(pathSeg);\n      }\n\n      return builder.pathSegList\n    };\n  }\n})();\n\n// String.padEnd polyfill for IE11\n//\n// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd\nif (!String.prototype.padEnd) {\n  String.prototype.padEnd = function padEnd(targetLength, padString) {\n    targetLength = targetLength >> 0; //floor if number or convert non-number to 0;\n    padString = String(typeof padString !== 'undefined' ? padString : ' ');\n    if (this.length > targetLength) {\n      return String(this)\n    } else {\n      targetLength = targetLength - this.length;\n      if (targetLength > padString.length) {\n        padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed\n      }\n      return String(this) + padString.slice(0, targetLength)\n    }\n  };\n}\n\n// Object.assign polyfill for IE11\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill\nif (typeof Object.assign !== 'function') {\n  // Must be writable: true, enumerable: false, configurable: true\n  Object.defineProperty(Object, 'assign', {\n    value: function assign(target, varArgs) {\n      if (target === null || target === undefined) {\n        throw new TypeError('Cannot convert undefined or null to object')\n      }\n\n      var to = Object(target);\n\n      for (var index = 1; index < arguments.length; index++) {\n        var nextSource = arguments[index];\n\n        if (nextSource !== null && nextSource !== undefined) {\n          for (var nextKey in nextSource) {\n            // Avoid bugs when hasOwnProperty is shadowed\n            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n              to[nextKey] = nextSource[nextKey];\n            }\n          }\n        }\n      }\n      return to\n    },\n    writable: true,\n    configurable: true\n  });\n}\n\n/* jshint ignore:end */\n\nChart.prototype.axis = function() {};\nChart.prototype.axis.labels = function(labels) {\n  var $$ = this.internal;\n  if (arguments.length) {\n    Object.keys(labels).forEach(function(axisId) {\n      $$.axis.setLabelText(axisId, labels[axisId]);\n    });\n    $$.axis.updateLabels();\n  }\n  // TODO: return some values?\n};\nChart.prototype.axis.max = function(max) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (arguments.length) {\n    if (typeof max === 'object') {\n      if (isValue(max.x)) {\n        config.axis_x_max = max.x;\n      }\n      if (isValue(max.y)) {\n        config.axis_y_max = max.y;\n      }\n      if (isValue(max.y2)) {\n        config.axis_y2_max = max.y2;\n      }\n    } else {\n      config.axis_y_max = config.axis_y2_max = max;\n    }\n    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\n  } else {\n    return {\n      x: config.axis_x_max,\n      y: config.axis_y_max,\n      y2: config.axis_y2_max\n    }\n  }\n};\nChart.prototype.axis.min = function(min) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (arguments.length) {\n    if (typeof min === 'object') {\n      if (isValue(min.x)) {\n        config.axis_x_min = min.x;\n      }\n      if (isValue(min.y)) {\n        config.axis_y_min = min.y;\n      }\n      if (isValue(min.y2)) {\n        config.axis_y2_min = min.y2;\n      }\n    } else {\n      config.axis_y_min = config.axis_y2_min = min;\n    }\n    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\n  } else {\n    return {\n      x: config.axis_x_min,\n      y: config.axis_y_min,\n      y2: config.axis_y2_min\n    }\n  }\n};\nChart.prototype.axis.range = function(range) {\n  if (arguments.length) {\n    if (isDefined(range.max)) {\n      this.axis.max(range.max);\n    }\n    if (isDefined(range.min)) {\n      this.axis.min(range.min);\n    }\n  } else {\n    return {\n      max: this.axis.max(),\n      min: this.axis.min()\n    }\n  }\n};\n\nChart.prototype.axis.types = function(types) {\n  const $$ = this.internal;\n  if (types === undefined) {\n    return {\n      y: $$.config.axis_y_type,\n      y2: $$.config.axis_y2_type\n    }\n  } else {\n    if (isDefined(types.y)) {\n      $$.config.axis_y_type = types.y;\n    }\n\n    if (isDefined(types.y2)) {\n      $$.config.axis_y2_type = types.y2;\n    }\n\n    $$.updateScales();\n    $$.redraw();\n  }\n};\n\nChart.prototype.category = function(i, category) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (arguments.length > 1) {\n    config.axis_x_categories[i] = category;\n    $$.redraw();\n  }\n  return config.axis_x_categories[i]\n};\nChart.prototype.categories = function(categories) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (!arguments.length) {\n    return config.axis_x_categories\n  }\n  config.axis_x_categories = categories;\n  $$.redraw();\n  return config.axis_x_categories\n};\n\nChart.prototype.resize = function(size) {\n  var $$ = this.internal,\n    config = $$.config;\n  config.size_width = size ? size.width : null;\n  config.size_height = size ? size.height : null;\n  this.flush();\n};\n\nChart.prototype.flush = function() {\n  var $$ = this.internal;\n  $$.updateAndRedraw({\n    withLegend: true,\n    withTransition: false,\n    withTransitionForTransform: false\n  });\n};\n\nChart.prototype.destroy = function() {\n  var $$ = this.internal;\n\n  window.clearInterval($$.intervalForObserveInserted);\n\n  if ($$.resizeTimeout !== undefined) {\n    window.clearTimeout($$.resizeTimeout);\n  }\n\n  if (window.detachEvent) {\n    window.detachEvent('onresize', $$.resizeIfElementDisplayed);\n  } else if (window.removeEventListener) {\n    window.removeEventListener('resize', $$.resizeIfElementDisplayed);\n  } else {\n    var wrapper = window.onresize;\n    // check if no one else removed our wrapper and remove our resizeFunction from it\n    if (wrapper && wrapper.add && wrapper.remove) {\n      wrapper.remove($$.resizeFunction);\n    }\n  }\n\n  // Removes the inner resize functions\n  $$.resizeFunction.remove();\n\n  // Unbinds from the window focus event\n  $$.unbindWindowFocus();\n\n  $$.selectChart.classed('c3', false).html('');\n\n  // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen.\n  Object.keys($$).forEach(function(key) {\n    $$[key] = null;\n  });\n\n  return null\n};\n\n// TODO: fix\nChart.prototype.color = function(id) {\n  var $$ = this.internal;\n  return $$.color(id) // more patterns\n};\n\nChart.prototype.data = function(targetIds) {\n  var targets = this.internal.data.targets;\n  return typeof targetIds === 'undefined'\n    ? targets\n    : targets.filter(function(t) {\n        return [].concat(targetIds).indexOf(t.id) >= 0\n      })\n};\nChart.prototype.data.shown = function(targetIds) {\n  return this.internal.filterTargetsToShow(this.data(targetIds))\n};\n\n/**\n * Get values of the data loaded in the chart.\n *\n * @param {String|Array} targetId This API returns the value of specified target.\n * @param flat\n * @return {Array} Data values\n */\nChart.prototype.data.values = function(targetId, flat = true) {\n  let values = null;\n\n  if (targetId) {\n    const targets = this.data(targetId);\n    if (targets && isArray(targets)) {\n      values = targets.reduce((ret, v) => {\n        const dataValue = v.values.map(d => d.value);\n        if (flat) {\n          ret = ret.concat(dataValue);\n        } else {\n          ret.push(dataValue);\n        }\n        return ret\n      }, []);\n    }\n  }\n\n  return values\n};\nChart.prototype.data.names = function(names) {\n  this.internal.clearLegendItemTextBoxCache();\n  return this.internal.updateDataAttributes('names', names)\n};\nChart.prototype.data.colors = function(colors) {\n  return this.internal.updateDataAttributes('colors', colors)\n};\nChart.prototype.data.axes = function(axes) {\n  return this.internal.updateDataAttributes('axes', axes)\n};\n\nChart.prototype.data.stackNormalized = function(normalized) {\n  if (normalized === undefined) {\n    return this.internal.isStackNormalized()\n  }\n\n  this.internal.config.data_stack_normalize = !!normalized;\n  this.internal.redraw();\n};\n\nChart.prototype.donut = function() {};\n\nChart.prototype.donut.padAngle = function(padAngle) {\n  if (padAngle === undefined) {\n    return this.internal.config.donut_padAngle\n  }\n  this.internal.config.donut_padAngle = padAngle;\n  this.flush();\n};\n\nChart.prototype.flow = function(args) {\n  var $$ = this.internal,\n    targets,\n    data,\n    notfoundIds = [],\n    orgDataCount = $$.getMaxDataCount(),\n    dataCount,\n    domain,\n    baseTarget,\n    baseValue,\n    length = 0,\n    tail = 0,\n    diff,\n    to;\n\n  if (args.json) {\n    data = $$.convertJsonToData(args.json, args.keys);\n  } else if (args.rows) {\n    data = $$.convertRowsToData(args.rows);\n  } else if (args.columns) {\n    data = $$.convertColumnsToData(args.columns);\n  } else {\n    return\n  }\n  targets = $$.convertDataToTargets(data, true);\n\n  // Update/Add data\n  $$.data.targets.forEach(function(t) {\n    var found = false,\n      i,\n      j;\n    for (i = 0; i < targets.length; i++) {\n      if (t.id === targets[i].id) {\n        found = true;\n\n        if (t.values[t.values.length - 1]) {\n          tail = t.values[t.values.length - 1].index + 1;\n        }\n        length = targets[i].values.length;\n\n        for (j = 0; j < length; j++) {\n          targets[i].values[j].index = tail + j;\n          if (!$$.isTimeSeries()) {\n            targets[i].values[j].x = tail + j;\n          }\n        }\n        t.values = t.values.concat(targets[i].values);\n\n        targets.splice(i, 1);\n        break\n      }\n    }\n    if (!found) {\n      notfoundIds.push(t.id);\n    }\n  });\n\n  // Append null for not found targets\n  $$.data.targets.forEach(function(t) {\n    var i, j;\n    for (i = 0; i < notfoundIds.length; i++) {\n      if (t.id === notfoundIds[i]) {\n        tail = t.values[t.values.length - 1].index + 1;\n        for (j = 0; j < length; j++) {\n          t.values.push({\n            id: t.id,\n            index: tail + j,\n            x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,\n            value: null\n          });\n        }\n      }\n    }\n  });\n\n  // Generate null values for new target\n  if ($$.data.targets.length) {\n    targets.forEach(function(t) {\n      var i,\n        missing = [];\n      for (i = $$.data.targets[0].values[0].index; i < tail; i++) {\n        missing.push({\n          id: t.id,\n          index: i,\n          x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,\n          value: null\n        });\n      }\n      t.values.forEach(function(v) {\n        v.index += tail;\n        if (!$$.isTimeSeries()) {\n          v.x += tail;\n        }\n      });\n      t.values = missing.concat(t.values);\n    });\n  }\n  $$.data.targets = $$.data.targets.concat(targets); // add remained\n\n  // check data count because behavior needs to change when it's only one\n  dataCount = $$.getMaxDataCount();\n  baseTarget = $$.data.targets[0];\n  baseValue = baseTarget.values[0];\n\n  // Update length to flow if needed\n  if (isDefined(args.to)) {\n    length = 0;\n    to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to;\n    baseTarget.values.forEach(function(v) {\n      if (v.x < to) {\n        length++;\n      }\n    });\n  } else if (isDefined(args.length)) {\n    length = args.length;\n  }\n\n  // If only one data, update the domain to flow from left edge of the chart\n  if (!orgDataCount) {\n    if ($$.isTimeSeries()) {\n      if (baseTarget.values.length > 1) {\n        diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x;\n      } else {\n        diff = baseValue.x - $$.getXDomain($$.data.targets)[0];\n      }\n    } else {\n      diff = 1;\n    }\n    domain = [baseValue.x - diff, baseValue.x];\n    $$.updateXDomain(null, true, true, false, domain);\n  } else if (orgDataCount === 1) {\n    if ($$.isTimeSeries()) {\n      diff =\n        (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;\n      domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];\n      $$.updateXDomain(null, true, true, false, domain);\n    }\n  }\n\n  // Set targets\n  $$.updateTargets($$.data.targets);\n\n  // Redraw with new targets\n  $$.redraw({\n    flow: {\n      index: baseValue.index,\n      length: length,\n      duration: isValue(args.duration)\n        ? args.duration\n        : $$.config.transition_duration,\n      done: args.done,\n      orgDataCount: orgDataCount\n    },\n    withLegend: true,\n    withTransition: orgDataCount > 1,\n    withTrimXDomain: false,\n    withUpdateXAxis: true\n  });\n};\n\nChartInternal.prototype.generateFlow = function(args) {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3;\n\n  return function() {\n    var targets = args.targets,\n      flow = args.flow,\n      drawBar = args.drawBar,\n      drawLine = args.drawLine,\n      drawArea = args.drawArea,\n      cx = args.cx,\n      cy = args.cy,\n      xv = args.xv,\n      xForText = args.xForText,\n      yForText = args.yForText,\n      duration = args.duration;\n\n    var translateX,\n      scaleX = 1,\n      transform,\n      flowIndex = flow.index,\n      flowLength = flow.length,\n      flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex),\n      flowEnd = $$.getValueOnIndex(\n        $$.data.targets[0].values,\n        flowIndex + flowLength\n      ),\n      orgDomain = $$.x.domain(),\n      domain,\n      durationForFlow = flow.duration || duration,\n      done = flow.done || function() {},\n      wait = $$.generateWait();\n\n    var xgrid,\n      xgridLines,\n      mainRegion,\n      mainText,\n      mainBar,\n      mainLine,\n      mainArea,\n      mainCircle;\n\n    // set flag\n    $$.flowing = true;\n\n    // remove head data after rendered\n    $$.data.targets.forEach(function(d) {\n      d.values.splice(0, flowLength);\n    });\n\n    // update x domain to generate axis elements for flow\n    domain = $$.updateXDomain(targets, true, true);\n    // update elements related to x scale\n    if ($$.updateXGrid) {\n      $$.updateXGrid(true);\n    }\n\n    xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid\n    xgridLines = $$.xgridLines || d3.selectAll([]);\n    mainRegion = $$.mainRegion || d3.selectAll([]);\n    mainText = $$.mainText || d3.selectAll([]);\n    mainBar = $$.mainBar || d3.selectAll([]);\n    mainLine = $$.mainLine || d3.selectAll([]);\n    mainArea = $$.mainArea || d3.selectAll([]);\n    mainCircle = $$.mainCircle || d3.selectAll([]);\n\n    // generate transform to flow\n    if (!flow.orgDataCount) {\n      // if empty\n      if ($$.data.targets[0].values.length !== 1) {\n        translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);\n      } else {\n        if ($$.isTimeSeries()) {\n          flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0);\n          flowEnd = $$.getValueOnIndex(\n            $$.data.targets[0].values,\n            $$.data.targets[0].values.length - 1\n          );\n          translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);\n        } else {\n          translateX = diffDomain(domain) / 2;\n        }\n      }\n    } else if (\n      flow.orgDataCount === 1 ||\n      (flowStart && flowStart.x) === (flowEnd && flowEnd.x)\n    ) {\n      translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);\n    } else {\n      if ($$.isTimeSeries()) {\n        translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);\n      } else {\n        translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);\n      }\n    }\n    scaleX = diffDomain(orgDomain) / diffDomain(domain);\n    transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)';\n\n    $$.hideXGridFocus();\n\n    var flowTransition = d3\n      .transition()\n      .ease(d3.easeLinear)\n      .duration(durationForFlow);\n    wait.add($$.xAxis($$.axes.x, flowTransition));\n    wait.add(mainBar.transition(flowTransition).attr('transform', transform));\n    wait.add(mainLine.transition(flowTransition).attr('transform', transform));\n    wait.add(mainArea.transition(flowTransition).attr('transform', transform));\n    wait.add(mainCircle.transition(flowTransition).attr('transform', transform));\n    wait.add(mainText.transition(flowTransition).attr('transform', transform));\n    wait.add(\n      mainRegion\n        .filter($$.isRegionOnX)\n        .transition(flowTransition)\n        .attr('transform', transform)\n    );\n    wait.add(xgrid.transition(flowTransition).attr('transform', transform));\n    wait.add(xgridLines.transition(flowTransition).attr('transform', transform));\n    wait(function() {\n      var i,\n        shapes = [],\n        texts = [];\n\n      // remove flowed elements\n      if (flowLength) {\n        for (i = 0; i < flowLength; i++) {\n          shapes.push('.' + CLASS.shape + '-' + (flowIndex + i));\n          texts.push('.' + CLASS.text + '-' + (flowIndex + i));\n        }\n        $$.svg\n          .selectAll('.' + CLASS.shapes)\n          .selectAll(shapes)\n          .remove();\n        $$.svg\n          .selectAll('.' + CLASS.texts)\n          .selectAll(texts)\n          .remove();\n        $$.svg.select('.' + CLASS.xgrid).remove();\n      }\n\n      // draw again for removing flowed elements and reverting attr\n      xgrid\n        .attr('transform', null)\n        .attr('x1', $$.xgridAttr.x1)\n        .attr('x2', $$.xgridAttr.x2)\n        .attr('y1', $$.xgridAttr.y1)\n        .attr('y2', $$.xgridAttr.y2)\n        .style('opacity', $$.xgridAttr.opacity);\n      xgridLines.attr('transform', null);\n      xgridLines\n        .select('line')\n        .attr('x1', config.axis_rotated ? 0 : xv)\n        .attr('x2', config.axis_rotated ? $$.width : xv);\n      xgridLines\n        .select('text')\n        .attr('x', config.axis_rotated ? $$.width : 0)\n        .attr('y', xv);\n      mainBar.attr('transform', null).attr('d', drawBar);\n      mainLine.attr('transform', null).attr('d', drawLine);\n      mainArea.attr('transform', null).attr('d', drawArea);\n      mainCircle\n        .attr('transform', null)\n        .attr('cx', cx)\n        .attr('cy', cy);\n      mainText\n        .attr('transform', null)\n        .attr('x', xForText)\n        .attr('y', yForText)\n        .style('fill-opacity', $$.opacityForText.bind($$));\n      mainRegion.attr('transform', null);\n      mainRegion\n        .filter($$.isRegionOnX)\n        .attr('x', $$.regionX.bind($$))\n        .attr('width', $$.regionWidth.bind($$));\n\n      // callback for end of flow\n      done();\n\n      $$.flowing = false;\n    });\n  }\n};\n\nChart.prototype.focus = function(targetIds) {\n  var $$ = this.internal,\n    candidates;\n\n  targetIds = $$.mapToTargetIds(targetIds)\n  ;(candidates = $$.svg.selectAll(\n    $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))\n  )),\n    this.revert();\n  this.defocus();\n  candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false);\n  if ($$.hasArcType()) {\n    $$.expandArc(targetIds);\n  }\n  $$.toggleFocusLegend(targetIds, true);\n\n  $$.focusedTargetIds = targetIds;\n  $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function(id) {\n    return targetIds.indexOf(id) < 0\n  });\n};\n\nChart.prototype.defocus = function(targetIds) {\n  var $$ = this.internal,\n    candidates;\n\n  targetIds = $$.mapToTargetIds(targetIds)\n  ;(candidates = $$.svg.selectAll(\n    $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))\n  )),\n    candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true);\n  if ($$.hasArcType()) {\n    $$.unexpandArc(targetIds);\n  }\n  $$.toggleFocusLegend(targetIds, false);\n\n  $$.focusedTargetIds = $$.focusedTargetIds.filter(function(id) {\n    return targetIds.indexOf(id) < 0\n  });\n  $$.defocusedTargetIds = targetIds;\n};\n\nChart.prototype.revert = function(targetIds) {\n  var $$ = this.internal,\n    candidates;\n\n  targetIds = $$.mapToTargetIds(targetIds);\n  candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets\n\n  candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false);\n  if ($$.hasArcType()) {\n    $$.unexpandArc(targetIds);\n  }\n  if ($$.config.legend_show) {\n    $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$)));\n    $$.legend\n      .selectAll($$.selectorLegends(targetIds))\n      .filter(function() {\n        return $$.d3.select(this).classed(CLASS.legendItemFocused)\n      })\n      .classed(CLASS.legendItemFocused, false);\n  }\n\n  $$.focusedTargetIds = [];\n  $$.defocusedTargetIds = [];\n};\n\nChart.prototype.xgrids = function(grids) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (!grids) {\n    return config.grid_x_lines\n  }\n  config.grid_x_lines = grids;\n  $$.redrawWithoutRescale();\n  return config.grid_x_lines\n};\nChart.prototype.xgrids.add = function(grids) {\n  var $$ = this.internal;\n  return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : []))\n};\nChart.prototype.xgrids.remove = function(params) {\n  // TODO: multiple\n  var $$ = this.internal;\n  $$.removeGridLines(params, true);\n};\n\nChart.prototype.ygrids = function(grids) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (!grids) {\n    return config.grid_y_lines\n  }\n  config.grid_y_lines = grids;\n  $$.redrawWithoutRescale();\n  return config.grid_y_lines\n};\nChart.prototype.ygrids.add = function(grids) {\n  var $$ = this.internal;\n  return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : []))\n};\nChart.prototype.ygrids.remove = function(params) {\n  // TODO: multiple\n  var $$ = this.internal;\n  $$.removeGridLines(params, false);\n};\n\nChart.prototype.groups = function(groups) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (isUndefined(groups)) {\n    return config.data_groups\n  }\n  config.data_groups = groups;\n  $$.redraw();\n  return config.data_groups\n};\n\nChart.prototype.legend = function() {};\nChart.prototype.legend.show = function(targetIds) {\n  var $$ = this.internal;\n  $$.showLegend($$.mapToTargetIds(targetIds));\n  $$.updateAndRedraw({ withLegend: true });\n};\nChart.prototype.legend.hide = function(targetIds) {\n  var $$ = this.internal;\n  $$.hideLegend($$.mapToTargetIds(targetIds));\n  $$.updateAndRedraw({ withLegend: false });\n};\n\nChart.prototype.load = function(args) {\n  var $$ = this.internal,\n    config = $$.config;\n  // update xs if specified\n  if (args.xs) {\n    $$.addXs(args.xs);\n  }\n  // update names if exists\n  if ('names' in args) {\n    Chart.prototype.data.names.bind(this)(args.names);\n  }\n  // update classes if exists\n  if ('classes' in args) {\n    Object.keys(args.classes).forEach(function(id) {\n      config.data_classes[id] = args.classes[id];\n    });\n  }\n  // update categories if exists\n  if ('categories' in args && $$.isCategorized()) {\n    config.axis_x_categories = args.categories;\n  }\n  // update axes if exists\n  if ('axes' in args) {\n    Object.keys(args.axes).forEach(function(id) {\n      config.data_axes[id] = args.axes[id];\n    });\n  }\n  // update colors if exists\n  if ('colors' in args) {\n    Object.keys(args.colors).forEach(function(id) {\n      config.data_colors[id] = args.colors[id];\n    });\n  }\n  // use cache if exists\n  if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) {\n    $$.load($$.getCaches(args.cacheIds), args.done);\n    return\n  }\n  // unload if needed\n  if (args.unload) {\n    // TODO: do not unload if target will load (included in url/rows/columns)\n    $$.unload(\n      $$.mapToTargetIds(args.unload === true ? null : args.unload),\n      function() {\n        $$.loadFromArgs(args);\n      }\n    );\n  } else {\n    $$.loadFromArgs(args);\n  }\n};\n\nChart.prototype.unload = function(args) {\n  var $$ = this.internal;\n  args = args || {};\n  if (args instanceof Array) {\n    args = { ids: args };\n  } else if (typeof args === 'string') {\n    args = { ids: [args] };\n  }\n  $$.unload($$.mapToTargetIds(args.ids), function() {\n    $$.redraw({\n      withUpdateOrgXDomain: true,\n      withUpdateXDomain: true,\n      withLegend: true\n    });\n    if (args.done) {\n      args.done();\n    }\n  });\n};\n\nChart.prototype.pie = function() {};\n\nChart.prototype.pie.padAngle = function(padAngle) {\n  if (padAngle === undefined) {\n    return this.internal.config.pie_padAngle\n  }\n  this.internal.config.pie_padAngle = padAngle;\n  this.flush();\n};\n\nChart.prototype.regions = function(regions) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (!regions) {\n    return config.regions\n  }\n  config.regions = regions;\n  $$.redrawWithoutRescale();\n  return config.regions\n};\nChart.prototype.regions.add = function(regions) {\n  var $$ = this.internal,\n    config = $$.config;\n  if (!regions) {\n    return config.regions\n  }\n  config.regions = config.regions.concat(regions);\n  $$.redrawWithoutRescale();\n  return config.regions\n};\nChart.prototype.regions.remove = function(options) {\n  var $$ = this.internal,\n    config = $$.config,\n    duration,\n    classes,\n    regions;\n\n  options = options || {};\n  duration = getOption(options, 'duration', config.transition_duration);\n  classes = getOption(options, 'classes', [CLASS.region]);\n\n  regions = $$.main.select('.' + CLASS.regions).selectAll(\n    classes.map(function(c) {\n      return '.' + c\n    })\n  )\n  ;(duration ? regions.transition().duration(duration) : regions)\n    .style('opacity', 0)\n    .remove();\n\n  config.regions = config.regions.filter(function(region) {\n    var found = false;\n    if (!region['class']) {\n      return true\n    }\n    region['class'].split(' ').forEach(function(c) {\n      if (classes.indexOf(c) >= 0) {\n        found = true;\n      }\n    });\n    return !found\n  });\n\n  return config.regions\n};\n\nChart.prototype.selected = function(targetId) {\n  var $$ = this.internal,\n    d3 = $$.d3;\n  return $$.main\n    .selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId))\n    .selectAll('.' + CLASS.shape)\n    .filter(function() {\n      return d3.select(this).classed(CLASS.SELECTED)\n    })\n    .nodes()\n    .map(function(d) {\n      var data = d.__data__;\n      return data.data ? data.data : data\n    })\n};\nChart.prototype.select = function(ids, indices, resetOther) {\n  var $$ = this.internal,\n    d3 = $$.d3,\n    config = $$.config;\n  if (!config.data_selection_enabled) {\n    return\n  }\n  $$.main\n    .selectAll('.' + CLASS.shapes)\n    .selectAll('.' + CLASS.shape)\n    .each(function(d, i) {\n      var shape = d3.select(this),\n        id = d.data ? d.data.id : d.id,\n        toggle = $$.getToggle(this, d).bind($$),\n        isTargetId =\n          config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,\n        isTargetIndex = !indices || indices.indexOf(i) >= 0,\n        isSelected = shape.classed(CLASS.SELECTED);\n      // line/area selection not supported yet\n      if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {\n        return\n      }\n      if (isTargetId && isTargetIndex) {\n        if (config.data_selection_isselectable(d) && !isSelected) {\n          toggle(true, shape.classed(CLASS.SELECTED, true), d, i);\n        }\n      } else if (isDefined(resetOther) && resetOther) {\n        if (isSelected) {\n          toggle(false, shape.classed(CLASS.SELECTED, false), d, i);\n        }\n      }\n    });\n};\nChart.prototype.unselect = function(ids, indices) {\n  var $$ = this.internal,\n    d3 = $$.d3,\n    config = $$.config;\n  if (!config.data_selection_enabled) {\n    return\n  }\n  $$.main\n    .selectAll('.' + CLASS.shapes)\n    .selectAll('.' + CLASS.shape)\n    .each(function(d, i) {\n      var shape = d3.select(this),\n        id = d.data ? d.data.id : d.id,\n        toggle = $$.getToggle(this, d).bind($$),\n        isTargetId =\n          config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,\n        isTargetIndex = !indices || indices.indexOf(i) >= 0,\n        isSelected = shape.classed(CLASS.SELECTED);\n      // line/area selection not supported yet\n      if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {\n        return\n      }\n      if (isTargetId && isTargetIndex) {\n        if (config.data_selection_isselectable(d)) {\n          if (isSelected) {\n            toggle(false, shape.classed(CLASS.SELECTED, false), d, i);\n          }\n        }\n      }\n    });\n};\n\nChart.prototype.show = function(targetIds, options) {\n  var $$ = this.internal,\n    targets;\n\n  targetIds = $$.mapToTargetIds(targetIds);\n  options = options || {};\n\n  $$.removeHiddenTargetIds(targetIds);\n  targets = $$.svg.selectAll($$.selectorTargets(targetIds));\n\n  targets\n    .transition()\n    .style('display', isIE() ? 'block' : 'initial', 'important')\n    .style('opacity', 1, 'important')\n    .call($$.endall, function() {\n      targets.style('opacity', null).style('opacity', 1);\n    });\n\n  if (options.withLegend) {\n    $$.showLegend(targetIds);\n  }\n\n  $$.redraw({\n    withUpdateOrgXDomain: true,\n    withUpdateXDomain: true,\n    withLegend: true\n  });\n};\n\nChart.prototype.hide = function(targetIds, options) {\n  var $$ = this.internal,\n    targets;\n\n  targetIds = $$.mapToTargetIds(targetIds);\n  options = options || {};\n\n  $$.addHiddenTargetIds(targetIds);\n  targets = $$.svg.selectAll($$.selectorTargets(targetIds));\n\n  targets\n    .transition()\n    .style('opacity', 0, 'important')\n    .call($$.endall, function() {\n      targets.style('opacity', null).style('opacity', 0);\n      targets.style('display', 'none');\n    });\n\n  if (options.withLegend) {\n    $$.hideLegend(targetIds);\n  }\n\n  $$.redraw({\n    withUpdateOrgXDomain: true,\n    withUpdateXDomain: true,\n    withLegend: true\n  });\n};\n\nChart.prototype.toggle = function(targetIds, options) {\n  var that = this,\n    $$ = this.internal;\n  $$.mapToTargetIds(targetIds).forEach(function(targetId) {\n    $$.isTargetToShow(targetId)\n      ? that.hide(targetId, options)\n      : that.show(targetId, options);\n  });\n};\n\nChart.prototype.subchart = function() {};\n\nChart.prototype.subchart.isShown = function() {\n  const $$ = this.internal;\n\n  return $$.config.subchart_show\n};\n\nChart.prototype.subchart.show = function() {\n  const $$ = this.internal;\n\n  if ($$.config.subchart_show) {\n    return\n  }\n\n  $$.config.subchart_show = true;\n\n  // insert DOM\n  $$.initSubchart();\n\n  // update dimensions with sub chart now visible\n  $$.updateDimension();\n\n  // insert brush (depends on sizes previously updated)\n  $$.initSubchartBrush();\n\n  // attach data\n  $$.updateTargetsForSubchart($$.getTargets());\n\n  // reset fade-in state\n  $$.mapToIds($$.data.targets).forEach(function(id) {\n    $$.withoutFadeIn[id] = false;\n  });\n\n  // redraw chart !\n  $$.updateAndRedraw();\n\n  // update visible targets !\n  $$.showTargets();\n};\n\nChart.prototype.subchart.hide = function() {\n  const $$ = this.internal;\n\n  if (!$$.config.subchart_show) {\n    return\n  }\n\n  $$.config.subchart_show = false;\n\n  // remove DOM\n  $$.removeSubchart();\n\n  // re-render chart\n  $$.redraw();\n};\n\nChart.prototype.tooltip = function() {};\nChart.prototype.tooltip.show = function(args) {\n  var $$ = this.internal,\n    targets,\n    data,\n    mouse = {};\n\n  // determine mouse position on the chart\n  if (args.mouse) {\n    mouse = args.mouse;\n  } else {\n    // determine focus data\n    if (args.data) {\n      data = args.data;\n    } else if (typeof args.x !== 'undefined') {\n      if (args.id) {\n        targets = $$.data.targets.filter(function(t) {\n          return t.id === args.id\n        });\n      } else {\n        targets = $$.data.targets;\n      }\n      data = $$.filterByX(targets, args.x).slice(0, 1)[0];\n    }\n    mouse = data ? $$.getMousePosition(data) : null;\n  }\n\n  // emulate mouse events to show\n  $$.dispatchEvent('mousemove', mouse);\n\n  $$.config.tooltip_onshow.call($$, data);\n};\nChart.prototype.tooltip.hide = function() {\n  // TODO: get target data by checking the state of focus\n  this.internal.dispatchEvent('mouseout', 0);\n\n  this.internal.config.tooltip_onhide.call(this);\n};\n\nChart.prototype.transform = function(type, targetIds) {\n  var $$ = this.internal,\n    options =\n      ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null;\n  $$.transformTo(targetIds, type, options);\n};\n\nChartInternal.prototype.transformTo = function(\n  targetIds,\n  type,\n  optionsForRedraw\n) {\n  var $$ = this,\n    withTransitionForAxis = !$$.hasArcType(),\n    options = optionsForRedraw || {\n      withTransitionForAxis: withTransitionForAxis\n    };\n  options.withTransitionForTransform = false;\n  $$.transiting = false;\n  $$.setTargetType(targetIds, type);\n  $$.updateTargets($$.data.targets); // this is needed when transforming to arc\n  $$.updateAndRedraw(options);\n};\n\nChart.prototype.x = function(x) {\n  var $$ = this.internal;\n  if (arguments.length) {\n    $$.updateTargetX($$.data.targets, x);\n    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\n  }\n  return $$.data.xs\n};\nChart.prototype.xs = function(xs) {\n  var $$ = this.internal;\n  if (arguments.length) {\n    $$.updateTargetXs($$.data.targets, xs);\n    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\n  }\n  return $$.data.xs\n};\n\nChart.prototype.zoom = function(domain) {\n  var $$ = this.internal;\n  if (domain) {\n    if ($$.isTimeSeries()) {\n      domain = domain.map(function(x) {\n        return $$.parseDate(x)\n      });\n    }\n    if ($$.config.subchart_show) {\n      $$.brush.selectionAsValue(domain, true);\n    } else {\n      $$.updateXDomain(null, true, false, false, domain);\n      $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false });\n    }\n    $$.config.zoom_onzoom.call(this, $$.x.orgDomain());\n    return domain\n  } else {\n    return $$.x.domain()\n  }\n};\nChart.prototype.zoom.enable = function(enabled) {\n  var $$ = this.internal;\n  $$.config.zoom_enabled = enabled;\n  $$.updateAndRedraw();\n};\nChart.prototype.unzoom = function() {\n  var $$ = this.internal;\n  if ($$.config.subchart_show) {\n    $$.brush.clear();\n  } else {\n    $$.updateXDomain(null, true, false, false, $$.subX.domain());\n    $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false });\n  }\n};\n\nChart.prototype.zoom.max = function(max) {\n  var $$ = this.internal,\n    config = $$.config,\n    d3 = $$.d3;\n  if (max === 0 || max) {\n    config.zoom_x_max = d3.max([$$.orgXDomain[1], max]);\n  } else {\n    return config.zoom_x_max\n  }\n};\n\nChart.prototype.zoom.min = function(min) {\n  var $$ = this.internal,\n    config = $$.config,\n    d3 = $$.d3;\n  if (min === 0 || min) {\n    config.zoom_x_min = d3.min([$$.orgXDomain[0], min]);\n  } else {\n    return config.zoom_x_min\n  }\n};\n\nChart.prototype.zoom.range = function(range) {\n  if (arguments.length) {\n    if (isDefined(range.max)) {\n      this.domain.max(range.max);\n    }\n    if (isDefined(range.min)) {\n      this.domain.min(range.min);\n    }\n  } else {\n    return {\n      max: this.domain.max(),\n      min: this.domain.min()\n    }\n  }\n};\n\nChartInternal.prototype.initPie = function() {\n  var $$ = this,\n    d3 = $$.d3;\n  $$.pie = d3\n    .pie()\n    .padAngle(this.getPadAngle.bind(this))\n    .value(function(d) {\n      return d.values.reduce(function(a, b) {\n        return a + b.value\n      }, 0)\n    });\n\n  let orderFct = $$.getOrderFunction();\n\n  // we need to reverse the returned order if asc or desc to have the slice in expected order.\n  if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) {\n    let defaultSort = orderFct;\n    orderFct = (t1, t2) => defaultSort(t1, t2) * -1;\n  }\n\n  $$.pie.sort(orderFct || null);\n};\n\nChartInternal.prototype.updateRadius = function() {\n  var $$ = this,\n    config = $$.config,\n    w = config.gauge_width || config.donut_width,\n    gaugeArcWidth =\n      $$.filterTargetsToShow($$.data.targets).length *\n      $$.config.gauge_arcs_minWidth;\n  $$.radiusExpanded =\n    (Math.min($$.arcWidth, $$.arcHeight) / 2) * ($$.hasType('gauge') ? 0.85 : 1);\n  $$.radius = $$.radiusExpanded * 0.95;\n  $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6;\n  $$.innerRadius =\n    $$.hasType('donut') || $$.hasType('gauge')\n      ? $$.radius * $$.innerRadiusRatio\n      : 0;\n  $$.gaugeArcWidth = w\n    ? w\n    : gaugeArcWidth <= $$.radius - $$.innerRadius\n    ? $$.radius - $$.innerRadius\n    : gaugeArcWidth <= $$.radius\n    ? gaugeArcWidth\n    : $$.radius;\n};\n\nChartInternal.prototype.getPadAngle = function() {\n  if (this.hasType('pie')) {\n    return this.config.pie_padAngle || 0\n  } else if (this.hasType('donut')) {\n    return this.config.donut_padAngle || 0\n  } else {\n    return 0\n  }\n};\n\nChartInternal.prototype.updateArc = function() {\n  var $$ = this;\n  $$.svgArc = $$.getSvgArc();\n  $$.svgArcExpanded = $$.getSvgArcExpanded();\n  $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98);\n};\n\nChartInternal.prototype.updateAngle = function(d) {\n  var $$ = this,\n    config = $$.config,\n    found = false,\n    index = 0,\n    gMin,\n    gMax,\n    gTic,\n    gValue;\n\n  if (!config) {\n    return null\n  }\n\n  $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function(t) {\n    if (!found && t.data.id === d.data.id) {\n      found = true;\n      d = t;\n      d.index = index;\n    }\n    index++;\n  });\n  if (isNaN(d.startAngle)) {\n    d.startAngle = 0;\n  }\n  if (isNaN(d.endAngle)) {\n    d.endAngle = d.startAngle;\n  }\n  if ($$.isGaugeType(d.data)) {\n    gMin = config.gauge_min;\n    gMax = config.gauge_max;\n    gTic = (Math.PI * (config.gauge_fullCircle ? 2 : 1)) / (gMax - gMin);\n    gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin;\n    d.startAngle = config.gauge_startingAngle;\n    d.endAngle = d.startAngle + gTic * gValue;\n  }\n  return found ? d : null\n};\n\nChartInternal.prototype.getSvgArc = function() {\n  var $$ = this,\n    hasGaugeType = $$.hasType('gauge'),\n    singleArcWidth =\n      $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,\n    arc = $$.d3\n      .arc()\n      .outerRadius(function(d) {\n        return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius\n      })\n      .innerRadius(function(d) {\n        return hasGaugeType\n          ? $$.radius - singleArcWidth * (d.index + 1)\n          : $$.innerRadius\n      }),\n    newArc = function(d, withoutUpdate) {\n      var updated;\n      if (withoutUpdate) {\n        return arc(d)\n      } // for interpolate\n      updated = $$.updateAngle(d);\n      return updated ? arc(updated) : 'M 0 0'\n    };\n  // TODO: extends all function\n  newArc.centroid = arc.centroid;\n  return newArc\n};\n\nChartInternal.prototype.getSvgArcExpanded = function(rate) {\n  rate = rate || 1;\n  var $$ = this,\n    hasGaugeType = $$.hasType('gauge'),\n    singleArcWidth =\n      $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,\n    expandWidth = Math.min(\n      $$.radiusExpanded * rate - $$.radius,\n      singleArcWidth * 0.8 - (1 - rate) * 100\n    ),\n    arc = $$.d3\n      .arc()\n      .outerRadius(function(d) {\n        return hasGaugeType\n          ? $$.radius - singleArcWidth * d.index + expandWidth\n          : $$.radiusExpanded * rate\n      })\n      .innerRadius(function(d) {\n        return hasGaugeType\n          ? $$.radius - singleArcWidth * (d.index + 1)\n          : $$.innerRadius\n      });\n  return function(d) {\n    var updated = $$.updateAngle(d);\n    return updated ? arc(updated) : 'M 0 0'\n  }\n};\n\nChartInternal.prototype.getArc = function(d, withoutUpdate, force) {\n  return force || this.isArcType(d.data)\n    ? this.svgArc(d, withoutUpdate)\n    : 'M 0 0'\n};\n\nChartInternal.prototype.transformForArcLabel = function(d) {\n  var $$ = this,\n    config = $$.config,\n    updated = $$.updateAngle(d),\n    c,\n    x,\n    y,\n    h,\n    ratio,\n    translate = '',\n    hasGauge = $$.hasType('gauge');\n  if (updated && !hasGauge) {\n    c = this.svgArc.centroid(updated);\n    x = isNaN(c[0]) ? 0 : c[0];\n    y = isNaN(c[1]) ? 0 : c[1];\n    h = Math.sqrt(x * x + y * y);\n    if ($$.hasType('donut') && config.donut_label_ratio) {\n      ratio = isFunction(config.donut_label_ratio)\n        ? config.donut_label_ratio(d, $$.radius, h)\n        : config.donut_label_ratio;\n    } else if ($$.hasType('pie') && config.pie_label_ratio) {\n      ratio = isFunction(config.pie_label_ratio)\n        ? config.pie_label_ratio(d, $$.radius, h)\n        : config.pie_label_ratio;\n    } else {\n      ratio =\n        $$.radius && h\n          ? ((36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) *\n              $$.radius) /\n            h\n          : 0;\n    }\n    translate = 'translate(' + x * ratio + ',' + y * ratio + ')';\n  } else if (\n    updated &&\n    hasGauge &&\n    $$.filterTargetsToShow($$.data.targets).length > 1\n  ) {\n    var y1 = Math.sin(updated.endAngle - Math.PI / 2);\n    x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25);\n    y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3;\n    translate = 'translate(' + x + ',' + y + ')';\n  }\n  return translate\n};\n\n/**\n * @deprecated Use `getRatio('arc', d)` instead.\n */\nChartInternal.prototype.getArcRatio = function(d) {\n  return this.getRatio('arc', d)\n};\n\nChartInternal.prototype.convertToArcData = function(d) {\n  return this.addName({\n    id: d.data.id,\n    value: d.value,\n    ratio: this.getRatio('arc', d),\n    index: d.index\n  })\n};\n\nChartInternal.prototype.textForArcLabel = function(d) {\n  var $$ = this,\n    updated,\n    value,\n    ratio,\n    id,\n    format;\n  if (!$$.shouldShowArcLabel()) {\n    return ''\n  }\n  updated = $$.updateAngle(d);\n  value = updated ? updated.value : null;\n  ratio = $$.getRatio('arc', updated);\n  id = d.data.id;\n  if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) {\n    return ''\n  }\n  format = $$.getArcLabelFormat();\n  return format\n    ? format(value, ratio, id)\n    : $$.defaultArcValueFormat(value, ratio)\n};\n\nChartInternal.prototype.textForGaugeMinMax = function(value, isMax) {\n  var $$ = this,\n    format = $$.getGaugeLabelExtents();\n\n  return format ? format(value, isMax) : value\n};\n\nChartInternal.prototype.expandArc = function(targetIds) {\n  var $$ = this,\n    interval;\n\n  // MEMO: avoid to cancel transition\n  if ($$.transiting) {\n    interval = window.setInterval(function() {\n      if (!$$.transiting) {\n        window.clearInterval(interval);\n        if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) {\n          $$.expandArc(targetIds);\n        }\n      }\n    }, 10);\n    return\n  }\n\n  targetIds = $$.mapToTargetIds(targetIds);\n\n  $$.svg\n    .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc))\n    .each(function(d) {\n      if (!$$.shouldExpand(d.data.id)) {\n        return\n      }\n      $$.d3\n        .select(this)\n        .selectAll('path')\n        .transition()\n        .duration($$.expandDuration(d.data.id))\n        .attr('d', $$.svgArcExpanded)\n        .transition()\n        .duration($$.expandDuration(d.data.id) * 2)\n        .attr('d', $$.svgArcExpandedSub)\n        .each(function(d) {\n          if ($$.isDonutType(d.data)) ;\n        });\n    });\n};\n\nChartInternal.prototype.unexpandArc = function(targetIds) {\n  var $$ = this;\n\n  if ($$.transiting) {\n    return\n  }\n\n  targetIds = $$.mapToTargetIds(targetIds);\n\n  $$.svg\n    .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc))\n    .selectAll('path')\n    .transition()\n    .duration(function(d) {\n      return $$.expandDuration(d.data.id)\n    })\n    .attr('d', $$.svgArc);\n  $$.svg.selectAll('.' + CLASS.arc);\n};\n\nChartInternal.prototype.expandDuration = function(id) {\n  var $$ = this,\n    config = $$.config;\n\n  if ($$.isDonutType(id)) {\n    return config.donut_expand_duration\n  } else if ($$.isGaugeType(id)) {\n    return config.gauge_expand_duration\n  } else if ($$.isPieType(id)) {\n    return config.pie_expand_duration\n  } else {\n    return 50\n  }\n};\n\nChartInternal.prototype.shouldExpand = function(id) {\n  var $$ = this,\n    config = $$.config;\n  return (\n    ($$.isDonutType(id) && config.donut_expand) ||\n    ($$.isGaugeType(id) && config.gauge_expand) ||\n    ($$.isPieType(id) && config.pie_expand)\n  )\n};\n\nChartInternal.prototype.shouldShowArcLabel = function() {\n  var $$ = this,\n    config = $$.config,\n    shouldShow = true;\n  if ($$.hasType('donut')) {\n    shouldShow = config.donut_label_show;\n  } else if ($$.hasType('pie')) {\n    shouldShow = config.pie_label_show;\n  }\n  // when gauge, always true\n  return shouldShow\n};\n\nChartInternal.prototype.meetsArcLabelThreshold = function(ratio) {\n  var $$ = this,\n    config = $$.config,\n    threshold = $$.hasType('donut')\n      ? config.donut_label_threshold\n      : config.pie_label_threshold;\n  return ratio >= threshold\n};\n\nChartInternal.prototype.getArcLabelFormat = function() {\n  var $$ = this,\n    config = $$.config,\n    format = config.pie_label_format;\n  if ($$.hasType('gauge')) {\n    format = config.gauge_label_format;\n  } else if ($$.hasType('donut')) {\n    format = config.donut_label_format;\n  }\n  return format\n};\n\nChartInternal.prototype.getGaugeLabelExtents = function() {\n  var $$ = this,\n    config = $$.config;\n  return config.gauge_label_extents\n};\n\nChartInternal.prototype.getArcTitle = function() {\n  var $$ = this;\n  return $$.hasType('donut') ? $$.config.donut_title : ''\n};\n\nChartInternal.prototype.updateTargetsForArc = function(targets) {\n  var $$ = this,\n    main = $$.main,\n    mainPies,\n    mainPieEnter,\n    classChartArc = $$.classChartArc.bind($$),\n    classArcs = $$.classArcs.bind($$),\n    classFocus = $$.classFocus.bind($$);\n  mainPies = main\n    .select('.' + CLASS.chartArcs)\n    .selectAll('.' + CLASS.chartArc)\n    .data($$.pie(targets))\n    .attr('class', function(d) {\n      return classChartArc(d) + classFocus(d.data)\n    });\n  mainPieEnter = mainPies\n    .enter()\n    .append('g')\n    .attr('class', classChartArc);\n  mainPieEnter.append('g').attr('class', classArcs);\n  mainPieEnter\n    .append('text')\n    .attr('dy', $$.hasType('gauge') ? '-.1em' : '.35em')\n    .style('opacity', 0)\n    .style('text-anchor', 'middle')\n    .style('pointer-events', 'none');\n  // MEMO: can not keep same color..., but not bad to update color in redraw\n  //mainPieUpdate.exit().remove();\n};\n\nChartInternal.prototype.initArc = function() {\n  var $$ = this;\n  $$.arcs = $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartArcs)\n    .attr('transform', $$.getTranslate('arc'));\n  $$.arcs\n    .append('text')\n    .attr('class', CLASS.chartArcsTitle)\n    .style('text-anchor', 'middle')\n    .text($$.getArcTitle());\n};\n\nChartInternal.prototype.redrawArc = function(\n  duration,\n  durationForExit,\n  withTransform\n) {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    main = $$.main,\n    arcs,\n    mainArc,\n    arcLabelLines,\n    mainArcLabelLine,\n    hasGaugeType = $$.hasType('gauge');\n  arcs = main\n    .selectAll('.' + CLASS.arcs)\n    .selectAll('.' + CLASS.arc)\n    .data($$.arcData.bind($$));\n  mainArc = arcs\n    .enter()\n    .append('path')\n    .attr('class', $$.classArc.bind($$))\n    .style('fill', function(d) {\n      return $$.color(d.data)\n    })\n    .style('cursor', function(d) {\n      return config.interaction_enabled && config.data_selection_isselectable(d)\n        ? 'pointer'\n        : null\n    })\n    .each(function(d) {\n      if ($$.isGaugeType(d.data)) {\n        d.startAngle = d.endAngle = config.gauge_startingAngle;\n      }\n      this._current = d;\n    })\n    .merge(arcs);\n  if (hasGaugeType) {\n    arcLabelLines = main\n      .selectAll('.' + CLASS.arcs)\n      .selectAll('.' + CLASS.arcLabelLine)\n      .data($$.arcData.bind($$));\n    mainArcLabelLine = arcLabelLines\n      .enter()\n      .append('rect')\n      .attr('class', function(d) {\n        return (\n          CLASS.arcLabelLine +\n          ' ' +\n          CLASS.target +\n          ' ' +\n          CLASS.target +\n          '-' +\n          d.data.id\n        )\n      })\n      .merge(arcLabelLines);\n\n    if ($$.filterTargetsToShow($$.data.targets).length === 1) {\n      mainArcLabelLine.style('display', 'none');\n    } else {\n      mainArcLabelLine\n        .style('fill', function(d) {\n          return $$.levelColor\n            ? $$.levelColor(\n                d.data.values.reduce(function(total, item) {\n                  return total + item.value\n                }, 0)\n              )\n            : $$.color(d.data)\n        })\n        .style('display', config.gauge_labelLine_show ? '' : 'none')\n        .each(function(d) {\n          var lineLength = 0,\n            lineThickness = 2,\n            x = 0,\n            y = 0,\n            transform = '';\n          if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) {\n            var updated = $$.updateAngle(d),\n              innerLineLength =\n                ($$.gaugeArcWidth /\n                  $$.filterTargetsToShow($$.data.targets).length) *\n                (updated.index + 1),\n              lineAngle = updated.endAngle - Math.PI / 2,\n              arcInnerRadius = $$.radius - innerLineLength,\n              linePositioningAngle =\n                lineAngle - (arcInnerRadius === 0 ? 0 : 1 / arcInnerRadius);\n            lineLength = $$.radiusExpanded - $$.radius + innerLineLength;\n            x = Math.cos(linePositioningAngle) * arcInnerRadius;\n            y = Math.sin(linePositioningAngle) * arcInnerRadius;\n            transform =\n              'rotate(' +\n              (lineAngle * 180) / Math.PI +\n              ', ' +\n              x +\n              ', ' +\n              y +\n              ')';\n          }\n          d3.select(this)\n            .attr('x', x)\n            .attr('y', y)\n            .attr('width', lineLength)\n            .attr('height', lineThickness)\n            .attr('transform', transform)\n            .style(\n              'stroke-dasharray',\n              '0, ' + (lineLength + lineThickness) + ', 0'\n            );\n        });\n    }\n  }\n  mainArc\n    .attr('transform', function(d) {\n      return !$$.isGaugeType(d.data) && withTransform ? 'scale(0)' : ''\n    })\n    .on(\n      'mouseover',\n      config.interaction_enabled\n        ? function(d) {\n            var updated, arcData;\n            if ($$.transiting) {\n              // skip while transiting\n              return\n            }\n            updated = $$.updateAngle(d);\n            if (updated) {\n              arcData = $$.convertToArcData(updated);\n              // transitions\n              $$.expandArc(updated.data.id);\n              $$.api.focus(updated.data.id);\n              $$.toggleFocusLegend(updated.data.id, true);\n              $$.config.data_onmouseover(arcData, this);\n            }\n          }\n        : null\n    )\n    .on(\n      'mousemove',\n      config.interaction_enabled\n        ? function(d) {\n            var updated = $$.updateAngle(d),\n              arcData,\n              selectedData;\n            if (updated) {\n(arcData = $$.convertToArcData(updated)),\n                (selectedData = [arcData]);\n              $$.showTooltip(selectedData, this);\n            }\n          }\n        : null\n    )\n    .on(\n      'mouseout',\n      config.interaction_enabled\n        ? function(d) {\n            var updated, arcData;\n            if ($$.transiting) {\n              // skip while transiting\n              return\n            }\n            updated = $$.updateAngle(d);\n            if (updated) {\n              arcData = $$.convertToArcData(updated);\n              // transitions\n              $$.unexpandArc(updated.data.id);\n              $$.api.revert();\n              $$.revertLegend();\n              $$.hideTooltip();\n              $$.config.data_onmouseout(arcData, this);\n            }\n          }\n        : null\n    )\n    .on(\n      'click',\n      config.interaction_enabled\n        ? function(d, i) {\n            var updated = $$.updateAngle(d),\n              arcData;\n            if (updated) {\n              arcData = $$.convertToArcData(updated);\n              if ($$.toggleShape) {\n                $$.toggleShape(this, arcData, i);\n              }\n              $$.config.data_onclick.call($$.api, arcData, this);\n            }\n          }\n        : null\n    )\n    .each(function() {\n      $$.transiting = true;\n    })\n    .transition()\n    .duration(duration)\n    .attrTween('d', function(d) {\n      var updated = $$.updateAngle(d),\n        interpolate;\n      if (!updated) {\n        return function() {\n          return 'M 0 0'\n        }\n      }\n      //                if (this._current === d) {\n      //                    this._current = {\n      //                        startAngle: Math.PI*2,\n      //                        endAngle: Math.PI*2,\n      //                    };\n      //                }\n      if (isNaN(this._current.startAngle)) {\n        this._current.startAngle = 0;\n      }\n      if (isNaN(this._current.endAngle)) {\n        this._current.endAngle = this._current.startAngle;\n      }\n      interpolate = d3.interpolate(this._current, updated);\n      this._current = interpolate(0);\n      return function(t) {\n        // prevents crashing the charts once in transition and chart.destroy() has been called\n        if ($$.config === null) {\n          return 'M 0 0'\n        }\n        var interpolated = interpolate(t);\n        interpolated.data = d.data; // data.id will be updated by interporator\n        return $$.getArc(interpolated, true)\n      }\n    })\n    .attr('transform', withTransform ? 'scale(1)' : '')\n    .style('fill', function(d) {\n      return $$.levelColor\n        ? $$.levelColor(\n            d.data.values.reduce(function(total, item) {\n              return total + item.value\n            }, 0)\n          )\n        : $$.color(d.data.id)\n    }) // Where gauge reading color would receive customization.\n    .call($$.endall, function() {\n      $$.transiting = false;\n    });\n  arcs\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n    .remove();\n  main\n    .selectAll('.' + CLASS.chartArc)\n    .select('text')\n    .style('opacity', 0)\n    .attr('class', function(d) {\n      return $$.isGaugeType(d.data) ? CLASS.gaugeValue : ''\n    })\n    .text($$.textForArcLabel.bind($$))\n    .attr('transform', $$.transformForArcLabel.bind($$))\n    .style('font-size', function(d) {\n      return $$.isGaugeType(d.data) &&\n        $$.filterTargetsToShow($$.data.targets).length === 1\n        ? Math.round($$.radius / 5) + 'px'\n        : ''\n    })\n    .transition()\n    .duration(duration)\n    .style('opacity', function(d) {\n      return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0\n    });\n  main\n    .select('.' + CLASS.chartArcsTitle)\n    .style('opacity', $$.hasType('donut') || hasGaugeType ? 1 : 0);\n\n  if (hasGaugeType) {\n    let index = 0;\n    const backgroundArc = $$.arcs\n      .select('g.' + CLASS.chartArcsBackground)\n      .selectAll('path.' + CLASS.chartArcsBackground)\n      .data($$.data.targets);\n\n    backgroundArc\n      .enter()\n      .append('path')\n      .attr(\n        'class',\n        (d, i) =>\n          CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i\n      )\n      .merge(backgroundArc)\n      .attr('d', d1 => {\n        if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) {\n          return 'M 0 0'\n        }\n\n        var d = {\n          data: [{ value: config.gauge_max }],\n          startAngle: config.gauge_startingAngle,\n          endAngle:\n            -1 *\n            config.gauge_startingAngle *\n            (config.gauge_fullCircle ? Math.PI : 1),\n          index: index++\n        };\n        return $$.getArc(d, true, true)\n      });\n\n    backgroundArc.exit().remove();\n\n    $$.arcs\n      .select('.' + CLASS.chartArcsGaugeUnit)\n      .attr('dy', '.75em')\n      .text(config.gauge_label_show ? config.gauge_units : '');\n    $$.arcs\n      .select('.' + CLASS.chartArcsGaugeMin)\n      .attr(\n        'dx',\n        -1 *\n          ($$.innerRadius +\n            ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) +\n          'px'\n      )\n      .attr('dy', '1.2em')\n      .text(\n        config.gauge_label_show\n          ? $$.textForGaugeMinMax(config.gauge_min, false)\n          : ''\n      );\n    $$.arcs\n      .select('.' + CLASS.chartArcsGaugeMax)\n      .attr(\n        'dx',\n        $$.innerRadius +\n          ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) +\n          'px'\n      )\n      .attr('dy', '1.2em')\n      .text(\n        config.gauge_label_show\n          ? $$.textForGaugeMinMax(config.gauge_max, true)\n          : ''\n      );\n  }\n};\nChartInternal.prototype.initGauge = function() {\n  var arcs = this.arcs;\n  if (this.hasType('gauge')) {\n    arcs.append('g').attr('class', CLASS.chartArcsBackground);\n    arcs\n      .append('text')\n      .attr('class', CLASS.chartArcsGaugeUnit)\n      .style('text-anchor', 'middle')\n      .style('pointer-events', 'none');\n    arcs\n      .append('text')\n      .attr('class', CLASS.chartArcsGaugeMin)\n      .style('text-anchor', 'middle')\n      .style('pointer-events', 'none');\n    arcs\n      .append('text')\n      .attr('class', CLASS.chartArcsGaugeMax)\n      .style('text-anchor', 'middle')\n      .style('pointer-events', 'none');\n  }\n};\nChartInternal.prototype.getGaugeLabelHeight = function() {\n  return this.config.gauge_label_show ? 20 : 0\n};\n\n/**\n * Store value into cache\n *\n * @param key\n * @param value\n */\nChartInternal.prototype.addToCache = function(key, value) {\n  this.cache[`$${key}`] = value;\n};\n\n/**\n * Returns a cached value or undefined\n *\n * @param key\n * @return {*}\n */\nChartInternal.prototype.getFromCache = function(key) {\n  return this.cache[`$${key}`]\n};\n\n/**\n * Reset cached data\n */\nChartInternal.prototype.resetCache = function() {\n  Object.keys(this.cache)\n    .filter(key => /^\\$/.test(key))\n    .forEach(key => {\n      delete this.cache[key];\n    });\n};\n\n// Old API that stores Targets\n\nChartInternal.prototype.hasCaches = function(ids) {\n  for (var i = 0; i < ids.length; i++) {\n    if (!(ids[i] in this.cache)) {\n      return false\n    }\n  }\n  return true\n};\nChartInternal.prototype.addCache = function(id, target) {\n  this.cache[id] = this.cloneTarget(target);\n};\nChartInternal.prototype.getCaches = function(ids) {\n  var targets = [],\n    i;\n  for (i = 0; i < ids.length; i++) {\n    if (ids[i] in this.cache) {\n      targets.push(this.cloneTarget(this.cache[ids[i]]));\n    }\n  }\n  return targets\n};\n\nChartInternal.prototype.categoryName = function(i) {\n  var config = this.config;\n  return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i\n};\n\nChartInternal.prototype.generateTargetClass = function(targetId) {\n  return targetId || targetId === 0 ? ('-' + targetId).replace(/\\s/g, '-') : ''\n};\nChartInternal.prototype.generateClass = function(prefix, targetId) {\n  return ' ' + prefix + ' ' + prefix + this.generateTargetClass(targetId)\n};\nChartInternal.prototype.classText = function(d) {\n  return this.generateClass(CLASS.text, d.index)\n};\nChartInternal.prototype.classTexts = function(d) {\n  return this.generateClass(CLASS.texts, d.id)\n};\nChartInternal.prototype.classShape = function(d) {\n  return this.generateClass(CLASS.shape, d.index)\n};\nChartInternal.prototype.classShapes = function(d) {\n  return this.generateClass(CLASS.shapes, d.id)\n};\nChartInternal.prototype.classLine = function(d) {\n  return this.classShape(d) + this.generateClass(CLASS.line, d.id)\n};\nChartInternal.prototype.classLines = function(d) {\n  return this.classShapes(d) + this.generateClass(CLASS.lines, d.id)\n};\nChartInternal.prototype.classCircle = function(d) {\n  return this.classShape(d) + this.generateClass(CLASS.circle, d.index)\n};\nChartInternal.prototype.classCircles = function(d) {\n  return this.classShapes(d) + this.generateClass(CLASS.circles, d.id)\n};\nChartInternal.prototype.classBar = function(d) {\n  return this.classShape(d) + this.generateClass(CLASS.bar, d.index)\n};\nChartInternal.prototype.classBars = function(d) {\n  return this.classShapes(d) + this.generateClass(CLASS.bars, d.id)\n};\nChartInternal.prototype.classArc = function(d) {\n  return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id)\n};\nChartInternal.prototype.classArcs = function(d) {\n  return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id)\n};\nChartInternal.prototype.classArea = function(d) {\n  return this.classShape(d) + this.generateClass(CLASS.area, d.id)\n};\nChartInternal.prototype.classAreas = function(d) {\n  return this.classShapes(d) + this.generateClass(CLASS.areas, d.id)\n};\nChartInternal.prototype.classRegion = function(d, i) {\n  return (\n    this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : '')\n  )\n};\nChartInternal.prototype.classEvent = function(d) {\n  return this.generateClass(CLASS.eventRect, d.index)\n};\nChartInternal.prototype.classTarget = function(id) {\n  var $$ = this;\n  var additionalClassSuffix = $$.config.data_classes[id],\n    additionalClass = '';\n  if (additionalClassSuffix) {\n    additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix;\n  }\n  return $$.generateClass(CLASS.target, id) + additionalClass\n};\nChartInternal.prototype.classFocus = function(d) {\n  return this.classFocused(d) + this.classDefocused(d)\n};\nChartInternal.prototype.classFocused = function(d) {\n  return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '')\n};\nChartInternal.prototype.classDefocused = function(d) {\n  return (\n    ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : '')\n  )\n};\nChartInternal.prototype.classChartText = function(d) {\n  return CLASS.chartText + this.classTarget(d.id)\n};\nChartInternal.prototype.classChartLine = function(d) {\n  return CLASS.chartLine + this.classTarget(d.id)\n};\nChartInternal.prototype.classChartBar = function(d) {\n  return CLASS.chartBar + this.classTarget(d.id)\n};\nChartInternal.prototype.classChartArc = function(d) {\n  return CLASS.chartArc + this.classTarget(d.data.id)\n};\nChartInternal.prototype.getTargetSelectorSuffix = function(targetId) {\n  const targetClass = this.generateTargetClass(targetId);\n  if (window.CSS && window.CSS.escape) {\n    return window.CSS.escape(targetClass)\n  }\n\n  // fallback on imperfect method for old browsers (does not handles unicode)\n  return targetClass.replace(/([?!@#$%^&*()=+,.<>'\":;\\[\\]\\/|~`{}\\\\])/g, '\\\\$1')\n};\nChartInternal.prototype.selectorTarget = function(id, prefix) {\n  return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id)\n};\nChartInternal.prototype.selectorTargets = function(ids, prefix) {\n  var $$ = this;\n  ids = ids || [];\n  return ids.length\n    ? ids.map(function(id) {\n        return $$.selectorTarget(id, prefix)\n      })\n    : null\n};\nChartInternal.prototype.selectorLegend = function(id) {\n  return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id)\n};\nChartInternal.prototype.selectorLegends = function(ids) {\n  var $$ = this;\n  return ids && ids.length\n    ? ids.map(function(id) {\n        return $$.selectorLegend(id)\n      })\n    : null\n};\n\nChartInternal.prototype.getClipPath = function(id) {\n  return 'url(' + (isIE(9) ? '' : document.URL.split('#')[0]) + '#' + id + ')'\n};\nChartInternal.prototype.appendClip = function(parent, id) {\n  return parent\n    .append('clipPath')\n    .attr('id', id)\n    .append('rect')\n};\nChartInternal.prototype.getAxisClipX = function(forHorizontal) {\n  // axis line width + padding for left\n  var left = Math.max(30, this.margin.left);\n  return forHorizontal ? -(1 + left) : -(left - 1)\n};\nChartInternal.prototype.getAxisClipY = function(forHorizontal) {\n  return forHorizontal ? -20 : -this.margin.top\n};\nChartInternal.prototype.getXAxisClipX = function() {\n  var $$ = this;\n  return $$.getAxisClipX(!$$.config.axis_rotated)\n};\nChartInternal.prototype.getXAxisClipY = function() {\n  var $$ = this;\n  return $$.getAxisClipY(!$$.config.axis_rotated)\n};\nChartInternal.prototype.getYAxisClipX = function() {\n  var $$ = this;\n  return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated)\n};\nChartInternal.prototype.getYAxisClipY = function() {\n  var $$ = this;\n  return $$.getAxisClipY($$.config.axis_rotated)\n};\nChartInternal.prototype.getAxisClipWidth = function(forHorizontal) {\n  var $$ = this,\n    left = Math.max(30, $$.margin.left),\n    right = Math.max(30, $$.margin.right);\n  // width + axis line width + padding for left/right\n  return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20\n};\nChartInternal.prototype.getAxisClipHeight = function(forHorizontal) {\n  // less than 20 is not enough to show the axis label 'outer' without legend\n  return (\n    (forHorizontal ? this.margin.bottom : this.margin.top + this.height) + 20\n  )\n};\nChartInternal.prototype.getXAxisClipWidth = function() {\n  var $$ = this;\n  return $$.getAxisClipWidth(!$$.config.axis_rotated)\n};\nChartInternal.prototype.getXAxisClipHeight = function() {\n  var $$ = this;\n  return $$.getAxisClipHeight(!$$.config.axis_rotated)\n};\nChartInternal.prototype.getYAxisClipWidth = function() {\n  var $$ = this;\n  return (\n    $$.getAxisClipWidth($$.config.axis_rotated) +\n    ($$.config.axis_y_inner ? 20 : 0)\n  )\n};\nChartInternal.prototype.getYAxisClipHeight = function() {\n  var $$ = this;\n  return $$.getAxisClipHeight($$.config.axis_rotated)\n};\n\nChartInternal.prototype.generateColor = function() {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3,\n    colors = config.data_colors,\n    pattern = notEmpty(config.color_pattern)\n      ? config.color_pattern\n      : d3.schemeCategory10,\n    callback = config.data_color,\n    ids = [];\n\n  return function(d) {\n    var id = d.id || (d.data && d.data.id) || d,\n      color;\n\n    // if callback function is provided\n    if (colors[id] instanceof Function) {\n      color = colors[id](d);\n    }\n    // if specified, choose that color\n    else if (colors[id]) {\n      color = colors[id];\n    }\n    // if not specified, choose from pattern\n    else {\n      if (ids.indexOf(id) < 0) {\n        ids.push(id);\n      }\n      color = pattern[ids.indexOf(id) % pattern.length];\n      colors[id] = color;\n    }\n    return callback instanceof Function ? callback(color, d) : color\n  }\n};\nChartInternal.prototype.generateLevelColor = function() {\n  var $$ = this,\n    config = $$.config,\n    colors = config.color_pattern,\n    threshold = config.color_threshold,\n    asValue = threshold.unit === 'value',\n    values =\n      threshold.values && threshold.values.length ? threshold.values : [],\n    max = threshold.max || 100;\n  return notEmpty(threshold) && notEmpty(colors)\n    ? function(value) {\n        var i,\n          v,\n          color = colors[colors.length - 1];\n        for (i = 0; i < values.length; i++) {\n          v = asValue ? value : (value * 100) / max;\n          if (v < values[i]) {\n            color = colors[i];\n            break\n          }\n        }\n        return color\n      }\n    : null\n};\n\nChartInternal.prototype.getDefaultConfig = function() {\n  var config = {\n    bindto: '#chart',\n    svg_classname: undefined,\n    size_width: undefined,\n    size_height: undefined,\n    padding_left: undefined,\n    padding_right: undefined,\n    padding_top: undefined,\n    padding_bottom: undefined,\n    resize_auto: true,\n    zoom_enabled: false,\n    zoom_initialRange: undefined,\n    zoom_type: 'scroll',\n    zoom_disableDefaultBehavior: false,\n    zoom_privileged: false,\n    zoom_rescale: false,\n    zoom_onzoom: function() {},\n    zoom_onzoomstart: function() {},\n    zoom_onzoomend: function() {},\n    zoom_x_min: undefined,\n    zoom_x_max: undefined,\n    interaction_brighten: true,\n    interaction_enabled: true,\n    onmouseover: function() {},\n    onmouseout: function() {},\n    onresize: function() {},\n    onresized: function() {},\n    oninit: function() {},\n    onrendered: function() {},\n    transition_duration: 350,\n    data_epochs: 'epochs',\n    data_x: undefined,\n    data_xs: {},\n    data_xFormat: '%Y-%m-%d',\n    data_xLocaltime: true,\n    data_xSort: true,\n    data_idConverter: function(id) {\n      return id\n    },\n    data_names: {},\n    data_classes: {},\n    data_groups: [],\n    data_axes: {},\n    data_type: undefined,\n    data_types: {},\n    data_labels: {},\n    data_order: 'desc',\n    data_regions: {},\n    data_color: undefined,\n    data_colors: {},\n    data_hide: false,\n    data_filter: undefined,\n    data_selection_enabled: false,\n    data_selection_grouped: false,\n    data_selection_isselectable: function() {\n      return true\n    },\n    data_selection_multiple: true,\n    data_selection_draggable: false,\n    data_stack_normalize: false,\n    data_onclick: function() {},\n    data_onmouseover: function() {},\n    data_onmouseout: function() {},\n    data_onselected: function() {},\n    data_onunselected: function() {},\n    data_url: undefined,\n    data_headers: undefined,\n    data_json: undefined,\n    data_rows: undefined,\n    data_columns: undefined,\n    data_mimeType: undefined,\n    data_keys: undefined,\n    // configuration for no plot-able data supplied.\n    data_empty_label_text: '',\n    // subchart\n    subchart_show: false,\n    subchart_size_height: 60,\n    subchart_axis_x_show: true,\n    subchart_onbrush: function() {},\n    // color\n    color_pattern: [],\n    color_threshold: {},\n    // legend\n    legend_show: true,\n    legend_hide: false,\n    legend_position: 'bottom',\n    legend_inset_anchor: 'top-left',\n    legend_inset_x: 10,\n    legend_inset_y: 0,\n    legend_inset_step: undefined,\n    legend_item_onclick: undefined,\n    legend_item_onmouseover: undefined,\n    legend_item_onmouseout: undefined,\n    legend_equally: false,\n    legend_padding: 0,\n    legend_item_tile_width: 10,\n    legend_item_tile_height: 10,\n    // axis\n    axis_rotated: false,\n    axis_x_show: true,\n    axis_x_type: 'indexed',\n    axis_x_localtime: true,\n    axis_x_categories: [],\n    axis_x_tick_centered: false,\n    axis_x_tick_format: undefined,\n    axis_x_tick_culling: {},\n    axis_x_tick_culling_max: 10,\n    axis_x_tick_count: undefined,\n    axis_x_tick_fit: true,\n    axis_x_tick_values: null,\n    axis_x_tick_rotate: 0,\n    axis_x_tick_outer: true,\n    axis_x_tick_multiline: true,\n    axis_x_tick_multilineMax: 0,\n    axis_x_tick_width: null,\n    axis_x_max: undefined,\n    axis_x_min: undefined,\n    axis_x_padding: {},\n    axis_x_height: undefined,\n    axis_x_selection: undefined,\n    axis_x_label: {},\n    axis_x_inner: undefined,\n    axis_y_show: true,\n    axis_y_type: 'linear',\n    axis_y_max: undefined,\n    axis_y_min: undefined,\n    axis_y_inverted: false,\n    axis_y_center: undefined,\n    axis_y_inner: undefined,\n    axis_y_label: {},\n    axis_y_tick_format: undefined,\n    axis_y_tick_outer: true,\n    axis_y_tick_values: null,\n    axis_y_tick_rotate: 0,\n    axis_y_tick_count: undefined,\n    axis_y_tick_time_type: undefined,\n    axis_y_tick_time_interval: undefined,\n    axis_y_padding: {},\n    axis_y_default: undefined,\n    axis_y2_show: false,\n    axis_y2_type: 'linear',\n    axis_y2_max: undefined,\n    axis_y2_min: undefined,\n    axis_y2_inverted: false,\n    axis_y2_center: undefined,\n    axis_y2_inner: undefined,\n    axis_y2_label: {},\n    axis_y2_tick_format: undefined,\n    axis_y2_tick_outer: true,\n    axis_y2_tick_values: null,\n    axis_y2_tick_count: undefined,\n    axis_y2_padding: {},\n    axis_y2_default: undefined,\n    // grid\n    grid_x_show: false,\n    grid_x_type: 'tick',\n    grid_x_lines: [],\n    grid_y_show: false,\n    // not used\n    // grid_y_type: 'tick',\n    grid_y_lines: [],\n    grid_y_ticks: 10,\n    grid_focus_show: true,\n    grid_lines_front: true,\n    // point - point of each data\n    point_show: true,\n    point_r: 2.5,\n    point_sensitivity: 10,\n    point_focus_expand_enabled: true,\n    point_focus_expand_r: undefined,\n    point_select_r: undefined,\n    // line\n    line_connectNull: false,\n    line_step_type: 'step',\n    // bar\n    bar_width: undefined,\n    bar_width_ratio: 0.6,\n    bar_width_max: undefined,\n    bar_zerobased: true,\n    bar_space: 0,\n    // area\n    area_zerobased: true,\n    area_above: false,\n    // pie\n    pie_label_show: true,\n    pie_label_format: undefined,\n    pie_label_threshold: 0.05,\n    pie_label_ratio: undefined,\n    pie_expand: {},\n    pie_expand_duration: 50,\n    pie_padAngle: 0,\n    // gauge\n    gauge_fullCircle: false,\n    gauge_label_show: true,\n    gauge_labelLine_show: true,\n    gauge_label_format: undefined,\n    gauge_min: 0,\n    gauge_max: 100,\n    gauge_startingAngle: (-1 * Math.PI) / 2,\n    gauge_label_extents: undefined,\n    gauge_units: undefined,\n    gauge_width: undefined,\n    gauge_arcs_minWidth: 5,\n    gauge_expand: {},\n    gauge_expand_duration: 50,\n    // donut\n    donut_label_show: true,\n    donut_label_format: undefined,\n    donut_label_threshold: 0.05,\n    donut_label_ratio: undefined,\n    donut_width: undefined,\n    donut_title: '',\n    donut_expand: {},\n    donut_expand_duration: 50,\n    donut_padAngle: 0,\n    // spline\n    spline_interpolation_type: 'cardinal',\n    // stanford\n    stanford_lines: [],\n    stanford_regions: [],\n    stanford_texts: [],\n    stanford_scaleMin: undefined,\n    stanford_scaleMax: undefined,\n    stanford_scaleWidth: undefined,\n    stanford_scaleFormat: undefined,\n    stanford_scaleValues: undefined,\n    stanford_colors: undefined,\n    stanford_padding: {\n      top: 0,\n      right: 0,\n      bottom: 0,\n      left: 0\n    },\n    // region - region to change style\n    regions: [],\n    // tooltip - show when mouseover on each data\n    tooltip_show: true,\n    tooltip_grouped: true,\n    tooltip_order: undefined,\n    tooltip_format_title: undefined,\n    tooltip_format_name: undefined,\n    tooltip_format_value: undefined,\n    tooltip_horizontal: undefined,\n    tooltip_position: undefined,\n    tooltip_contents: function(\n      d,\n      defaultTitleFormat,\n      defaultValueFormat,\n      color\n    ) {\n      return this.getTooltipContent\n        ? this.getTooltipContent(\n            d,\n            defaultTitleFormat,\n            defaultValueFormat,\n            color\n          )\n        : ''\n    },\n    tooltip_init_show: false,\n    tooltip_init_x: 0,\n    tooltip_init_position: { top: '0px', left: '50px' },\n    tooltip_onshow: function() {},\n    tooltip_onhide: function() {},\n    // title\n    title_text: undefined,\n    title_padding: {\n      top: 0,\n      right: 0,\n      bottom: 0,\n      left: 0\n    },\n    title_position: 'top-center'\n  };\n\n  Object.keys(this.additionalConfig).forEach(function(key) {\n    config[key] = this.additionalConfig[key];\n  }, this);\n\n  return config\n};\nChartInternal.prototype.additionalConfig = {};\n\nChartInternal.prototype.loadConfig = function(config) {\n  var this_config = this.config,\n    target,\n    keys,\n    read;\n  function find() {\n    var key = keys.shift();\n    //        console.log(\"key =>\", key, \", target =>\", target);\n    if (key && target && typeof target === 'object' && key in target) {\n      target = target[key];\n      return find()\n    } else if (!key) {\n      return target\n    } else {\n      return undefined\n    }\n  }\n  Object.keys(this_config).forEach(function(key) {\n    target = config;\n    keys = key.split('_');\n    read = find();\n    //        console.log(\"CONFIG : \", key, read);\n    if (isDefined(read)) {\n      this_config[key] = read;\n    }\n  });\n};\n\nChartInternal.prototype.convertUrlToData = function(\n  url,\n  mimeType,\n  headers,\n  keys,\n  done\n) {\n  var $$ = this,\n    type = mimeType ? mimeType : 'csv',\n    f,\n    converter;\n\n  if (type === 'json') {\n    f = $$.d3.json;\n    converter = $$.convertJsonToData;\n  } else if (type === 'tsv') {\n    f = $$.d3.tsv;\n    converter = $$.convertXsvToData;\n  } else {\n    f = $$.d3.csv;\n    converter = $$.convertXsvToData;\n  }\n\n  f(url, headers)\n    .then(function(data) {\n      done.call($$, converter.call($$, data, keys));\n    })\n    .catch(function(error) {\n      throw error\n    });\n};\nChartInternal.prototype.convertXsvToData = function(xsv) {\n  var keys = xsv.columns,\n    rows = xsv;\n  if (rows.length === 0) {\n    return {\n      keys,\n      rows: [keys.reduce((row, key) => Object.assign(row, { [key]: null }), {})]\n    }\n  } else {\n    // [].concat() is to convert result into a plain array otherwise\n    // test is not happy because rows have properties.\n    return { keys, rows: [].concat(xsv) }\n  }\n};\nChartInternal.prototype.convertJsonToData = function(json, keys) {\n  var $$ = this,\n    new_rows = [],\n    targetKeys,\n    data;\n  if (keys) {\n    // when keys specified, json would be an array that includes objects\n    if (keys.x) {\n      targetKeys = keys.value.concat(keys.x);\n      $$.config.data_x = keys.x;\n    } else {\n      targetKeys = keys.value;\n    }\n    new_rows.push(targetKeys);\n    json.forEach(function(o) {\n      var new_row = [];\n      targetKeys.forEach(function(key) {\n        // convert undefined to null because undefined data will be removed in convertDataToTargets()\n        var v = $$.findValueInJson(o, key);\n        if (isUndefined(v)) {\n          v = null;\n        }\n        new_row.push(v);\n      });\n      new_rows.push(new_row);\n    });\n    data = $$.convertRowsToData(new_rows);\n  } else {\n    Object.keys(json).forEach(function(key) {\n      new_rows.push([key].concat(json[key]));\n    });\n    data = $$.convertColumnsToData(new_rows);\n  }\n  return data\n};\n/**\n * Finds value from the given nested object by the given path.\n * If it's not found, then this returns undefined.\n * @param {Object} object the object\n * @param {string} path the path\n */\nChartInternal.prototype.findValueInJson = function(object, path) {\n  if (path in object) {\n    // If object has a key that contains . or [], return the key's value\n    // instead of searching for an inner object.\n    // See https://github.com/c3js/c3/issues/1691 for details.\n    return object[path]\n  }\n\n  path = path.replace(/\\[(\\w+)\\]/g, '.$1'); // convert indexes to properties (replace [] with .)\n  path = path.replace(/^\\./, ''); // strip a leading dot\n  var pathArray = path.split('.');\n  for (var i = 0; i < pathArray.length; ++i) {\n    var k = pathArray[i];\n    if (k in object) {\n      object = object[k];\n    } else {\n      return\n    }\n  }\n  return object\n};\n\n/**\n * Converts the rows to normalized data.\n * @param {any[][]} rows The row data\n * @return {Object}\n */\nChartInternal.prototype.convertRowsToData = rows => {\n  const newRows = [];\n  const keys = rows[0];\n\n  for (let i = 1; i < rows.length; i++) {\n    const newRow = {};\n    for (let j = 0; j < rows[i].length; j++) {\n      if (isUndefined(rows[i][j])) {\n        throw new Error(\n          'Source data is missing a component at (' + i + ',' + j + ')!'\n        )\n      }\n      newRow[keys[j]] = rows[i][j];\n    }\n    newRows.push(newRow);\n  }\n  return { keys, rows: newRows }\n};\n\n/**\n * Converts the columns to normalized data.\n * @param {any[][]} columns The column data\n * @return {Object}\n */\nChartInternal.prototype.convertColumnsToData = columns => {\n  const newRows = [];\n  const keys = [];\n\n  for (let i = 0; i < columns.length; i++) {\n    const key = columns[i][0];\n    for (let j = 1; j < columns[i].length; j++) {\n      if (isUndefined(newRows[j - 1])) {\n        newRows[j - 1] = {};\n      }\n      if (isUndefined(columns[i][j])) {\n        throw new Error(\n          'Source data is missing a component at (' + i + ',' + j + ')!'\n        )\n      }\n      newRows[j - 1][key] = columns[i][j];\n    }\n    keys.push(key);\n  }\n\n  return { keys, rows: newRows }\n};\n\n/**\n * Converts the data format into the target format.\n * @param {!Object} data\n * @param {!Array} data.keys Ordered list of target IDs.\n * @param {!Array} data.rows Rows of data to convert.\n * @param {boolean} appendXs True to append to $$.data.xs, False to replace.\n * @return {!Array}\n */\nChartInternal.prototype.convertDataToTargets = function(data, appendXs) {\n  var $$ = this,\n    config = $$.config,\n    targets,\n    ids,\n    xs,\n    keys,\n    epochs;\n\n  // handles format where keys are not orderly provided\n  if (isArray(data)) {\n    keys = Object.keys(data[0]);\n  } else {\n    keys = data.keys;\n    data = data.rows;\n  }\n\n  xs = keys.filter($$.isX, $$);\n\n  if (!$$.isStanfordGraphType()) {\n    ids = keys.filter($$.isNotX, $$);\n  } else {\n    epochs = keys.filter($$.isEpochs, $$);\n    ids = keys.filter($$.isNotXAndNotEpochs, $$);\n\n    if (xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) {\n      throw new Error(\n        \"You must define the 'x' key name and the 'epochs' for Stanford Diagrams\"\n      )\n    }\n  }\n\n  // save x for update data by load when custom x and c3.x API\n  ids.forEach(function(id) {\n    var xKey = $$.getXKey(id);\n\n    if ($$.isCustomX() || $$.isTimeSeries()) {\n      // if included in input data\n      if (xs.indexOf(xKey) >= 0) {\n        $$.data.xs[id] = (appendXs && $$.data.xs[id]\n          ? $$.data.xs[id]\n          : []\n        ).concat(\n          data\n            .map(function(d) {\n              return d[xKey]\n            })\n            .filter(isValue)\n            .map(function(rawX, i) {\n              return $$.generateTargetX(rawX, id, i)\n            })\n        );\n      }\n      // if not included in input data, find from preloaded data of other id's x\n      else if (config.data_x) {\n        $$.data.xs[id] = $$.getOtherTargetXs();\n      }\n      // if not included in input data, find from preloaded data\n      else if (notEmpty(config.data_xs)) {\n        $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets);\n      }\n      // MEMO: if no x included, use same x of current will be used\n    } else {\n      $$.data.xs[id] = data.map(function(d, i) {\n        return i\n      });\n    }\n  });\n\n  // check x is defined\n  ids.forEach(function(id) {\n    if (!$$.data.xs[id]) {\n      throw new Error('x is not defined for id = \"' + id + '\".')\n    }\n  });\n\n  // convert to target\n  targets = ids.map(function(id, index) {\n    var convertedId = config.data_idConverter(id);\n    return {\n      id: convertedId,\n      id_org: id,\n      values: data\n        .map(function(d, i) {\n          var xKey = $$.getXKey(id),\n            rawX = d[xKey],\n            value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null,\n            x,\n            returnData;\n          // use x as categories if custom x and categorized\n          if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) {\n            if (index === 0 && i === 0) {\n              config.axis_x_categories = [];\n            }\n            x = config.axis_x_categories.indexOf(rawX);\n            if (x === -1) {\n              x = config.axis_x_categories.length;\n              config.axis_x_categories.push(rawX);\n            }\n          } else {\n            x = $$.generateTargetX(rawX, id, i);\n          }\n          // mark as x = undefined if value is undefined and filter to remove after mapped\n          if (isUndefined(d[id]) || $$.data.xs[id].length <= i) {\n            x = undefined;\n          }\n\n          returnData = { x: x, value: value, id: convertedId };\n\n          if ($$.isStanfordGraphType()) {\n            returnData.epochs = d[epochs];\n          }\n\n          return returnData\n        })\n        .filter(function(v) {\n          return isDefined(v.x)\n        })\n    }\n  });\n\n  // finish targets\n  targets.forEach(function(t) {\n    var i;\n    // sort values by its x\n    if (config.data_xSort) {\n      t.values = t.values.sort(function(v1, v2) {\n        var x1 = v1.x || v1.x === 0 ? v1.x : Infinity,\n          x2 = v2.x || v2.x === 0 ? v2.x : Infinity;\n        return x1 - x2\n      });\n    }\n    // indexing each value\n    i = 0;\n    t.values.forEach(function(v) {\n      v.index = i++;\n    });\n    // this needs to be sorted because its index and value.index is identical\n    $$.data.xs[t.id].sort(function(v1, v2) {\n      return v1 - v2\n    });\n  });\n\n  // cache information about values\n  $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets);\n  $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets);\n\n  // set target types\n  if (config.data_type) {\n    $$.setTargetType(\n      $$.mapToIds(targets).filter(function(id) {\n        return !(id in config.data_types)\n      }),\n      config.data_type\n    );\n  }\n\n  // cache as original id keyed\n  targets.forEach(function(d) {\n    $$.addCache(d.id_org, d);\n  });\n\n  return targets\n};\n\nChartInternal.prototype.isEpochs = function(key) {\n  var $$ = this,\n    config = $$.config;\n  return config.data_epochs && key === config.data_epochs\n};\nChartInternal.prototype.isX = function(key) {\n  var $$ = this,\n    config = $$.config;\n  return (\n    (config.data_x && key === config.data_x) ||\n    (notEmpty(config.data_xs) && hasValue(config.data_xs, key))\n  )\n};\nChartInternal.prototype.isNotX = function(key) {\n  return !this.isX(key)\n};\nChartInternal.prototype.isNotXAndNotEpochs = function(key) {\n  return !this.isX(key) && !this.isEpochs(key)\n};\n\n/**\n * Returns whether the normalized stack option is enabled or not.\n *\n * To be enabled it must also have data.groups defined.\n *\n * @return {boolean}\n */\nChartInternal.prototype.isStackNormalized = function() {\n  return this.config.data_stack_normalize && this.config.data_groups.length > 0\n};\n\n/**\n * Returns whether the axis is normalized or not.\n *\n * An axis is normalized as long as one of its associated target\n * is normalized.\n *\n * @param axisId Axis ID (y or y2)\n * @return {Boolean}\n */\nChartInternal.prototype.isAxisNormalized = function(axisId) {\n  const $$ = this;\n\n  if (!$$.isStackNormalized()) {\n    // shortcut\n    return false\n  }\n\n  return $$.data.targets\n    .filter(target => $$.axis.getId(target.id) === axisId)\n    .some(target => $$.isTargetNormalized(target.id))\n};\n\n/**\n * Returns whether the values for this target ID is normalized or not.\n *\n * To be normalized the option needs to be enabled and target needs\n * to be defined in `data.groups`.\n *\n * @param targetId ID of the target\n * @return {Boolean} True if the target is normalized, false otherwise.\n */\nChartInternal.prototype.isTargetNormalized = function(targetId) {\n  const $$ = this;\n\n  return (\n    $$.isStackNormalized() &&\n    $$.config.data_groups.some(group => group.includes(targetId))\n  )\n};\n\nChartInternal.prototype.getXKey = function(id) {\n  var $$ = this,\n    config = $$.config;\n  return config.data_x\n    ? config.data_x\n    : notEmpty(config.data_xs)\n    ? config.data_xs[id]\n    : null\n};\n\n/**\n * Get sum of visible data per index for given axis.\n *\n * Expect axisId to be either 'y' or 'y2'.\n *\n * @private\n * @param axisId Compute sum for data associated to given axis.\n * @return {Array}\n */\nChartInternal.prototype.getTotalPerIndex = function(axisId) {\n  const $$ = this;\n\n  if (!$$.isStackNormalized()) {\n    return null\n  }\n\n  const cached = $$.getFromCache('getTotalPerIndex');\n  if (cached !== undefined) {\n    return cached[axisId]\n  }\n\n  const sum = { y: [], y2: [] };\n\n  $$.data.targets\n    // keep only target that are normalized\n    .filter(target => $$.isTargetNormalized(target.id))\n\n    // keep only target that are visible\n    .filter(target => $$.isTargetToShow(target.id))\n\n    // compute sum per axis\n    .forEach(target => {\n      const sumByAxis = sum[$$.axis.getId(target.id)];\n\n      target.values.forEach((v, i) => {\n        if (!sumByAxis[i]) {\n          sumByAxis[i] = 0;\n        }\n        sumByAxis[i] += isNumber(v.value) ? v.value : 0;\n      });\n    });\n\n  $$.addToCache('getTotalPerIndex', sum);\n\n  return sum[axisId]\n};\n\n/**\n * Get sum of visible data.\n *\n * Should be used for normalised data only since all values\n * are expected to be positive.\n *\n * @private\n * @return {Number}\n */\nChartInternal.prototype.getTotalDataSum = function() {\n  const $$ = this;\n\n  const cached = $$.getFromCache('getTotalDataSum');\n  if (cached !== undefined) {\n    return cached\n  }\n\n  const totalDataSum = flattenArray(\n    $$.data.targets\n      .filter(target => $$.isTargetToShow(target.id))\n      .map(target => target.values)\n  )\n    .map(d => d.value)\n    .reduce((p, c) => p + c, 0);\n\n  $$.addToCache('getTotalDataSum', totalDataSum);\n\n  return totalDataSum\n};\n\nChartInternal.prototype.getXValuesOfXKey = function(key, targets) {\n  var $$ = this,\n    xValues,\n    ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : [];\n  ids.forEach(function(id) {\n    if ($$.getXKey(id) === key) {\n      xValues = $$.data.xs[id];\n    }\n  });\n  return xValues\n};\nChartInternal.prototype.getXValue = function(id, i) {\n  var $$ = this;\n  return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i])\n    ? $$.data.xs[id][i]\n    : i\n};\nChartInternal.prototype.getOtherTargetXs = function() {\n  var $$ = this,\n    idsForX = Object.keys($$.data.xs);\n  return idsForX.length ? $$.data.xs[idsForX[0]] : null\n};\nChartInternal.prototype.getOtherTargetX = function(index) {\n  var xs = this.getOtherTargetXs();\n  return xs && index < xs.length ? xs[index] : null\n};\nChartInternal.prototype.addXs = function(xs) {\n  var $$ = this;\n  Object.keys(xs).forEach(function(id) {\n    $$.config.data_xs[id] = xs[id];\n  });\n};\nChartInternal.prototype.addName = function(data) {\n  var $$ = this,\n    name;\n  if (data) {\n    name = $$.config.data_names[data.id];\n    data.name = name !== undefined ? name : data.id;\n  }\n  return data\n};\nChartInternal.prototype.getValueOnIndex = function(values, index) {\n  var valueOnIndex = values.filter(function(v) {\n    return v.index === index\n  });\n  return valueOnIndex.length ? valueOnIndex[0] : null\n};\nChartInternal.prototype.updateTargetX = function(targets, x) {\n  var $$ = this;\n  targets.forEach(function(t) {\n    t.values.forEach(function(v, i) {\n      v.x = $$.generateTargetX(x[i], t.id, i);\n    });\n    $$.data.xs[t.id] = x;\n  });\n};\nChartInternal.prototype.updateTargetXs = function(targets, xs) {\n  var $$ = this;\n  targets.forEach(function(t) {\n    if (xs[t.id]) {\n      $$.updateTargetX([t], xs[t.id]);\n    }\n  });\n};\nChartInternal.prototype.generateTargetX = function(rawX, id, index) {\n  var $$ = this,\n    x;\n  if ($$.isTimeSeries()) {\n    x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index));\n  } else if ($$.isCustomX() && !$$.isCategorized()) {\n    x = isValue(rawX) ? +rawX : $$.getXValue(id, index);\n  } else {\n    x = index;\n  }\n  return x\n};\nChartInternal.prototype.cloneTarget = function(target) {\n  return {\n    id: target.id,\n    id_org: target.id_org,\n    values: target.values.map(function(d) {\n      return {\n        x: d.x,\n        value: d.value,\n        id: d.id\n      }\n    })\n  }\n};\nChartInternal.prototype.getMaxDataCount = function() {\n  var $$ = this;\n  return $$.d3.max($$.data.targets, function(t) {\n    return t.values.length\n  })\n};\nChartInternal.prototype.mapToIds = function(targets) {\n  return targets.map(function(d) {\n    return d.id\n  })\n};\nChartInternal.prototype.mapToTargetIds = function(ids) {\n  var $$ = this;\n  return ids ? [].concat(ids) : $$.mapToIds($$.data.targets)\n};\nChartInternal.prototype.hasTarget = function(targets, id) {\n  var ids = this.mapToIds(targets),\n    i;\n  for (i = 0; i < ids.length; i++) {\n    if (ids[i] === id) {\n      return true\n    }\n  }\n  return false\n};\nChartInternal.prototype.isTargetToShow = function(targetId) {\n  return this.hiddenTargetIds.indexOf(targetId) < 0\n};\nChartInternal.prototype.isLegendToShow = function(targetId) {\n  return this.hiddenLegendIds.indexOf(targetId) < 0\n};\n\n/**\n * Returns only visible targets.\n *\n * This is the same as calling {@link filterTargetsToShow} on $$.data.targets.\n *\n * @return {Array}\n */\nChartInternal.prototype.getTargetsToShow = function() {\n  const $$ = this;\n  return $$.filterTargetsToShow($$.data.targets)\n};\n\nChartInternal.prototype.filterTargetsToShow = function(targets) {\n  var $$ = this;\n  return targets.filter(function(t) {\n    return $$.isTargetToShow(t.id)\n  })\n};\n\n/**\n * @return {Array} Returns all the targets attached to the chart, visible or not\n */\nChartInternal.prototype.getTargets = function() {\n  const $$ = this;\n  return $$.data.targets\n};\n\nChartInternal.prototype.mapTargetsToUniqueXs = function(targets) {\n  var $$ = this;\n  var xs = $$.d3\n    .set(\n      $$.d3.merge(\n        targets.map(function(t) {\n          return t.values.map(function(v) {\n            return +v.x\n          })\n        })\n      )\n    )\n    .values();\n  xs = $$.isTimeSeries()\n    ? xs.map(function(x) {\n        return new Date(+x)\n      })\n    : xs.map(function(x) {\n        return +x\n      });\n  return xs.sort(function(a, b) {\n    return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN\n  })\n};\nChartInternal.prototype.addHiddenTargetIds = function(targetIds) {\n  targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);\n  for (var i = 0; i < targetIds.length; i++) {\n    if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) {\n      this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]);\n    }\n  }\n  this.resetCache();\n};\nChartInternal.prototype.removeHiddenTargetIds = function(targetIds) {\n  this.hiddenTargetIds = this.hiddenTargetIds.filter(function(id) {\n    return targetIds.indexOf(id) < 0\n  });\n  this.resetCache();\n};\nChartInternal.prototype.addHiddenLegendIds = function(targetIds) {\n  targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);\n  for (var i = 0; i < targetIds.length; i++) {\n    if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) {\n      this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]);\n    }\n  }\n};\nChartInternal.prototype.removeHiddenLegendIds = function(targetIds) {\n  this.hiddenLegendIds = this.hiddenLegendIds.filter(function(id) {\n    return targetIds.indexOf(id) < 0\n  });\n};\nChartInternal.prototype.getValuesAsIdKeyed = function(targets) {\n  var ys = {};\n  targets.forEach(function(t) {\n    ys[t.id] = [];\n    t.values.forEach(function(v) {\n      ys[t.id].push(v.value);\n    });\n  });\n  return ys\n};\nChartInternal.prototype.checkValueInTargets = function(targets, checker) {\n  var ids = Object.keys(targets),\n    i,\n    j,\n    values;\n  for (i = 0; i < ids.length; i++) {\n    values = targets[ids[i]].values;\n    for (j = 0; j < values.length; j++) {\n      if (checker(values[j].value)) {\n        return true\n      }\n    }\n  }\n  return false\n};\nChartInternal.prototype.hasNegativeValueInTargets = function(targets) {\n  return this.checkValueInTargets(targets, function(v) {\n    return v < 0\n  })\n};\nChartInternal.prototype.hasPositiveValueInTargets = function(targets) {\n  return this.checkValueInTargets(targets, function(v) {\n    return v > 0\n  })\n};\nChartInternal.prototype.isOrderDesc = function() {\n  var config = this.config;\n  return (\n    typeof config.data_order === 'string' &&\n    config.data_order.toLowerCase() === 'desc'\n  )\n};\nChartInternal.prototype.isOrderAsc = function() {\n  var config = this.config;\n  return (\n    typeof config.data_order === 'string' &&\n    config.data_order.toLowerCase() === 'asc'\n  )\n};\nChartInternal.prototype.getOrderFunction = function() {\n  var $$ = this,\n    config = $$.config,\n    orderAsc = $$.isOrderAsc(),\n    orderDesc = $$.isOrderDesc();\n  if (orderAsc || orderDesc) {\n    var reducer = function(p, c) {\n      return p + Math.abs(c.value)\n    };\n    return function(t1, t2) {\n      var t1Sum = t1.values.reduce(reducer, 0),\n        t2Sum = t2.values.reduce(reducer, 0);\n      return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum\n    }\n  } else if (isFunction(config.data_order)) {\n    return config.data_order\n  } else if (isArray(config.data_order)) {\n    var order = config.data_order;\n    return function(t1, t2) {\n      return order.indexOf(t1.id) - order.indexOf(t2.id)\n    }\n  }\n};\nChartInternal.prototype.orderTargets = function(targets) {\n  var fct = this.getOrderFunction();\n  if (fct) {\n    targets.sort(fct);\n  }\n  return targets\n};\n\n/**\n * Returns all the values from the given targets at the given index.\n *\n * @param {Array} targets\n * @param {Number} index\n * @return {Array}\n */\nChartInternal.prototype.filterByIndex = function(targets, index) {\n  return this.d3.merge(\n    targets.map(t => t.values.filter(v => v.index === index))\n  )\n};\n\nChartInternal.prototype.filterByX = function(targets, x) {\n  return this.d3\n    .merge(\n      targets.map(function(t) {\n        return t.values\n      })\n    )\n    .filter(function(v) {\n      return v.x - x === 0\n    })\n};\nChartInternal.prototype.filterRemoveNull = function(data) {\n  return data.filter(function(d) {\n    return isValue(d.value)\n  })\n};\nChartInternal.prototype.filterByXDomain = function(targets, xDomain) {\n  return targets.map(function(t) {\n    return {\n      id: t.id,\n      id_org: t.id_org,\n      values: t.values.filter(function(v) {\n        return xDomain[0] <= v.x && v.x <= xDomain[1]\n      })\n    }\n  })\n};\nChartInternal.prototype.hasDataLabel = function() {\n  var config = this.config;\n  if (typeof config.data_labels === 'boolean' && config.data_labels) {\n    return true\n  } else if (\n    typeof config.data_labels === 'object' &&\n    notEmpty(config.data_labels)\n  ) {\n    return true\n  }\n  return false\n};\nChartInternal.prototype.getDataLabelLength = function(min, max, key) {\n  var $$ = this,\n    lengths = [0, 0],\n    paddingCoef = 1.3;\n  $$.selectChart\n    .select('svg')\n    .selectAll('.dummy')\n    .data([min, max])\n    .enter()\n    .append('text')\n    .text(function(d) {\n      return $$.dataLabelFormat(d.id)(d)\n    })\n    .each(function(d, i) {\n      lengths[i] = getBBox(this)[key] * paddingCoef;\n    })\n    .remove();\n  return lengths\n};\n/**\n * Returns true if the given data point is not arc type, otherwise false.\n * @param {Object} d The data point\n * @return {boolean}\n */\nChartInternal.prototype.isNoneArc = function(d) {\n  return this.hasTarget(this.data.targets, d.id)\n};\n\n/**\n * Returns true if the given data point is arc type, otherwise false.\n * @param {Object} d The data point\n * @return {boolean}\n */\nChartInternal.prototype.isArc = function(d) {\n  return 'data' in d && this.hasTarget(this.data.targets, d.data.id)\n};\n\n/**\n * Find the closest point from the given pos among the given targets or\n * undefined if none satisfies conditions.\n *\n * @param {Array} targets\n * @param {Array} pos An [x,y] coordinate\n * @return {Object|undefined}\n */\nChartInternal.prototype.findClosestFromTargets = function(targets, pos) {\n  const $$ = this;\n\n  // for each target, find the closest point\n  const candidates = targets\n    .map(t =>\n      $$.findClosest(\n        t.values,\n        pos,\n        $$.config.tooltip_horizontal\n          ? $$.horizontalDistance.bind($$)\n          : $$.dist.bind($$),\n        $$.config.point_sensitivity\n      )\n    )\n    .filter(v => v);\n\n  // returns the closest of candidates\n  if (candidates.length === 0) {\n    return undefined\n  } else if (candidates.length === 1) {\n    return candidates[0]\n  } else {\n    return $$.findClosest(candidates, pos, $$.dist.bind($$))\n  }\n};\n\n/**\n * Find the closest point from the x value or undefined if none satisfies conditions.\n *\n * @param {Array} targets\n * @param {Array} x A value on X axis\n * @return {Object|undefined}\n */\nChartInternal.prototype.findClosestFromTargetsByX = function(targets, x) {\n  let closest;\n  let diff;\n\n  targets.forEach(t => {\n    t.values.forEach(d => {\n      let newDiff = Math.abs(x - d.x);\n\n      if (diff === undefined || newDiff < diff) {\n        closest = d;\n        diff = newDiff;\n      }\n    });\n  });\n\n  return closest\n};\n\n/**\n * Using given compute distance method, returns the closest data point from the\n * given position.\n *\n * Giving optionally a minimum distance to satisfy.\n *\n * @param {Array} dataPoints List of DataPoints\n * @param {Array} pos An [x,y] coordinate\n * @param {Function} computeDist Function to compute distance between 2 points\n * @param {Number} minDist Minimal distance to satisfy\n * @return {Object|undefined} Closest data point\n */\nChartInternal.prototype.findClosest = function(\n  dataPoints,\n  pos,\n  computeDist,\n  minDist = Infinity\n) {\n  const $$ = this;\n\n  let closest;\n\n  // find closest bar\n  dataPoints\n    .filter(v => v && $$.isBarType(v.id))\n    .forEach(function(v) {\n      if (!closest) {\n        const shape = $$.main\n          .select(\n            '.' +\n              CLASS.bars +\n              $$.getTargetSelectorSuffix(v.id) +\n              ' .' +\n              CLASS.bar +\n              '-' +\n              v.index\n          )\n          .node();\n        if ($$.isWithinBar(pos, shape)) {\n          closest = v;\n        }\n      }\n    });\n\n  // find closest point from non-bar\n  dataPoints\n    .filter(v => v && !$$.isBarType(v.id))\n    .forEach(v => {\n      let d = computeDist(v, pos);\n      if (d < minDist) {\n        minDist = d;\n        closest = v;\n      }\n    });\n\n  return closest\n};\nChartInternal.prototype.dist = function(data, pos) {\n  var $$ = this,\n    config = $$.config,\n    xIndex = config.axis_rotated ? 1 : 0,\n    yIndex = config.axis_rotated ? 0 : 1,\n    y = $$.circleY(data, data.index),\n    x = $$.x(data.x);\n  return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2))\n};\nChartInternal.prototype.horizontalDistance = function(data, pos) {\n  var $$ = this,\n    config = $$.config,\n    xIndex = config.axis_rotated ? 1 : 0,\n    x = $$.x(data.x);\n\n  return Math.abs(x - pos[xIndex])\n};\nChartInternal.prototype.convertValuesToStep = function(values) {\n  var converted = [].concat(values),\n    i;\n\n  if (!this.isCategorized()) {\n    return values\n  }\n\n  for (i = values.length + 1; 0 < i; i--) {\n    converted[i] = converted[i - 1];\n  }\n\n  converted[0] = {\n    x: converted[0].x - 1,\n    value: converted[0].value,\n    id: converted[0].id\n  };\n  converted[values.length + 1] = {\n    x: converted[values.length].x + 1,\n    value: converted[values.length].value,\n    id: converted[values.length].id\n  };\n\n  return converted\n};\n\n/**\n * Get ratio value\n *\n * @param {String} type Ratio for given type\n * @param {Object} d Data value object\n * @param {Boolean} asPercent Convert the return as percent or not\n * @return {Number} Ratio value\n * @private\n */\nChartInternal.prototype.getRatio = function(type, d, asPercent = false) {\n  const $$ = this;\n  const api = $$.api;\n  let ratio = 0;\n\n  if (d && api.data.shown.call(api).length) {\n    ratio = d.ratio || d.value;\n\n    if (type === 'arc') {\n      if ($$.hasType('gauge')) {\n        ratio =\n          (d.endAngle - d.startAngle) /\n          (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1));\n      } else {\n        const total = $$.getTotalDataSum();\n\n        ratio = d.value / total;\n      }\n    } else if (type === 'index') {\n      const total = $$.getTotalPerIndex($$.axis.getId(d.id));\n\n      d.ratio =\n        isNumber(d.value) && total && total[d.index] > 0\n          ? d.value / total[d.index]\n          : 0;\n\n      ratio = d.ratio;\n    }\n  }\n\n  return asPercent && ratio ? ratio * 100 : ratio\n};\n\nChartInternal.prototype.updateDataAttributes = function(name, attrs) {\n  var $$ = this,\n    config = $$.config,\n    current = config['data_' + name];\n  if (typeof attrs === 'undefined') {\n    return current\n  }\n  Object.keys(attrs).forEach(function(id) {\n    current[id] = attrs[id];\n  });\n  $$.redraw({\n    withLegend: true\n  });\n  return current\n};\n\nChartInternal.prototype.load = function(targets, args) {\n  var $$ = this;\n  if (targets) {\n    // filter loading targets if needed\n    if (args.filter) {\n      targets = targets.filter(args.filter);\n    }\n    // set type if args.types || args.type specified\n    if (args.type || args.types) {\n      targets.forEach(function(t) {\n        var type = args.types && args.types[t.id] ? args.types[t.id] : args.type;\n        $$.setTargetType(t.id, type);\n      });\n    }\n    // Update/Add data\n    $$.data.targets.forEach(function(d) {\n      for (var i = 0; i < targets.length; i++) {\n        if (d.id === targets[i].id) {\n          d.values = targets[i].values;\n          targets.splice(i, 1);\n          break\n        }\n      }\n    });\n    $$.data.targets = $$.data.targets.concat(targets); // add remained\n  }\n\n  // Set targets\n  $$.updateTargets($$.data.targets);\n\n  // Redraw with new targets\n  $$.redraw({\n    withUpdateOrgXDomain: true,\n    withUpdateXDomain: true,\n    withLegend: true\n  });\n\n  if (args.done) {\n    args.done();\n  }\n};\nChartInternal.prototype.loadFromArgs = function(args) {\n  var $$ = this;\n\n  $$.resetCache();\n\n  if (args.data) {\n    $$.load($$.convertDataToTargets(args.data), args);\n  } else if (args.url) {\n    $$.convertUrlToData(\n      args.url,\n      args.mimeType,\n      args.headers,\n      args.keys,\n      function(data) {\n        $$.load($$.convertDataToTargets(data), args);\n      }\n    );\n  } else if (args.json) {\n    $$.load(\n      $$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)),\n      args\n    );\n  } else if (args.rows) {\n    $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args);\n  } else if (args.columns) {\n    $$.load(\n      $$.convertDataToTargets($$.convertColumnsToData(args.columns)),\n      args\n    );\n  } else {\n    $$.load(null, args);\n  }\n};\nChartInternal.prototype.unload = function(targetIds, done) {\n  var $$ = this;\n\n  $$.resetCache();\n\n  if (!done) {\n    done = function() {};\n  }\n  // filter existing target\n  targetIds = targetIds.filter(function(id) {\n    return $$.hasTarget($$.data.targets, id)\n  });\n  // If no target, call done and return\n  if (!targetIds || targetIds.length === 0) {\n    done();\n    return\n  }\n  $$.svg\n    .selectAll(\n      targetIds.map(function(id) {\n        return $$.selectorTarget(id)\n      })\n    )\n    .transition()\n    .style('opacity', 0)\n    .remove()\n    .call($$.endall, done);\n  targetIds.forEach(function(id) {\n    // Reset fadein for future load\n    $$.withoutFadeIn[id] = false;\n    // Remove target's elements\n    if ($$.legend) {\n      $$.legend\n        .selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id))\n        .remove();\n    }\n    // Remove target\n    $$.data.targets = $$.data.targets.filter(function(t) {\n      return t.id !== id\n    });\n  });\n};\n\nChartInternal.prototype.getYDomainMin = function(targets) {\n  var $$ = this,\n    config = $$.config,\n    ids = $$.mapToIds(targets),\n    ys = $$.getValuesAsIdKeyed(targets),\n    j,\n    k,\n    baseId,\n    idsInGroup,\n    id,\n    hasNegativeValue;\n  if (config.data_groups.length > 0) {\n    hasNegativeValue = $$.hasNegativeValueInTargets(targets);\n    for (j = 0; j < config.data_groups.length; j++) {\n      // Determine baseId\n      idsInGroup = config.data_groups[j].filter(function(id) {\n        return ids.indexOf(id) >= 0\n      });\n      if (idsInGroup.length === 0) {\n        continue\n      }\n      baseId = idsInGroup[0];\n      // Consider negative values\n      if (hasNegativeValue && ys[baseId]) {\n        ys[baseId].forEach(function(v, i) {\n          ys[baseId][i] = v < 0 ? v : 0;\n        });\n      }\n      // Compute min\n      for (k = 1; k < idsInGroup.length; k++) {\n        id = idsInGroup[k];\n        if (!ys[id]) {\n          continue\n        }\n        ys[id].forEach(function(v, i) {\n          if (\n            $$.axis.getId(id) === $$.axis.getId(baseId) &&\n            ys[baseId] &&\n            !(hasNegativeValue && +v > 0)\n          ) {\n            ys[baseId][i] += +v;\n          }\n        });\n      }\n    }\n  }\n  return $$.d3.min(\n    Object.keys(ys).map(function(key) {\n      return $$.d3.min(ys[key])\n    })\n  )\n};\nChartInternal.prototype.getYDomainMax = function(targets) {\n  var $$ = this,\n    config = $$.config,\n    ids = $$.mapToIds(targets),\n    ys = $$.getValuesAsIdKeyed(targets),\n    j,\n    k,\n    baseId,\n    idsInGroup,\n    id,\n    hasPositiveValue;\n  if (config.data_groups.length > 0) {\n    hasPositiveValue = $$.hasPositiveValueInTargets(targets);\n    for (j = 0; j < config.data_groups.length; j++) {\n      // Determine baseId\n      idsInGroup = config.data_groups[j].filter(function(id) {\n        return ids.indexOf(id) >= 0\n      });\n      if (idsInGroup.length === 0) {\n        continue\n      }\n      baseId = idsInGroup[0];\n      // Consider positive values\n      if (hasPositiveValue && ys[baseId]) {\n        ys[baseId].forEach(function(v, i) {\n          ys[baseId][i] = v > 0 ? v : 0;\n        });\n      }\n      // Compute max\n      for (k = 1; k < idsInGroup.length; k++) {\n        id = idsInGroup[k];\n        if (!ys[id]) {\n          continue\n        }\n        ys[id].forEach(function(v, i) {\n          if (\n            $$.axis.getId(id) === $$.axis.getId(baseId) &&\n            ys[baseId] &&\n            !(hasPositiveValue && +v < 0)\n          ) {\n            ys[baseId][i] += +v;\n          }\n        });\n      }\n    }\n  }\n  return $$.d3.max(\n    Object.keys(ys).map(function(key) {\n      return $$.d3.max(ys[key])\n    })\n  )\n};\nChartInternal.prototype.getYDomain = function(targets, axisId, xDomain) {\n  var $$ = this,\n    config = $$.config;\n\n  if ($$.isAxisNormalized(axisId)) {\n    return [0, 100]\n  }\n\n  var targetsByAxisId = targets.filter(function(t) {\n      return $$.axis.getId(t.id) === axisId\n    }),\n    yTargets = xDomain\n      ? $$.filterByXDomain(targetsByAxisId, xDomain)\n      : targetsByAxisId,\n    yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min,\n    yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max,\n    yDomainMin = $$.getYDomainMin(yTargets),\n    yDomainMax = $$.getYDomainMax(yTargets),\n    domain,\n    domainLength,\n    padding_top,\n    padding_bottom,\n    center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center,\n    yDomainAbs,\n    lengths,\n    diff,\n    ratio,\n    isAllPositive,\n    isAllNegative,\n    isZeroBased =\n      ($$.hasType('bar', yTargets) && config.bar_zerobased) ||\n      ($$.hasType('area', yTargets) && config.area_zerobased),\n    isInverted =\n      axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted,\n    showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated,\n    showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated;\n\n  // MEMO: avoid inverting domain unexpectedly\n  yDomainMin = isValue(yMin)\n    ? yMin\n    : isValue(yMax)\n    ? yDomainMin < yMax\n      ? yDomainMin\n      : yMax - 10\n    : yDomainMin;\n  yDomainMax = isValue(yMax)\n    ? yMax\n    : isValue(yMin)\n    ? yMin < yDomainMax\n      ? yDomainMax\n      : yMin + 10\n    : yDomainMax;\n\n  if (yTargets.length === 0) {\n    // use current domain if target of axisId is none\n    return axisId === 'y2' ? $$.y2.domain() : $$.y.domain()\n  }\n  if (isNaN(yDomainMin)) {\n    // set minimum to zero when not number\n    yDomainMin = 0;\n  }\n  if (isNaN(yDomainMax)) {\n    // set maximum to have same value as yDomainMin\n    yDomainMax = yDomainMin;\n  }\n  if (yDomainMin === yDomainMax) {\n    yDomainMin < 0 ? (yDomainMax = 0) : (yDomainMin = 0);\n  }\n  isAllPositive = yDomainMin >= 0 && yDomainMax >= 0;\n  isAllNegative = yDomainMin <= 0 && yDomainMax <= 0;\n\n  // Cancel zerobased if axis_*_min / axis_*_max specified\n  if ((isValue(yMin) && isAllPositive) || (isValue(yMax) && isAllNegative)) {\n    isZeroBased = false;\n  }\n\n  // Bar/Area chart should be 0-based if all positive|negative\n  if (isZeroBased) {\n    if (isAllPositive) {\n      yDomainMin = 0;\n    }\n    if (isAllNegative) {\n      yDomainMax = 0;\n    }\n  }\n\n  domainLength = Math.abs(yDomainMax - yDomainMin);\n  padding_top = padding_bottom = domainLength * 0.1;\n\n  if (typeof center !== 'undefined') {\n    yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax));\n    yDomainMax = center + yDomainAbs;\n    yDomainMin = center - yDomainAbs;\n  }\n  // add padding for data label\n  if (showHorizontalDataLabel) {\n    lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width');\n    diff = diffDomain($$.y.range());\n    ratio = [lengths[0] / diff, lengths[1] / diff];\n    padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1]));\n    padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1]));\n  } else if (showVerticalDataLabel) {\n    lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height');\n\n    const pixelsToAxisPadding = $$.getY(\n      config[`axis_${axisId}_type`],\n      // input domain as pixels\n      [0, config.axis_rotated ? $$.width : $$.height],\n      // output range as axis padding\n      [0, domainLength]\n    );\n\n    padding_top += pixelsToAxisPadding(lengths[1]);\n    padding_bottom += pixelsToAxisPadding(lengths[0]);\n  }\n  if (axisId === 'y' && notEmpty(config.axis_y_padding)) {\n    padding_top = $$.axis.getPadding(\n      config.axis_y_padding,\n      'top',\n      padding_top,\n      domainLength\n    );\n    padding_bottom = $$.axis.getPadding(\n      config.axis_y_padding,\n      'bottom',\n      padding_bottom,\n      domainLength\n    );\n  }\n  if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) {\n    padding_top = $$.axis.getPadding(\n      config.axis_y2_padding,\n      'top',\n      padding_top,\n      domainLength\n    );\n    padding_bottom = $$.axis.getPadding(\n      config.axis_y2_padding,\n      'bottom',\n      padding_bottom,\n      domainLength\n    );\n  }\n  // Bar/Area chart should be 0-based if all positive|negative\n  if (isZeroBased) {\n    if (isAllPositive) {\n      padding_bottom = yDomainMin;\n    }\n    if (isAllNegative) {\n      padding_top = -yDomainMax;\n    }\n  }\n  domain = [yDomainMin - padding_bottom, yDomainMax + padding_top];\n  return isInverted ? domain.reverse() : domain\n};\nChartInternal.prototype.getXDomainMin = function(targets) {\n  var $$ = this,\n    config = $$.config;\n  return isDefined(config.axis_x_min)\n    ? $$.isTimeSeries()\n      ? this.parseDate(config.axis_x_min)\n      : config.axis_x_min\n    : $$.d3.min(targets, function(t) {\n        return $$.d3.min(t.values, function(v) {\n          return v.x\n        })\n      })\n};\nChartInternal.prototype.getXDomainMax = function(targets) {\n  var $$ = this,\n    config = $$.config;\n  return isDefined(config.axis_x_max)\n    ? $$.isTimeSeries()\n      ? this.parseDate(config.axis_x_max)\n      : config.axis_x_max\n    : $$.d3.max(targets, function(t) {\n        return $$.d3.max(t.values, function(v) {\n          return v.x\n        })\n      })\n};\nChartInternal.prototype.getXDomainPadding = function(domain) {\n  var $$ = this,\n    config = $$.config,\n    diff = domain[1] - domain[0],\n    maxDataCount,\n    padding,\n    paddingLeft,\n    paddingRight;\n  if ($$.isCategorized()) {\n    padding = 0;\n  } else if ($$.hasType('bar')) {\n    maxDataCount = $$.getMaxDataCount();\n    padding = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : 0.5;\n  } else {\n    padding = diff * 0.01;\n  }\n  if (\n    typeof config.axis_x_padding === 'object' &&\n    notEmpty(config.axis_x_padding)\n  ) {\n    paddingLeft = isValue(config.axis_x_padding.left)\n      ? config.axis_x_padding.left\n      : padding;\n    paddingRight = isValue(config.axis_x_padding.right)\n      ? config.axis_x_padding.right\n      : padding;\n  } else if (typeof config.axis_x_padding === 'number') {\n    paddingLeft = paddingRight = config.axis_x_padding;\n  } else {\n    paddingLeft = paddingRight = padding;\n  }\n  return { left: paddingLeft, right: paddingRight }\n};\nChartInternal.prototype.getXDomain = function(targets) {\n  var $$ = this,\n    xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)],\n    firstX = xDomain[0],\n    lastX = xDomain[1],\n    padding = $$.getXDomainPadding(xDomain),\n    min = 0,\n    max = 0;\n  // show center of x domain if min and max are the same\n  if (firstX - lastX === 0 && !$$.isCategorized()) {\n    if ($$.isTimeSeries()) {\n      firstX = new Date(firstX.getTime() * 0.5);\n      lastX = new Date(lastX.getTime() * 1.5);\n    } else {\n      firstX = firstX === 0 ? 1 : firstX * 0.5;\n      lastX = lastX === 0 ? -1 : lastX * 1.5;\n    }\n  }\n  if (firstX || firstX === 0) {\n    min = $$.isTimeSeries()\n      ? new Date(firstX.getTime() - padding.left)\n      : firstX - padding.left;\n  }\n  if (lastX || lastX === 0) {\n    max = $$.isTimeSeries()\n      ? new Date(lastX.getTime() + padding.right)\n      : lastX + padding.right;\n  }\n  return [min, max]\n};\nChartInternal.prototype.updateXDomain = function(\n  targets,\n  withUpdateXDomain,\n  withUpdateOrgXDomain,\n  withTrim,\n  domain\n) {\n  var $$ = this,\n    config = $$.config;\n\n  if (withUpdateOrgXDomain) {\n    $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets)));\n    $$.orgXDomain = $$.x.domain();\n    if (config.zoom_enabled) {\n      $$.zoom.update();\n    }\n    $$.subX.domain($$.x.domain());\n    if ($$.brush) {\n      $$.brush.updateScale($$.subX);\n    }\n  }\n  if (withUpdateXDomain) {\n    $$.x.domain(\n      domain\n        ? domain\n        : !$$.brush || $$.brush.empty()\n        ? $$.orgXDomain\n        : $$.brush.selectionAsValue()\n    );\n  }\n\n  // Trim domain when too big by zoom mousemove event\n  if (withTrim) {\n    $$.x.domain($$.trimXDomain($$.x.orgDomain()));\n  }\n\n  return $$.x.domain()\n};\nChartInternal.prototype.trimXDomain = function(domain) {\n  var zoomDomain = this.getZoomDomain(),\n    min = zoomDomain[0],\n    max = zoomDomain[1];\n  if (domain[0] <= min) {\n    domain[1] = +domain[1] + (min - domain[0]);\n    domain[0] = min;\n  }\n  if (max <= domain[1]) {\n    domain[0] = +domain[0] - (domain[1] - max);\n    domain[1] = max;\n  }\n  return domain\n};\n\nChartInternal.prototype.drag = function(mouse) {\n  var $$ = this,\n    config = $$.config,\n    main = $$.main,\n    d3 = $$.d3;\n  var sx, sy, mx, my, minX, maxX, minY, maxY;\n\n  if ($$.hasArcType()) {\n    return\n  }\n  if (!config.data_selection_enabled) {\n    return\n  } // do nothing if not selectable\n  if (!config.data_selection_multiple) {\n    return\n  } // skip when single selection because drag is used for multiple selection\n\n  sx = $$.dragStart[0];\n  sy = $$.dragStart[1];\n  mx = mouse[0];\n  my = mouse[1];\n  minX = Math.min(sx, mx);\n  maxX = Math.max(sx, mx);\n  minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my);\n  maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my);\n\n  main\n    .select('.' + CLASS.dragarea)\n    .attr('x', minX)\n    .attr('y', minY)\n    .attr('width', maxX - minX)\n    .attr('height', maxY - minY);\n  // TODO: binary search when multiple xs\n  main\n    .selectAll('.' + CLASS.shapes)\n    .selectAll('.' + CLASS.shape)\n    .each(function(d, i) {\n      if (!config.data_selection_isselectable(d)) {\n        return\n      }\n      var shape = d3.select(this),\n        isSelected = shape.classed(CLASS.SELECTED),\n        isIncluded = shape.classed(CLASS.INCLUDED),\n        _x,\n        _y,\n        _w,\n        _h,\n        toggle,\n        isWithin = false,\n        box;\n      if (shape.classed(CLASS.circle)) {\n        _x = shape.attr('cx') * 1;\n        _y = shape.attr('cy') * 1;\n        toggle = $$.togglePoint;\n        isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY;\n      } else if (shape.classed(CLASS.bar)) {\n        box = getPathBox(this);\n        _x = box.x;\n        _y = box.y;\n        _w = box.width;\n        _h = box.height;\n        toggle = $$.togglePath;\n        isWithin =\n          !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY);\n      } else {\n        // line/area selection not supported yet\n        return\n      }\n      if (isWithin ^ isIncluded) {\n        shape.classed(CLASS.INCLUDED, !isIncluded);\n        // TODO: included/unincluded callback here\n        shape.classed(CLASS.SELECTED, !isSelected);\n        toggle.call($$, !isSelected, shape, d, i);\n      }\n    });\n};\n\nChartInternal.prototype.dragstart = function(mouse) {\n  var $$ = this,\n    config = $$.config;\n  if ($$.hasArcType()) {\n    return\n  }\n  if (!config.data_selection_enabled) {\n    return\n  } // do nothing if not selectable\n  $$.dragStart = mouse;\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('rect')\n    .attr('class', CLASS.dragarea)\n    .style('opacity', 0.1);\n  $$.dragging = true;\n};\n\nChartInternal.prototype.dragend = function() {\n  var $$ = this,\n    config = $$.config;\n  if ($$.hasArcType()) {\n    return\n  }\n  if (!config.data_selection_enabled) {\n    return\n  } // do nothing if not selectable\n  $$.main\n    .select('.' + CLASS.dragarea)\n    .transition()\n    .duration(100)\n    .style('opacity', 0)\n    .remove();\n  $$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false);\n  $$.dragging = false;\n};\n\nChartInternal.prototype.getYFormat = function(forArc) {\n  var $$ = this,\n    formatForY =\n      forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat,\n    formatForY2 =\n      forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format;\n  return function(v, ratio, id) {\n    var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY;\n    return format.call($$, v, ratio)\n  }\n};\nChartInternal.prototype.yFormat = function(v) {\n  var $$ = this,\n    config = $$.config,\n    format = config.axis_y_tick_format\n      ? config.axis_y_tick_format\n      : $$.defaultValueFormat;\n  return format(v)\n};\nChartInternal.prototype.y2Format = function(v) {\n  var $$ = this,\n    config = $$.config,\n    format = config.axis_y2_tick_format\n      ? config.axis_y2_tick_format\n      : $$.defaultValueFormat;\n  return format(v)\n};\nChartInternal.prototype.defaultValueFormat = function(v) {\n  return isValue(v) ? +v : ''\n};\nChartInternal.prototype.defaultArcValueFormat = function(v, ratio) {\n  return (ratio * 100).toFixed(1) + '%'\n};\nChartInternal.prototype.dataLabelFormat = function(targetId) {\n  var $$ = this,\n    data_labels = $$.config.data_labels,\n    format,\n    defaultFormat = function(v) {\n      return isValue(v) ? +v : ''\n    };\n  // find format according to axis id\n  if (typeof data_labels.format === 'function') {\n    format = data_labels.format;\n  } else if (typeof data_labels.format === 'object') {\n    if (data_labels.format[targetId]) {\n      format =\n        data_labels.format[targetId] === true\n          ? defaultFormat\n          : data_labels.format[targetId];\n    } else {\n      format = function() {\n        return ''\n      };\n    }\n  } else {\n    format = defaultFormat;\n  }\n  return format\n};\n\nChartInternal.prototype.initGrid = function() {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3;\n  $$.grid = $$.main\n    .append('g')\n    .attr('clip-path', $$.clipPathForGrid)\n    .attr('class', CLASS.grid);\n  if (config.grid_x_show) {\n    $$.grid.append('g').attr('class', CLASS.xgrids);\n  }\n  if (config.grid_y_show) {\n    $$.grid.append('g').attr('class', CLASS.ygrids);\n  }\n  if (config.grid_focus_show) {\n    $$.grid\n      .append('g')\n      .attr('class', CLASS.xgridFocus)\n      .append('line')\n      .attr('class', CLASS.xgridFocus);\n  }\n  $$.xgrid = d3.selectAll([]);\n  if (!config.grid_lines_front) {\n    $$.initGridLines();\n  }\n};\nChartInternal.prototype.initGridLines = function() {\n  var $$ = this,\n    d3 = $$.d3;\n  $$.gridLines = $$.main\n    .append('g')\n    .attr('clip-path', $$.clipPathForGrid)\n    .attr('class', CLASS.grid + ' ' + CLASS.gridLines);\n  $$.gridLines.append('g').attr('class', CLASS.xgridLines);\n  $$.gridLines.append('g').attr('class', CLASS.ygridLines);\n  $$.xgridLines = d3.selectAll([]);\n};\nChartInternal.prototype.updateXGrid = function(withoutUpdate) {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3,\n    xgridData = $$.generateGridData(config.grid_x_type, $$.x),\n    tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0;\n\n  $$.xgridAttr = config.axis_rotated\n    ? {\n        x1: 0,\n        x2: $$.width,\n        y1: function(d) {\n          return $$.x(d) - tickOffset\n        },\n        y2: function(d) {\n          return $$.x(d) - tickOffset\n        }\n      }\n    : {\n        x1: function(d) {\n          return $$.x(d) + tickOffset\n        },\n        x2: function(d) {\n          return $$.x(d) + tickOffset\n        },\n        y1: 0,\n        y2: $$.height\n      };\n  $$.xgridAttr.opacity = function() {\n    var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1');\n    return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1\n  };\n\n  var xgrid = $$.main\n    .select('.' + CLASS.xgrids)\n    .selectAll('.' + CLASS.xgrid)\n    .data(xgridData);\n  var xgridEnter = xgrid\n    .enter()\n    .append('line')\n    .attr('class', CLASS.xgrid)\n    .attr('x1', $$.xgridAttr.x1)\n    .attr('x2', $$.xgridAttr.x2)\n    .attr('y1', $$.xgridAttr.y1)\n    .attr('y2', $$.xgridAttr.y2)\n    .style('opacity', 0);\n  $$.xgrid = xgridEnter.merge(xgrid);\n  if (!withoutUpdate) {\n    $$.xgrid\n      .attr('x1', $$.xgridAttr.x1)\n      .attr('x2', $$.xgridAttr.x2)\n      .attr('y1', $$.xgridAttr.y1)\n      .attr('y2', $$.xgridAttr.y2)\n      .style('opacity', $$.xgridAttr.opacity);\n  }\n  xgrid.exit().remove();\n};\n\nChartInternal.prototype.updateYGrid = function() {\n  var $$ = this,\n    config = $$.config,\n    gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks);\n  var ygrid = $$.main\n    .select('.' + CLASS.ygrids)\n    .selectAll('.' + CLASS.ygrid)\n    .data(gridValues);\n  var ygridEnter = ygrid\n    .enter()\n    .append('line')\n    // TODO: x1, x2, y1, y2, opacity need to be set here maybe\n    .attr('class', CLASS.ygrid);\n  $$.ygrid = ygridEnter.merge(ygrid);\n  $$.ygrid\n    .attr('x1', config.axis_rotated ? $$.y : 0)\n    .attr('x2', config.axis_rotated ? $$.y : $$.width)\n    .attr('y1', config.axis_rotated ? 0 : $$.y)\n    .attr('y2', config.axis_rotated ? $$.height : $$.y);\n  ygrid.exit().remove();\n  $$.smoothLines($$.ygrid, 'grid');\n};\n\nChartInternal.prototype.gridTextAnchor = function(d) {\n  return d.position ? d.position : 'end'\n};\nChartInternal.prototype.gridTextDx = function(d) {\n  return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4\n};\nChartInternal.prototype.xGridTextX = function(d) {\n  return d.position === 'start'\n    ? -this.height\n    : d.position === 'middle'\n    ? -this.height / 2\n    : 0\n};\nChartInternal.prototype.yGridTextX = function(d) {\n  return d.position === 'start'\n    ? 0\n    : d.position === 'middle'\n    ? this.width / 2\n    : this.width\n};\nChartInternal.prototype.updateGrid = function(duration) {\n  var $$ = this,\n    main = $$.main,\n    config = $$.config,\n    xgridLine,\n    xgridLineEnter,\n    ygridLine,\n    ygridLineEnter,\n    xv = $$.xv.bind($$),\n    yv = $$.yv.bind($$),\n    xGridTextX = $$.xGridTextX.bind($$),\n    yGridTextX = $$.yGridTextX.bind($$);\n\n  // hide if arc type\n  $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');\n\n  main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden');\n  if (config.grid_x_show) {\n    $$.updateXGrid();\n  }\n  xgridLine = main\n    .select('.' + CLASS.xgridLines)\n    .selectAll('.' + CLASS.xgridLine)\n    .data(config.grid_x_lines);\n  // enter\n  xgridLineEnter = xgridLine\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : '')\n    });\n  xgridLineEnter\n    .append('line')\n    .attr('x1', config.axis_rotated ? 0 : xv)\n    .attr('x2', config.axis_rotated ? $$.width : xv)\n    .attr('y1', config.axis_rotated ? xv : 0)\n    .attr('y2', config.axis_rotated ? xv : $$.height)\n    .style('opacity', 0);\n  xgridLineEnter\n    .append('text')\n    .attr('text-anchor', $$.gridTextAnchor)\n    .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\n    .attr('x', config.axis_rotated ? yGridTextX : xGridTextX)\n    .attr('y', xv)\n    .attr('dx', $$.gridTextDx)\n    .attr('dy', -5)\n    .style('opacity', 0);\n  // udpate\n  $$.xgridLines = xgridLineEnter.merge(xgridLine);\n  // done in d3.transition() of the end of this function\n  // exit\n  xgridLine\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove();\n\n  // Y-Grid\n  if (config.grid_y_show) {\n    $$.updateYGrid();\n  }\n  ygridLine = main\n    .select('.' + CLASS.ygridLines)\n    .selectAll('.' + CLASS.ygridLine)\n    .data(config.grid_y_lines);\n  // enter\n  ygridLineEnter = ygridLine\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : '')\n    });\n  ygridLineEnter\n    .append('line')\n    .attr('x1', config.axis_rotated ? yv : 0)\n    .attr('x2', config.axis_rotated ? yv : $$.width)\n    .attr('y1', config.axis_rotated ? 0 : yv)\n    .attr('y2', config.axis_rotated ? $$.height : yv)\n    .style('opacity', 0);\n  ygridLineEnter\n    .append('text')\n    .attr('text-anchor', $$.gridTextAnchor)\n    .attr('transform', config.axis_rotated ? 'rotate(-90)' : '')\n    .attr('x', config.axis_rotated ? xGridTextX : yGridTextX)\n    .attr('y', yv)\n    .attr('dx', $$.gridTextDx)\n    .attr('dy', -5)\n    .style('opacity', 0);\n  // update\n  $$.ygridLines = ygridLineEnter.merge(ygridLine);\n  $$.ygridLines\n    .select('line')\n    .transition()\n    .duration(duration)\n    .attr('x1', config.axis_rotated ? yv : 0)\n    .attr('x2', config.axis_rotated ? yv : $$.width)\n    .attr('y1', config.axis_rotated ? 0 : yv)\n    .attr('y2', config.axis_rotated ? $$.height : yv)\n    .style('opacity', 1);\n  $$.ygridLines\n    .select('text')\n    .transition()\n    .duration(duration)\n    .attr(\n      'x',\n      config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)\n    )\n    .attr('y', yv)\n    .text(function(d) {\n      return d.text\n    })\n    .style('opacity', 1);\n  // exit\n  ygridLine\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove();\n};\nChartInternal.prototype.redrawGrid = function(withTransition, transition) {\n  var $$ = this,\n    config = $$.config,\n    xv = $$.xv.bind($$),\n    lines = $$.xgridLines.select('line'),\n    texts = $$.xgridLines.select('text');\n  return [\n    (withTransition ? lines.transition(transition) : lines)\n      .attr('x1', config.axis_rotated ? 0 : xv)\n      .attr('x2', config.axis_rotated ? $$.width : xv)\n      .attr('y1', config.axis_rotated ? xv : 0)\n      .attr('y2', config.axis_rotated ? xv : $$.height)\n      .style('opacity', 1),\n    (withTransition ? texts.transition(transition) : texts)\n      .attr(\n        'x',\n        config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)\n      )\n      .attr('y', xv)\n      .text(function(d) {\n        return d.text\n      })\n      .style('opacity', 1)\n  ]\n};\nChartInternal.prototype.showXGridFocus = function(selectedData) {\n  var $$ = this,\n    config = $$.config,\n    dataToShow = selectedData.filter(function(d) {\n      return d && isValue(d.value)\n    }),\n    focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus),\n    xx = $$.xx.bind($$);\n  if (!config.tooltip_show) {\n    return\n  }\n  // Hide when stanford plot exists\n  if ($$.hasType('stanford') || $$.hasArcType()) {\n    return\n  }\n  focusEl\n    .style('visibility', 'visible')\n    .data([dataToShow[0]])\n    .attr(config.axis_rotated ? 'y1' : 'x1', xx)\n    .attr(config.axis_rotated ? 'y2' : 'x2', xx);\n  $$.smoothLines(focusEl, 'grid');\n};\nChartInternal.prototype.hideXGridFocus = function() {\n  this.main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden');\n};\nChartInternal.prototype.updateXgridFocus = function() {\n  var $$ = this,\n    config = $$.config;\n  $$.main\n    .select('line.' + CLASS.xgridFocus)\n    .attr('x1', config.axis_rotated ? 0 : -10)\n    .attr('x2', config.axis_rotated ? $$.width : -10)\n    .attr('y1', config.axis_rotated ? -10 : 0)\n    .attr('y2', config.axis_rotated ? -10 : $$.height);\n};\nChartInternal.prototype.generateGridData = function(type, scale) {\n  var $$ = this,\n    gridData = [],\n    xDomain,\n    firstYear,\n    lastYear,\n    i,\n    tickNum = $$.main\n      .select('.' + CLASS.axisX)\n      .selectAll('.tick')\n      .size();\n  if (type === 'year') {\n    xDomain = $$.getXDomain();\n    firstYear = xDomain[0].getFullYear();\n    lastYear = xDomain[1].getFullYear();\n    for (i = firstYear; i <= lastYear; i++) {\n      gridData.push(new Date(i + '-01-01 00:00:00'));\n    }\n  } else {\n    gridData = scale.ticks(10);\n    if (gridData.length > tickNum) {\n      // use only int\n      gridData = gridData.filter(function(d) {\n        return ('' + d).indexOf('.') < 0\n      });\n    }\n  }\n  return gridData\n};\nChartInternal.prototype.getGridFilterToRemove = function(params) {\n  return params\n    ? function(line) {\n        var found = false\n        ;[].concat(params).forEach(function(param) {\n          if (\n            ('value' in param && line.value === param.value) ||\n            ('class' in param && line['class'] === param['class'])\n          ) {\n            found = true;\n          }\n        });\n        return found\n      }\n    : function() {\n        return true\n      }\n};\nChartInternal.prototype.removeGridLines = function(params, forX) {\n  var $$ = this,\n    config = $$.config,\n    toRemove = $$.getGridFilterToRemove(params),\n    toShow = function(line) {\n      return !toRemove(line)\n    },\n    classLines = forX ? CLASS.xgridLines : CLASS.ygridLines,\n    classLine = forX ? CLASS.xgridLine : CLASS.ygridLine;\n  $$.main\n    .select('.' + classLines)\n    .selectAll('.' + classLine)\n    .filter(toRemove)\n    .transition()\n    .duration(config.transition_duration)\n    .style('opacity', 0)\n    .remove();\n  if (forX) {\n    config.grid_x_lines = config.grid_x_lines.filter(toShow);\n  } else {\n    config.grid_y_lines = config.grid_y_lines.filter(toShow);\n  }\n};\n\nChartInternal.prototype.initEventRect = function() {\n  var $$ = this,\n    config = $$.config;\n\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.eventRects)\n    .style('fill-opacity', 0);\n  $$.eventRect = $$.main\n    .select('.' + CLASS.eventRects)\n    .append('rect')\n    .attr('class', CLASS.eventRect);\n\n  // event rect handle zoom event as well\n  if (config.zoom_enabled && $$.zoom) {\n    $$.eventRect.call($$.zoom).on('dblclick.zoom', null);\n    if (config.zoom_initialRange) {\n      // WORKAROUND: Add transition to apply transform immediately when no subchart\n      $$.eventRect\n        .transition()\n        .duration(0)\n        .call($$.zoom.transform, $$.zoomTransform(config.zoom_initialRange));\n    }\n  }\n};\nChartInternal.prototype.redrawEventRect = function() {\n  const $$ = this,\n    d3 = $$.d3,\n    config = $$.config;\n\n  function mouseout() {\n    $$.svg.select('.' + CLASS.eventRect).style('cursor', null);\n    $$.hideXGridFocus();\n    $$.hideTooltip();\n    $$.unexpandCircles();\n    $$.unexpandBars();\n  }\n\n  const isHoveringDataPoint = (mouse, closest) =>\n    closest &&\n    ($$.isBarType(closest.id) ||\n      $$.dist(closest, mouse) < config.point_sensitivity);\n\n  const withName = d => (d ? $$.addName(Object.assign({}, d)) : null);\n\n  // rects for mouseover\n  $$.main\n    .select('.' + CLASS.eventRects)\n    .style(\n      'cursor',\n      config.zoom_enabled\n        ? config.axis_rotated\n          ? 'ns-resize'\n          : 'ew-resize'\n        : null\n    );\n\n  $$.eventRect\n    .attr('x', 0)\n    .attr('y', 0)\n    .attr('width', $$.width)\n    .attr('height', $$.height)\n    .on(\n      'mouseout',\n      config.interaction_enabled\n        ? function() {\n            if (!config) {\n              return\n            } // chart is destroyed\n            if ($$.hasArcType()) {\n              return\n            }\n            if ($$.mouseover) {\n              config.data_onmouseout.call($$.api, $$.mouseover);\n              $$.mouseover = undefined;\n            }\n            mouseout();\n          }\n        : null\n    )\n    .on(\n      'mousemove',\n      config.interaction_enabled\n        ? function() {\n            // do nothing when dragging\n            if ($$.dragging) {\n              return\n            }\n\n            const targetsToShow = $$.getTargetsToShow();\n\n            // do nothing if arc type\n            if ($$.hasArcType(targetsToShow)) {\n              return\n            }\n\n            const mouse = d3.mouse(this);\n            const closest = withName(\n              $$.findClosestFromTargets(targetsToShow, mouse)\n            );\n            const isMouseCloseToDataPoint = isHoveringDataPoint(mouse, closest);\n\n            // ensure onmouseout is always called if mousemove switch between 2 targets\n            if (\n              $$.mouseover &&\n              (!closest ||\n                closest.id !== $$.mouseover.id ||\n                closest.index !== $$.mouseover.index)\n            ) {\n              config.data_onmouseout.call($$.api, $$.mouseover);\n              $$.mouseover = undefined;\n            }\n            if (closest && !$$.mouseover) {\n              config.data_onmouseover.call($$.api, closest);\n              $$.mouseover = closest;\n            }\n\n            // show cursor as pointer if we're hovering a data point close enough\n            $$.svg\n              .select('.' + CLASS.eventRect)\n              .style('cursor', isMouseCloseToDataPoint ? 'pointer' : null);\n\n            // if tooltip not grouped, we want to display only data from closest data point\n            const showSingleDataPoint =\n              !config.tooltip_grouped || $$.hasType('stanford', targetsToShow);\n\n            // find data to highlight\n            let selectedData;\n            if (showSingleDataPoint) {\n              if (closest) {\n                selectedData = [closest];\n              }\n            } else {\n              let closestByX;\n              if (closest) {\n                // reuse closest value\n                closestByX = closest;\n              } else {\n                // try to find the closest value by X values from the mouse position\n                const mouseX = config.axis_rotated ? mouse[1] : mouse[0];\n                closestByX = $$.findClosestFromTargetsByX(\n                  targetsToShow,\n                  $$.x.invert(mouseX)\n                );\n              }\n\n              // highlight all data for this 'x' value\n              if (closestByX) {\n                selectedData = $$.filterByX(targetsToShow, closestByX.x);\n              }\n            }\n\n            // ensure we have data to show\n            if (!selectedData || selectedData.length === 0) {\n              return mouseout()\n            }\n\n            // inject names for each point\n            selectedData = selectedData.map(withName);\n\n            // show tooltip\n            $$.showTooltip(selectedData, this);\n\n            // expand points\n            if (config.point_focus_expand_enabled) {\n              $$.unexpandCircles();\n              selectedData.forEach(function(d) {\n                $$.expandCircles(d.index, d.id, false);\n              });\n            }\n\n            // expand bars\n            $$.unexpandBars();\n            selectedData.forEach(function(d) {\n              $$.expandBars(d.index, d.id, false);\n            });\n\n            // Show xgrid focus line\n            $$.showXGridFocus(selectedData);\n          }\n        : null\n    )\n    .on(\n      'click',\n      config.interaction_enabled\n        ? function() {\n            const targetsToShow = $$.getTargetsToShow();\n\n            if ($$.hasArcType(targetsToShow)) {\n              return\n            }\n\n            const mouse = d3.mouse(this);\n            const closest = withName(\n              $$.findClosestFromTargets(targetsToShow, mouse)\n            );\n\n            if (!isHoveringDataPoint(mouse, closest)) {\n              return\n            }\n\n            // select if selection enabled\n            let sameXData;\n            if (!config.data_selection_grouped || $$.isStanfordType(closest)) {\n              sameXData = [closest];\n            } else {\n              sameXData = $$.filterByX(targetsToShow, closest.x);\n            }\n\n            // toggle selected state\n            sameXData.forEach(function(d) {\n              $$.main\n                .selectAll(\n                  '.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id)\n                )\n                .selectAll('.' + CLASS.shape + '-' + d.index)\n                .each(function() {\n                  if (\n                    config.data_selection_grouped ||\n                    $$.isWithinShape(this, d)\n                  ) {\n                    $$.toggleShape(this, d, d.index);\n                  }\n                });\n            });\n\n            // call data_onclick on the closest data point\n            if (closest) {\n              const shape = $$.main\n                .selectAll(\n                  '.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id)\n                )\n                .select('.' + CLASS.shape + '-' + closest.index);\n              config.data_onclick.call($$.api, closest, shape.node());\n            }\n          }\n        : null\n    )\n    .call(\n      config.interaction_enabled && config.data_selection_draggable && $$.drag\n        ? d3\n            .drag()\n            .on('drag', function() {\n              $$.drag(d3.mouse(this));\n            })\n            .on('start', function() {\n              $$.dragstart(d3.mouse(this));\n            })\n            .on('end', function() {\n              $$.dragend();\n            })\n        : function() {}\n    );\n};\nChartInternal.prototype.getMousePosition = function(data) {\n  var $$ = this;\n  return [$$.x(data.x), $$.getYScale(data.id)(data.value)]\n};\nChartInternal.prototype.dispatchEvent = function(type, mouse) {\n  var $$ = this,\n    selector = '.' + CLASS.eventRect,\n    eventRect = $$.main.select(selector).node(),\n    box = eventRect.getBoundingClientRect(),\n    x = box.left + (mouse ? mouse[0] : 0),\n    y = box.top + (mouse ? mouse[1] : 0),\n    event = document.createEvent('MouseEvents');\n\n  event.initMouseEvent(\n    type,\n    true,\n    true,\n    window,\n    0,\n    x,\n    y,\n    x,\n    y,\n    false,\n    false,\n    false,\n    false,\n    0,\n    null\n  );\n  eventRect.dispatchEvent(event);\n};\n\nChartInternal.prototype.initLegend = function() {\n  var $$ = this;\n  $$.legendItemTextBox = {};\n  $$.legendHasRendered = false;\n  $$.legend = $$.svg.append('g').attr('transform', $$.getTranslate('legend'));\n  if (!$$.config.legend_show) {\n    $$.legend.style('visibility', 'hidden');\n    $$.hiddenLegendIds = $$.mapToIds($$.data.targets);\n    return\n  }\n  // MEMO: call here to update legend box and tranlate for all\n  // MEMO: translate will be updated by this, so transform not needed in updateLegend()\n  $$.updateLegendWithDefaults();\n};\nChartInternal.prototype.updateLegendWithDefaults = function() {\n  var $$ = this;\n  $$.updateLegend($$.mapToIds($$.data.targets), {\n    withTransform: false,\n    withTransitionForTransform: false,\n    withTransition: false\n  });\n};\nChartInternal.prototype.updateSizeForLegend = function(\n  legendHeight,\n  legendWidth\n) {\n  var $$ = this,\n    config = $$.config,\n    insetLegendPosition = {\n      top: $$.isLegendTop\n        ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5\n        : $$.currentHeight -\n          legendHeight -\n          $$.getCurrentPaddingBottom() -\n          config.legend_inset_y,\n      left: $$.isLegendLeft\n        ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5\n        : $$.currentWidth -\n          legendWidth -\n          $$.getCurrentPaddingRight() -\n          config.legend_inset_x +\n          0.5\n    };\n\n  $$.margin3 = {\n    top: $$.isLegendRight\n      ? 0\n      : $$.isLegendInset\n      ? insetLegendPosition.top\n      : $$.currentHeight - legendHeight,\n    right: NaN,\n    bottom: 0,\n    left: $$.isLegendRight\n      ? $$.currentWidth - legendWidth\n      : $$.isLegendInset\n      ? insetLegendPosition.left\n      : 0\n  };\n};\nChartInternal.prototype.transformLegend = function(withTransition) {\n  var $$ = this\n  ;(withTransition ? $$.legend.transition() : $$.legend).attr(\n    'transform',\n    $$.getTranslate('legend')\n  );\n};\nChartInternal.prototype.updateLegendStep = function(step) {\n  this.legendStep = step;\n};\nChartInternal.prototype.updateLegendItemWidth = function(w) {\n  this.legendItemWidth = w;\n};\nChartInternal.prototype.updateLegendItemHeight = function(h) {\n  this.legendItemHeight = h;\n};\nChartInternal.prototype.getLegendWidth = function() {\n  var $$ = this;\n  return $$.config.legend_show\n    ? $$.isLegendRight || $$.isLegendInset\n      ? $$.legendItemWidth * ($$.legendStep + 1)\n      : $$.currentWidth\n    : 0\n};\nChartInternal.prototype.getLegendHeight = function() {\n  var $$ = this,\n    h = 0;\n  if ($$.config.legend_show) {\n    if ($$.isLegendRight) {\n      h = $$.currentHeight;\n    } else {\n      h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1);\n    }\n  }\n  return h\n};\nChartInternal.prototype.opacityForLegend = function(legendItem) {\n  return legendItem.classed(CLASS.legendItemHidden) ? null : 1\n};\nChartInternal.prototype.opacityForUnfocusedLegend = function(legendItem) {\n  return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3\n};\nChartInternal.prototype.toggleFocusLegend = function(targetIds, focus) {\n  var $$ = this;\n  targetIds = $$.mapToTargetIds(targetIds);\n  $$.legend\n    .selectAll('.' + CLASS.legendItem)\n    .filter(function(id) {\n      return targetIds.indexOf(id) >= 0\n    })\n    .classed(CLASS.legendItemFocused, focus)\n    .transition()\n    .duration(100)\n    .style('opacity', function() {\n      var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend;\n      return opacity.call($$, $$.d3.select(this))\n    });\n};\nChartInternal.prototype.revertLegend = function() {\n  var $$ = this,\n    d3 = $$.d3;\n  $$.legend\n    .selectAll('.' + CLASS.legendItem)\n    .classed(CLASS.legendItemFocused, false)\n    .transition()\n    .duration(100)\n    .style('opacity', function() {\n      return $$.opacityForLegend(d3.select(this))\n    });\n};\nChartInternal.prototype.showLegend = function(targetIds) {\n  var $$ = this,\n    config = $$.config;\n  if (!config.legend_show) {\n    config.legend_show = true;\n    $$.legend.style('visibility', 'visible');\n    if (!$$.legendHasRendered) {\n      $$.updateLegendWithDefaults();\n    }\n  }\n  $$.removeHiddenLegendIds(targetIds);\n  $$.legend\n    .selectAll($$.selectorLegends(targetIds))\n    .style('visibility', 'visible')\n    .transition()\n    .style('opacity', function() {\n      return $$.opacityForLegend($$.d3.select(this))\n    });\n};\nChartInternal.prototype.hideLegend = function(targetIds) {\n  var $$ = this,\n    config = $$.config;\n  if (config.legend_show && isEmpty(targetIds)) {\n    config.legend_show = false;\n    $$.legend.style('visibility', 'hidden');\n  }\n  $$.addHiddenLegendIds(targetIds);\n  $$.legend\n    .selectAll($$.selectorLegends(targetIds))\n    .style('opacity', 0)\n    .style('visibility', 'hidden');\n};\nChartInternal.prototype.clearLegendItemTextBoxCache = function() {\n  this.legendItemTextBox = {};\n};\nChartInternal.prototype.updateLegend = function(\n  targetIds,\n  options,\n  transitions\n) {\n  var $$ = this,\n    config = $$.config;\n  var xForLegend,\n    xForLegendText,\n    xForLegendRect,\n    yForLegend,\n    yForLegendText,\n    yForLegendRect,\n    x1ForLegendTile,\n    x2ForLegendTile,\n    yForLegendTile;\n  var paddingTop = 4,\n    paddingRight = 10,\n    maxWidth = 0,\n    maxHeight = 0,\n    posMin = 10,\n    tileWidth = config.legend_item_tile_width + 5;\n  var l,\n    totalLength = 0,\n    offsets = {},\n    widths = {},\n    heights = {},\n    margins = [0],\n    steps = {},\n    step = 0;\n  var withTransition, withTransitionForTransform;\n  var texts, rects, tiles, background;\n\n  // Skip elements when their name is set to null\n  targetIds = targetIds.filter(function(id) {\n    return !isDefined(config.data_names[id]) || config.data_names[id] !== null\n  });\n\n  options = options || {};\n  withTransition = getOption(options, 'withTransition', true);\n  withTransitionForTransform = getOption(\n    options,\n    'withTransitionForTransform',\n    true\n  );\n\n  function getTextBox(textElement, id) {\n    if (!$$.legendItemTextBox[id]) {\n      $$.legendItemTextBox[id] = $$.getTextRect(\n        textElement.textContent,\n        CLASS.legendItem,\n        textElement\n      );\n    }\n    return $$.legendItemTextBox[id]\n  }\n\n  function updatePositions(textElement, id, index) {\n    var reset = index === 0,\n      isLast = index === targetIds.length - 1,\n      box = getTextBox(textElement, id),\n      itemWidth =\n        box.width +\n        tileWidth +\n        (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) +\n        config.legend_padding,\n      itemHeight = box.height + paddingTop,\n      itemLength =\n        $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth,\n      areaLength =\n        $$.isLegendRight || $$.isLegendInset\n          ? $$.getLegendHeight()\n          : $$.getLegendWidth(),\n      margin,\n      maxLength;\n\n    // MEMO: care about condifion of step, totalLength\n    function updateValues(id, withoutStep) {\n      if (!withoutStep) {\n        margin = (areaLength - totalLength - itemLength) / 2;\n        if (margin < posMin) {\n          margin = (areaLength - itemLength) / 2;\n          totalLength = 0;\n          step++;\n        }\n      }\n      steps[id] = step;\n      margins[step] = $$.isLegendInset ? 10 : margin;\n      offsets[id] = totalLength;\n      totalLength += itemLength;\n    }\n\n    if (reset) {\n      totalLength = 0;\n      step = 0;\n      maxWidth = 0;\n      maxHeight = 0;\n    }\n\n    if (config.legend_show && !$$.isLegendToShow(id)) {\n      widths[id] = heights[id] = steps[id] = offsets[id] = 0;\n      return\n    }\n\n    widths[id] = itemWidth;\n    heights[id] = itemHeight;\n\n    if (!maxWidth || itemWidth >= maxWidth) {\n      maxWidth = itemWidth;\n    }\n    if (!maxHeight || itemHeight >= maxHeight) {\n      maxHeight = itemHeight;\n    }\n    maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth;\n\n    if (config.legend_equally) {\n      Object.keys(widths).forEach(function(id) {\n        widths[id] = maxWidth;\n      });\n      Object.keys(heights).forEach(function(id) {\n        heights[id] = maxHeight;\n      });\n      margin = (areaLength - maxLength * targetIds.length) / 2;\n      if (margin < posMin) {\n        totalLength = 0;\n        step = 0;\n        targetIds.forEach(function(id) {\n          updateValues(id);\n        });\n      } else {\n        updateValues(id, true);\n      }\n    } else {\n      updateValues(id);\n    }\n  }\n\n  if ($$.isLegendInset) {\n    step = config.legend_inset_step\n      ? config.legend_inset_step\n      : targetIds.length;\n    $$.updateLegendStep(step);\n  }\n\n  if ($$.isLegendRight) {\n    xForLegend = function(id) {\n      return maxWidth * steps[id]\n    };\n    yForLegend = function(id) {\n      return margins[steps[id]] + offsets[id]\n    };\n  } else if ($$.isLegendInset) {\n    xForLegend = function(id) {\n      return maxWidth * steps[id] + 10\n    };\n    yForLegend = function(id) {\n      return margins[steps[id]] + offsets[id]\n    };\n  } else {\n    xForLegend = function(id) {\n      return margins[steps[id]] + offsets[id]\n    };\n    yForLegend = function(id) {\n      return maxHeight * steps[id]\n    };\n  }\n  xForLegendText = function(id, i) {\n    return xForLegend(id, i) + 4 + config.legend_item_tile_width\n  };\n  yForLegendText = function(id, i) {\n    return yForLegend(id, i) + 9\n  };\n  xForLegendRect = function(id, i) {\n    return xForLegend(id, i)\n  };\n  yForLegendRect = function(id, i) {\n    return yForLegend(id, i) - 5\n  };\n  x1ForLegendTile = function(id, i) {\n    return xForLegend(id, i) - 2\n  };\n  x2ForLegendTile = function(id, i) {\n    return xForLegend(id, i) - 2 + config.legend_item_tile_width\n  };\n  yForLegendTile = function(id, i) {\n    return yForLegend(id, i) + 4\n  };\n\n  // Define g for legend area\n  l = $$.legend\n    .selectAll('.' + CLASS.legendItem)\n    .data(targetIds)\n    .enter()\n    .append('g')\n    .attr('class', function(id) {\n      return $$.generateClass(CLASS.legendItem, id)\n    })\n    .style('visibility', function(id) {\n      return $$.isLegendToShow(id) ? 'visible' : 'hidden'\n    })\n    .style('cursor', function() {\n      return config.interaction_enabled ? 'pointer' : 'auto'\n    })\n    .on(\n      'click',\n      config.interaction_enabled\n        ? function(id) {\n            if (config.legend_item_onclick) {\n              config.legend_item_onclick.call($$, id);\n            } else {\n              if ($$.d3.event.altKey) {\n                $$.api.hide();\n                $$.api.show(id);\n              } else {\n                $$.api.toggle(id);\n                $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert();\n              }\n            }\n          }\n        : null\n    )\n    .on(\n      'mouseover',\n      config.interaction_enabled\n        ? function(id) {\n            if (config.legend_item_onmouseover) {\n              config.legend_item_onmouseover.call($$, id);\n            } else {\n              $$.d3.select(this).classed(CLASS.legendItemFocused, true);\n              if (!$$.transiting && $$.isTargetToShow(id)) {\n                $$.api.focus(id);\n              }\n            }\n          }\n        : null\n    )\n    .on(\n      'mouseout',\n      config.interaction_enabled\n        ? function(id) {\n            if (config.legend_item_onmouseout) {\n              config.legend_item_onmouseout.call($$, id);\n            } else {\n              $$.d3.select(this).classed(CLASS.legendItemFocused, false);\n              $$.api.revert();\n            }\n          }\n        : null\n    );\n\n  l.append('text')\n    .text(function(id) {\n      return isDefined(config.data_names[id]) ? config.data_names[id] : id\n    })\n    .each(function(id, i) {\n      updatePositions(this, id, i);\n    })\n    .style('pointer-events', 'none')\n    .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200)\n    .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText);\n\n  l.append('rect')\n    .attr('class', CLASS.legendItemEvent)\n    .style('fill-opacity', 0)\n    .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200)\n    .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect);\n\n  l.append('line')\n    .attr('class', CLASS.legendItemTile)\n    .style('stroke', $$.color)\n    .style('pointer-events', 'none')\n    .attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200)\n    .attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile)\n    .attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200)\n    .attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile)\n    .attr('stroke-width', config.legend_item_tile_height);\n\n  // Set background for inset legend\n  background = $$.legend.select('.' + CLASS.legendBackground + ' rect');\n  if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) {\n    background = $$.legend\n      .insert('g', '.' + CLASS.legendItem)\n      .attr('class', CLASS.legendBackground)\n      .append('rect');\n  }\n\n  texts = $$.legend\n    .selectAll('text')\n    .data(targetIds)\n    .text(function(id) {\n      return isDefined(config.data_names[id]) ? config.data_names[id] : id\n    }) // MEMO: needed for update\n    .each(function(id, i) {\n      updatePositions(this, id, i);\n    })\n  ;(withTransition ? texts.transition() : texts)\n    .attr('x', xForLegendText)\n    .attr('y', yForLegendText);\n\n  rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent).data(targetIds)\n  ;(withTransition ? rects.transition() : rects)\n    .attr('width', function(id) {\n      return widths[id]\n    })\n    .attr('height', function(id) {\n      return heights[id]\n    })\n    .attr('x', xForLegendRect)\n    .attr('y', yForLegendRect);\n\n  tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile).data(targetIds)\n  ;(withTransition ? tiles.transition() : tiles)\n    .style(\n      'stroke',\n      $$.levelColor\n        ? function(id) {\n            return $$.levelColor(\n              $$.cache[id].values.reduce(function(total, item) {\n                return total + item.value\n              }, 0)\n            )\n          }\n        : $$.color\n    )\n    .attr('x1', x1ForLegendTile)\n    .attr('y1', yForLegendTile)\n    .attr('x2', x2ForLegendTile)\n    .attr('y2', yForLegendTile);\n\n  if (background) {\n(withTransition ? background.transition() : background)\n      .attr('height', $$.getLegendHeight() - 12)\n      .attr('width', maxWidth * (step + 1) + 10);\n  }\n\n  // toggle legend state\n  $$.legend\n    .selectAll('.' + CLASS.legendItem)\n    .classed(CLASS.legendItemHidden, function(id) {\n      return !$$.isTargetToShow(id)\n    });\n\n  // Update all to reflect change of legend\n  $$.updateLegendItemWidth(maxWidth);\n  $$.updateLegendItemHeight(maxHeight);\n  $$.updateLegendStep(step);\n  // Update size and scale\n  $$.updateSizes();\n  $$.updateScales();\n  $$.updateSvgSize();\n  // Update g positions\n  $$.transformAll(withTransitionForTransform, transitions);\n  $$.legendHasRendered = true;\n};\n\nChartInternal.prototype.initRegion = function() {\n  var $$ = this;\n  $$.region = $$.main\n    .append('g')\n    .attr('clip-path', $$.clipPath)\n    .attr('class', CLASS.regions);\n};\nChartInternal.prototype.updateRegion = function(duration) {\n  var $$ = this,\n    config = $$.config;\n\n  // hide if arc type\n  $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');\n\n  var mainRegion = $$.main\n    .select('.' + CLASS.regions)\n    .selectAll('.' + CLASS.region)\n    .data(config.regions);\n  var g = mainRegion.enter().append('g');\n  g.append('rect')\n    .attr('x', $$.regionX.bind($$))\n    .attr('y', $$.regionY.bind($$))\n    .attr('width', $$.regionWidth.bind($$))\n    .attr('height', $$.regionHeight.bind($$))\n    .style('fill-opacity', function(d) {\n      return isValue(d.opacity) ? d.opacity : 0.1\n    });\n  g.append('text').text($$.labelRegion.bind($$));\n  $$.mainRegion = g.merge(mainRegion).attr('class', $$.classRegion.bind($$));\n  mainRegion\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove();\n};\nChartInternal.prototype.redrawRegion = function(withTransition, transition) {\n  var $$ = this,\n    regions = $$.mainRegion,\n    regionLabels = $$.mainRegion.selectAll('text');\n  return [\n    (withTransition ? regions.transition(transition) : regions)\n      .attr('x', $$.regionX.bind($$))\n      .attr('y', $$.regionY.bind($$))\n      .attr('width', $$.regionWidth.bind($$))\n      .attr('height', $$.regionHeight.bind($$))\n      .style('fill-opacity', function(d) {\n        return isValue(d.opacity) ? d.opacity : 0.1\n      }),\n    (withTransition ? regionLabels.transition(transition) : regionLabels)\n      .attr('x', $$.labelOffsetX.bind($$))\n      .attr('y', $$.labelOffsetY.bind($$))\n      .attr('transform', $$.labelTransform.bind($$))\n      .attr('style', 'text-anchor: left;')\n  ]\n};\nChartInternal.prototype.regionX = function(d) {\n  var $$ = this,\n    config = $$.config,\n    xPos,\n    yScale = d.axis === 'y' ? $$.y : $$.y2;\n  if (d.axis === 'y' || d.axis === 'y2') {\n    xPos = config.axis_rotated ? ('start' in d ? yScale(d.start) : 0) : 0;\n  } else {\n    xPos = config.axis_rotated\n      ? 0\n      : 'start' in d\n      ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start)\n      : 0;\n  }\n  return xPos\n};\nChartInternal.prototype.regionY = function(d) {\n  var $$ = this,\n    config = $$.config,\n    yPos,\n    yScale = d.axis === 'y' ? $$.y : $$.y2;\n  if (d.axis === 'y' || d.axis === 'y2') {\n    yPos = config.axis_rotated ? 0 : 'end' in d ? yScale(d.end) : 0;\n  } else {\n    yPos = config.axis_rotated\n      ? 'start' in d\n        ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start)\n        : 0\n      : 0;\n  }\n  return yPos\n};\nChartInternal.prototype.regionWidth = function(d) {\n  var $$ = this,\n    config = $$.config,\n    start = $$.regionX(d),\n    end,\n    yScale = d.axis === 'y' ? $$.y : $$.y2;\n  if (d.axis === 'y' || d.axis === 'y2') {\n    end = config.axis_rotated\n      ? 'end' in d\n        ? yScale(d.end)\n        : $$.width\n      : $$.width;\n  } else {\n    end = config.axis_rotated\n      ? $$.width\n      : 'end' in d\n      ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end)\n      : $$.width;\n  }\n  return end < start ? 0 : end - start\n};\nChartInternal.prototype.regionHeight = function(d) {\n  var $$ = this,\n    config = $$.config,\n    start = this.regionY(d),\n    end,\n    yScale = d.axis === 'y' ? $$.y : $$.y2;\n  if (d.axis === 'y' || d.axis === 'y2') {\n    end = config.axis_rotated\n      ? $$.height\n      : 'start' in d\n      ? yScale(d.start)\n      : $$.height;\n  } else {\n    end = config.axis_rotated\n      ? 'end' in d\n        ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end)\n        : $$.height\n      : $$.height;\n  }\n  return end < start ? 0 : end - start\n};\nChartInternal.prototype.isRegionOnX = function(d) {\n  return !d.axis || d.axis === 'x'\n};\nChartInternal.prototype.labelRegion = function(d) {\n  return 'label' in d ? d.label : ''\n};\nChartInternal.prototype.labelTransform = function(d) {\n  return 'vertical' in d && d.vertical ? 'rotate(90)' : ''\n};\nChartInternal.prototype.labelOffsetX = function(d) {\n  var paddingX = 'paddingX' in d ? d.paddingX : 3;\n  var paddingY = 'paddingY' in d ? d.paddingY : 3;\n  return 'vertical' in d && d.vertical\n    ? this.regionY(d) + paddingY\n    : this.regionX(d) + paddingX\n};\nChartInternal.prototype.labelOffsetY = function(d) {\n  var paddingX = 'paddingX' in d ? d.paddingX : 3;\n  var paddingY = 'paddingY' in d ? d.paddingY : 3;\n  return 'vertical' in d && d.vertical\n    ? -(this.regionX(d) + paddingX)\n    : this.regionY(d) + 10 + paddingY\n};\n\nfunction c3LogScale(d3, linearScale, logScale) {\n  var PROJECTION = [0.01, 10];\n\n  if (!linearScale) {\n    linearScale = d3.scaleLinear();\n    linearScale.range(PROJECTION);\n  }\n\n  if (!logScale) {\n    logScale = d3.scaleLog();\n    logScale.domain(PROJECTION);\n    logScale.nice();\n  }\n\n  // copied from https://github.com/compute-io/logspace\n  function logspace(a, b, len) {\n    var arr, end, tmp, d;\n\n    if (arguments.length < 3) {\n      len = 10;\n    } else {\n      if (len === 0) {\n        return []\n      }\n    }\n    // Calculate the increment:\n    end = len - 1;\n    d = (b - a) / end;\n\n    // Build the output array...\n    arr = new Array(len);\n    tmp = a;\n    arr[0] = Math.pow(10, tmp);\n    for (var i = 1; i < end; i++) {\n      tmp += d;\n      arr[i] = Math.pow(10, tmp);\n    }\n    arr[end] = Math.pow(10, b);\n    return arr\n  }\n\n  function scale(x) {\n    return logScale(linearScale(x))\n  }\n\n  scale.domain = function(x) {\n    if (!arguments.length) {\n      return linearScale.domain()\n    }\n    linearScale.domain(x);\n    return scale\n  };\n\n  scale.range = function(x) {\n    if (!arguments.length) {\n      return logScale.range()\n    }\n    logScale.range(x);\n    return scale\n  };\n\n  scale.ticks = function(m) {\n    return logspace(-2, 1, m || 10).map(function(v) {\n      return linearScale.invert(v)\n    })\n  };\n\n  scale.copy = function() {\n    return c3LogScale(d3, linearScale.copy(), logScale.copy())\n  };\n\n  return scale\n}\n\nChartInternal.prototype.getScale = function(min, max, forTimeseries) {\n  return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([\n    min,\n    max\n  ])\n};\nChartInternal.prototype.getX = function(min, max, domain, offset) {\n  var $$ = this,\n    scale = $$.getScale(min, max, $$.isTimeSeries()),\n    _scale = domain ? scale.domain(domain) : scale,\n    key;\n  // Define customized scale if categorized axis\n  if ($$.isCategorized()) {\n    offset =\n      offset ||\n      function() {\n        return 0\n      };\n    scale = function(d, raw) {\n      var v = _scale(d) + offset(d);\n      return raw ? v : Math.ceil(v)\n    };\n  } else {\n    scale = function(d, raw) {\n      var v = _scale(d);\n      return raw ? v : Math.ceil(v)\n    };\n  }\n  // define functions\n  for (key in _scale) {\n    scale[key] = _scale[key];\n  }\n  scale.orgDomain = function() {\n    return _scale.domain()\n  };\n  // define custom domain() for categorized axis\n  if ($$.isCategorized()) {\n    scale.domain = function(domain) {\n      if (!arguments.length) {\n        domain = this.orgDomain();\n        return [domain[0], domain[1] + 1]\n      }\n      _scale.domain(domain);\n      return scale\n    };\n  }\n  return scale\n};\n\n/**\n * Creates and configures a D3 scale instance for the given type.\n *\n * By defaults it returns a Linear scale.\n *\n * @param {String} type Type of d3-scale to create. Type can be 'linear', 'time', 'timeseries' or 'log'.\n * @param {Array} domain The scale domain such as [from, to]\n * @param {Array} range The scale's range such as [from, to]\n *\n * @return A d3-scale instance\n */\nChartInternal.prototype.getY = function(type, domain, range) {\n  let scale;\n  if (type === 'timeseries' || type === 'time') {\n    scale = this.d3.scaleTime();\n  } else if (type === 'log') {\n    scale = c3LogScale(this.d3);\n  } else if (type === 'linear' || type === undefined) {\n    scale = this.d3.scaleLinear();\n  } else {\n    throw new Error(`Invalid Y axis type: \"${type}\"`)\n  }\n\n  if (domain) {\n    scale.domain(domain);\n  }\n\n  if (range) {\n    scale.range(range);\n  }\n\n  return scale\n};\nChartInternal.prototype.getYScale = function(id) {\n  return this.axis.getId(id) === 'y2' ? this.y2 : this.y\n};\nChartInternal.prototype.getSubYScale = function(id) {\n  return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY\n};\nChartInternal.prototype.updateScales = function() {\n  var $$ = this,\n    config = $$.config,\n    forInit = !$$.x;\n  // update edges\n  $$.xMin = config.axis_rotated ? 1 : 0;\n  $$.xMax = config.axis_rotated ? $$.height : $$.width;\n  $$.yMin = config.axis_rotated ? 0 : $$.height;\n  $$.yMax = config.axis_rotated ? $$.width : 1;\n  $$.subXMin = $$.xMin;\n  $$.subXMax = $$.xMax;\n  $$.subYMin = config.axis_rotated ? 0 : $$.height2;\n  $$.subYMax = config.axis_rotated ? $$.width2 : 1;\n  // update scales\n  $$.x = $$.getX(\n    $$.xMin,\n    $$.xMax,\n    forInit ? undefined : $$.x.orgDomain(),\n    function() {\n      return $$.xAxis.tickOffset()\n    }\n  );\n  $$.y = $$.getY(\n    config.axis_y_type,\n    forInit ? config.axis_y_default : $$.y.domain(),\n    [$$.yMin, $$.yMax]\n  );\n  $$.y2 = $$.getY(\n    config.axis_y2_type,\n    forInit ? config.axis_y2_default : $$.y2.domain(),\n    [$$.yMin, $$.yMax]\n  );\n  $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function(d) {\n    return d % 1 ? 0 : $$.subXAxis.tickOffset()\n  });\n  $$.subY = $$.getY(\n    config.axis_y_type,\n    forInit ? config.axis_y_default : $$.subY.domain(),\n    [$$.subYMin, $$.subYMax]\n  );\n  $$.subY2 = $$.getY(\n    config.axis_y2_type,\n    forInit ? config.axis_y2_default : $$.subY2.domain(),\n    [$$.subYMin, $$.subYMax]\n  );\n  // update axes\n  $$.xAxisTickFormat = $$.axis.getXAxisTickFormat();\n  $$.xAxisTickValues = $$.axis.getXAxisTickValues();\n  $$.yAxisTickValues = $$.axis.getYAxisTickValues();\n  $$.y2AxisTickValues = $$.axis.getY2AxisTickValues();\n\n  $$.xAxis = $$.axis.getXAxis(\n    $$.x,\n    $$.xOrient,\n    $$.xAxisTickFormat,\n    $$.xAxisTickValues,\n    config.axis_x_tick_outer\n  );\n  $$.subXAxis = $$.axis.getXAxis(\n    $$.subX,\n    $$.subXOrient,\n    $$.xAxisTickFormat,\n    $$.xAxisTickValues,\n    config.axis_x_tick_outer\n  );\n  $$.yAxis = $$.axis.getYAxis(\n    'y',\n    $$.y,\n    $$.yOrient,\n    $$.yAxisTickValues,\n    config.axis_y_tick_outer\n  );\n  $$.y2Axis = $$.axis.getYAxis(\n    'y2',\n    $$.y2,\n    $$.y2Orient,\n    $$.y2AxisTickValues,\n    config.axis_y2_tick_outer\n  );\n\n  // Set initialized scales to brush and zoom\n  if (!forInit) {\n    if ($$.brush) {\n      $$.brush.updateScale($$.subX);\n    }\n  }\n  // update for arc\n  if ($$.updateArc) {\n    $$.updateArc();\n  }\n};\n\nChartInternal.prototype.selectPoint = function(target, d, i) {\n  var $$ = this,\n    config = $$.config,\n    cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$),\n    cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$),\n    r = $$.pointSelectR.bind($$);\n  config.data_onselected.call($$.api, d, target.node());\n  // add selected-circle on low layer g\n  $$.main\n    .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id))\n    .selectAll('.' + CLASS.selectedCircle + '-' + i)\n    .data([d])\n    .enter()\n    .append('circle')\n    .attr('class', function() {\n      return $$.generateClass(CLASS.selectedCircle, i)\n    })\n    .attr('cx', cx)\n    .attr('cy', cy)\n    .attr('stroke', function() {\n      return $$.color(d)\n    })\n    .attr('r', function(d) {\n      return $$.pointSelectR(d) * 1.4\n    })\n    .transition()\n    .duration(100)\n    .attr('r', r);\n};\nChartInternal.prototype.unselectPoint = function(target, d, i) {\n  var $$ = this;\n  $$.config.data_onunselected.call($$.api, d, target.node());\n  // remove selected-circle from low layer g\n  $$.main\n    .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id))\n    .selectAll('.' + CLASS.selectedCircle + '-' + i)\n    .transition()\n    .duration(100)\n    .attr('r', 0)\n    .remove();\n};\nChartInternal.prototype.togglePoint = function(selected, target, d, i) {\n  selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i);\n};\nChartInternal.prototype.selectPath = function(target, d) {\n  var $$ = this;\n  $$.config.data_onselected.call($$, d, target.node());\n  if ($$.config.interaction_brighten) {\n    target\n      .transition()\n      .duration(100)\n      .style('fill', function() {\n        return $$.d3.rgb($$.color(d)).brighter(0.75)\n      });\n  }\n};\nChartInternal.prototype.unselectPath = function(target, d) {\n  var $$ = this;\n  $$.config.data_onunselected.call($$, d, target.node());\n  if ($$.config.interaction_brighten) {\n    target\n      .transition()\n      .duration(100)\n      .style('fill', function() {\n        return $$.color(d)\n      });\n  }\n};\nChartInternal.prototype.togglePath = function(selected, target, d, i) {\n  selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i);\n};\nChartInternal.prototype.getToggle = function(that, d) {\n  var $$ = this,\n    toggle;\n  if (that.nodeName === 'circle') {\n    if ($$.isStepType(d)) {\n      // circle is hidden in step chart, so treat as within the click area\n      toggle = function() {}; // TODO: how to select step chart?\n    } else {\n      toggle = $$.togglePoint;\n    }\n  } else if (that.nodeName === 'path') {\n    toggle = $$.togglePath;\n  }\n  return toggle\n};\nChartInternal.prototype.toggleShape = function(that, d, i) {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    shape = d3.select(that),\n    isSelected = shape.classed(CLASS.SELECTED),\n    toggle = $$.getToggle(that, d).bind($$);\n\n  if (config.data_selection_enabled && config.data_selection_isselectable(d)) {\n    if (!config.data_selection_multiple) {\n      $$.main\n        .selectAll(\n          '.' +\n            CLASS.shapes +\n            (config.data_selection_grouped\n              ? $$.getTargetSelectorSuffix(d.id)\n              : '')\n        )\n        .selectAll('.' + CLASS.shape)\n        .each(function(d, i) {\n          var shape = d3.select(this);\n          if (shape.classed(CLASS.SELECTED)) {\n            toggle(false, shape.classed(CLASS.SELECTED, false), d, i);\n          }\n        });\n    }\n    shape.classed(CLASS.SELECTED, !isSelected);\n    toggle(!isSelected, shape, d, i);\n  }\n};\n\nChartInternal.prototype.initBar = function() {\n  var $$ = this;\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartBars);\n};\nChartInternal.prototype.updateTargetsForBar = function(targets) {\n  var $$ = this,\n    config = $$.config,\n    mainBars,\n    mainBarEnter,\n    classChartBar = $$.classChartBar.bind($$),\n    classBars = $$.classBars.bind($$),\n    classFocus = $$.classFocus.bind($$);\n  mainBars = $$.main\n    .select('.' + CLASS.chartBars)\n    .selectAll('.' + CLASS.chartBar)\n    .data(targets)\n    .attr('class', function(d) {\n      return classChartBar(d) + classFocus(d)\n    });\n  mainBarEnter = mainBars\n    .enter()\n    .append('g')\n    .attr('class', classChartBar)\n    .style('pointer-events', 'none');\n  // Bars for each data\n  mainBarEnter\n    .append('g')\n    .attr('class', classBars)\n    .style('cursor', function(d) {\n      return config.data_selection_isselectable(d) ? 'pointer' : null\n    });\n};\nChartInternal.prototype.updateBar = function(durationForExit) {\n  var $$ = this,\n    barData = $$.barData.bind($$),\n    classBar = $$.classBar.bind($$),\n    initialOpacity = $$.initialOpacity.bind($$),\n    color = function(d) {\n      return $$.color(d.id)\n    };\n  var mainBar = $$.main\n    .selectAll('.' + CLASS.bars)\n    .selectAll('.' + CLASS.bar)\n    .data(barData);\n  var mainBarEnter = mainBar\n    .enter()\n    .append('path')\n    .attr('class', classBar)\n    .style('stroke', color)\n    .style('fill', color);\n  $$.mainBar = mainBarEnter.merge(mainBar).style('opacity', initialOpacity);\n  mainBar\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0);\n};\nChartInternal.prototype.redrawBar = function(\n  drawBar,\n  withTransition,\n  transition\n) {\n  const $$ = this;\n\n  return [\n    (withTransition ? this.mainBar.transition(transition) : this.mainBar)\n      .attr('d', drawBar)\n      .style('stroke', this.color)\n      .style('fill', this.color)\n      .style('opacity', d => ($$.isTargetToShow(d.id) ? 1 : 0))\n  ]\n};\nChartInternal.prototype.getBarW = function(axis, barTargetsNum) {\n  var $$ = this,\n    config = $$.config,\n    w =\n      typeof config.bar_width === 'number'\n        ? config.bar_width\n        : barTargetsNum\n        ? (axis.tickInterval() * config.bar_width_ratio) / barTargetsNum\n        : 0;\n  return config.bar_width_max && w > config.bar_width_max\n    ? config.bar_width_max\n    : w\n};\nChartInternal.prototype.getBars = function(i, id) {\n  var $$ = this;\n  return (id\n    ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id))\n    : $$.main\n  ).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''))\n};\nChartInternal.prototype.expandBars = function(i, id, reset) {\n  var $$ = this;\n  if (reset) {\n    $$.unexpandBars();\n  }\n  $$.getBars(i, id).classed(CLASS.EXPANDED, true);\n};\nChartInternal.prototype.unexpandBars = function(i) {\n  var $$ = this;\n  $$.getBars(i).classed(CLASS.EXPANDED, false);\n};\nChartInternal.prototype.generateDrawBar = function(barIndices, isSub) {\n  var $$ = this,\n    config = $$.config,\n    getPoints = $$.generateGetBarPoints(barIndices, isSub);\n  return function(d, i) {\n    // 4 points that make a bar\n    var points = getPoints(d, i);\n\n    // switch points if axis is rotated, not applicable for sub chart\n    var indexX = config.axis_rotated ? 1 : 0;\n    var indexY = config.axis_rotated ? 0 : 1;\n\n    var path =\n      'M ' +\n      points[0][indexX] +\n      ',' +\n      points[0][indexY] +\n      ' ' +\n      'L' +\n      points[1][indexX] +\n      ',' +\n      points[1][indexY] +\n      ' ' +\n      'L' +\n      points[2][indexX] +\n      ',' +\n      points[2][indexY] +\n      ' ' +\n      'L' +\n      points[3][indexX] +\n      ',' +\n      points[3][indexY] +\n      ' ' +\n      'z';\n\n    return path\n  }\n};\nChartInternal.prototype.generateGetBarPoints = function(barIndices, isSub) {\n  var $$ = this,\n    axis = isSub ? $$.subXAxis : $$.xAxis,\n    barTargetsNum = barIndices.__max__ + 1,\n    barW = $$.getBarW(axis, barTargetsNum),\n    barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub),\n    barY = $$.getShapeY(!!isSub),\n    barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub),\n    barSpaceOffset = barW * ($$.config.bar_space / 2),\n    yScale = isSub ? $$.getSubYScale : $$.getYScale;\n  return function(d, i) {\n    var y0 = yScale.call($$, d.id)(0),\n      offset = barOffset(d, i) || y0, // offset is for stacked bar chart\n      posX = barX(d),\n      posY = barY(d);\n    // fix posY not to overflow opposite quadrant\n    if ($$.config.axis_rotated) {\n      if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\n        posY = y0;\n      }\n    }\n\n    posY -= y0 - offset;\n\n    // 4 points that make a bar\n    return [\n      [posX + barSpaceOffset, offset],\n      [posX + barSpaceOffset, posY],\n      [posX + barW - barSpaceOffset, posY],\n      [posX + barW - barSpaceOffset, offset]\n    ]\n  }\n};\n\n/**\n * Returns whether the data point is within the given bar shape.\n *\n * @param mouse\n * @param barShape\n * @return {boolean}\n */\nChartInternal.prototype.isWithinBar = function(mouse, barShape) {\n  return isWithinBox(mouse, getBBox(barShape), 2)\n};\n\nChartInternal.prototype.getShapeIndices = function(typeFilter) {\n  var $$ = this,\n    config = $$.config,\n    indices = {},\n    i = 0,\n    j,\n    k;\n  $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(\n    function(d) {\n      for (j = 0; j < config.data_groups.length; j++) {\n        if (config.data_groups[j].indexOf(d.id) < 0) {\n          continue\n        }\n        for (k = 0; k < config.data_groups[j].length; k++) {\n          if (config.data_groups[j][k] in indices) {\n            indices[d.id] = indices[config.data_groups[j][k]];\n            break\n          }\n        }\n      }\n      if (isUndefined(indices[d.id])) {\n        indices[d.id] = i++;\n      }\n    }\n  );\n  indices.__max__ = i - 1;\n  return indices\n};\nChartInternal.prototype.getShapeX = function(\n  offset,\n  targetsNum,\n  indices,\n  isSub\n) {\n  var $$ = this,\n    scale = isSub ? $$.subX : $$.x;\n  return function(d) {\n    var index = d.id in indices ? indices[d.id] : 0;\n    return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0\n  }\n};\nChartInternal.prototype.getShapeY = function(isSub) {\n  const $$ = this;\n\n  return function(d) {\n    const scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id);\n    return scale(\n      $$.isTargetNormalized(d.id) ? $$.getRatio('index', d, true) : d.value\n    )\n  }\n};\nChartInternal.prototype.getShapeOffset = function(typeFilter, indices, isSub) {\n  var $$ = this,\n    targets = $$.orderTargets(\n      $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))\n    ),\n    targetIds = targets.map(function(t) {\n      return t.id\n    });\n  return function(d, i) {\n    var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id),\n      y0 = scale(0),\n      offset = y0;\n    targets.forEach(function(t) {\n      const rowValues = $$.isStepType(d)\n        ? $$.convertValuesToStep(t.values)\n        : t.values;\n      const isTargetNormalized = $$.isTargetNormalized(d.id);\n      const values = rowValues.map(v =>\n        isTargetNormalized ? $$.getRatio('index', v, true) : v.value\n      );\n\n      if (t.id === d.id || indices[t.id] !== indices[d.id]) {\n        return\n      }\n      if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) {\n        // check if the x values line up\n        if (isUndefined(rowValues[i]) || +rowValues[i].x !== +d.x) {\n          // \"+\" for timeseries\n          // if not, try to find the value that does line up\n          i = -1;\n          rowValues.forEach(function(v, j) {\n            const x1 = v.x.constructor === Date ? +v.x : v.x;\n            const x2 = d.x.constructor === Date ? +d.x : d.x;\n\n            if (x1 === x2) {\n              i = j;\n            }\n          });\n        }\n        if (i in rowValues && rowValues[i].value * d.value >= 0) {\n          offset += scale(values[i]) - y0;\n        }\n      }\n    });\n    return offset\n  }\n};\nChartInternal.prototype.isWithinShape = function(that, d) {\n  var $$ = this,\n    shape = $$.d3.select(that),\n    isWithin;\n  if (!$$.isTargetToShow(d.id)) {\n    isWithin = false;\n  } else if (that.nodeName === 'circle') {\n    isWithin = $$.isStepType(d)\n      ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value))\n      : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5);\n  } else if (that.nodeName === 'path') {\n    isWithin = shape.classed(CLASS.bar)\n      ? $$.isWithinBar($$.d3.mouse(that), that)\n      : true;\n  }\n  return isWithin\n};\n\nChartInternal.prototype.getInterpolate = function(d) {\n  var $$ = this,\n    d3 = $$.d3,\n    types = {\n      linear: d3.curveLinear,\n      'linear-closed': d3.curveLinearClosed,\n      basis: d3.curveBasis,\n      'basis-open': d3.curveBasisOpen,\n      'basis-closed': d3.curveBasisClosed,\n      bundle: d3.curveBundle,\n      cardinal: d3.curveCardinal,\n      'cardinal-open': d3.curveCardinalOpen,\n      'cardinal-closed': d3.curveCardinalClosed,\n      monotone: d3.curveMonotoneX,\n      step: d3.curveStep,\n      'step-before': d3.curveStepBefore,\n      'step-after': d3.curveStepAfter\n    },\n    type;\n\n  if ($$.isSplineType(d)) {\n    type = types[$$.config.spline_interpolation_type] || types.cardinal;\n  } else if ($$.isStepType(d)) {\n    type = types[$$.config.line_step_type];\n  } else {\n    type = types.linear;\n  }\n  return type\n};\n\nChartInternal.prototype.initLine = function() {\n  var $$ = this;\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartLines);\n};\nChartInternal.prototype.updateTargetsForLine = function(targets) {\n  var $$ = this,\n    config = $$.config,\n    mainLines,\n    mainLineEnter,\n    classChartLine = $$.classChartLine.bind($$),\n    classLines = $$.classLines.bind($$),\n    classAreas = $$.classAreas.bind($$),\n    classCircles = $$.classCircles.bind($$),\n    classFocus = $$.classFocus.bind($$);\n  mainLines = $$.main\n    .select('.' + CLASS.chartLines)\n    .selectAll('.' + CLASS.chartLine)\n    .data(targets)\n    .attr('class', function(d) {\n      return classChartLine(d) + classFocus(d)\n    });\n  mainLineEnter = mainLines\n    .enter()\n    .append('g')\n    .attr('class', classChartLine)\n    .style('opacity', 0)\n    .style('pointer-events', 'none');\n  // Lines for each data\n  mainLineEnter.append('g').attr('class', classLines);\n  // Areas\n  mainLineEnter.append('g').attr('class', classAreas);\n  // Circles for each data point on lines\n  mainLineEnter.append('g').attr('class', function(d) {\n    return $$.generateClass(CLASS.selectedCircles, d.id)\n  });\n  mainLineEnter\n    .append('g')\n    .attr('class', classCircles)\n    .style('cursor', function(d) {\n      return config.data_selection_isselectable(d) ? 'pointer' : null\n    });\n  // Update date for selected circles\n  targets.forEach(function(t) {\n    $$.main\n      .selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id))\n      .selectAll('.' + CLASS.selectedCircle)\n      .each(function(d) {\n        d.value = t.values[d.index].value;\n      });\n  });\n  // MEMO: can not keep same color...\n  //mainLineUpdate.exit().remove();\n};\nChartInternal.prototype.updateLine = function(durationForExit) {\n  var $$ = this;\n  var mainLine = $$.main\n    .selectAll('.' + CLASS.lines)\n    .selectAll('.' + CLASS.line)\n    .data($$.lineData.bind($$));\n  var mainLineEnter = mainLine\n    .enter()\n    .append('path')\n    .attr('class', $$.classLine.bind($$))\n    .style('stroke', $$.color);\n  $$.mainLine = mainLineEnter\n    .merge(mainLine)\n    .style('opacity', $$.initialOpacity.bind($$))\n    .style('shape-rendering', function(d) {\n      return $$.isStepType(d) ? 'crispEdges' : ''\n    })\n    .attr('transform', null);\n  mainLine\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0);\n};\nChartInternal.prototype.redrawLine = function(\n  drawLine,\n  withTransition,\n  transition\n) {\n  return [\n    (withTransition ? this.mainLine.transition(transition) : this.mainLine)\n      .attr('d', drawLine)\n      .style('stroke', this.color)\n      .style('opacity', 1)\n  ]\n};\nChartInternal.prototype.generateDrawLine = function(lineIndices, isSub) {\n  var $$ = this,\n    config = $$.config,\n    line = $$.d3.line(),\n    getPoints = $$.generateGetLinePoints(lineIndices, isSub),\n    yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,\n    xValue = function(d) {\n      return (isSub ? $$.subxx : $$.xx).call($$, d)\n    },\n    yValue = function(d, i) {\n      return config.data_groups.length > 0\n        ? getPoints(d, i)[0][1]\n        : yScaleGetter.call($$, d.id)(d.value)\n    };\n\n  line = config.axis_rotated\n    ? line.x(yValue).y(xValue)\n    : line.x(xValue).y(yValue);\n  if (!config.line_connectNull) {\n    line = line.defined(function(d) {\n      return d.value != null\n    });\n  }\n  return function(d) {\n    var values = config.line_connectNull\n        ? $$.filterRemoveNull(d.values)\n        : d.values,\n      x = isSub ? $$.subX : $$.x,\n      y = yScaleGetter.call($$, d.id),\n      x0 = 0,\n      y0 = 0,\n      path;\n    if ($$.isLineType(d)) {\n      if (config.data_regions[d.id]) {\n        path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]);\n      } else {\n        if ($$.isStepType(d)) {\n          values = $$.convertValuesToStep(values);\n        }\n        path = line.curve($$.getInterpolate(d))(values);\n      }\n    } else {\n      if (values[0]) {\n        x0 = x(values[0].x);\n        y0 = y(values[0].value);\n      }\n      path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0;\n    }\n    return path ? path : 'M 0 0'\n  }\n};\nChartInternal.prototype.generateGetLinePoints = function(lineIndices, isSub) {\n  // partial duplication of generateGetBarPoints\n  var $$ = this,\n    config = $$.config,\n    lineTargetsNum = lineIndices.__max__ + 1,\n    x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub),\n    y = $$.getShapeY(!!isSub),\n    lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub),\n    yScale = isSub ? $$.getSubYScale : $$.getYScale;\n  return function(d, i) {\n    var y0 = yScale.call($$, d.id)(0),\n      offset = lineOffset(d, i) || y0, // offset is for stacked area chart\n      posX = x(d),\n      posY = y(d);\n    // fix posY not to overflow opposite quadrant\n    if (config.axis_rotated) {\n      if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\n        posY = y0;\n      }\n    }\n    // 1 point that marks the line position\n    return [\n      [posX, posY - (y0 - offset)],\n      [posX, posY - (y0 - offset)], // needed for compatibility\n      [posX, posY - (y0 - offset)], // needed for compatibility\n      [posX, posY - (y0 - offset)] // needed for compatibility\n    ]\n  }\n};\n\nChartInternal.prototype.lineWithRegions = function(d, x, y, _regions) {\n  var $$ = this,\n    config = $$.config,\n    prev = -1,\n    i,\n    j,\n    s = 'M',\n    sWithRegion,\n    xp,\n    yp,\n    dx,\n    dy,\n    dd,\n    diff,\n    diffx2,\n    xOffset = $$.isCategorized() ? 0.5 : 0,\n    xValue,\n    yValue,\n    regions = [];\n\n  function isWithinRegions(x, regions) {\n    var i;\n    for (i = 0; i < regions.length; i++) {\n      if (regions[i].start < x && x <= regions[i].end) {\n        return true\n      }\n    }\n    return false\n  }\n\n  // Check start/end of regions\n  if (isDefined(_regions)) {\n    for (i = 0; i < _regions.length; i++) {\n      regions[i] = {};\n      if (isUndefined(_regions[i].start)) {\n        regions[i].start = d[0].x;\n      } else {\n        regions[i].start = $$.isTimeSeries()\n          ? $$.parseDate(_regions[i].start)\n          : _regions[i].start;\n      }\n      if (isUndefined(_regions[i].end)) {\n        regions[i].end = d[d.length - 1].x;\n      } else {\n        regions[i].end = $$.isTimeSeries()\n          ? $$.parseDate(_regions[i].end)\n          : _regions[i].end;\n      }\n    }\n  }\n\n  // Set scales\n  xValue = config.axis_rotated\n    ? function(d) {\n        return y(d.value)\n      }\n    : function(d) {\n        return x(d.x)\n      };\n  yValue = config.axis_rotated\n    ? function(d) {\n        return x(d.x)\n      }\n    : function(d) {\n        return y(d.value)\n      };\n\n  // Define svg generator function for region\n  function generateM(points) {\n    return (\n      'M' +\n      points[0][0] +\n      ' ' +\n      points[0][1] +\n      ' ' +\n      points[1][0] +\n      ' ' +\n      points[1][1]\n    )\n  }\n  if ($$.isTimeSeries()) {\n    sWithRegion = function(d0, d1, j, diff) {\n      var x0 = d0.x.getTime(),\n        x_diff = d1.x - d0.x,\n        xv0 = new Date(x0 + x_diff * j),\n        xv1 = new Date(x0 + x_diff * (j + diff)),\n        points;\n      if (config.axis_rotated) {\n        points = [\n          [y(yp(j)), x(xv0)],\n          [y(yp(j + diff)), x(xv1)]\n        ];\n      } else {\n        points = [\n          [x(xv0), y(yp(j))],\n          [x(xv1), y(yp(j + diff))]\n        ];\n      }\n      return generateM(points)\n    };\n  } else {\n    sWithRegion = function(d0, d1, j, diff) {\n      var points;\n      if (config.axis_rotated) {\n        points = [\n          [y(yp(j), true), x(xp(j))],\n          [y(yp(j + diff), true), x(xp(j + diff))]\n        ];\n      } else {\n        points = [\n          [x(xp(j), true), y(yp(j))],\n          [x(xp(j + diff), true), y(yp(j + diff))]\n        ];\n      }\n      return generateM(points)\n    };\n  }\n\n  // Generate\n  for (i = 0; i < d.length; i++) {\n    // Draw as normal\n    if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) {\n      s += ' ' + xValue(d[i]) + ' ' + yValue(d[i]);\n    }\n    // Draw with region // TODO: Fix for horizotal charts\n    else {\n      xp = $$.getScale(\n        d[i - 1].x + xOffset,\n        d[i].x + xOffset,\n        $$.isTimeSeries()\n      );\n      yp = $$.getScale(d[i - 1].value, d[i].value);\n\n      dx = x(d[i].x) - x(d[i - 1].x);\n      dy = y(d[i].value) - y(d[i - 1].value);\n      dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));\n      diff = 2 / dd;\n      diffx2 = diff * 2;\n\n      for (j = diff; j <= 1; j += diffx2) {\n        s += sWithRegion(d[i - 1], d[i], j, diff);\n      }\n    }\n    prev = d[i].x;\n  }\n\n  return s\n};\n\nChartInternal.prototype.updateArea = function(durationForExit) {\n  var $$ = this,\n    d3 = $$.d3;\n  var mainArea = $$.main\n    .selectAll('.' + CLASS.areas)\n    .selectAll('.' + CLASS.area)\n    .data($$.lineData.bind($$));\n  var mainAreaEnter = mainArea\n    .enter()\n    .append('path')\n    .attr('class', $$.classArea.bind($$))\n    .style('fill', $$.color)\n    .style('opacity', function() {\n      $$.orgAreaOpacity = +d3.select(this).style('opacity');\n      return 0\n    });\n  $$.mainArea = mainAreaEnter\n    .merge(mainArea)\n    .style('opacity', $$.orgAreaOpacity);\n  mainArea\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0);\n};\nChartInternal.prototype.redrawArea = function(\n  drawArea,\n  withTransition,\n  transition\n) {\n  return [\n    (withTransition ? this.mainArea.transition(transition) : this.mainArea)\n      .attr('d', drawArea)\n      .style('fill', this.color)\n      .style('opacity', this.orgAreaOpacity)\n  ]\n};\nChartInternal.prototype.generateDrawArea = function(areaIndices, isSub) {\n  var $$ = this,\n    config = $$.config,\n    area = $$.d3.area(),\n    getPoints = $$.generateGetAreaPoints(areaIndices, isSub),\n    yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,\n    xValue = function(d) {\n      return (isSub ? $$.subxx : $$.xx).call($$, d)\n    },\n    value0 = function(d, i) {\n      return config.data_groups.length > 0\n        ? getPoints(d, i)[0][1]\n        : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id))\n    },\n    value1 = function(d, i) {\n      return config.data_groups.length > 0\n        ? getPoints(d, i)[1][1]\n        : yScaleGetter.call($$, d.id)(d.value)\n    };\n\n  area = config.axis_rotated\n    ? area\n        .x0(value0)\n        .x1(value1)\n        .y(xValue)\n    : area\n        .x(xValue)\n        .y0(config.area_above ? 0 : value0)\n        .y1(value1);\n  if (!config.line_connectNull) {\n    area = area.defined(function(d) {\n      return d.value !== null\n    });\n  }\n\n  return function(d) {\n    var values = config.line_connectNull\n        ? $$.filterRemoveNull(d.values)\n        : d.values,\n      x0 = 0,\n      y0 = 0,\n      path;\n    if ($$.isAreaType(d)) {\n      if ($$.isStepType(d)) {\n        values = $$.convertValuesToStep(values);\n      }\n      path = area.curve($$.getInterpolate(d))(values);\n    } else {\n      if (values[0]) {\n        x0 = $$.x(values[0].x);\n        y0 = $$.getYScale(d.id)(values[0].value);\n      }\n      path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0;\n    }\n    return path ? path : 'M 0 0'\n  }\n};\nChartInternal.prototype.getAreaBaseValue = function() {\n  return 0\n};\nChartInternal.prototype.generateGetAreaPoints = function(areaIndices, isSub) {\n  // partial duplication of generateGetBarPoints\n  var $$ = this,\n    config = $$.config,\n    areaTargetsNum = areaIndices.__max__ + 1,\n    x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub),\n    y = $$.getShapeY(!!isSub),\n    areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub),\n    yScale = isSub ? $$.getSubYScale : $$.getYScale;\n  return function(d, i) {\n    var y0 = yScale.call($$, d.id)(0),\n      offset = areaOffset(d, i) || y0, // offset is for stacked area chart\n      posX = x(d),\n      posY = y(d);\n    // fix posY not to overflow opposite quadrant\n    if (config.axis_rotated) {\n      if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\n        posY = y0;\n      }\n    }\n    // 1 point that marks the area position\n    return [\n      [posX, offset],\n      [posX, posY - (y0 - offset)],\n      [posX, posY - (y0 - offset)], // needed for compatibility\n      [posX, offset] // needed for compatibility\n    ]\n  }\n};\n\nChartInternal.prototype.updateCircle = function(cx, cy) {\n  var $$ = this;\n  var mainCircle = $$.main\n    .selectAll('.' + CLASS.circles)\n    .selectAll('.' + CLASS.circle)\n    .data($$.lineOrScatterOrStanfordData.bind($$));\n\n  var mainCircleEnter = mainCircle\n    .enter()\n    .append('circle')\n    .attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '')\n    .attr('class', $$.classCircle.bind($$))\n    .attr('cx', cx)\n    .attr('cy', cy)\n    .attr('r', $$.pointR.bind($$))\n    .style(\n      'color',\n      $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color\n    );\n\n  $$.mainCircle = mainCircleEnter\n    .merge(mainCircle)\n    .style(\n      'opacity',\n      $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$)\n    );\n\n  mainCircle.exit().style('opacity', 0);\n};\nChartInternal.prototype.redrawCircle = function(\n  cx,\n  cy,\n  withTransition,\n  transition\n) {\n  var $$ = this,\n    selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle);\n  return [\n    (withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle)\n      .style('opacity', this.opacityForCircle.bind($$))\n      .style(\n        'color',\n        $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color\n      )\n      .attr('cx', cx)\n      .attr('cy', cy),\n    (withTransition ? selectedCircles.transition(transition) : selectedCircles)\n      .attr('cx', cx)\n      .attr('cy', cy)\n  ]\n};\nChartInternal.prototype.circleX = function(d) {\n  return d.x || d.x === 0 ? this.x(d.x) : null\n};\nChartInternal.prototype.updateCircleY = function() {\n  var $$ = this,\n    lineIndices,\n    getPoints;\n  if ($$.config.data_groups.length > 0) {\n(lineIndices = $$.getShapeIndices($$.isLineType)),\n      (getPoints = $$.generateGetLinePoints(lineIndices));\n    $$.circleY = function(d, i) {\n      return getPoints(d, i)[0][1]\n    };\n  } else {\n    $$.circleY = function(d) {\n      return $$.getYScale(d.id)(d.value)\n    };\n  }\n};\nChartInternal.prototype.getCircles = function(i, id) {\n  var $$ = this;\n  return (id\n    ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id))\n    : $$.main\n  ).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''))\n};\nChartInternal.prototype.expandCircles = function(i, id, reset) {\n  var $$ = this,\n    r = $$.pointExpandedR.bind($$);\n  if (reset) {\n    $$.unexpandCircles();\n  }\n  $$.getCircles(i, id)\n    .classed(CLASS.EXPANDED, true)\n    .attr('r', r);\n};\nChartInternal.prototype.unexpandCircles = function(i) {\n  var $$ = this,\n    r = $$.pointR.bind($$);\n  $$.getCircles(i)\n    .filter(function() {\n      return $$.d3.select(this).classed(CLASS.EXPANDED)\n    })\n    .classed(CLASS.EXPANDED, false)\n    .attr('r', r);\n};\nChartInternal.prototype.pointR = function(d) {\n  var $$ = this,\n    config = $$.config;\n  return $$.isStepType(d)\n    ? 0\n    : isFunction(config.point_r)\n    ? config.point_r(d)\n    : config.point_r\n};\nChartInternal.prototype.pointExpandedR = function(d) {\n  var $$ = this,\n    config = $$.config;\n  if (config.point_focus_expand_enabled) {\n    return isFunction(config.point_focus_expand_r)\n      ? config.point_focus_expand_r(d)\n      : config.point_focus_expand_r\n      ? config.point_focus_expand_r\n      : $$.pointR(d) * 1.75\n  } else {\n    return $$.pointR(d)\n  }\n};\nChartInternal.prototype.pointSelectR = function(d) {\n  var $$ = this,\n    config = $$.config;\n  return isFunction(config.point_select_r)\n    ? config.point_select_r(d)\n    : config.point_select_r\n    ? config.point_select_r\n    : $$.pointR(d) * 4\n};\nChartInternal.prototype.isWithinCircle = function(that, r) {\n  var d3 = this.d3,\n    mouse = d3.mouse(that),\n    d3_this = d3.select(that),\n    cx = +d3_this.attr('cx'),\n    cy = +d3_this.attr('cy');\n  return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r\n};\nChartInternal.prototype.isWithinStep = function(that, y) {\n  return Math.abs(y - this.d3.mouse(that)[1]) < 30\n};\n\nChartInternal.prototype.getCurrentWidth = function() {\n  var $$ = this,\n    config = $$.config;\n  return config.size_width ? config.size_width : $$.getParentWidth()\n};\nChartInternal.prototype.getCurrentHeight = function() {\n  var $$ = this,\n    config = $$.config,\n    h = config.size_height ? config.size_height : $$.getParentHeight();\n  return h > 0\n    ? h\n    : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1)\n};\nChartInternal.prototype.getCurrentPaddingTop = function() {\n  var $$ = this,\n    config = $$.config,\n    padding = isValue(config.padding_top) ? config.padding_top : 0;\n  if ($$.title && $$.title.node()) {\n    padding += $$.getTitlePadding();\n  }\n  return padding\n};\nChartInternal.prototype.getCurrentPaddingBottom = function() {\n  var config = this.config;\n  return isValue(config.padding_bottom) ? config.padding_bottom : 0\n};\nChartInternal.prototype.getCurrentPaddingLeft = function(withoutRecompute) {\n  var $$ = this,\n    config = $$.config;\n  if (isValue(config.padding_left)) {\n    return config.padding_left\n  } else if (config.axis_rotated) {\n    return !config.axis_x_show || config.axis_x_inner\n      ? 1\n      : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40)\n  } else if (!config.axis_y_show || config.axis_y_inner) {\n    // && !config.axis_rotated\n    return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1\n  } else {\n    return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute))\n  }\n};\nChartInternal.prototype.getCurrentPaddingRight = function() {\n  var $$ = this,\n    config = $$.config,\n    padding = 0,\n    defaultPadding = 10,\n    legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0;\n\n  if (isValue(config.padding_right)) {\n    padding = config.padding_right + 1; // 1 is needed not to hide tick line\n  } else if (config.axis_rotated) {\n    padding = defaultPadding + legendWidthOnRight;\n  } else if (!config.axis_y2_show || config.axis_y2_inner) {\n    // && !config.axis_rotated\n    padding =\n      2 +\n      legendWidthOnRight +\n      ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0);\n  } else {\n    padding = ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight;\n  }\n\n  if ($$.colorScale && $$.colorScale.node()) {\n    padding += $$.getColorScalePadding();\n  }\n\n  return padding\n};\n\nChartInternal.prototype.getParentRectValue = function(key) {\n  var parent = this.selectChart.node(),\n    v;\n  while (parent && parent.tagName !== 'BODY') {\n    try {\n      v = parent.getBoundingClientRect()[key];\n    } catch (e) {\n      if (key === 'width') {\n        // In IE in certain cases getBoundingClientRect\n        // will cause an \"unspecified error\"\n        v = parent.offsetWidth;\n      }\n    }\n    if (v) {\n      break\n    }\n    parent = parent.parentNode;\n  }\n  return v\n};\nChartInternal.prototype.getParentWidth = function() {\n  return this.getParentRectValue('width')\n};\nChartInternal.prototype.getParentHeight = function() {\n  var h = this.selectChart.style('height');\n  return h.indexOf('px') > 0 ? +h.replace('px', '') : 0\n};\n\nChartInternal.prototype.getSvgLeft = function(withoutRecompute) {\n  var $$ = this,\n    config = $$.config,\n    hasLeftAxisRect =\n      config.axis_rotated || (!config.axis_rotated && !config.axis_y_inner),\n    leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY,\n    leftAxis = $$.main.select('.' + leftAxisClass).node(),\n    svgRect =\n      leftAxis && hasLeftAxisRect\n        ? leftAxis.getBoundingClientRect()\n        : { right: 0 },\n    chartRect = $$.selectChart.node().getBoundingClientRect(),\n    hasArc = $$.hasArcType(),\n    svgLeft =\n      svgRect.right -\n      chartRect.left -\n      (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute));\n  return svgLeft > 0 ? svgLeft : 0\n};\n\nChartInternal.prototype.getAxisWidthByAxisId = function(id, withoutRecompute) {\n  var $$ = this,\n    position = $$.axis.getLabelPositionById(id);\n  return (\n    $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40)\n  )\n};\nChartInternal.prototype.getHorizontalAxisHeight = function(axisId) {\n  var $$ = this,\n    config = $$.config,\n    h = 30;\n  if (axisId === 'x' && !config.axis_x_show) {\n    return 8\n  }\n  if (axisId === 'x' && config.axis_x_height) {\n    return config.axis_x_height\n  }\n  if (axisId === 'y' && !config.axis_y_show) {\n    return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1\n  }\n  if (axisId === 'y2' && !config.axis_y2_show) {\n    return $$.rotated_padding_top\n  }\n  // Calculate x axis height when tick rotated\n  if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {\n    h =\n      30 +\n      $$.axis.getMaxTickWidth(axisId) *\n        Math.cos((Math.PI * (90 - Math.abs(config.axis_x_tick_rotate))) / 180);\n  }\n  // Calculate y axis height when tick rotated\n  if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) {\n    h =\n      30 +\n      $$.axis.getMaxTickWidth(axisId) *\n        Math.cos((Math.PI * (90 - Math.abs(config.axis_y_tick_rotate))) / 180);\n  }\n  return (\n    h +\n    ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) +\n    (axisId === 'y2' ? -10 : 0)\n  )\n};\n\nChartInternal.prototype.initBrush = function(scale) {\n  var $$ = this,\n    d3 = $$.d3;\n  // TODO: dynamically change brushY/brushX according to axis_rotated.\n  $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX())\n    .on('brush', function() {\n      var event = d3.event.sourceEvent;\n      if (event && event.type === 'zoom') {\n        return\n      }\n      $$.redrawForBrush();\n    })\n    .on('end', function() {\n      var event = d3.event.sourceEvent;\n      if (event && event.type === 'zoom') {\n        return\n      }\n      if ($$.brush.empty() && event && event.type !== 'end') {\n        $$.brush.clear();\n      }\n    });\n  $$.brush.updateExtent = function() {\n    var range = this.scale.range(),\n      extent;\n    if ($$.config.axis_rotated) {\n      extent = [\n        [0, range[0]],\n        [$$.width2, range[1]]\n      ];\n    } else {\n      extent = [\n        [range[0], 0],\n        [range[1], $$.height2]\n      ];\n    }\n    this.extent(extent);\n    return this\n  };\n  $$.brush.updateScale = function(scale) {\n    this.scale = scale;\n    return this\n  };\n  $$.brush.update = function(scale) {\n    this.updateScale(scale || $$.subX).updateExtent();\n    $$.context.select('.' + CLASS.brush).call(this);\n  };\n  $$.brush.clear = function() {\n    $$.context.select('.' + CLASS.brush).call($$.brush.move, null);\n  };\n  $$.brush.selection = function() {\n    return d3.brushSelection($$.context.select('.' + CLASS.brush).node())\n  };\n  $$.brush.selectionAsValue = function(selectionAsValue, withTransition) {\n    var selection, brush;\n    if (selectionAsValue) {\n      if ($$.context) {\n        selection = [\n          this.scale(selectionAsValue[0]),\n          this.scale(selectionAsValue[1])\n        ];\n        brush = $$.context.select('.' + CLASS.brush);\n        if (withTransition) {\n          brush = brush.transition();\n        }\n        $$.brush.move(brush, selection);\n      }\n      return []\n    }\n    selection = $$.brush.selection() || [0, 0];\n    return [this.scale.invert(selection[0]), this.scale.invert(selection[1])]\n  };\n  $$.brush.empty = function() {\n    var selection = $$.brush.selection();\n    return !selection || selection[0] === selection[1]\n  };\n  return $$.brush.updateScale(scale)\n};\nChartInternal.prototype.initSubchart = function() {\n  var $$ = this,\n    config = $$.config,\n    context = ($$.context = $$.svg\n      .append('g')\n      .attr('transform', $$.getTranslate('context')));\n\n  // set style\n  context.style('visibility', 'visible');\n\n  // Define g for chart area\n  context\n    .append('g')\n    .attr('clip-path', $$.clipPathForSubchart)\n    .attr('class', CLASS.chart);\n\n  // Define g for bar chart area\n  context\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartBars);\n\n  // Define g for line chart area\n  context\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartLines);\n\n  // Add extent rect for Brush\n  context\n    .append('g')\n    .attr('clip-path', $$.clipPath)\n    .attr('class', CLASS.brush);\n\n  // ATTENTION: This must be called AFTER chart added\n  // Add Axis\n  $$.axes.subx = context\n    .append('g')\n    .attr('class', CLASS.axisX)\n    .attr('transform', $$.getTranslate('subx'))\n    .attr('clip-path', config.axis_rotated ? '' : $$.clipPathForXAxis);\n};\nChartInternal.prototype.initSubchartBrush = function() {\n  var $$ = this;\n  // Add extent rect for Brush\n  $$.initBrush($$.subX).updateExtent();\n  $$.context.select('.' + CLASS.brush).call($$.brush);\n};\nChartInternal.prototype.updateTargetsForSubchart = function(targets) {\n  var $$ = this,\n    context = $$.context,\n    config = $$.config,\n    contextLineEnter,\n    contextLine,\n    contextBarEnter,\n    contextBar,\n    classChartBar = $$.classChartBar.bind($$),\n    classBars = $$.classBars.bind($$),\n    classChartLine = $$.classChartLine.bind($$),\n    classLines = $$.classLines.bind($$),\n    classAreas = $$.classAreas.bind($$);\n\n  //-- Bar --//\n  contextBar = context\n    .select('.' + CLASS.chartBars)\n    .selectAll('.' + CLASS.chartBar)\n    .data(targets);\n  contextBarEnter = contextBar\n    .enter()\n    .append('g')\n    .style('opacity', 0);\n  contextBarEnter.merge(contextBar).attr('class', classChartBar);\n  // Bars for each data\n  contextBarEnter.append('g').attr('class', classBars);\n\n  //-- Line --//\n  contextLine = context\n    .select('.' + CLASS.chartLines)\n    .selectAll('.' + CLASS.chartLine)\n    .data(targets);\n  contextLineEnter = contextLine\n    .enter()\n    .append('g')\n    .style('opacity', 0);\n  contextLineEnter.merge(contextLine).attr('class', classChartLine);\n  // Lines for each data\n  contextLineEnter.append('g').attr('class', classLines);\n  // Area\n  contextLineEnter.append('g').attr('class', classAreas);\n\n  //-- Brush --//\n  context\n    .selectAll('.' + CLASS.brush + ' rect')\n    .attr(\n      config.axis_rotated ? 'width' : 'height',\n      config.axis_rotated ? $$.width2 : $$.height2\n    );\n};\nChartInternal.prototype.updateBarForSubchart = function(durationForExit) {\n  var $$ = this;\n  var contextBar = $$.context\n    .selectAll('.' + CLASS.bars)\n    .selectAll('.' + CLASS.bar)\n    .data($$.barData.bind($$));\n  var contextBarEnter = contextBar\n    .enter()\n    .append('path')\n    .attr('class', $$.classBar.bind($$))\n    .style('stroke', 'none')\n    .style('fill', $$.color);\n  contextBar\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n    .remove();\n  $$.contextBar = contextBarEnter\n    .merge(contextBar)\n    .style('opacity', $$.initialOpacity.bind($$));\n};\nChartInternal.prototype.redrawBarForSubchart = function(\n  drawBarOnSub,\n  withTransition,\n  duration\n) {\n(withTransition\n    ? this.contextBar.transition(Math.random().toString()).duration(duration)\n    : this.contextBar\n  )\n    .attr('d', drawBarOnSub)\n    .style('opacity', 1);\n};\nChartInternal.prototype.updateLineForSubchart = function(durationForExit) {\n  var $$ = this;\n  var contextLine = $$.context\n    .selectAll('.' + CLASS.lines)\n    .selectAll('.' + CLASS.line)\n    .data($$.lineData.bind($$));\n  var contextLineEnter = contextLine\n    .enter()\n    .append('path')\n    .attr('class', $$.classLine.bind($$))\n    .style('stroke', $$.color);\n  contextLine\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n    .remove();\n  $$.contextLine = contextLineEnter\n    .merge(contextLine)\n    .style('opacity', $$.initialOpacity.bind($$));\n};\nChartInternal.prototype.redrawLineForSubchart = function(\n  drawLineOnSub,\n  withTransition,\n  duration\n) {\n(withTransition\n    ? this.contextLine.transition(Math.random().toString()).duration(duration)\n    : this.contextLine\n  )\n    .attr('d', drawLineOnSub)\n    .style('opacity', 1);\n};\nChartInternal.prototype.updateAreaForSubchart = function(durationForExit) {\n  var $$ = this,\n    d3 = $$.d3;\n  var contextArea = $$.context\n    .selectAll('.' + CLASS.areas)\n    .selectAll('.' + CLASS.area)\n    .data($$.lineData.bind($$));\n  var contextAreaEnter = contextArea\n    .enter()\n    .append('path')\n    .attr('class', $$.classArea.bind($$))\n    .style('fill', $$.color)\n    .style('opacity', function() {\n      $$.orgAreaOpacity = +d3.select(this).style('opacity');\n      return 0\n    });\n  contextArea\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n    .remove();\n  $$.contextArea = contextAreaEnter.merge(contextArea).style('opacity', 0);\n};\nChartInternal.prototype.redrawAreaForSubchart = function(\n  drawAreaOnSub,\n  withTransition,\n  duration\n) {\n(withTransition\n    ? this.contextArea.transition(Math.random().toString()).duration(duration)\n    : this.contextArea\n  )\n    .attr('d', drawAreaOnSub)\n    .style('fill', this.color)\n    .style('opacity', this.orgAreaOpacity);\n};\nChartInternal.prototype.redrawSubchart = function(\n  withSubchart,\n  transitions,\n  duration,\n  durationForExit,\n  areaIndices,\n  barIndices,\n  lineIndices\n) {\n  var $$ = this,\n    d3 = $$.d3,\n    drawAreaOnSub,\n    drawBarOnSub,\n    drawLineOnSub;\n\n  // reflect main chart to extent on subchart if zoomed\n  if (d3.event && d3.event.type === 'zoom') {\n    $$.brush.selectionAsValue($$.x.orgDomain());\n  }\n  // update subchart elements if needed\n  if (withSubchart) {\n    // extent rect\n    if (!$$.brush.empty()) {\n      $$.brush.selectionAsValue($$.x.orgDomain());\n    }\n    // setup drawer - MEMO: this must be called after axis updated\n    drawAreaOnSub = $$.generateDrawArea(areaIndices, true);\n    drawBarOnSub = $$.generateDrawBar(barIndices, true);\n    drawLineOnSub = $$.generateDrawLine(lineIndices, true);\n\n    $$.updateBarForSubchart(duration);\n    $$.updateLineForSubchart(duration);\n    $$.updateAreaForSubchart(duration);\n\n    $$.redrawBarForSubchart(drawBarOnSub, duration, duration);\n    $$.redrawLineForSubchart(drawLineOnSub, duration, duration);\n    $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration);\n  }\n};\nChartInternal.prototype.redrawForBrush = function() {\n  var $$ = this,\n    x = $$.x,\n    d3 = $$.d3,\n    s;\n  $$.redraw({\n    withTransition: false,\n    withY: $$.config.zoom_rescale,\n    withSubchart: false,\n    withUpdateXDomain: true,\n    withEventRect: false,\n    withDimension: false\n  });\n  // update zoom transation binded to event rect\n  s = d3.event.selection || $$.brush.scale.range();\n  $$.main\n    .select('.' + CLASS.eventRect)\n    .call(\n      $$.zoom.transform,\n      d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0)\n    );\n  $$.config.subchart_onbrush.call($$.api, x.orgDomain());\n};\nChartInternal.prototype.transformContext = function(\n  withTransition,\n  transitions\n) {\n  var $$ = this,\n    subXAxis;\n  if (transitions && transitions.axisSubX) {\n    subXAxis = transitions.axisSubX;\n  } else {\n    subXAxis = $$.context.select('.' + CLASS.axisX);\n    if (withTransition) {\n      subXAxis = subXAxis.transition();\n    }\n  }\n  $$.context.attr('transform', $$.getTranslate('context'));\n  subXAxis.attr('transform', $$.getTranslate('subx'));\n};\nChartInternal.prototype.getDefaultSelection = function() {\n  var $$ = this,\n    config = $$.config,\n    selection = isFunction(config.axis_x_selection)\n      ? config.axis_x_selection($$.getXDomain($$.data.targets))\n      : config.axis_x_selection;\n  if ($$.isTimeSeries()) {\n    selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])];\n  }\n  return selection\n};\n\nChartInternal.prototype.removeSubchart = function() {\n  const $$ = this;\n\n  $$.brush = null;\n  $$.context.remove();\n  $$.context = null;\n};\n\nChartInternal.prototype.initText = function() {\n  var $$ = this;\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartTexts);\n  $$.mainText = $$.d3.selectAll([]);\n};\nChartInternal.prototype.updateTargetsForText = function(targets) {\n  var $$ = this,\n    classChartText = $$.classChartText.bind($$),\n    classTexts = $$.classTexts.bind($$),\n    classFocus = $$.classFocus.bind($$);\n  var mainText = $$.main\n    .select('.' + CLASS.chartTexts)\n    .selectAll('.' + CLASS.chartText)\n    .data(targets);\n  var mainTextEnter = mainText\n    .enter()\n    .append('g')\n    .attr('class', classChartText)\n    .style('opacity', 0)\n    .style('pointer-events', 'none');\n  mainTextEnter.append('g').attr('class', classTexts);\n  mainTextEnter.merge(mainText).attr('class', function(d) {\n    return classChartText(d) + classFocus(d)\n  });\n};\nChartInternal.prototype.updateText = function(\n  xForText,\n  yForText,\n  durationForExit\n) {\n  var $$ = this,\n    config = $$.config,\n    barOrLineData = $$.barOrLineData.bind($$),\n    classText = $$.classText.bind($$);\n  var mainText = $$.main\n    .selectAll('.' + CLASS.texts)\n    .selectAll('.' + CLASS.text)\n    .data(barOrLineData);\n  var mainTextEnter = mainText\n    .enter()\n    .append('text')\n    .attr('class', classText)\n    .attr('text-anchor', function(d) {\n      return config.axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle'\n    })\n    .style('stroke', 'none')\n    .attr('x', xForText)\n    .attr('y', yForText)\n    .style('fill', function(d) {\n      return $$.color(d)\n    })\n    .style('fill-opacity', 0);\n  $$.mainText = mainTextEnter.merge(mainText).text(function(d, i, j) {\n    return $$.dataLabelFormat(d.id)(d.value, d.id, i, j)\n  });\n  mainText\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('fill-opacity', 0)\n    .remove();\n};\nChartInternal.prototype.redrawText = function(\n  xForText,\n  yForText,\n  forFlow,\n  withTransition,\n  transition\n) {\n  return [\n    (withTransition ? this.mainText.transition(transition) : this.mainText)\n      .attr('x', xForText)\n      .attr('y', yForText)\n      .style('fill', this.color)\n      .style('fill-opacity', forFlow ? 0 : this.opacityForText.bind(this))\n  ]\n};\nChartInternal.prototype.getTextRect = function(text, cls, element) {\n  var dummy = this.d3\n      .select('body')\n      .append('div')\n      .classed('c3', true),\n    svg = dummy\n      .append('svg')\n      .style('visibility', 'hidden')\n      .style('position', 'fixed')\n      .style('top', 0)\n      .style('left', 0),\n    font = this.d3.select(element).style('font'),\n    rect;\n  svg\n    .selectAll('.dummy')\n    .data([text])\n    .enter()\n    .append('text')\n    .classed(cls ? cls : '', true)\n    .style('font', font)\n    .text(text)\n    .each(function() {\n      rect = getBBox(this);\n    });\n  dummy.remove();\n  return rect\n};\nChartInternal.prototype.generateXYForText = function(\n  areaIndices,\n  barIndices,\n  lineIndices,\n  forX\n) {\n  var $$ = this,\n    getAreaPoints = $$.generateGetAreaPoints(areaIndices, false),\n    getBarPoints = $$.generateGetBarPoints(barIndices, false),\n    getLinePoints = $$.generateGetLinePoints(lineIndices, false),\n    getter = forX ? $$.getXForText : $$.getYForText;\n  return function(d, i) {\n    var getPoints = $$.isAreaType(d)\n      ? getAreaPoints\n      : $$.isBarType(d)\n      ? getBarPoints\n      : getLinePoints;\n    return getter.call($$, getPoints(d, i), d, this)\n  }\n};\nChartInternal.prototype.getXForText = function(points, d, textElement) {\n  var $$ = this,\n    box = getBBox(textElement),\n    xPos,\n    padding;\n  if ($$.config.axis_rotated) {\n    padding = $$.isBarType(d) ? 4 : 6;\n    xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1);\n  } else {\n    xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0];\n  }\n  // show labels regardless of the domain if value is null\n  if (d.value === null) {\n    if (xPos > $$.width) {\n      xPos = $$.width - box.width;\n    } else if (xPos < 0) {\n      xPos = 4;\n    }\n  }\n  return xPos\n};\nChartInternal.prototype.getYForText = function(points, d, textElement) {\n  var $$ = this,\n    box = getBBox(textElement),\n    yPos;\n  if ($$.config.axis_rotated) {\n    yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2;\n  } else {\n    yPos = points[2][1];\n    if (d.value < 0 || (d.value === 0 && !$$.hasPositiveValue)) {\n      yPos += box.height;\n      if ($$.isBarType(d) && $$.isSafari()) {\n        yPos -= 3;\n      } else if (!$$.isBarType(d) && $$.isChrome()) {\n        yPos += 3;\n      }\n    } else {\n      yPos += $$.isBarType(d) ? -3 : -6;\n    }\n  }\n  // show labels regardless of the domain if value is null\n  if (d.value === null && !$$.config.axis_rotated) {\n    if (yPos < box.height) {\n      yPos = box.height;\n    } else if (yPos > this.height) {\n      yPos = this.height - 4;\n    }\n  }\n  return yPos\n};\n\nChartInternal.prototype.initTitle = function() {\n  var $$ = this;\n  $$.title = $$.svg\n    .append('text')\n    .text($$.config.title_text)\n    .attr('class', $$.CLASS.title);\n};\nChartInternal.prototype.redrawTitle = function() {\n  var $$ = this;\n  $$.title.attr('x', $$.xForTitle.bind($$)).attr('y', $$.yForTitle.bind($$));\n};\nChartInternal.prototype.xForTitle = function() {\n  var $$ = this,\n    config = $$.config,\n    position = config.title_position || 'left',\n    x;\n  if (position.indexOf('right') >= 0) {\n    x =\n      $$.currentWidth -\n      $$.getTextRect(\n        $$.title.node().textContent,\n        $$.CLASS.title,\n        $$.title.node()\n      ).width -\n      config.title_padding.right;\n  } else if (position.indexOf('center') >= 0) {\n    x = Math.max(\n      ($$.currentWidth -\n        $$.getTextRect(\n          $$.title.node().textContent,\n          $$.CLASS.title,\n          $$.title.node()\n        ).width) /\n        2,\n      0\n    );\n  } else {\n    // left\n    x = config.title_padding.left;\n  }\n  return x\n};\nChartInternal.prototype.yForTitle = function() {\n  var $$ = this;\n  return (\n    $$.config.title_padding.top +\n    $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node())\n      .height\n  )\n};\nChartInternal.prototype.getTitlePadding = function() {\n  var $$ = this;\n  return $$.yForTitle() + $$.config.title_padding.bottom\n};\n\nfunction powerOfTen(d) {\n  return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1\n}\n\nChartInternal.prototype.drawColorScale = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    target = $$.data.targets[0],\n    barWidth,\n    barHeight,\n    axis,\n    points,\n    legendAxis,\n    axisScale,\n    inverseScale,\n    height;\n\n  barWidth = !isNaN(config.stanford_scaleWidth)\n    ? config.stanford_scaleWidth\n    : 20;\n  barHeight = 5;\n\n  if (barHeight < 0 || barWidth < 0) {\n    throw Error(\"Colorscale's barheight and barwidth must be greater than 0.\")\n  }\n\n  height =\n    $$.height - config.stanford_padding.bottom - config.stanford_padding.top;\n\n  points = d3.range(config.stanford_padding.bottom, height, barHeight);\n\n  inverseScale = d3\n    .scaleSequential(target.colors)\n    .domain([points[points.length - 1], points[0]]);\n\n  if ($$.colorScale) {\n    $$.colorScale.remove();\n  }\n\n  $$.colorScale = $$.svg\n    .append('g')\n    .attr('width', 50)\n    .attr('height', height)\n    .attr('class', CLASS.colorScale);\n\n  $$.colorScale\n    .append('g')\n    .attr('transform', `translate(0, ${config.stanford_padding.top})`)\n    .selectAll('bars')\n    .data(points)\n    .enter()\n    .append('rect')\n    .attr('y', (d, i) => i * barHeight)\n    .attr('x', 0)\n    .attr('width', barWidth)\n    .attr('height', barHeight)\n    .attr('fill', function(d) {\n      return inverseScale(d)\n    });\n\n  // Legend Axis\n  axisScale = d3\n    .scaleLog()\n    .domain([target.minEpochs, target.maxEpochs])\n    .range([\n      points[0] +\n        config.stanford_padding.top +\n        points[points.length - 1] +\n        barHeight -\n        1,\n      points[0] + config.stanford_padding.top\n    ]);\n\n  legendAxis = d3.axisRight(axisScale);\n\n  if (config.stanford_scaleFormat === 'pow10') {\n    legendAxis.tickValues([1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]);\n  } else if (isFunction(config.stanford_scaleFormat)) {\n    legendAxis.tickFormat(config.stanford_scaleFormat);\n  } else {\n    legendAxis.tickFormat(d3.format('d'));\n  }\n\n  if (isFunction(config.stanford_scaleValues)) {\n    legendAxis.tickValues(\n      config.stanford_scaleValues(target.minEpochs, target.maxEpochs)\n    );\n  }\n\n  // Draw Axis\n  axis = $$.colorScale\n    .append('g')\n    .attr('class', 'legend axis')\n    .attr('transform', `translate(${barWidth},0)`)\n    .call(legendAxis);\n\n  if (config.stanford_scaleFormat === 'pow10') {\n    axis\n      .selectAll('.tick text')\n      .text(null)\n      .filter(powerOfTen)\n      .text(10)\n      .append('tspan')\n      .attr('dy', '-.7em') // https://bl.ocks.org/mbostock/6738229\n      .text(function(d) {\n        return Math.round(Math.log(d) / Math.LN10)\n      });\n  }\n\n  $$.colorScale.attr(\n    'transform',\n    `translate(${$$.currentWidth - $$.xForColorScale()}, 0)`\n  );\n};\n\nChartInternal.prototype.xForColorScale = function() {\n  var $$ = this;\n\n  return $$.config.stanford_padding.right + getBBox($$.colorScale.node()).width\n};\n\nChartInternal.prototype.getColorScalePadding = function() {\n  var $$ = this;\n  return $$.xForColorScale() + $$.config.stanford_padding.left + 20\n};\n\nChartInternal.prototype.isStanfordGraphType = function() {\n  var $$ = this;\n\n  return $$.config.data_type === 'stanford'\n};\n\nChartInternal.prototype.initStanfordData = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    target = $$.data.targets[0],\n    epochs,\n    maxEpochs,\n    minEpochs;\n\n  // Make larger values appear on top\n  target.values.sort(compareEpochs);\n\n  // Get array of epochs\n  epochs = target.values.map(a => a.epochs);\n\n  minEpochs = !isNaN(config.stanford_scaleMin)\n    ? config.stanford_scaleMin\n    : d3.min(epochs);\n  maxEpochs = !isNaN(config.stanford_scaleMax)\n    ? config.stanford_scaleMax\n    : d3.max(epochs);\n\n  if (minEpochs > maxEpochs) {\n    throw Error('Number of minEpochs has to be smaller than maxEpochs')\n  }\n\n  target.colors = isFunction(config.stanford_colors)\n    ? config.stanford_colors\n    : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5));\n\n  target.colorscale = d3\n    .scaleSequentialLog(target.colors)\n    .domain([minEpochs, maxEpochs]);\n\n  target.minEpochs = minEpochs;\n  target.maxEpochs = maxEpochs;\n};\n\nChartInternal.prototype.getStanfordPointColor = function(d) {\n  var $$ = this,\n    target = $$.data.targets[0];\n\n  return target.colorscale(d.epochs)\n};\n\n// http://jsfiddle.net/Xotic750/KtzLq/\nChartInternal.prototype.getCentroid = function(points) {\n  var area = getRegionArea(points);\n\n  var x = 0,\n    y = 0,\n    i,\n    j,\n    f,\n    point1,\n    point2;\n\n  for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {\n    point1 = points[i];\n    point2 = points[j];\n    f = point1.x * point2.y - point2.x * point1.y;\n    x += (point1.x + point2.x) * f;\n    y += (point1.y + point2.y) * f;\n  }\n\n  f = area * 6;\n\n  return {\n    x: x / f,\n    y: y / f\n  }\n};\n\nChartInternal.prototype.getStanfordTooltipTitle = function(d) {\n  var $$ = this,\n    labelX = $$.axis.getLabelText('x'),\n    labelY = $$.axis.getLabelText('y');\n\n  return `\n      <tr><th>${labelX ? sanitise(labelX) : 'x'}</th><th class='value'>${\n    d.x\n  }</th></tr>\n      <tr><th>${labelY ? sanitise(labelY) : 'y'}</th><th class='value'>${\n    d.value\n  }</th></tr>\n    `\n};\n\nChartInternal.prototype.countEpochsInRegion = function(region) {\n  var $$ = this,\n    target = $$.data.targets[0],\n    total,\n    count;\n\n  total = target.values.reduce(\n    (accumulator, currentValue) => accumulator + Number(currentValue.epochs),\n    0\n  );\n\n  count = target.values.reduce((accumulator, currentValue) => {\n    if (pointInRegion(currentValue, region)) {\n      return accumulator + Number(currentValue.epochs)\n    }\n\n    return accumulator\n  }, 0);\n\n  return {\n    value: count,\n    percentage: count !== 0 ? ((count / total) * 100).toFixed(1) : 0\n  }\n};\n\nvar getRegionArea = function(points) {\n  // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript\n  var area = 0,\n    i,\n    j,\n    point1,\n    point2;\n\n  for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {\n    point1 = points[i];\n    point2 = points[j];\n    area += point1.x * point2.y;\n    area -= point1.y * point2.x;\n  }\n\n  area /= 2;\n\n  return area\n};\n\nvar pointInRegion = function(point, region) {\n  // thanks to: http://bl.ocks.org/bycoffe/5575904\n  // ray-casting algorithm based on\n  // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html\n  let xi,\n    yi,\n    yj,\n    xj,\n    intersect,\n    x = point.x,\n    y = point.value,\n    inside = false;\n\n  for (let i = 0, j = region.length - 1; i < region.length; j = i++) {\n    xi = region[i].x;\n    yi = region[i].y;\n\n    xj = region[j].x;\n    yj = region[j].y;\n\n    intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;\n\n    if (intersect) {\n      inside = !inside;\n    }\n  }\n\n  return inside\n};\n\nvar compareEpochs = function(a, b) {\n  if (a.epochs < b.epochs) {\n    return -1\n  }\n  if (a.epochs > b.epochs) {\n    return 1\n  }\n\n  return 0\n};\n\nChartInternal.prototype.initStanfordElements = function() {\n  var $$ = this;\n\n  // Avoid blocking eventRect\n  $$.stanfordElements = $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.stanfordElements);\n\n  $$.stanfordElements.append('g').attr('class', CLASS.stanfordLines);\n  $$.stanfordElements.append('g').attr('class', CLASS.stanfordTexts);\n  $$.stanfordElements.append('g').attr('class', CLASS.stanfordRegions);\n};\n\nChartInternal.prototype.updateStanfordElements = function(duration) {\n  var $$ = this,\n    main = $$.main,\n    config = $$.config,\n    stanfordLine,\n    stanfordLineEnter,\n    stanfordRegion,\n    stanfordRegionEnter,\n    stanfordText,\n    stanfordTextEnter,\n    xvCustom = $$.xvCustom.bind($$),\n    yvCustom = $$.yvCustom.bind($$),\n    countPointsInRegion = $$.countEpochsInRegion.bind($$);\n\n  // Stanford-Lines\n  stanfordLine = main\n    .select('.' + CLASS.stanfordLines)\n    .style('shape-rendering', 'geometricprecision')\n    .selectAll('.' + CLASS.stanfordLine)\n    .data(config.stanford_lines);\n\n  // enter\n  stanfordLineEnter = stanfordLine\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : '')\n    });\n  stanfordLineEnter\n    .append('line')\n    .attr('x1', d =>\n      config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1')\n    )\n    .attr('x2', d =>\n      config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2')\n    )\n    .attr('y1', d =>\n      config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1')\n    )\n    .attr('y2', d =>\n      config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2')\n    )\n    .style('opacity', 0);\n\n  // update\n  $$.stanfordLines = stanfordLineEnter.merge(stanfordLine);\n  $$.stanfordLines\n    .select('line')\n    .transition()\n    .duration(duration)\n    .attr('x1', d =>\n      config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1')\n    )\n    .attr('x2', d =>\n      config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2')\n    )\n    .attr('y1', d =>\n      config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1')\n    )\n    .attr('y2', d =>\n      config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2')\n    )\n    .style('opacity', 1);\n\n  // exit\n  stanfordLine\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove();\n\n  // Stanford-Text\n  stanfordText = main\n    .select('.' + CLASS.stanfordTexts)\n    .selectAll('.' + CLASS.stanfordText)\n    .data(config.stanford_texts);\n\n  // enter\n  stanfordTextEnter = stanfordText\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : '')\n    });\n  stanfordTextEnter\n    .append('text')\n    .attr('x', d => (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')))\n    .attr('y', d => (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')))\n    .style('opacity', 0);\n\n  // update\n  $$.stanfordTexts = stanfordTextEnter.merge(stanfordText);\n  $$.stanfordTexts\n    .select('text')\n    .transition()\n    .duration(duration)\n    .attr('x', d => (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')))\n    .attr('y', d => (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')))\n    .text(function(d) {\n      return d.content\n    })\n    .style('opacity', 1);\n\n  // exit\n  stanfordText\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove();\n\n  // Stanford-Regions\n  stanfordRegion = main\n    .select('.' + CLASS.stanfordRegions)\n    .selectAll('.' + CLASS.stanfordRegion)\n    .data(config.stanford_regions);\n\n  // enter\n  stanfordRegionEnter = stanfordRegion\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : '')\n    });\n  stanfordRegionEnter\n    .append('polygon')\n    .attr('points', d => {\n      return d.points\n        .map(value => {\n          return [\n            config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'),\n            config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')\n          ].join(',')\n        })\n        .join(' ')\n    })\n    .style('opacity', 0);\n  stanfordRegionEnter\n    .append('text')\n    .attr('x', d => $$.getCentroid(d.points).x)\n    .attr('y', d => $$.getCentroid(d.points).y)\n    .style('opacity', 0);\n\n  // update\n  $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion);\n  $$.stanfordRegions\n    .select('polygon')\n    .transition()\n    .duration(duration)\n    .attr('points', d => {\n      return d.points\n        .map(value => {\n          return [\n            config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'),\n            config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')\n          ].join(',')\n        })\n        .join(' ')\n    })\n    .style('opacity', d => {\n      return d.opacity ? d.opacity : 0.2\n    });\n  $$.stanfordRegions\n    .select('text')\n    .transition()\n    .duration(duration)\n    .attr('x', d =>\n      config.axis_rotated\n        ? yvCustom($$.getCentroid(d.points), 'y')\n        : xvCustom($$.getCentroid(d.points), 'x')\n    )\n    .attr('y', d =>\n      config.axis_rotated\n        ? xvCustom($$.getCentroid(d.points), 'x')\n        : yvCustom($$.getCentroid(d.points), 'y')\n    )\n    .text(function(d) {\n      if (d.text) {\n        var value, percentage, temp;\n\n        if ($$.isStanfordGraphType()) {\n          temp = countPointsInRegion(d.points);\n          value = temp.value;\n          percentage = temp.percentage;\n        }\n\n        return d.text(value, percentage)\n      }\n\n      return ''\n    })\n    .attr('text-anchor', 'middle')\n    .attr('dominant-baseline', 'middle')\n    .style('opacity', 1);\n  // exit\n  stanfordRegion\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove();\n};\n\nChartInternal.prototype.initTooltip = function() {\n  var $$ = this,\n    config = $$.config,\n    i;\n  $$.tooltip = $$.selectChart\n    .style('position', 'relative')\n    .append('div')\n    .attr('class', CLASS.tooltipContainer)\n    .style('position', 'absolute')\n    .style('pointer-events', 'none')\n    .style('display', 'none');\n  // Show tooltip if needed\n  if (config.tooltip_init_show) {\n    if ($$.isTimeSeries() && isString(config.tooltip_init_x)) {\n      config.tooltip_init_x = $$.parseDate(config.tooltip_init_x);\n      for (i = 0; i < $$.data.targets[0].values.length; i++) {\n        if ($$.data.targets[0].values[i].x - config.tooltip_init_x === 0) {\n          break\n        }\n      }\n      config.tooltip_init_x = i;\n    }\n    $$.tooltip.html(\n      config.tooltip_contents.call(\n        $$,\n        $$.data.targets.map(function(d) {\n          return $$.addName(d.values[config.tooltip_init_x])\n        }),\n        $$.axis.getXAxisTickFormat(),\n        $$.getYFormat($$.hasArcType()),\n        $$.color\n      )\n    );\n    $$.tooltip\n      .style('top', config.tooltip_init_position.top)\n      .style('left', config.tooltip_init_position.left)\n      .style('display', 'block');\n  }\n};\nChartInternal.prototype.getTooltipSortFunction = function() {\n  var $$ = this,\n    config = $$.config;\n\n  if (config.data_groups.length === 0 || config.tooltip_order !== undefined) {\n    // if data are not grouped or if an order is specified\n    // for the tooltip values we sort them by their values\n\n    var order = config.tooltip_order;\n    if (order === undefined) {\n      order = config.data_order;\n    }\n\n    var valueOf = function(obj) {\n      return obj ? obj.value : null\n    };\n\n    // if data are not grouped, we sort them by their value\n    if (isString(order) && order.toLowerCase() === 'asc') {\n      return function(a, b) {\n        return valueOf(a) - valueOf(b)\n      }\n    } else if (isString(order) && order.toLowerCase() === 'desc') {\n      return function(a, b) {\n        return valueOf(b) - valueOf(a)\n      }\n    } else if (isFunction(order)) {\n      // if the function is from data_order we need\n      // to wrap the returned function in order to format\n      // the sorted value to the expected format\n\n      var sortFunction = order;\n\n      if (config.tooltip_order === undefined) {\n        sortFunction = function(a, b) {\n          return order(\n            a\n              ? {\n                  id: a.id,\n                  values: [a]\n                }\n              : null,\n            b\n              ? {\n                  id: b.id,\n                  values: [b]\n                }\n              : null\n          )\n        };\n      }\n\n      return sortFunction\n    } else if (isArray(order)) {\n      return function(a, b) {\n        return order.indexOf(a.id) - order.indexOf(b.id)\n      }\n    }\n  } else {\n    // if data are grouped, we follow the order of grouped targets\n    var ids = $$.orderTargets($$.data.targets).map(function(i) {\n      return i.id\n    });\n\n    // if it was either asc or desc we need to invert the order\n    // returned by orderTargets\n    if ($$.isOrderAsc() || $$.isOrderDesc()) {\n      ids = ids.reverse();\n    }\n\n    return function(a, b) {\n      return ids.indexOf(a.id) - ids.indexOf(b.id)\n    }\n  }\n};\nChartInternal.prototype.getTooltipContent = function(\n  d,\n  defaultTitleFormat,\n  defaultValueFormat,\n  color\n) {\n  var $$ = this,\n    config = $$.config,\n    titleFormat = config.tooltip_format_title || defaultTitleFormat,\n    nameFormat =\n      config.tooltip_format_name ||\n      function(name) {\n        return name\n      },\n    text,\n    i,\n    title,\n    value,\n    name,\n    bgcolor;\n\n  var valueFormat = config.tooltip_format_value;\n  if (!valueFormat) {\n    valueFormat = $$.isTargetNormalized(d.id)\n      ? (v, ratio) => `${(ratio * 100).toFixed(2)}%`\n      : defaultValueFormat;\n  }\n\n  var tooltipSortFunction = this.getTooltipSortFunction();\n  if (tooltipSortFunction) {\n    d.sort(tooltipSortFunction);\n  }\n\n  for (i = 0; i < d.length; i++) {\n    if (!(d[i] && (d[i].value || d[i].value === 0))) {\n      continue\n    }\n\n    if ($$.isStanfordGraphType()) {\n      // Custom tooltip for stanford plots\n      if (!text) {\n        title = $$.getStanfordTooltipTitle(d[i]);\n        text = \"<table class='\" + $$.CLASS.tooltip + \"'>\" + title;\n      }\n\n      bgcolor = $$.getStanfordPointColor(d[i]);\n      name = sanitise(config.data_epochs); // Epochs key name\n      value = d[i].epochs;\n    } else {\n      // Regular tooltip\n      if (!text) {\n        title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x);\n        text =\n          \"<table class='\" +\n          $$.CLASS.tooltip +\n          \"'>\" +\n          (title || title === 0\n            ? \"<tr><th colspan='2'>\" + title + '</th></tr>'\n            : '');\n      }\n\n      value = sanitise(\n        valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d)\n      );\n      if (value !== undefined) {\n        // Skip elements when their name is set to null\n        if (d[i].name === null) {\n          continue\n        }\n\n        name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index));\n        bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);\n      }\n    }\n\n    if (value !== undefined) {\n      text +=\n        \"<tr class='\" +\n        $$.CLASS.tooltipName +\n        '-' +\n        $$.getTargetSelectorSuffix(d[i].id) +\n        \"'>\";\n      text +=\n        \"<td class='name'><span style='background-color:\" +\n        bgcolor +\n        \"'></span>\" +\n        name +\n        '</td>';\n      text += \"<td class='value'>\" + value + '</td>';\n      text += '</tr>';\n    }\n  }\n  return text + '</table>'\n};\nChartInternal.prototype.tooltipPosition = function(\n  dataToShow,\n  tWidth,\n  tHeight,\n  element\n) {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3;\n  var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight;\n  var forArc = $$.hasArcType(),\n    mouse = d3.mouse(element);\n  // Determin tooltip position\n  if (forArc) {\n    tooltipLeft =\n      ($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2 + mouse[0];\n    tooltipTop =\n      ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20;\n  } else {\n    svgLeft = $$.getSvgLeft(true);\n    if (config.axis_rotated) {\n      tooltipLeft = svgLeft + mouse[0] + 100;\n      tooltipRight = tooltipLeft + tWidth;\n      chartRight = $$.currentWidth - $$.getCurrentPaddingRight();\n      tooltipTop = $$.x(dataToShow[0].x) + 20;\n    } else {\n      tooltipLeft =\n        svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20;\n      tooltipRight = tooltipLeft + tWidth;\n      chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight();\n      tooltipTop = mouse[1] + 15;\n    }\n\n    if (tooltipRight > chartRight) {\n      // 20 is needed for Firefox to keep tooltip width\n      tooltipLeft -= tooltipRight - chartRight + 20;\n    }\n    if (tooltipTop + tHeight > $$.currentHeight) {\n      tooltipTop -= tHeight + 30;\n    }\n  }\n  if (tooltipTop < 0) {\n    tooltipTop = 0;\n  }\n  return {\n    top: tooltipTop,\n    left: tooltipLeft\n  }\n};\nChartInternal.prototype.showTooltip = function(selectedData, element) {\n  var $$ = this,\n    config = $$.config;\n  var tWidth, tHeight, position;\n  var forArc = $$.hasArcType(),\n    dataToShow = selectedData.filter(function(d) {\n      return d && isValue(d.value)\n    }),\n    positionFunction =\n      config.tooltip_position || ChartInternal.prototype.tooltipPosition;\n  if (dataToShow.length === 0 || !config.tooltip_show) {\n    $$.hideTooltip();\n    return\n  }\n  $$.tooltip\n    .html(\n      config.tooltip_contents.call(\n        $$,\n        selectedData,\n        $$.axis.getXAxisTickFormat(),\n        $$.getYFormat(forArc),\n        $$.color\n      )\n    )\n    .style('display', 'block');\n\n  // Get tooltip dimensions\n  tWidth = $$.tooltip.property('offsetWidth');\n  tHeight = $$.tooltip.property('offsetHeight');\n\n  position = positionFunction.call(this, dataToShow, tWidth, tHeight, element);\n  // Set tooltip\n  $$.tooltip\n    .style('top', position.top + 'px')\n    .style('left', position.left + 'px');\n};\nChartInternal.prototype.hideTooltip = function() {\n  this.tooltip.style('display', 'none');\n};\n\nChartInternal.prototype.setTargetType = function(targetIds, type) {\n  var $$ = this,\n    config = $$.config;\n  $$.mapToTargetIds(targetIds).forEach(function(id) {\n    $$.withoutFadeIn[id] = type === config.data_types[id];\n    config.data_types[id] = type;\n  });\n  if (!targetIds) {\n    config.data_type = type;\n  }\n};\nChartInternal.prototype.hasType = function(type, targets) {\n  var $$ = this,\n    types = $$.config.data_types,\n    has = false;\n  targets = targets || $$.data.targets;\n  if (targets && targets.length) {\n    targets.forEach(function(target) {\n      var t = types[target.id];\n      if ((t && t.indexOf(type) >= 0) || (!t && type === 'line')) {\n        has = true;\n      }\n    });\n  } else if (Object.keys(types).length) {\n    Object.keys(types).forEach(function(id) {\n      if (types[id] === type) {\n        has = true;\n      }\n    });\n  } else {\n    has = $$.config.data_type === type;\n  }\n  return has\n};\nChartInternal.prototype.hasArcType = function(targets) {\n  return (\n    this.hasType('pie', targets) ||\n    this.hasType('donut', targets) ||\n    this.hasType('gauge', targets)\n  )\n};\nChartInternal.prototype.isLineType = function(d) {\n  var config = this.config,\n    id = isString(d) ? d : d.id;\n  return (\n    !config.data_types[id] ||\n    ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(\n      config.data_types[id]\n    ) >= 0\n  )\n};\nChartInternal.prototype.isStepType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0\n};\nChartInternal.prototype.isSplineType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0\n};\nChartInternal.prototype.isAreaType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return (\n    ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >=\n    0\n  )\n};\nChartInternal.prototype.isBarType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return this.config.data_types[id] === 'bar'\n};\nChartInternal.prototype.isScatterType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return this.config.data_types[id] === 'scatter'\n};\nChartInternal.prototype.isStanfordType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return this.config.data_types[id] === 'stanford'\n};\nChartInternal.prototype.isPieType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return this.config.data_types[id] === 'pie'\n};\nChartInternal.prototype.isGaugeType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return this.config.data_types[id] === 'gauge'\n};\nChartInternal.prototype.isDonutType = function(d) {\n  var id = isString(d) ? d : d.id;\n  return this.config.data_types[id] === 'donut'\n};\nChartInternal.prototype.isArcType = function(d) {\n  return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d)\n};\nChartInternal.prototype.lineData = function(d) {\n  return this.isLineType(d) ? [d] : []\n};\nChartInternal.prototype.arcData = function(d) {\n  return this.isArcType(d.data) ? [d] : []\n};\n/* not used\n function scatterData(d) {\n return isScatterType(d) ? d.values : [];\n }\n */\nChartInternal.prototype.barData = function(d) {\n  return this.isBarType(d) ? d.values : []\n};\nChartInternal.prototype.lineOrScatterOrStanfordData = function(d) {\n  return this.isLineType(d) || this.isScatterType(d) || this.isStanfordType(d)\n    ? d.values\n    : []\n};\nChartInternal.prototype.barOrLineData = function(d) {\n  return this.isBarType(d) || this.isLineType(d) ? d.values : []\n};\n\nChartInternal.prototype.isSafari = function() {\n  var ua = window.navigator.userAgent;\n  return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0\n};\nChartInternal.prototype.isChrome = function() {\n  var ua = window.navigator.userAgent;\n  return ua.indexOf('Chrome') >= 0\n};\n\nChartInternal.prototype.initZoom = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    startEvent;\n\n  $$.zoom = d3\n    .zoom()\n    .on('start', function() {\n      if (config.zoom_type !== 'scroll') {\n        return\n      }\n\n      var e = d3.event.sourceEvent;\n      if (e && e.type === 'brush') {\n        return\n      }\n      startEvent = e;\n      config.zoom_onzoomstart.call($$.api, e);\n    })\n    .on('zoom', function() {\n      if (config.zoom_type !== 'scroll') {\n        return\n      }\n\n      var e = d3.event.sourceEvent;\n      if (e && e.type === 'brush') {\n        return\n      }\n\n      $$.redrawForZoom();\n\n      config.zoom_onzoom.call($$.api, $$.x.orgDomain());\n    })\n    .on('end', function() {\n      if (config.zoom_type !== 'scroll') {\n        return\n      }\n\n      var e = d3.event.sourceEvent;\n      if (e && e.type === 'brush') {\n        return\n      }\n      // if click, do nothing. otherwise, click interaction will be canceled.\n      if (\n        e &&\n        startEvent.clientX === e.clientX &&\n        startEvent.clientY === e.clientY\n      ) {\n        return\n      }\n      config.zoom_onzoomend.call($$.api, $$.x.orgDomain());\n    });\n\n  $$.zoom.updateDomain = function() {\n    if (d3.event && d3.event.transform) {\n      $$.x.domain(d3.event.transform.rescaleX($$.subX).domain());\n    }\n    return this\n  };\n  $$.zoom.updateExtent = function() {\n    this.scaleExtent([1, Infinity])\n      .translateExtent([\n        [0, 0],\n        [$$.width, $$.height]\n      ])\n      .extent([\n        [0, 0],\n        [$$.width, $$.height]\n      ]);\n    return this\n  };\n  $$.zoom.update = function() {\n    return this.updateExtent().updateDomain()\n  };\n\n  return $$.zoom.updateExtent()\n};\nChartInternal.prototype.zoomTransform = function(range) {\n  var $$ = this,\n    s = [$$.x(range[0]), $$.x(range[1])];\n  return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0)\n};\n\nChartInternal.prototype.initDragZoom = function() {\n  const $$ = this;\n  const d3 = $$.d3;\n  const config = $$.config;\n  const context = ($$.context = $$.svg);\n  const brushXPos = $$.margin.left + 20.5;\n  const brushYPos = $$.margin.top + 0.5;\n\n  if (!(config.zoom_type === 'drag' && config.zoom_enabled)) {\n    return\n  }\n\n  const getZoomedDomain = selection =>\n    selection && selection.map(x => $$.x.invert(x));\n\n  const brush = ($$.dragZoomBrush = d3\n    .brushX()\n    .on('start', () => {\n      $$.api.unzoom();\n\n      $$.svg.select('.' + CLASS.dragZoom).classed('disabled', false);\n\n      config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent);\n    })\n    .on('brush', () => {\n      config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection));\n    })\n    .on('end', () => {\n      if (d3.event.selection == null) {\n        return\n      }\n\n      const zoomedDomain = getZoomedDomain(d3.event.selection);\n\n      if (!config.zoom_disableDefaultBehavior) {\n        $$.api.zoom(zoomedDomain);\n      }\n\n      $$.svg.select('.' + CLASS.dragZoom).classed('disabled', true);\n\n      config.zoom_onzoomend.call($$.api, zoomedDomain);\n    }));\n\n  context\n    .append('g')\n    .classed(CLASS.dragZoom, true)\n    .attr('clip-path', $$.clipPath)\n    .attr('transform', 'translate(' + brushXPos + ',' + brushYPos + ')')\n    .call(brush);\n};\n\nChartInternal.prototype.getZoomDomain = function() {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3,\n    min = d3.min([$$.orgXDomain[0], config.zoom_x_min]),\n    max = d3.max([$$.orgXDomain[1], config.zoom_x_max]);\n  return [min, max]\n};\nChartInternal.prototype.redrawForZoom = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    zoom = $$.zoom,\n    x = $$.x;\n  if (!config.zoom_enabled) {\n    return\n  }\n  if ($$.filterTargetsToShow($$.data.targets).length === 0) {\n    return\n  }\n\n  zoom.update();\n\n  if (config.zoom_disableDefaultBehavior) {\n    return\n  }\n\n  if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) {\n    x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]);\n  }\n\n  $$.redraw({\n    withTransition: false,\n    withY: config.zoom_rescale,\n    withSubchart: false,\n    withEventRect: false,\n    withDimension: false\n  });\n\n  if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') {\n    $$.cancelClick = true;\n  }\n};\n\nexport default c3;\n"
  },
  {
    "path": "docs/js/c3.js",
    "content": "/* @license C3.js v0.7.20 | (c) C3 Team and other contributors | http://c3js.org/ */\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) :\n  (global = global || self, global.c3 = factory());\n}(this, (function () { 'use strict';\n\n  function ChartInternal(api) {\r\n      var $$ = this;\r\n      // Note: This part will be replaced by rollup-plugin-modify\r\n      // When bundling esm output. Beware of changing this line.\r\n      // TODO: Maybe we should check that the modification by rollup-plugin-modify\r\n      // is valid during unit tests.\r\n      $$.d3 = window.d3\r\n          ? window.d3\r\n          : typeof require !== 'undefined'\r\n              ? require('d3')\r\n              : undefined;\r\n      $$.api = api;\r\n      $$.config = $$.getDefaultConfig();\r\n      $$.data = {};\r\n      $$.cache = {};\r\n      $$.axes = {};\r\n  }\n\n  /**\r\n   * The Chart class\r\n   *\r\n   * The methods of this class is the public APIs of the chart object.\r\n   */\r\n  function Chart(config) {\r\n      this.internal = new ChartInternal(this);\r\n      this.internal.loadConfig(config);\r\n      this.internal.beforeInit(config);\r\n      this.internal.init();\r\n      this.internal.afterInit(config);\r\n      (function bindThis(fn, target, argThis) {\r\n          Object.keys(fn).forEach(function (key) {\r\n              target[key] = fn[key].bind(argThis);\r\n              if (Object.keys(fn[key]).length > 0) {\r\n                  bindThis(fn[key], target[key], argThis);\r\n              }\r\n          });\r\n      })(Chart.prototype, this, this);\r\n  }\n\n  var asHalfPixel = function (n) {\r\n      return Math.ceil(n) + 0.5;\r\n  };\r\n  var ceil10 = function (v) {\r\n      return Math.ceil(v / 10) * 10;\r\n  };\r\n  var diffDomain = function (d) {\r\n      return d[1] - d[0];\r\n  };\r\n  var getOption = function (options, key, defaultValue) {\r\n      return isDefined(options[key]) ? options[key] : defaultValue;\r\n  };\r\n  var getPathBox = function (path) {\r\n      var box = getBBox(path), items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)], minX = items[0].x, minY = Math.min(items[0].y, items[1].y);\r\n      return { x: minX, y: minY, width: box.width, height: box.height };\r\n  };\r\n  var getBBox = function (element) {\r\n      try {\r\n          return element.getBBox();\r\n      }\r\n      catch (ignore) {\r\n          // Firefox will throw an exception if getBBox() is called whereas the\r\n          // element is rendered with display:none\r\n          // See https://github.com/c3js/c3/issues/2692\r\n          // The previous code was using `getBoundingClientRect` which was returning\r\n          // everything at 0 in this case so let's reproduce this behavior here.\r\n          return { x: 0, y: 0, width: 0, height: 0 };\r\n      }\r\n  };\r\n  var hasValue = function (dict, value) {\r\n      var found = false;\r\n      Object.keys(dict).forEach(function (key) {\r\n          if (dict[key] === value) {\r\n              found = true;\r\n          }\r\n      });\r\n      return found;\r\n  };\r\n  var isArray = function (o) {\r\n      return Array.isArray(o);\r\n  };\r\n  var isDefined = function (v) {\r\n      return typeof v !== 'undefined';\r\n  };\r\n  var isEmpty = function (o) {\r\n      return (typeof o === 'undefined' ||\r\n          o === null ||\r\n          (isString(o) && o.length === 0) ||\r\n          (typeof o === 'object' && Object.keys(o).length === 0));\r\n  };\r\n  var isFunction = function (o) {\r\n      return typeof o === 'function';\r\n  };\r\n  var isNumber = function (o) {\r\n      return typeof o === 'number';\r\n  };\r\n  var isString = function (o) {\r\n      return typeof o === 'string';\r\n  };\r\n  var isUndefined = function (v) {\r\n      return typeof v === 'undefined';\r\n  };\r\n  var isValue = function (v) {\r\n      return v || v === 0;\r\n  };\r\n  var notEmpty = function (o) {\r\n      return !isEmpty(o);\r\n  };\r\n  var sanitise = function (str) {\r\n      return typeof str === 'string'\r\n          ? str.replace(/</g, '&lt;').replace(/>/g, '&gt;')\r\n          : str;\r\n  };\r\n  var flattenArray = function (arr) {\r\n      return Array.isArray(arr) ? [].concat.apply([], arr) : [];\r\n  };\r\n  /**\r\n   * Returns whether the point is within the given box.\r\n   *\r\n   * @param {Array} point An [x,y] coordinate\r\n   * @param {Object} box An object with {x, y, width, height} keys\r\n   * @param {Number} sensitivity An offset to ease check on very small boxes\r\n   */\r\n  var isWithinBox = function (point, box, sensitivity) {\r\n      if (sensitivity === void 0) { sensitivity = 0; }\r\n      var xStart = box.x - sensitivity;\r\n      var xEnd = box.x + box.width + sensitivity;\r\n      var yStart = box.y + box.height + sensitivity;\r\n      var yEnd = box.y - sensitivity;\r\n      return (xStart < point[0] && point[0] < xEnd && yEnd < point[1] && point[1] < yStart);\r\n  };\r\n  /**\r\n   * Returns Internet Explorer version number (or false if no Internet Explorer used).\r\n   *\r\n   * @param string agent Optional parameter to specify user agent\r\n   */\r\n  var getIEVersion = function (agent) {\r\n      // https://stackoverflow.com/questions/19999388/check-if-user-is-using-ie\r\n      if (typeof agent === 'undefined') {\r\n          agent = window.navigator.userAgent;\r\n      }\r\n      var pos = agent.indexOf('MSIE '); // up to IE10\r\n      if (pos > 0) {\r\n          return parseInt(agent.substring(pos + 5, agent.indexOf('.', pos)), 10);\r\n      }\r\n      pos = agent.indexOf('Trident/'); // IE11\r\n      if (pos > 0) {\r\n          pos = agent.indexOf('rv:');\r\n          return parseInt(agent.substring(pos + 3, agent.indexOf('.', pos)), 10);\r\n      }\r\n      return false;\r\n  };\r\n  /**\r\n   * Returns whether the used browser is Internet Explorer.\r\n   *\r\n   * @param version Optional parameter to specify IE version\r\n   */\r\n  var isIE = function (version) {\r\n      var ver = getIEVersion();\r\n      if (typeof version === 'undefined') {\r\n          return !!ver;\r\n      }\r\n      return version === ver;\r\n  };\n\n  function AxisInternal(component, params) {\r\n      var internal = this;\r\n      internal.component = component;\r\n      internal.params = params || {};\r\n      internal.d3 = component.d3;\r\n      internal.scale = internal.d3.scaleLinear();\r\n      internal.range;\r\n      internal.orient = 'bottom';\r\n      internal.innerTickSize = 6;\r\n      internal.outerTickSize = this.params.withOuterTick ? 6 : 0;\r\n      internal.tickPadding = 3;\r\n      internal.tickValues = null;\r\n      internal.tickFormat;\r\n      internal.tickArguments;\r\n      internal.tickOffset = 0;\r\n      internal.tickCulling = true;\r\n      internal.tickCentered;\r\n      internal.tickTextCharSize;\r\n      internal.tickTextRotate = internal.params.tickTextRotate;\r\n      internal.tickLength;\r\n      internal.axis = internal.generateAxis();\r\n  }\r\n  AxisInternal.prototype.axisX = function (selection, x, tickOffset) {\r\n      selection.attr('transform', function (d) {\r\n          return 'translate(' + Math.ceil(x(d) + tickOffset) + ', 0)';\r\n      });\r\n  };\r\n  AxisInternal.prototype.axisY = function (selection, y) {\r\n      selection.attr('transform', function (d) {\r\n          return 'translate(0,' + Math.ceil(y(d)) + ')';\r\n      });\r\n  };\r\n  AxisInternal.prototype.scaleExtent = function (domain) {\r\n      var start = domain[0], stop = domain[domain.length - 1];\r\n      return start < stop ? [start, stop] : [stop, start];\r\n  };\r\n  AxisInternal.prototype.generateTicks = function (scale) {\r\n      var internal = this;\r\n      var i, domain, ticks = [];\r\n      if (scale.ticks) {\r\n          return scale.ticks.apply(scale, internal.tickArguments);\r\n      }\r\n      domain = scale.domain();\r\n      for (i = Math.ceil(domain[0]); i < domain[1]; i++) {\r\n          ticks.push(i);\r\n      }\r\n      if (ticks.length > 0 && ticks[0] > 0) {\r\n          ticks.unshift(ticks[0] - (ticks[1] - ticks[0]));\r\n      }\r\n      return ticks;\r\n  };\r\n  AxisInternal.prototype.copyScale = function () {\r\n      var internal = this;\r\n      var newScale = internal.scale.copy(), domain;\r\n      if (internal.params.isCategory) {\r\n          domain = internal.scale.domain();\r\n          newScale.domain([domain[0], domain[1] - 1]);\r\n      }\r\n      return newScale;\r\n  };\r\n  AxisInternal.prototype.textFormatted = function (v) {\r\n      var internal = this, formatted = internal.tickFormat ? internal.tickFormat(v) : v;\r\n      return typeof formatted !== 'undefined' ? formatted : '';\r\n  };\r\n  AxisInternal.prototype.updateRange = function () {\r\n      var internal = this;\r\n      internal.range = internal.scale.rangeExtent\r\n          ? internal.scale.rangeExtent()\r\n          : internal.scaleExtent(internal.scale.range());\r\n      return internal.range;\r\n  };\r\n  AxisInternal.prototype.updateTickTextCharSize = function (tick) {\r\n      var internal = this;\r\n      if (internal.tickTextCharSize) {\r\n          return internal.tickTextCharSize;\r\n      }\r\n      var size = {\r\n          h: 11.5,\r\n          w: 5.5\r\n      };\r\n      tick\r\n          .select('text')\r\n          .text(function (d) {\r\n          return internal.textFormatted(d);\r\n      })\r\n          .each(function (d) {\r\n          var box = getBBox(this), text = internal.textFormatted(d), h = box.height, w = text ? box.width / text.length : undefined;\r\n          if (h && w) {\r\n              size.h = h;\r\n              size.w = w;\r\n          }\r\n      })\r\n          .text('');\r\n      internal.tickTextCharSize = size;\r\n      return size;\r\n  };\r\n  AxisInternal.prototype.isVertical = function () {\r\n      return this.orient === 'left' || this.orient === 'right';\r\n  };\r\n  AxisInternal.prototype.tspanData = function (d, i, scale) {\r\n      var internal = this;\r\n      var splitted = internal.params.tickMultiline\r\n          ? internal.splitTickText(d, scale)\r\n          : [].concat(internal.textFormatted(d));\r\n      if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) {\r\n          splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax);\r\n      }\r\n      return splitted.map(function (s) {\r\n          return { index: i, splitted: s, length: splitted.length };\r\n      });\r\n  };\r\n  AxisInternal.prototype.splitTickText = function (d, scale) {\r\n      var internal = this, tickText = internal.textFormatted(d), maxWidth = internal.params.tickWidth, subtext, spaceIndex, textWidth, splitted = [];\r\n      if (Object.prototype.toString.call(tickText) === '[object Array]') {\r\n          return tickText;\r\n      }\r\n      if (!maxWidth || maxWidth <= 0) {\r\n          maxWidth = internal.isVertical()\r\n              ? 95\r\n              : internal.params.isCategory\r\n                  ? Math.ceil(scale(1) - scale(0)) - 12\r\n                  : 110;\r\n      }\r\n      function split(splitted, text) {\r\n          spaceIndex = undefined;\r\n          for (var i = 1; i < text.length; i++) {\r\n              if (text.charAt(i) === ' ') {\r\n                  spaceIndex = i;\r\n              }\r\n              subtext = text.substr(0, i + 1);\r\n              textWidth = internal.tickTextCharSize.w * subtext.length;\r\n              // if text width gets over tick width, split by space index or crrent index\r\n              if (maxWidth < textWidth) {\r\n                  return split(splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)), text.slice(spaceIndex ? spaceIndex + 1 : i));\r\n              }\r\n          }\r\n          return splitted.concat(text);\r\n      }\r\n      return split(splitted, tickText + '');\r\n  };\r\n  AxisInternal.prototype.ellipsify = function (splitted, max) {\r\n      if (splitted.length <= max) {\r\n          return splitted;\r\n      }\r\n      var ellipsified = splitted.slice(0, max);\r\n      var remaining = 3;\r\n      for (var i = max - 1; i >= 0; i--) {\r\n          var available = ellipsified[i].length;\r\n          ellipsified[i] = ellipsified[i]\r\n              .substr(0, available - remaining)\r\n              .padEnd(available, '.');\r\n          remaining -= available;\r\n          if (remaining <= 0) {\r\n              break;\r\n          }\r\n      }\r\n      return ellipsified;\r\n  };\r\n  AxisInternal.prototype.updateTickLength = function () {\r\n      var internal = this;\r\n      internal.tickLength =\r\n          Math.max(internal.innerTickSize, 0) + internal.tickPadding;\r\n  };\r\n  AxisInternal.prototype.lineY2 = function (d) {\r\n      var internal = this, tickPosition = internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset);\r\n      return internal.range[0] < tickPosition && tickPosition < internal.range[1]\r\n          ? internal.innerTickSize\r\n          : 0;\r\n  };\r\n  AxisInternal.prototype.textY = function () {\r\n      var internal = this, rotate = internal.tickTextRotate;\r\n      return rotate\r\n          ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1)\r\n          : internal.tickLength;\r\n  };\r\n  AxisInternal.prototype.textTransform = function () {\r\n      var internal = this, rotate = internal.tickTextRotate;\r\n      return rotate ? 'rotate(' + rotate + ')' : '';\r\n  };\r\n  AxisInternal.prototype.textTextAnchor = function () {\r\n      var internal = this, rotate = internal.tickTextRotate;\r\n      return rotate ? (rotate > 0 ? 'start' : 'end') : 'middle';\r\n  };\r\n  AxisInternal.prototype.tspanDx = function () {\r\n      var internal = this, rotate = internal.tickTextRotate;\r\n      return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0;\r\n  };\r\n  AxisInternal.prototype.tspanDy = function (d, i) {\r\n      var internal = this, dy = internal.tickTextCharSize.h;\r\n      if (i === 0) {\r\n          if (internal.isVertical()) {\r\n              dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3);\r\n          }\r\n          else {\r\n              dy = '.71em';\r\n          }\r\n      }\r\n      return dy;\r\n  };\r\n  AxisInternal.prototype.generateAxis = function () {\r\n      var internal = this, d3 = internal.d3, params = internal.params;\r\n      function axis(g, transition) {\r\n          var self;\r\n          g.each(function () {\r\n              var g = (axis.g = d3.select(this));\r\n              var scale0 = this.__chart__ || internal.scale, scale1 = (this.__chart__ = internal.copyScale());\r\n              var ticksValues = internal.tickValues\r\n                  ? internal.tickValues\r\n                  : internal.generateTicks(scale1), ticks = g.selectAll('.tick').data(ticksValues, scale1), tickEnter = ticks\r\n                  .enter()\r\n                  .insert('g', '.domain')\r\n                  .attr('class', 'tick')\r\n                  .style('opacity', 1e-6), \r\n              // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks.\r\n              tickExit = ticks.exit().remove(), tickUpdate = ticks.merge(tickEnter), tickTransform, tickX, tickY;\r\n              if (params.isCategory) {\r\n                  internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);\r\n                  tickX = internal.tickCentered ? 0 : internal.tickOffset;\r\n                  tickY = internal.tickCentered ? internal.tickOffset : 0;\r\n              }\r\n              else {\r\n                  internal.tickOffset = tickX = 0;\r\n              }\r\n              internal.updateRange();\r\n              internal.updateTickLength();\r\n              internal.updateTickTextCharSize(g.select('.tick'));\r\n              var lineUpdate = tickUpdate\r\n                  .select('line')\r\n                  .merge(tickEnter.append('line')), textUpdate = tickUpdate.select('text').merge(tickEnter.append('text'));\r\n              var tspans = tickUpdate\r\n                  .selectAll('text')\r\n                  .selectAll('tspan')\r\n                  .data(function (d, i) {\r\n                  return internal.tspanData(d, i, scale1);\r\n              }), tspanEnter = tspans.enter().append('tspan'), tspanUpdate = tspanEnter.merge(tspans).text(function (d) {\r\n                  return d.splitted;\r\n              });\r\n              tspans.exit().remove();\r\n              var path = g.selectAll('.domain').data([0]), pathUpdate = path\r\n                  .enter()\r\n                  .append('path')\r\n                  .merge(path)\r\n                  .attr('class', 'domain');\r\n              // TODO: each attr should be one function and change its behavior by internal.orient, probably\r\n              switch (internal.orient) {\r\n                  case 'bottom': {\r\n                      tickTransform = internal.axisX;\r\n                      lineUpdate\r\n                          .attr('x1', tickX)\r\n                          .attr('x2', tickX)\r\n                          .attr('y2', function (d, i) {\r\n                          return internal.lineY2(d, i);\r\n                      });\r\n                      textUpdate\r\n                          .attr('x', 0)\r\n                          .attr('y', function (d, i) {\r\n                          return internal.textY(d, i);\r\n                      })\r\n                          .attr('transform', function (d, i) {\r\n                          return internal.textTransform(d, i);\r\n                      })\r\n                          .style('text-anchor', function (d, i) {\r\n                          return internal.textTextAnchor(d, i);\r\n                      });\r\n                      tspanUpdate\r\n                          .attr('x', 0)\r\n                          .attr('dy', function (d, i) {\r\n                          return internal.tspanDy(d, i);\r\n                      })\r\n                          .attr('dx', function (d, i) {\r\n                          return internal.tspanDx(d, i);\r\n                      });\r\n                      pathUpdate.attr('d', 'M' +\r\n                          internal.range[0] +\r\n                          ',' +\r\n                          internal.outerTickSize +\r\n                          'V0H' +\r\n                          internal.range[1] +\r\n                          'V' +\r\n                          internal.outerTickSize);\r\n                      break;\r\n                  }\r\n                  case 'top': {\r\n                      // TODO: rotated tick text\r\n                      tickTransform = internal.axisX;\r\n                      lineUpdate\r\n                          .attr('x1', tickX)\r\n                          .attr('x2', tickX)\r\n                          .attr('y2', function (d, i) {\r\n                          return -1 * internal.lineY2(d, i);\r\n                      });\r\n                      textUpdate\r\n                          .attr('x', 0)\r\n                          .attr('y', function (d, i) {\r\n                          return (-1 * internal.textY(d, i) -\r\n                              (params.isCategory ? 2 : internal.tickLength - 2));\r\n                      })\r\n                          .attr('transform', function (d, i) {\r\n                          return internal.textTransform(d, i);\r\n                      })\r\n                          .style('text-anchor', function (d, i) {\r\n                          return internal.textTextAnchor(d, i);\r\n                      });\r\n                      tspanUpdate\r\n                          .attr('x', 0)\r\n                          .attr('dy', function (d, i) {\r\n                          return internal.tspanDy(d, i);\r\n                      })\r\n                          .attr('dx', function (d, i) {\r\n                          return internal.tspanDx(d, i);\r\n                      });\r\n                      pathUpdate.attr('d', 'M' +\r\n                          internal.range[0] +\r\n                          ',' +\r\n                          -internal.outerTickSize +\r\n                          'V0H' +\r\n                          internal.range[1] +\r\n                          'V' +\r\n                          -internal.outerTickSize);\r\n                      break;\r\n                  }\r\n                  case 'left': {\r\n                      tickTransform = internal.axisY;\r\n                      lineUpdate\r\n                          .attr('x2', -internal.innerTickSize)\r\n                          .attr('y1', tickY)\r\n                          .attr('y2', tickY);\r\n                      textUpdate\r\n                          .attr('x', -internal.tickLength)\r\n                          .attr('y', internal.tickOffset)\r\n                          .style('text-anchor', 'end');\r\n                      tspanUpdate\r\n                          .attr('x', -internal.tickLength)\r\n                          .attr('dy', function (d, i) {\r\n                          return internal.tspanDy(d, i);\r\n                      });\r\n                      pathUpdate.attr('d', 'M' +\r\n                          -internal.outerTickSize +\r\n                          ',' +\r\n                          internal.range[0] +\r\n                          'H0V' +\r\n                          internal.range[1] +\r\n                          'H' +\r\n                          -internal.outerTickSize);\r\n                      break;\r\n                  }\r\n                  case 'right': {\r\n                      tickTransform = internal.axisY;\r\n                      lineUpdate\r\n                          .attr('x2', internal.innerTickSize)\r\n                          .attr('y1', tickY)\r\n                          .attr('y2', tickY);\r\n                      textUpdate\r\n                          .attr('x', internal.tickLength)\r\n                          .attr('y', internal.tickOffset)\r\n                          .style('text-anchor', 'start');\r\n                      tspanUpdate.attr('x', internal.tickLength).attr('dy', function (d, i) {\r\n                          return internal.tspanDy(d, i);\r\n                      });\r\n                      pathUpdate.attr('d', 'M' +\r\n                          internal.outerTickSize +\r\n                          ',' +\r\n                          internal.range[0] +\r\n                          'H0V' +\r\n                          internal.range[1] +\r\n                          'H' +\r\n                          internal.outerTickSize);\r\n                      break;\r\n                  }\r\n              }\r\n              if (scale1.rangeBand) {\r\n                  var x = scale1, dx = x.rangeBand() / 2;\r\n                  scale0 = scale1 = function (d) {\r\n                      return x(d) + dx;\r\n                  };\r\n              }\r\n              else if (scale0.rangeBand) {\r\n                  scale0 = scale1;\r\n              }\r\n              else {\r\n                  tickExit.call(tickTransform, scale1, internal.tickOffset);\r\n              }\r\n              tickEnter.call(tickTransform, scale0, internal.tickOffset);\r\n              self = (transition ? tickUpdate.transition(transition) : tickUpdate)\r\n                  .style('opacity', 1)\r\n                  .call(tickTransform, scale1, internal.tickOffset);\r\n          });\r\n          return self;\r\n      }\r\n      axis.scale = function (x) {\r\n          if (!arguments.length) {\r\n              return internal.scale;\r\n          }\r\n          internal.scale = x;\r\n          return axis;\r\n      };\r\n      axis.orient = function (x) {\r\n          if (!arguments.length) {\r\n              return internal.orient;\r\n          }\r\n          internal.orient =\r\n              x in { top: 1, right: 1, bottom: 1, left: 1 } ? x + '' : 'bottom';\r\n          return axis;\r\n      };\r\n      axis.tickFormat = function (format) {\r\n          if (!arguments.length) {\r\n              return internal.tickFormat;\r\n          }\r\n          internal.tickFormat = format;\r\n          return axis;\r\n      };\r\n      axis.tickCentered = function (isCentered) {\r\n          if (!arguments.length) {\r\n              return internal.tickCentered;\r\n          }\r\n          internal.tickCentered = isCentered;\r\n          return axis;\r\n      };\r\n      axis.tickOffset = function () {\r\n          return internal.tickOffset;\r\n      };\r\n      axis.tickInterval = function () {\r\n          var interval, length;\r\n          if (params.isCategory) {\r\n              interval = internal.tickOffset * 2;\r\n          }\r\n          else {\r\n              length =\r\n                  axis.g\r\n                      .select('path.domain')\r\n                      .node()\r\n                      .getTotalLength() -\r\n                      internal.outerTickSize * 2;\r\n              interval = length / axis.g.selectAll('line').size();\r\n          }\r\n          return interval === Infinity ? 0 : interval;\r\n      };\r\n      axis.ticks = function () {\r\n          if (!arguments.length) {\r\n              return internal.tickArguments;\r\n          }\r\n          internal.tickArguments = arguments;\r\n          return axis;\r\n      };\r\n      axis.tickCulling = function (culling) {\r\n          if (!arguments.length) {\r\n              return internal.tickCulling;\r\n          }\r\n          internal.tickCulling = culling;\r\n          return axis;\r\n      };\r\n      axis.tickValues = function (x) {\r\n          if (typeof x === 'function') {\r\n              internal.tickValues = function () {\r\n                  return x(internal.scale.domain());\r\n              };\r\n          }\r\n          else {\r\n              if (!arguments.length) {\r\n                  return internal.tickValues;\r\n              }\r\n              internal.tickValues = x;\r\n          }\r\n          return axis;\r\n      };\r\n      return axis;\r\n  };\n\n  var CLASS = {\r\n      target: 'c3-target',\r\n      chart: 'c3-chart',\r\n      chartLine: 'c3-chart-line',\r\n      chartLines: 'c3-chart-lines',\r\n      chartBar: 'c3-chart-bar',\r\n      chartBars: 'c3-chart-bars',\r\n      chartText: 'c3-chart-text',\r\n      chartTexts: 'c3-chart-texts',\r\n      chartArc: 'c3-chart-arc',\r\n      chartArcs: 'c3-chart-arcs',\r\n      chartArcsTitle: 'c3-chart-arcs-title',\r\n      chartArcsBackground: 'c3-chart-arcs-background',\r\n      chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit',\r\n      chartArcsGaugeMax: 'c3-chart-arcs-gauge-max',\r\n      chartArcsGaugeMin: 'c3-chart-arcs-gauge-min',\r\n      selectedCircle: 'c3-selected-circle',\r\n      selectedCircles: 'c3-selected-circles',\r\n      eventRect: 'c3-event-rect',\r\n      eventRects: 'c3-event-rects',\r\n      eventRectsSingle: 'c3-event-rects-single',\r\n      eventRectsMultiple: 'c3-event-rects-multiple',\r\n      zoomRect: 'c3-zoom-rect',\r\n      brush: 'c3-brush',\r\n      dragZoom: 'c3-drag-zoom',\r\n      focused: 'c3-focused',\r\n      defocused: 'c3-defocused',\r\n      region: 'c3-region',\r\n      regions: 'c3-regions',\r\n      title: 'c3-title',\r\n      tooltipContainer: 'c3-tooltip-container',\r\n      tooltip: 'c3-tooltip',\r\n      tooltipName: 'c3-tooltip-name',\r\n      shape: 'c3-shape',\r\n      shapes: 'c3-shapes',\r\n      line: 'c3-line',\r\n      lines: 'c3-lines',\r\n      bar: 'c3-bar',\r\n      bars: 'c3-bars',\r\n      circle: 'c3-circle',\r\n      circles: 'c3-circles',\r\n      arc: 'c3-arc',\r\n      arcLabelLine: 'c3-arc-label-line',\r\n      arcs: 'c3-arcs',\r\n      area: 'c3-area',\r\n      areas: 'c3-areas',\r\n      empty: 'c3-empty',\r\n      text: 'c3-text',\r\n      texts: 'c3-texts',\r\n      gaugeValue: 'c3-gauge-value',\r\n      grid: 'c3-grid',\r\n      gridLines: 'c3-grid-lines',\r\n      xgrid: 'c3-xgrid',\r\n      xgrids: 'c3-xgrids',\r\n      xgridLine: 'c3-xgrid-line',\r\n      xgridLines: 'c3-xgrid-lines',\r\n      xgridFocus: 'c3-xgrid-focus',\r\n      ygrid: 'c3-ygrid',\r\n      ygrids: 'c3-ygrids',\r\n      ygridLine: 'c3-ygrid-line',\r\n      ygridLines: 'c3-ygrid-lines',\r\n      colorScale: 'c3-colorscale',\r\n      stanfordElements: 'c3-stanford-elements',\r\n      stanfordLine: 'c3-stanford-line',\r\n      stanfordLines: 'c3-stanford-lines',\r\n      stanfordRegion: 'c3-stanford-region',\r\n      stanfordRegions: 'c3-stanford-regions',\r\n      stanfordText: 'c3-stanford-text',\r\n      stanfordTexts: 'c3-stanford-texts',\r\n      axis: 'c3-axis',\r\n      axisX: 'c3-axis-x',\r\n      axisXLabel: 'c3-axis-x-label',\r\n      axisY: 'c3-axis-y',\r\n      axisYLabel: 'c3-axis-y-label',\r\n      axisY2: 'c3-axis-y2',\r\n      axisY2Label: 'c3-axis-y2-label',\r\n      legendBackground: 'c3-legend-background',\r\n      legendItem: 'c3-legend-item',\r\n      legendItemEvent: 'c3-legend-item-event',\r\n      legendItemTile: 'c3-legend-item-tile',\r\n      legendItemHidden: 'c3-legend-item-hidden',\r\n      legendItemFocused: 'c3-legend-item-focused',\r\n      dragarea: 'c3-dragarea',\r\n      EXPANDED: '_expanded_',\r\n      SELECTED: '_selected_',\r\n      INCLUDED: '_included_'\r\n  };\n\n  var AxisClass = /** @class */ (function () {\r\n      function AxisClass(owner) {\r\n          this.owner = owner;\r\n          this.d3 = owner.d3;\r\n          this.internal = AxisInternal;\r\n      }\r\n      return AxisClass;\r\n  }());\r\n  var Axis = AxisClass;\r\n  Axis.prototype.init = function init() {\r\n      var $$ = this.owner, config = $$.config, main = $$.main;\r\n      $$.axes.x = main\r\n          .append('g')\r\n          .attr('class', CLASS.axis + ' ' + CLASS.axisX)\r\n          .attr('clip-path', config.axis_x_inner ? '' : $$.clipPathForXAxis)\r\n          .attr('transform', $$.getTranslate('x'))\r\n          .style('visibility', config.axis_x_show ? 'visible' : 'hidden');\r\n      $$.axes.x\r\n          .append('text')\r\n          .attr('class', CLASS.axisXLabel)\r\n          .attr('transform', config.axis_rotated ? 'rotate(-90)' : '')\r\n          .style('text-anchor', this.textAnchorForXAxisLabel.bind(this));\r\n      $$.axes.y = main\r\n          .append('g')\r\n          .attr('class', CLASS.axis + ' ' + CLASS.axisY)\r\n          .attr('clip-path', config.axis_y_inner ? '' : $$.clipPathForYAxis)\r\n          .attr('transform', $$.getTranslate('y'))\r\n          .style('visibility', config.axis_y_show ? 'visible' : 'hidden');\r\n      $$.axes.y\r\n          .append('text')\r\n          .attr('class', CLASS.axisYLabel)\r\n          .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\r\n          .style('text-anchor', this.textAnchorForYAxisLabel.bind(this));\r\n      $$.axes.y2 = main\r\n          .append('g')\r\n          .attr('class', CLASS.axis + ' ' + CLASS.axisY2)\r\n          // clip-path?\r\n          .attr('transform', $$.getTranslate('y2'))\r\n          .style('visibility', config.axis_y2_show ? 'visible' : 'hidden');\r\n      $$.axes.y2\r\n          .append('text')\r\n          .attr('class', CLASS.axisY2Label)\r\n          .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\r\n          .style('text-anchor', this.textAnchorForY2AxisLabel.bind(this));\r\n  };\r\n  Axis.prototype.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {\r\n      var $$ = this.owner, config = $$.config, axisParams = {\r\n          isCategory: $$.isCategorized(),\r\n          withOuterTick: withOuterTick,\r\n          tickMultiline: config.axis_x_tick_multiline,\r\n          tickMultilineMax: config.axis_x_tick_multiline\r\n              ? Number(config.axis_x_tick_multilineMax)\r\n              : 0,\r\n          tickWidth: config.axis_x_tick_width,\r\n          tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate,\r\n          withoutTransition: withoutTransition\r\n      }, axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient);\r\n      if ($$.isTimeSeries() && tickValues && typeof tickValues !== 'function') {\r\n          tickValues = tickValues.map(function (v) {\r\n              return $$.parseDate(v);\r\n          });\r\n      }\r\n      // Set tick\r\n      axis.tickFormat(tickFormat).tickValues(tickValues);\r\n      if ($$.isCategorized()) {\r\n          axis.tickCentered(config.axis_x_tick_centered);\r\n          if (isEmpty(config.axis_x_tick_culling)) {\r\n              config.axis_x_tick_culling = false;\r\n          }\r\n      }\r\n      return axis;\r\n  };\r\n  Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues(targets, axis) {\r\n      var $$ = this.owner, config = $$.config, tickValues;\r\n      if (config.axis_x_tick_fit || config.axis_x_tick_count) {\r\n          tickValues = this.generateTickValues($$.mapTargetsToUniqueXs(targets), config.axis_x_tick_count, $$.isTimeSeries());\r\n      }\r\n      if (axis) {\r\n          axis.tickValues(tickValues);\r\n      }\r\n      else {\r\n          $$.xAxis.tickValues(tickValues);\r\n          $$.subXAxis.tickValues(tickValues);\r\n      }\r\n      return tickValues;\r\n  };\r\n  Axis.prototype.getYAxis = function getYAxis(axisId, scale, orient, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {\r\n      var $$ = this.owner;\r\n      var config = $$.config;\r\n      var tickFormat = config[\"axis_\" + axisId + \"_tick_format\"];\r\n      if (!tickFormat && $$.isAxisNormalized(axisId)) {\r\n          tickFormat = function (x) { return x + \"%\"; };\r\n      }\r\n      var axis = new this.internal(this, {\r\n          withOuterTick: withOuterTick,\r\n          withoutTransition: withoutTransition,\r\n          tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate\r\n      }).axis\r\n          .scale(scale)\r\n          .orient(orient);\r\n      if (tickFormat) {\r\n          axis.tickFormat(tickFormat);\r\n      }\r\n      if ($$.isTimeSeriesY()) {\r\n          axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval);\r\n      }\r\n      else {\r\n          axis.tickValues(tickValues);\r\n      }\r\n      return axis;\r\n  };\r\n  Axis.prototype.getId = function getId(id) {\r\n      var config = this.owner.config;\r\n      return id in config.data_axes ? config.data_axes[id] : 'y';\r\n  };\r\n  Axis.prototype.getXAxisTickFormat = function getXAxisTickFormat() {\r\n      // #2251 previously set any negative values to a whole number,\r\n      // however both should be truncated according to the users format specification\r\n      var $$ = this.owner, config = $$.config;\r\n      var format = $$.isTimeSeries()\r\n          ? $$.defaultAxisTimeFormat\r\n          : $$.isCategorized()\r\n              ? $$.categoryName\r\n              : function (v) {\r\n                  return v;\r\n              };\r\n      if (config.axis_x_tick_format) {\r\n          if (isFunction(config.axis_x_tick_format)) {\r\n              format = config.axis_x_tick_format;\r\n          }\r\n          else if ($$.isTimeSeries()) {\r\n              format = function (date) {\r\n                  return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : '';\r\n              };\r\n          }\r\n      }\r\n      return isFunction(format)\r\n          ? function (v) {\r\n              return format.call($$, v);\r\n          }\r\n          : format;\r\n  };\r\n  Axis.prototype.getTickValues = function getTickValues(tickValues, axis) {\r\n      return tickValues ? tickValues : axis ? axis.tickValues() : undefined;\r\n  };\r\n  Axis.prototype.getXAxisTickValues = function getXAxisTickValues() {\r\n      return this.getTickValues(this.owner.config.axis_x_tick_values, this.owner.xAxis);\r\n  };\r\n  Axis.prototype.getYAxisTickValues = function getYAxisTickValues() {\r\n      return this.getTickValues(this.owner.config.axis_y_tick_values, this.owner.yAxis);\r\n  };\r\n  Axis.prototype.getY2AxisTickValues = function getY2AxisTickValues() {\r\n      return this.getTickValues(this.owner.config.axis_y2_tick_values, this.owner.y2Axis);\r\n  };\r\n  Axis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(axisId) {\r\n      var $$ = this.owner, config = $$.config, option;\r\n      if (axisId === 'y') {\r\n          option = config.axis_y_label;\r\n      }\r\n      else if (axisId === 'y2') {\r\n          option = config.axis_y2_label;\r\n      }\r\n      else if (axisId === 'x') {\r\n          option = config.axis_x_label;\r\n      }\r\n      return option;\r\n  };\r\n  Axis.prototype.getLabelText = function getLabelText(axisId) {\r\n      var option = this.getLabelOptionByAxisId(axisId);\r\n      return isString(option) ? option : option ? option.text : null;\r\n  };\r\n  Axis.prototype.setLabelText = function setLabelText(axisId, text) {\r\n      var $$ = this.owner, config = $$.config, option = this.getLabelOptionByAxisId(axisId);\r\n      if (isString(option)) {\r\n          if (axisId === 'y') {\r\n              config.axis_y_label = text;\r\n          }\r\n          else if (axisId === 'y2') {\r\n              config.axis_y2_label = text;\r\n          }\r\n          else if (axisId === 'x') {\r\n              config.axis_x_label = text;\r\n          }\r\n      }\r\n      else if (option) {\r\n          option.text = text;\r\n      }\r\n  };\r\n  Axis.prototype.getLabelPosition = function getLabelPosition(axisId, defaultPosition) {\r\n      var option = this.getLabelOptionByAxisId(axisId), position = option && typeof option === 'object' && option.position\r\n          ? option.position\r\n          : defaultPosition;\r\n      return {\r\n          isInner: position.indexOf('inner') >= 0,\r\n          isOuter: position.indexOf('outer') >= 0,\r\n          isLeft: position.indexOf('left') >= 0,\r\n          isCenter: position.indexOf('center') >= 0,\r\n          isRight: position.indexOf('right') >= 0,\r\n          isTop: position.indexOf('top') >= 0,\r\n          isMiddle: position.indexOf('middle') >= 0,\r\n          isBottom: position.indexOf('bottom') >= 0\r\n      };\r\n  };\r\n  Axis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() {\r\n      return this.getLabelPosition('x', this.owner.config.axis_rotated ? 'inner-top' : 'inner-right');\r\n  };\r\n  Axis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() {\r\n      return this.getLabelPosition('y', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');\r\n  };\r\n  Axis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() {\r\n      return this.getLabelPosition('y2', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');\r\n  };\r\n  Axis.prototype.getLabelPositionById = function getLabelPositionById(id) {\r\n      return id === 'y2'\r\n          ? this.getY2AxisLabelPosition()\r\n          : id === 'y'\r\n              ? this.getYAxisLabelPosition()\r\n              : this.getXAxisLabelPosition();\r\n  };\r\n  Axis.prototype.textForXAxisLabel = function textForXAxisLabel() {\r\n      return this.getLabelText('x');\r\n  };\r\n  Axis.prototype.textForYAxisLabel = function textForYAxisLabel() {\r\n      return this.getLabelText('y');\r\n  };\r\n  Axis.prototype.textForY2AxisLabel = function textForY2AxisLabel() {\r\n      return this.getLabelText('y2');\r\n  };\r\n  Axis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) {\r\n      var $$ = this.owner;\r\n      if (forHorizontal) {\r\n          return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width;\r\n      }\r\n      else {\r\n          return position.isBottom\r\n              ? -$$.height\r\n              : position.isMiddle\r\n                  ? -$$.height / 2\r\n                  : 0;\r\n      }\r\n  };\r\n  Axis.prototype.dxForAxisLabel = function dxForAxisLabel(forHorizontal, position) {\r\n      if (forHorizontal) {\r\n          return position.isLeft ? '0.5em' : position.isRight ? '-0.5em' : '0';\r\n      }\r\n      else {\r\n          return position.isTop ? '-0.5em' : position.isBottom ? '0.5em' : '0';\r\n      }\r\n  };\r\n  Axis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(forHorizontal, position) {\r\n      if (forHorizontal) {\r\n          return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end';\r\n      }\r\n      else {\r\n          return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end';\r\n      }\r\n  };\r\n  Axis.prototype.xForXAxisLabel = function xForXAxisLabel() {\r\n      return this.xForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());\r\n  };\r\n  Axis.prototype.xForYAxisLabel = function xForYAxisLabel() {\r\n      return this.xForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());\r\n  };\r\n  Axis.prototype.xForY2AxisLabel = function xForY2AxisLabel() {\r\n      return this.xForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());\r\n  };\r\n  Axis.prototype.dxForXAxisLabel = function dxForXAxisLabel() {\r\n      return this.dxForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());\r\n  };\r\n  Axis.prototype.dxForYAxisLabel = function dxForYAxisLabel() {\r\n      return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());\r\n  };\r\n  Axis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() {\r\n      return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());\r\n  };\r\n  Axis.prototype.dyForXAxisLabel = function dyForXAxisLabel() {\r\n      var $$ = this.owner, config = $$.config, position = this.getXAxisLabelPosition();\r\n      if (config.axis_rotated) {\r\n          return position.isInner\r\n              ? '1.2em'\r\n              : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x'));\r\n      }\r\n      else {\r\n          return position.isInner ? '-0.5em' : $$.getHorizontalAxisHeight('x') - 10;\r\n      }\r\n  };\r\n  Axis.prototype.dyForYAxisLabel = function dyForYAxisLabel() {\r\n      var $$ = this.owner, position = this.getYAxisLabelPosition();\r\n      if ($$.config.axis_rotated) {\r\n          return position.isInner ? '-0.5em' : '3em';\r\n      }\r\n      else {\r\n          return position.isInner\r\n              ? '1.2em'\r\n              : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10);\r\n      }\r\n  };\r\n  Axis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() {\r\n      var $$ = this.owner, position = this.getY2AxisLabelPosition();\r\n      if ($$.config.axis_rotated) {\r\n          return position.isInner ? '1.2em' : '-2.2em';\r\n      }\r\n      else {\r\n          return position.isInner\r\n              ? '-0.5em'\r\n              : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15);\r\n      }\r\n  };\r\n  Axis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() {\r\n      var $$ = this.owner;\r\n      return this.textAnchorForAxisLabel(!$$.config.axis_rotated, this.getXAxisLabelPosition());\r\n  };\r\n  Axis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() {\r\n      var $$ = this.owner;\r\n      return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getYAxisLabelPosition());\r\n  };\r\n  Axis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() {\r\n      var $$ = this.owner;\r\n      return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getY2AxisLabelPosition());\r\n  };\r\n  Axis.prototype.getMaxTickWidth = function getMaxTickWidth(id, withoutRecompute) {\r\n      var $$ = this.owner, maxWidth = 0, targetsToShow, scale, axis, dummy, svg;\r\n      if (withoutRecompute && $$.currentMaxTickWidths[id]) {\r\n          return $$.currentMaxTickWidths[id];\r\n      }\r\n      if ($$.svg) {\r\n          targetsToShow = $$.filterTargetsToShow($$.data.targets);\r\n          if (id === 'y') {\r\n              scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));\r\n              axis = this.getYAxis(id, scale, $$.yOrient, $$.yAxisTickValues, false, true, true);\r\n          }\r\n          else if (id === 'y2') {\r\n              scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));\r\n              axis = this.getYAxis(id, scale, $$.y2Orient, $$.y2AxisTickValues, false, true, true);\r\n          }\r\n          else {\r\n              scale = $$.x.copy().domain($$.getXDomain(targetsToShow));\r\n              axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true);\r\n              this.updateXAxisTickValues(targetsToShow, axis);\r\n          }\r\n          dummy = $$.d3\r\n              .select('body')\r\n              .append('div')\r\n              .classed('c3', true);\r\n          (svg = dummy\r\n              .append('svg')\r\n              .style('visibility', 'hidden')\r\n              .style('position', 'fixed')\r\n              .style('top', 0)\r\n              .style('left', 0)),\r\n              svg\r\n                  .append('g')\r\n                  .call(axis)\r\n                  .each(function () {\r\n                  $$.d3\r\n                      .select(this)\r\n                      .selectAll('text')\r\n                      .each(function () {\r\n                      var box = getBBox(this);\r\n                      if (maxWidth < box.width) {\r\n                          maxWidth = box.width;\r\n                      }\r\n                  });\r\n                  dummy.remove();\r\n              });\r\n      }\r\n      $$.currentMaxTickWidths[id] =\r\n          maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth;\r\n      return $$.currentMaxTickWidths[id];\r\n  };\r\n  Axis.prototype.updateLabels = function updateLabels(withTransition) {\r\n      var $$ = this.owner;\r\n      var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel), axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel), axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label);\r\n      (withTransition ? axisXLabel.transition() : axisXLabel)\r\n          .attr('x', this.xForXAxisLabel.bind(this))\r\n          .attr('dx', this.dxForXAxisLabel.bind(this))\r\n          .attr('dy', this.dyForXAxisLabel.bind(this))\r\n          .text(this.textForXAxisLabel.bind(this));\r\n      (withTransition ? axisYLabel.transition() : axisYLabel)\r\n          .attr('x', this.xForYAxisLabel.bind(this))\r\n          .attr('dx', this.dxForYAxisLabel.bind(this))\r\n          .attr('dy', this.dyForYAxisLabel.bind(this))\r\n          .text(this.textForYAxisLabel.bind(this));\r\n      (withTransition ? axisY2Label.transition() : axisY2Label)\r\n          .attr('x', this.xForY2AxisLabel.bind(this))\r\n          .attr('dx', this.dxForY2AxisLabel.bind(this))\r\n          .attr('dy', this.dyForY2AxisLabel.bind(this))\r\n          .text(this.textForY2AxisLabel.bind(this));\r\n  };\r\n  Axis.prototype.getPadding = function getPadding(padding, key, defaultValue, domainLength) {\r\n      var p = typeof padding === 'number' ? padding : padding[key];\r\n      if (!isValue(p)) {\r\n          return defaultValue;\r\n      }\r\n      if (padding.unit === 'ratio') {\r\n          return padding[key] * domainLength;\r\n      }\r\n      // assume padding is pixels if unit is not specified\r\n      return this.convertPixelsToAxisPadding(p, domainLength);\r\n  };\r\n  Axis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(pixels, domainLength) {\r\n      var $$ = this.owner, length = $$.config.axis_rotated ? $$.width : $$.height;\r\n      return domainLength * (pixels / length);\r\n  };\r\n  Axis.prototype.generateTickValues = function generateTickValues(values, tickCount, forTimeSeries) {\r\n      var tickValues = values, targetCount, start, end, count, interval, i, tickValue;\r\n      if (tickCount) {\r\n          targetCount = isFunction(tickCount) ? tickCount() : tickCount;\r\n          // compute ticks according to tickCount\r\n          if (targetCount === 1) {\r\n              tickValues = [values[0]];\r\n          }\r\n          else if (targetCount === 2) {\r\n              tickValues = [values[0], values[values.length - 1]];\r\n          }\r\n          else if (targetCount > 2) {\r\n              count = targetCount - 2;\r\n              start = values[0];\r\n              end = values[values.length - 1];\r\n              interval = (end - start) / (count + 1);\r\n              // re-construct unique values\r\n              tickValues = [start];\r\n              for (i = 0; i < count; i++) {\r\n                  tickValue = +start + interval * (i + 1);\r\n                  tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue);\r\n              }\r\n              tickValues.push(end);\r\n          }\r\n      }\r\n      if (!forTimeSeries) {\r\n          tickValues = tickValues.sort(function (a, b) {\r\n              return a - b;\r\n          });\r\n      }\r\n      return tickValues;\r\n  };\r\n  Axis.prototype.generateTransitions = function generateTransitions(duration) {\r\n      var $$ = this.owner, axes = $$.axes;\r\n      return {\r\n          axisX: duration ? axes.x.transition().duration(duration) : axes.x,\r\n          axisY: duration ? axes.y.transition().duration(duration) : axes.y,\r\n          axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2,\r\n          axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx\r\n      };\r\n  };\r\n  Axis.prototype.redraw = function redraw(duration, isHidden) {\r\n      var $$ = this.owner, transition = duration ? $$.d3.transition().duration(duration) : null;\r\n      $$.axes.x.style('opacity', isHidden ? 0 : 1).call($$.xAxis, transition);\r\n      $$.axes.y.style('opacity', isHidden ? 0 : 1).call($$.yAxis, transition);\r\n      $$.axes.y2.style('opacity', isHidden ? 0 : 1).call($$.y2Axis, transition);\r\n      $$.axes.subx.style('opacity', isHidden ? 0 : 1).call($$.subXAxis, transition);\r\n  };\n\n  var c3 = {\r\n      version: '0.7.20',\r\n      chart: {\r\n          fn: Chart.prototype,\r\n          internal: {\r\n              fn: ChartInternal.prototype,\r\n              axis: {\r\n                  fn: AxisClass.prototype,\r\n                  internal: {\r\n                      fn: AxisInternal.prototype\r\n                  }\r\n              }\r\n          }\r\n      },\r\n      generate: function (config) {\r\n          return new Chart(config);\r\n      }\r\n  };\r\n  ChartInternal.prototype.beforeInit = function () {\r\n      // can do something\r\n  };\r\n  ChartInternal.prototype.afterInit = function () {\r\n      // can do something\r\n  };\r\n  ChartInternal.prototype.init = function () {\r\n      var $$ = this, config = $$.config;\r\n      $$.initParams();\r\n      if (config.data_url) {\r\n          $$.convertUrlToData(config.data_url, config.data_mimeType, config.data_headers, config.data_keys, $$.initWithData);\r\n      }\r\n      else if (config.data_json) {\r\n          $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));\r\n      }\r\n      else if (config.data_rows) {\r\n          $$.initWithData($$.convertRowsToData(config.data_rows));\r\n      }\r\n      else if (config.data_columns) {\r\n          $$.initWithData($$.convertColumnsToData(config.data_columns));\r\n      }\r\n      else {\r\n          throw Error('url or json or rows or columns is required.');\r\n      }\r\n  };\r\n  ChartInternal.prototype.initParams = function () {\r\n      var $$ = this, d3 = $$.d3, config = $$.config;\r\n      // MEMO: clipId needs to be unique because it conflicts when multiple charts exist\r\n      $$.clipId = 'c3-' + new Date().valueOf() + '-clip';\r\n      $$.clipIdForXAxis = $$.clipId + '-xaxis';\r\n      $$.clipIdForYAxis = $$.clipId + '-yaxis';\r\n      $$.clipIdForGrid = $$.clipId + '-grid';\r\n      $$.clipIdForSubchart = $$.clipId + '-subchart';\r\n      $$.clipPath = $$.getClipPath($$.clipId);\r\n      $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis);\r\n      $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis);\r\n      $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid);\r\n      $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart);\r\n      $$.dragStart = null;\r\n      $$.dragging = false;\r\n      $$.flowing = false;\r\n      $$.cancelClick = false;\r\n      $$.mouseover = undefined;\r\n      $$.transiting = false;\r\n      $$.color = $$.generateColor();\r\n      $$.levelColor = $$.generateLevelColor();\r\n      $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)($$.config.data_xFormat);\r\n      $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat;\r\n      $$.defaultAxisTimeFormat = function (date) {\r\n          if (date.getMilliseconds()) {\r\n              return d3.timeFormat('.%L')(date);\r\n          }\r\n          if (date.getSeconds()) {\r\n              return d3.timeFormat(':%S')(date);\r\n          }\r\n          if (date.getMinutes()) {\r\n              return d3.timeFormat('%I:%M')(date);\r\n          }\r\n          if (date.getHours()) {\r\n              return d3.timeFormat('%I %p')(date);\r\n          }\r\n          if (date.getDay() && date.getDate() !== 1) {\r\n              return d3.timeFormat('%-m/%-d')(date);\r\n          }\r\n          if (date.getDate() !== 1) {\r\n              return d3.timeFormat('%-m/%-d')(date);\r\n          }\r\n          if (date.getMonth()) {\r\n              return d3.timeFormat('%-m/%-d')(date);\r\n          }\r\n          return d3.timeFormat('%Y/%-m/%-d')(date);\r\n      };\r\n      $$.hiddenTargetIds = [];\r\n      $$.hiddenLegendIds = [];\r\n      $$.focusedTargetIds = [];\r\n      $$.defocusedTargetIds = [];\r\n      $$.xOrient = config.axis_rotated\r\n          ? config.axis_x_inner\r\n              ? 'right'\r\n              : 'left'\r\n          : config.axis_x_inner\r\n              ? 'top'\r\n              : 'bottom';\r\n      $$.yOrient = config.axis_rotated\r\n          ? config.axis_y_inner\r\n              ? 'top'\r\n              : 'bottom'\r\n          : config.axis_y_inner\r\n              ? 'right'\r\n              : 'left';\r\n      $$.y2Orient = config.axis_rotated\r\n          ? config.axis_y2_inner\r\n              ? 'bottom'\r\n              : 'top'\r\n          : config.axis_y2_inner\r\n              ? 'left'\r\n              : 'right';\r\n      $$.subXOrient = config.axis_rotated ? 'left' : 'bottom';\r\n      $$.isLegendRight = config.legend_position === 'right';\r\n      $$.isLegendInset = config.legend_position === 'inset';\r\n      $$.isLegendTop =\r\n          config.legend_inset_anchor === 'top-left' ||\r\n              config.legend_inset_anchor === 'top-right';\r\n      $$.isLegendLeft =\r\n          config.legend_inset_anchor === 'top-left' ||\r\n              config.legend_inset_anchor === 'bottom-left';\r\n      $$.legendStep = 0;\r\n      $$.legendItemWidth = 0;\r\n      $$.legendItemHeight = 0;\r\n      $$.currentMaxTickWidths = {\r\n          x: 0,\r\n          y: 0,\r\n          y2: 0\r\n      };\r\n      $$.rotated_padding_left = 30;\r\n      $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30;\r\n      $$.rotated_padding_top = 5;\r\n      $$.withoutFadeIn = {};\r\n      $$.intervalForObserveInserted = undefined;\r\n      $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js\r\n  };\r\n  ChartInternal.prototype.initChartElements = function () {\r\n      if (this.initBar) {\r\n          this.initBar();\r\n      }\r\n      if (this.initLine) {\r\n          this.initLine();\r\n      }\r\n      if (this.initArc) {\r\n          this.initArc();\r\n      }\r\n      if (this.initGauge) {\r\n          this.initGauge();\r\n      }\r\n      if (this.initText) {\r\n          this.initText();\r\n      }\r\n  };\r\n  ChartInternal.prototype.initWithData = function (data) {\r\n      var $$ = this, d3 = $$.d3, config = $$.config;\r\n      var defs, main, binding = true;\r\n      $$.axis = new AxisClass($$);\r\n      if (!config.bindto) {\r\n          $$.selectChart = d3.selectAll([]);\r\n      }\r\n      else if (typeof config.bindto.node === 'function') {\r\n          $$.selectChart = config.bindto;\r\n      }\r\n      else {\r\n          $$.selectChart = d3.select(config.bindto);\r\n      }\r\n      if ($$.selectChart.empty()) {\r\n          $$.selectChart = d3\r\n              .select(document.createElement('div'))\r\n              .style('opacity', 0);\r\n          $$.observeInserted($$.selectChart);\r\n          binding = false;\r\n      }\r\n      $$.selectChart.html('').classed('c3', true);\r\n      // Init data as targets\r\n      $$.data.xs = {};\r\n      $$.data.targets = $$.convertDataToTargets(data);\r\n      if (config.data_filter) {\r\n          $$.data.targets = $$.data.targets.filter(config.data_filter);\r\n      }\r\n      // Set targets to hide if needed\r\n      if (config.data_hide) {\r\n          $$.addHiddenTargetIds(config.data_hide === true\r\n              ? $$.mapToIds($$.data.targets)\r\n              : config.data_hide);\r\n      }\r\n      if (config.legend_hide) {\r\n          $$.addHiddenLegendIds(config.legend_hide === true\r\n              ? $$.mapToIds($$.data.targets)\r\n              : config.legend_hide);\r\n      }\r\n      if ($$.isStanfordGraphType()) {\r\n          $$.initStanfordData();\r\n      }\r\n      // Init sizes and scales\r\n      $$.updateSizes();\r\n      $$.updateScales();\r\n      // Set domains for each scale\r\n      $$.x.domain(d3.extent($$.getXDomain($$.data.targets)));\r\n      $$.y.domain($$.getYDomain($$.data.targets, 'y'));\r\n      $$.y2.domain($$.getYDomain($$.data.targets, 'y2'));\r\n      $$.subX.domain($$.x.domain());\r\n      $$.subY.domain($$.y.domain());\r\n      $$.subY2.domain($$.y2.domain());\r\n      // Save original x domain for zoom update\r\n      $$.orgXDomain = $$.x.domain();\r\n      /*-- Basic Elements --*/\r\n      // Define svgs\r\n      $$.svg = $$.selectChart\r\n          .append('svg')\r\n          .style('overflow', 'hidden')\r\n          .on('mouseenter', function () {\r\n          return config.onmouseover.call($$);\r\n      })\r\n          .on('mouseleave', function () {\r\n          return config.onmouseout.call($$);\r\n      });\r\n      if ($$.config.svg_classname) {\r\n          $$.svg.attr('class', $$.config.svg_classname);\r\n      }\r\n      // Define defs\r\n      defs = $$.svg.append('defs');\r\n      $$.clipChart = $$.appendClip(defs, $$.clipId);\r\n      $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis);\r\n      $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis);\r\n      $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid);\r\n      $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart);\r\n      $$.updateSvgSize();\r\n      // Define regions\r\n      main = $$.main = $$.svg.append('g').attr('transform', $$.getTranslate('main'));\r\n      if ($$.initPie) {\r\n          $$.initPie();\r\n      }\r\n      if ($$.initDragZoom) {\r\n          $$.initDragZoom();\r\n      }\r\n      if (config.subchart_show && $$.initSubchart) {\r\n          $$.initSubchart();\r\n      }\r\n      if ($$.initTooltip) {\r\n          $$.initTooltip();\r\n      }\r\n      if ($$.initLegend) {\r\n          $$.initLegend();\r\n      }\r\n      if ($$.initTitle) {\r\n          $$.initTitle();\r\n      }\r\n      if ($$.initZoom) {\r\n          $$.initZoom();\r\n      }\r\n      if ($$.isStanfordGraphType()) {\r\n          $$.drawColorScale();\r\n      }\r\n      // Update selection based on size and scale\r\n      // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart.\r\n      if (config.subchart_show && $$.initSubchartBrush) {\r\n          $$.initSubchartBrush();\r\n      }\r\n      /*-- Main Region --*/\r\n      // text when empty\r\n      main\r\n          .append('text')\r\n          .attr('class', CLASS.text + ' ' + CLASS.empty)\r\n          .attr('text-anchor', 'middle') // horizontal centering of text at x position in all browsers.\r\n          .attr('dominant-baseline', 'middle'); // vertical centering of text at y position in all browsers, except IE.\r\n      // Regions\r\n      $$.initRegion();\r\n      // Grids\r\n      $$.initGrid();\r\n      // Define g for chart area\r\n      main\r\n          .append('g')\r\n          .attr('clip-path', $$.clipPath)\r\n          .attr('class', CLASS.chart);\r\n      // Grid lines\r\n      if (config.grid_lines_front) {\r\n          $$.initGridLines();\r\n      }\r\n      $$.initStanfordElements();\r\n      // Cover whole with rects for events\r\n      $$.initEventRect();\r\n      // Define g for chart\r\n      $$.initChartElements();\r\n      // Add Axis\r\n      $$.axis.init();\r\n      // Set targets\r\n      $$.updateTargets($$.data.targets);\r\n      // Set default extent if defined\r\n      if (config.axis_x_selection) {\r\n          $$.brush.selectionAsValue($$.getDefaultSelection());\r\n      }\r\n      // Draw with targets\r\n      if (binding) {\r\n          $$.updateDimension();\r\n          $$.config.oninit.call($$);\r\n          $$.redraw({\r\n              withTransition: false,\r\n              withTransform: true,\r\n              withUpdateXDomain: true,\r\n              withUpdateOrgXDomain: true,\r\n              withTransitionForAxis: false\r\n          });\r\n      }\r\n      // Bind to resize event\r\n      $$.bindResize();\r\n      // Bind to window focus event\r\n      $$.bindWindowFocus();\r\n      // export element of the chart\r\n      $$.api.element = $$.selectChart.node();\r\n  };\r\n  ChartInternal.prototype.smoothLines = function (el, type) {\r\n      var $$ = this;\r\n      if (type === 'grid') {\r\n          el.each(function () {\r\n              var g = $$.d3.select(this), x1 = g.attr('x1'), x2 = g.attr('x2'), y1 = g.attr('y1'), y2 = g.attr('y2');\r\n              g.attr({\r\n                  x1: Math.ceil(x1),\r\n                  x2: Math.ceil(x2),\r\n                  y1: Math.ceil(y1),\r\n                  y2: Math.ceil(y2)\r\n              });\r\n          });\r\n      }\r\n  };\r\n  ChartInternal.prototype.updateSizes = function () {\r\n      var $$ = this, config = $$.config;\r\n      var legendHeight = $$.legend ? $$.getLegendHeight() : 0, legendWidth = $$.legend ? $$.getLegendWidth() : 0, legendHeightForBottom = $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight, hasArc = $$.hasArcType(), xAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'), subchartXAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x', true), subchartHeight = config.subchart_show && !hasArc\r\n          ? config.subchart_size_height + subchartXAxisHeight\r\n          : 0;\r\n      $$.currentWidth = $$.getCurrentWidth();\r\n      $$.currentHeight = $$.getCurrentHeight();\r\n      // for main\r\n      $$.margin = config.axis_rotated\r\n          ? {\r\n              top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(),\r\n              right: hasArc ? 0 : $$.getCurrentPaddingRight(),\r\n              bottom: $$.getHorizontalAxisHeight('y') +\r\n                  legendHeightForBottom +\r\n                  $$.getCurrentPaddingBottom(),\r\n              left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft())\r\n          }\r\n          : {\r\n              top: 4 + $$.getCurrentPaddingTop(),\r\n              right: hasArc ? 0 : $$.getCurrentPaddingRight(),\r\n              bottom: xAxisHeight +\r\n                  subchartHeight +\r\n                  legendHeightForBottom +\r\n                  $$.getCurrentPaddingBottom(),\r\n              left: hasArc ? 0 : $$.getCurrentPaddingLeft()\r\n          };\r\n      // for subchart\r\n      $$.margin2 = config.axis_rotated\r\n          ? {\r\n              top: $$.margin.top,\r\n              right: NaN,\r\n              bottom: 20 + legendHeightForBottom,\r\n              left: $$.rotated_padding_left\r\n          }\r\n          : {\r\n              top: $$.currentHeight - subchartHeight - legendHeightForBottom,\r\n              right: NaN,\r\n              bottom: subchartXAxisHeight + legendHeightForBottom,\r\n              left: $$.margin.left\r\n          };\r\n      // for legend\r\n      $$.margin3 = {\r\n          top: 0,\r\n          right: NaN,\r\n          bottom: 0,\r\n          left: 0\r\n      };\r\n      if ($$.updateSizeForLegend) {\r\n          $$.updateSizeForLegend(legendHeight, legendWidth);\r\n      }\r\n      $$.width = $$.currentWidth - $$.margin.left - $$.margin.right;\r\n      $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom;\r\n      if ($$.width < 0) {\r\n          $$.width = 0;\r\n      }\r\n      if ($$.height < 0) {\r\n          $$.height = 0;\r\n      }\r\n      $$.width2 = config.axis_rotated\r\n          ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right\r\n          : $$.width;\r\n      $$.height2 = config.axis_rotated\r\n          ? $$.height\r\n          : $$.currentHeight - $$.margin2.top - $$.margin2.bottom;\r\n      if ($$.width2 < 0) {\r\n          $$.width2 = 0;\r\n      }\r\n      if ($$.height2 < 0) {\r\n          $$.height2 = 0;\r\n      }\r\n      // for arc\r\n      $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0);\r\n      $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10);\r\n      if ($$.hasType('gauge') && !config.gauge_fullCircle) {\r\n          $$.arcHeight += $$.height - $$.getGaugeLabelHeight();\r\n      }\r\n      if ($$.updateRadius) {\r\n          $$.updateRadius();\r\n      }\r\n      if ($$.isLegendRight && hasArc) {\r\n          $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1;\r\n      }\r\n  };\r\n  ChartInternal.prototype.updateTargets = function (targets) {\r\n      var $$ = this, config = $$.config;\r\n      /*-- Main --*/\r\n      //-- Text --//\r\n      $$.updateTargetsForText(targets);\r\n      //-- Bar --//\r\n      $$.updateTargetsForBar(targets);\r\n      //-- Line --//\r\n      $$.updateTargetsForLine(targets);\r\n      //-- Arc --//\r\n      if ($$.hasArcType() && $$.updateTargetsForArc) {\r\n          $$.updateTargetsForArc(targets);\r\n      }\r\n      /*-- Sub --*/\r\n      if (config.subchart_show && $$.updateTargetsForSubchart) {\r\n          $$.updateTargetsForSubchart(targets);\r\n      }\r\n      // Fade-in each chart\r\n      $$.showTargets();\r\n  };\r\n  ChartInternal.prototype.showTargets = function () {\r\n      var $$ = this;\r\n      $$.svg\r\n          .selectAll('.' + CLASS.target)\r\n          .filter(function (d) {\r\n          return $$.isTargetToShow(d.id);\r\n      })\r\n          .transition()\r\n          .duration($$.config.transition_duration)\r\n          .style('opacity', 1);\r\n  };\r\n  ChartInternal.prototype.redraw = function (options, transitions) {\r\n      var $$ = this, main = $$.main, d3 = $$.d3, config = $$.config;\r\n      var areaIndices = $$.getShapeIndices($$.isAreaType), barIndices = $$.getShapeIndices($$.isBarType), lineIndices = $$.getShapeIndices($$.isLineType);\r\n      var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis, withTransform, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain, withLegend, withEventRect, withDimension, withUpdateXAxis;\r\n      var hideAxis = $$.hasArcType();\r\n      var drawArea, drawBar, drawLine, xForText, yForText;\r\n      var duration, durationForExit, durationForAxis;\r\n      var transitionsToWait, waitForDraw, flow, transition;\r\n      var targetsToShow = $$.filterTargetsToShow($$.data.targets), tickValues, i, intervalForCulling, xDomainForZoom;\r\n      var xv = $$.xv.bind($$), cx, cy;\r\n      options = options || {};\r\n      withY = getOption(options, 'withY', true);\r\n      withSubchart = getOption(options, 'withSubchart', true);\r\n      withTransition = getOption(options, 'withTransition', true);\r\n      withTransform = getOption(options, 'withTransform', false);\r\n      withUpdateXDomain = getOption(options, 'withUpdateXDomain', false);\r\n      withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', false);\r\n      withTrimXDomain = getOption(options, 'withTrimXDomain', true);\r\n      withUpdateXAxis = getOption(options, 'withUpdateXAxis', withUpdateXDomain);\r\n      withLegend = getOption(options, 'withLegend', false);\r\n      withEventRect = getOption(options, 'withEventRect', true);\r\n      withDimension = getOption(options, 'withDimension', true);\r\n      withTransitionForExit = getOption(options, 'withTransitionForExit', withTransition);\r\n      withTransitionForAxis = getOption(options, 'withTransitionForAxis', withTransition);\r\n      duration = withTransition ? config.transition_duration : 0;\r\n      durationForExit = withTransitionForExit ? duration : 0;\r\n      durationForAxis = withTransitionForAxis ? duration : 0;\r\n      transitions = transitions || $$.axis.generateTransitions(durationForAxis);\r\n      // update legend and transform each g\r\n      if (withLegend && config.legend_show) {\r\n          $$.updateLegend($$.mapToIds($$.data.targets), options, transitions);\r\n      }\r\n      else if (withDimension) {\r\n          // need to update dimension (e.g. axis.y.tick.values) because y tick values should change\r\n          // no need to update axis in it because they will be updated in redraw()\r\n          $$.updateDimension(true);\r\n      }\r\n      // MEMO: needed for grids calculation\r\n      if ($$.isCategorized() && targetsToShow.length === 0) {\r\n          $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]);\r\n      }\r\n      if (targetsToShow.length) {\r\n          $$.updateXDomain(targetsToShow, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain);\r\n          if (!config.axis_x_tick_values) {\r\n              tickValues = $$.axis.updateXAxisTickValues(targetsToShow);\r\n          }\r\n      }\r\n      else {\r\n          $$.xAxis.tickValues([]);\r\n          $$.subXAxis.tickValues([]);\r\n      }\r\n      if (config.zoom_rescale && !options.flow) {\r\n          xDomainForZoom = $$.x.orgDomain();\r\n      }\r\n      $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom));\r\n      $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom));\r\n      if (!config.axis_y_tick_values && config.axis_y_tick_count) {\r\n          $$.yAxis.tickValues($$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count));\r\n      }\r\n      if (!config.axis_y2_tick_values && config.axis_y2_tick_count) {\r\n          $$.y2Axis.tickValues($$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count));\r\n      }\r\n      // axes\r\n      $$.axis.redraw(durationForAxis, hideAxis);\r\n      // Update axis label\r\n      $$.axis.updateLabels(withTransition);\r\n      // show/hide if manual culling needed\r\n      if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) {\r\n          if (config.axis_x_tick_culling && tickValues) {\r\n              for (i = 1; i < tickValues.length; i++) {\r\n                  if (tickValues.length / i < config.axis_x_tick_culling_max) {\r\n                      intervalForCulling = i;\r\n                      break;\r\n                  }\r\n              }\r\n              $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function (e) {\r\n                  var index = tickValues.indexOf(e);\r\n                  if (index >= 0) {\r\n                      d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block');\r\n                  }\r\n              });\r\n          }\r\n          else {\r\n              $$.svg\r\n                  .selectAll('.' + CLASS.axisX + ' .tick text')\r\n                  .style('display', 'block');\r\n          }\r\n      }\r\n      // setup drawer - MEMO: these must be called after axis updated\r\n      drawArea = $$.generateDrawArea\r\n          ? $$.generateDrawArea(areaIndices, false)\r\n          : undefined;\r\n      drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined;\r\n      drawLine = $$.generateDrawLine\r\n          ? $$.generateDrawLine(lineIndices, false)\r\n          : undefined;\r\n      xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true);\r\n      yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false);\r\n      // update circleY based on updated parameters\r\n      $$.updateCircleY();\r\n      // generate circle x/y functions depending on updated params\r\n      cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$);\r\n      cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$);\r\n      // Update sub domain\r\n      if (withY) {\r\n          $$.subY.domain($$.getYDomain(targetsToShow, 'y'));\r\n          $$.subY2.domain($$.getYDomain(targetsToShow, 'y2'));\r\n      }\r\n      // xgrid focus\r\n      $$.updateXgridFocus();\r\n      // Data empty label positioning and text.\r\n      main\r\n          .select('text.' + CLASS.text + '.' + CLASS.empty)\r\n          .attr('x', $$.width / 2)\r\n          .attr('y', $$.height / 2)\r\n          .text(config.data_empty_label_text)\r\n          .transition()\r\n          .style('opacity', targetsToShow.length ? 0 : 1);\r\n      // event rect\r\n      if (withEventRect) {\r\n          $$.redrawEventRect();\r\n      }\r\n      // grid\r\n      $$.updateGrid(duration);\r\n      $$.updateStanfordElements(duration);\r\n      // rect for regions\r\n      $$.updateRegion(duration);\r\n      // bars\r\n      $$.updateBar(durationForExit);\r\n      // lines, areas and circles\r\n      $$.updateLine(durationForExit);\r\n      $$.updateArea(durationForExit);\r\n      $$.updateCircle(cx, cy);\r\n      // text\r\n      if ($$.hasDataLabel()) {\r\n          $$.updateText(xForText, yForText, durationForExit);\r\n      }\r\n      // title\r\n      if ($$.redrawTitle) {\r\n          $$.redrawTitle();\r\n      }\r\n      // arc\r\n      if ($$.redrawArc) {\r\n          $$.redrawArc(duration, durationForExit, withTransform);\r\n      }\r\n      // subchart\r\n      if (config.subchart_show && $$.redrawSubchart) {\r\n          $$.redrawSubchart(withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices);\r\n      }\r\n      if ($$.isStanfordGraphType()) {\r\n          $$.drawColorScale();\r\n      }\r\n      // circles for select\r\n      main\r\n          .selectAll('.' + CLASS.selectedCircles)\r\n          .filter($$.isBarType.bind($$))\r\n          .selectAll('circle')\r\n          .remove();\r\n      if (options.flow) {\r\n          flow = $$.generateFlow({\r\n              targets: targetsToShow,\r\n              flow: options.flow,\r\n              duration: options.flow.duration,\r\n              drawBar: drawBar,\r\n              drawLine: drawLine,\r\n              drawArea: drawArea,\r\n              cx: cx,\r\n              cy: cy,\r\n              xv: xv,\r\n              xForText: xForText,\r\n              yForText: yForText\r\n          });\r\n      }\r\n      if (duration && $$.isTabVisible()) {\r\n          // Only use transition if tab visible. See #938.\r\n          // transition should be derived from one transition\r\n          transition = d3.transition().duration(duration);\r\n          transitionsToWait = [];\r\n          [\r\n              $$.redrawBar(drawBar, true, transition),\r\n              $$.redrawLine(drawLine, true, transition),\r\n              $$.redrawArea(drawArea, true, transition),\r\n              $$.redrawCircle(cx, cy, true, transition),\r\n              $$.redrawText(xForText, yForText, options.flow, true, transition),\r\n              $$.redrawRegion(true, transition),\r\n              $$.redrawGrid(true, transition)\r\n          ].forEach(function (transitions) {\r\n              transitions.forEach(function (transition) {\r\n                  transitionsToWait.push(transition);\r\n              });\r\n          });\r\n          // Wait for end of transitions to call flow and onrendered callback\r\n          waitForDraw = $$.generateWait();\r\n          transitionsToWait.forEach(function (t) {\r\n              waitForDraw.add(t);\r\n          });\r\n          waitForDraw(function () {\r\n              if (flow) {\r\n                  flow();\r\n              }\r\n              if (config.onrendered) {\r\n                  config.onrendered.call($$);\r\n              }\r\n          });\r\n      }\r\n      else {\r\n          $$.redrawBar(drawBar);\r\n          $$.redrawLine(drawLine);\r\n          $$.redrawArea(drawArea);\r\n          $$.redrawCircle(cx, cy);\r\n          $$.redrawText(xForText, yForText, options.flow);\r\n          $$.redrawRegion();\r\n          $$.redrawGrid();\r\n          if (flow) {\r\n              flow();\r\n          }\r\n          if (config.onrendered) {\r\n              config.onrendered.call($$);\r\n          }\r\n      }\r\n      // update fadein condition\r\n      $$.mapToIds($$.data.targets).forEach(function (id) {\r\n          $$.withoutFadeIn[id] = true;\r\n      });\r\n  };\r\n  ChartInternal.prototype.updateAndRedraw = function (options) {\r\n      var $$ = this, config = $$.config, transitions;\r\n      options = options || {};\r\n      // same with redraw\r\n      options.withTransition = getOption(options, 'withTransition', true);\r\n      options.withTransform = getOption(options, 'withTransform', false);\r\n      options.withLegend = getOption(options, 'withLegend', false);\r\n      // NOT same with redraw\r\n      options.withUpdateXDomain = getOption(options, 'withUpdateXDomain', true);\r\n      options.withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', true);\r\n      options.withTransitionForExit = false;\r\n      options.withTransitionForTransform = getOption(options, 'withTransitionForTransform', options.withTransition);\r\n      // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called)\r\n      $$.updateSizes();\r\n      // MEMO: called in updateLegend in redraw if withLegend\r\n      if (!(options.withLegend && config.legend_show)) {\r\n          transitions = $$.axis.generateTransitions(options.withTransitionForAxis ? config.transition_duration : 0);\r\n          // Update scales\r\n          $$.updateScales();\r\n          $$.updateSvgSize();\r\n          // Update g positions\r\n          $$.transformAll(options.withTransitionForTransform, transitions);\r\n      }\r\n      // Draw with new sizes & scales\r\n      $$.redraw(options, transitions);\r\n  };\r\n  ChartInternal.prototype.redrawWithoutRescale = function () {\r\n      this.redraw({\r\n          withY: false,\r\n          withSubchart: false,\r\n          withEventRect: false,\r\n          withTransitionForAxis: false\r\n      });\r\n  };\r\n  ChartInternal.prototype.isTimeSeries = function () {\r\n      return this.config.axis_x_type === 'timeseries';\r\n  };\r\n  ChartInternal.prototype.isCategorized = function () {\r\n      return this.config.axis_x_type.indexOf('categor') >= 0;\r\n  };\r\n  ChartInternal.prototype.isCustomX = function () {\r\n      var $$ = this, config = $$.config;\r\n      return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs));\r\n  };\r\n  ChartInternal.prototype.isTimeSeriesY = function () {\r\n      return this.config.axis_y_type === 'timeseries';\r\n  };\r\n  ChartInternal.prototype.getTranslate = function (target) {\r\n      var $$ = this, config = $$.config, x, y;\r\n      if (target === 'main') {\r\n          x = asHalfPixel($$.margin.left);\r\n          y = asHalfPixel($$.margin.top);\r\n      }\r\n      else if (target === 'context') {\r\n          x = asHalfPixel($$.margin2.left);\r\n          y = asHalfPixel($$.margin2.top);\r\n      }\r\n      else if (target === 'legend') {\r\n          x = $$.margin3.left;\r\n          y = $$.margin3.top;\r\n      }\r\n      else if (target === 'x') {\r\n          x = 0;\r\n          y = config.axis_rotated ? 0 : $$.height;\r\n      }\r\n      else if (target === 'y') {\r\n          x = 0;\r\n          y = config.axis_rotated ? $$.height : 0;\r\n      }\r\n      else if (target === 'y2') {\r\n          x = config.axis_rotated ? 0 : $$.width;\r\n          y = config.axis_rotated ? 1 : 0;\r\n      }\r\n      else if (target === 'subx') {\r\n          x = 0;\r\n          y = config.axis_rotated ? 0 : $$.height2;\r\n      }\r\n      else if (target === 'arc') {\r\n          x = $$.arcWidth / 2;\r\n          y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label\r\n      }\r\n      return 'translate(' + x + ',' + y + ')';\r\n  };\r\n  ChartInternal.prototype.initialOpacity = function (d) {\r\n      return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0;\r\n  };\r\n  ChartInternal.prototype.initialOpacityForCircle = function (d) {\r\n      return d.value !== null && this.withoutFadeIn[d.id]\r\n          ? this.opacityForCircle(d)\r\n          : 0;\r\n  };\r\n  ChartInternal.prototype.opacityForCircle = function (d) {\r\n      var isPointShouldBeShown = isFunction(this.config.point_show)\r\n          ? this.config.point_show(d)\r\n          : this.config.point_show;\r\n      var opacity = isPointShouldBeShown || this.isStanfordType(d) ? 1 : 0;\r\n      return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0;\r\n  };\r\n  ChartInternal.prototype.opacityForText = function () {\r\n      return this.hasDataLabel() ? 1 : 0;\r\n  };\r\n  ChartInternal.prototype.xx = function (d) {\r\n      return d ? this.x(d.x) : null;\r\n  };\r\n  ChartInternal.prototype.xvCustom = function (d, xyValue) {\r\n      var $$ = this, value = xyValue ? d[xyValue] : d.value;\r\n      if ($$.isTimeSeries()) {\r\n          value = $$.parseDate(d.value);\r\n      }\r\n      else if ($$.isCategorized() && typeof d.value === 'string') {\r\n          value = $$.config.axis_x_categories.indexOf(d.value);\r\n      }\r\n      return Math.ceil($$.x(value));\r\n  };\r\n  ChartInternal.prototype.yvCustom = function (d, xyValue) {\r\n      var $$ = this, yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y, value = xyValue ? d[xyValue] : d.value;\r\n      return Math.ceil(yScale(value));\r\n  };\r\n  ChartInternal.prototype.xv = function (d) {\r\n      var $$ = this, value = d.value;\r\n      if ($$.isTimeSeries()) {\r\n          value = $$.parseDate(d.value);\r\n      }\r\n      else if ($$.isCategorized() && typeof d.value === 'string') {\r\n          value = $$.config.axis_x_categories.indexOf(d.value);\r\n      }\r\n      return Math.ceil($$.x(value));\r\n  };\r\n  ChartInternal.prototype.yv = function (d) {\r\n      var $$ = this, yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y;\r\n      return Math.ceil(yScale(d.value));\r\n  };\r\n  ChartInternal.prototype.subxx = function (d) {\r\n      return d ? this.subX(d.x) : null;\r\n  };\r\n  ChartInternal.prototype.transformMain = function (withTransition, transitions) {\r\n      var $$ = this, xAxis, yAxis, y2Axis;\r\n      if (transitions && transitions.axisX) {\r\n          xAxis = transitions.axisX;\r\n      }\r\n      else {\r\n          xAxis = $$.main.select('.' + CLASS.axisX);\r\n          if (withTransition) {\r\n              xAxis = xAxis.transition();\r\n          }\r\n      }\r\n      if (transitions && transitions.axisY) {\r\n          yAxis = transitions.axisY;\r\n      }\r\n      else {\r\n          yAxis = $$.main.select('.' + CLASS.axisY);\r\n          if (withTransition) {\r\n              yAxis = yAxis.transition();\r\n          }\r\n      }\r\n      if (transitions && transitions.axisY2) {\r\n          y2Axis = transitions.axisY2;\r\n      }\r\n      else {\r\n          y2Axis = $$.main.select('.' + CLASS.axisY2);\r\n          if (withTransition) {\r\n              y2Axis = y2Axis.transition();\r\n          }\r\n      }\r\n      (withTransition ? $$.main.transition() : $$.main).attr('transform', $$.getTranslate('main'));\r\n      xAxis.attr('transform', $$.getTranslate('x'));\r\n      yAxis.attr('transform', $$.getTranslate('y'));\r\n      y2Axis.attr('transform', $$.getTranslate('y2'));\r\n      $$.main\r\n          .select('.' + CLASS.chartArcs)\r\n          .attr('transform', $$.getTranslate('arc'));\r\n  };\r\n  ChartInternal.prototype.transformAll = function (withTransition, transitions) {\r\n      var $$ = this;\r\n      $$.transformMain(withTransition, transitions);\r\n      if ($$.config.subchart_show) {\r\n          $$.transformContext(withTransition, transitions);\r\n      }\r\n      if ($$.legend) {\r\n          $$.transformLegend(withTransition);\r\n      }\r\n  };\r\n  ChartInternal.prototype.updateSvgSize = function () {\r\n      var $$ = this, brush = $$.svg.select(\".\" + CLASS.brush + \" .overlay\");\r\n      $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight);\r\n      $$.svg\r\n          .selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid])\r\n          .select('rect')\r\n          .attr('width', $$.width)\r\n          .attr('height', $$.height);\r\n      $$.svg\r\n          .select('#' + $$.clipIdForXAxis)\r\n          .select('rect')\r\n          .attr('x', $$.getXAxisClipX.bind($$))\r\n          .attr('y', $$.getXAxisClipY.bind($$))\r\n          .attr('width', $$.getXAxisClipWidth.bind($$))\r\n          .attr('height', $$.getXAxisClipHeight.bind($$));\r\n      $$.svg\r\n          .select('#' + $$.clipIdForYAxis)\r\n          .select('rect')\r\n          .attr('x', $$.getYAxisClipX.bind($$))\r\n          .attr('y', $$.getYAxisClipY.bind($$))\r\n          .attr('width', $$.getYAxisClipWidth.bind($$))\r\n          .attr('height', $$.getYAxisClipHeight.bind($$));\r\n      $$.svg\r\n          .select('#' + $$.clipIdForSubchart)\r\n          .select('rect')\r\n          .attr('width', $$.width)\r\n          .attr('height', (brush.size() && brush.attr('height')) || 0);\r\n      // MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>\r\n      $$.selectChart.style('max-height', $$.currentHeight + 'px');\r\n  };\r\n  ChartInternal.prototype.updateDimension = function (withoutAxis) {\r\n      var $$ = this;\r\n      if (!withoutAxis) {\r\n          if ($$.config.axis_rotated) {\r\n              $$.axes.x.call($$.xAxis);\r\n              $$.axes.subx.call($$.subXAxis);\r\n          }\r\n          else {\r\n              $$.axes.y.call($$.yAxis);\r\n              $$.axes.y2.call($$.y2Axis);\r\n          }\r\n      }\r\n      $$.updateSizes();\r\n      $$.updateScales();\r\n      $$.updateSvgSize();\r\n      $$.transformAll(false);\r\n  };\r\n  ChartInternal.prototype.observeInserted = function (selection) {\r\n      var $$ = this, observer;\r\n      if (typeof MutationObserver === 'undefined') {\r\n          window.console.error('MutationObserver not defined.');\r\n          return;\r\n      }\r\n      observer = new MutationObserver(function (mutations) {\r\n          mutations.forEach(function (mutation) {\r\n              if (mutation.type === 'childList' && mutation.previousSibling) {\r\n                  observer.disconnect();\r\n                  // need to wait for completion of load because size calculation requires the actual sizes determined after that completion\r\n                  $$.intervalForObserveInserted = window.setInterval(function () {\r\n                      // parentNode will NOT be null when completed\r\n                      if (selection.node().parentNode) {\r\n                          window.clearInterval($$.intervalForObserveInserted);\r\n                          $$.updateDimension();\r\n                          if ($$.brush) {\r\n                              $$.brush.update();\r\n                          }\r\n                          $$.config.oninit.call($$);\r\n                          $$.redraw({\r\n                              withTransform: true,\r\n                              withUpdateXDomain: true,\r\n                              withUpdateOrgXDomain: true,\r\n                              withTransition: false,\r\n                              withTransitionForTransform: false,\r\n                              withLegend: true\r\n                          });\r\n                          selection.transition().style('opacity', 1);\r\n                      }\r\n                  }, 10);\r\n              }\r\n          });\r\n      });\r\n      observer.observe(selection.node(), {\r\n          attributes: true,\r\n          childList: true,\r\n          characterData: true\r\n      });\r\n  };\r\n  /**\r\n   * Binds handlers to the window resize event.\r\n   */\r\n  ChartInternal.prototype.bindResize = function () {\r\n      var $$ = this, config = $$.config;\r\n      $$.resizeFunction = $$.generateResize(); // need to call .remove\r\n      $$.resizeFunction.add(function () {\r\n          config.onresize.call($$);\r\n      });\r\n      if (config.resize_auto) {\r\n          $$.resizeFunction.add(function () {\r\n              if ($$.resizeTimeout !== undefined) {\r\n                  window.clearTimeout($$.resizeTimeout);\r\n              }\r\n              $$.resizeTimeout = window.setTimeout(function () {\r\n                  delete $$.resizeTimeout;\r\n                  $$.updateAndRedraw({\r\n                      withUpdateXDomain: false,\r\n                      withUpdateOrgXDomain: false,\r\n                      withTransition: false,\r\n                      withTransitionForTransform: false,\r\n                      withLegend: true\r\n                  });\r\n                  if ($$.brush) {\r\n                      $$.brush.update();\r\n                  }\r\n              }, 100);\r\n          });\r\n      }\r\n      $$.resizeFunction.add(function () {\r\n          config.onresized.call($$);\r\n      });\r\n      $$.resizeIfElementDisplayed = function () {\r\n          // if element not displayed skip it\r\n          if ($$.api == null || !$$.api.element.offsetParent) {\r\n              return;\r\n          }\r\n          $$.resizeFunction();\r\n      };\r\n      window.addEventListener('resize', $$.resizeIfElementDisplayed, false);\r\n  };\r\n  /**\r\n   * Binds handlers to the window focus event.\r\n   */\r\n  ChartInternal.prototype.bindWindowFocus = function () {\r\n      var _this = this;\r\n      if (this.windowFocusHandler) {\r\n          // The handler is already set\r\n          return;\r\n      }\r\n      this.windowFocusHandler = function () {\r\n          _this.redraw();\r\n      };\r\n      window.addEventListener('focus', this.windowFocusHandler);\r\n  };\r\n  /**\r\n   * Unbinds from the window focus event.\r\n   */\r\n  ChartInternal.prototype.unbindWindowFocus = function () {\r\n      window.removeEventListener('focus', this.windowFocusHandler);\r\n      delete this.windowFocusHandler;\r\n  };\r\n  ChartInternal.prototype.generateResize = function () {\r\n      var resizeFunctions = [];\r\n      function callResizeFunctions() {\r\n          resizeFunctions.forEach(function (f) {\r\n              f();\r\n          });\r\n      }\r\n      callResizeFunctions.add = function (f) {\r\n          resizeFunctions.push(f);\r\n      };\r\n      callResizeFunctions.remove = function (f) {\r\n          for (var i = 0; i < resizeFunctions.length; i++) {\r\n              if (resizeFunctions[i] === f) {\r\n                  resizeFunctions.splice(i, 1);\r\n                  break;\r\n              }\r\n          }\r\n      };\r\n      return callResizeFunctions;\r\n  };\r\n  ChartInternal.prototype.endall = function (transition, callback) {\r\n      var n = 0;\r\n      transition\r\n          .each(function () {\r\n          ++n;\r\n      })\r\n          .on('end', function () {\r\n          if (!--n) {\r\n              callback.apply(this, arguments);\r\n          }\r\n      });\r\n  };\r\n  ChartInternal.prototype.generateWait = function () {\r\n      var $$ = this;\r\n      var transitionsToWait = [], f = function (callback) {\r\n          var timer = setInterval(function () {\r\n              if (!$$.isTabVisible()) {\r\n                  return;\r\n              }\r\n              var done = 0;\r\n              transitionsToWait.forEach(function (t) {\r\n                  if (t.empty()) {\r\n                      done += 1;\r\n                      return;\r\n                  }\r\n                  try {\r\n                      t.transition();\r\n                  }\r\n                  catch (e) {\r\n                      done += 1;\r\n                  }\r\n              });\r\n              if (done === transitionsToWait.length) {\r\n                  clearInterval(timer);\r\n                  if (callback) {\r\n                      callback();\r\n                  }\r\n              }\r\n          }, 50);\r\n      };\r\n      f.add = function (transition) {\r\n          transitionsToWait.push(transition);\r\n      };\r\n      return f;\r\n  };\r\n  ChartInternal.prototype.parseDate = function (date) {\r\n      var $$ = this, parsedDate;\r\n      if (date instanceof Date) {\r\n          parsedDate = date;\r\n      }\r\n      else if (typeof date === 'string') {\r\n          parsedDate = $$.dataTimeParse(date);\r\n      }\r\n      else if (typeof date === 'object') {\r\n          parsedDate = new Date(+date);\r\n      }\r\n      else if (typeof date === 'number' && !isNaN(date)) {\r\n          parsedDate = new Date(+date);\r\n      }\r\n      if (!parsedDate || isNaN(+parsedDate)) {\r\n          window.console.error(\"Failed to parse x '\" + date + \"' to Date object\");\r\n      }\r\n      return parsedDate;\r\n  };\r\n  ChartInternal.prototype.isTabVisible = function () {\r\n      return !document.hidden;\r\n  };\r\n  ChartInternal.prototype.getPathBox = getPathBox;\r\n  ChartInternal.prototype.CLASS = CLASS;\n\n  /* jshint ignore:start */\r\n  (function () {\r\n      if (!('SVGPathSeg' in window)) {\r\n          // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg\r\n          window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) {\r\n              this.pathSegType = type;\r\n              this.pathSegTypeAsLetter = typeAsLetter;\r\n              this._owningPathSegList = owningPathSegList;\r\n          };\r\n          window.SVGPathSeg.prototype.classname = 'SVGPathSeg';\r\n          window.SVGPathSeg.PATHSEG_UNKNOWN = 0;\r\n          window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;\r\n          window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;\r\n          window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;\r\n          window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;\r\n          window.SVGPathSeg.PATHSEG_LINETO_REL = 5;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;\r\n          window.SVGPathSeg.PATHSEG_ARC_ABS = 10;\r\n          window.SVGPathSeg.PATHSEG_ARC_REL = 11;\r\n          window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;\r\n          window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;\r\n          window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;\r\n          window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;\r\n          window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;\r\n          // Notify owning PathSegList on any changes so they can be synchronized back to the path element.\r\n          window.SVGPathSeg.prototype._segmentChanged = function () {\r\n              if (this._owningPathSegList)\r\n                  this._owningPathSegList.segmentChanged(this);\r\n          };\r\n          window.SVGPathSegClosePath = function (owningPathSegList) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, 'z', owningPathSegList);\r\n          };\r\n          window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegClosePath.prototype.toString = function () {\r\n              return '[object SVGPathSegClosePath]';\r\n          };\r\n          window.SVGPathSegClosePath.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter;\r\n          };\r\n          window.SVGPathSegClosePath.prototype.clone = function () {\r\n              return new window.SVGPathSegClosePath(undefined);\r\n          };\r\n          window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, 'M', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegMovetoAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegMovetoAbs]';\r\n          };\r\n          window.SVGPathSegMovetoAbs.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegMovetoAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, 'm', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegMovetoRel.prototype.toString = function () {\r\n              return '[object SVGPathSegMovetoRel]';\r\n          };\r\n          window.SVGPathSegMovetoRel.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegMovetoRel.prototype.clone = function () {\r\n              return new window.SVGPathSegMovetoRel(undefined, this._x, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, 'L', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegLinetoAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegLinetoAbs]';\r\n          };\r\n          window.SVGPathSegLinetoAbs.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegLinetoAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, 'l', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegLinetoRel.prototype.toString = function () {\r\n              return '[object SVGPathSegLinetoRel]';\r\n          };\r\n          window.SVGPathSegLinetoRel.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegLinetoRel.prototype.clone = function () {\r\n              return new window.SVGPathSegLinetoRel(undefined, this._x, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, 'C', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._x1 = x1;\r\n              this._y1 = y1;\r\n              this._x2 = x2;\r\n              this._y2 = y2;\r\n          };\r\n          window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoCubicAbs]';\r\n          };\r\n          window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._x1 +\r\n                  ' ' +\r\n                  this._y1 +\r\n                  ' ' +\r\n                  this._x2 +\r\n                  ' ' +\r\n                  this._y2 +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x1', {\r\n              get: function () {\r\n                  return this._x1;\r\n              },\r\n              set: function (x1) {\r\n                  this._x1 = x1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y1', {\r\n              get: function () {\r\n                  return this._y1;\r\n              },\r\n              set: function (y1) {\r\n                  this._y1 = y1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x2', {\r\n              get: function () {\r\n                  return this._x2;\r\n              },\r\n              set: function (x2) {\r\n                  this._x2 = x2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y2', {\r\n              get: function () {\r\n                  return this._y2;\r\n              },\r\n              set: function (y2) {\r\n                  this._y2 = y2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, 'c', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._x1 = x1;\r\n              this._y1 = y1;\r\n              this._x2 = x2;\r\n              this._y2 = y2;\r\n          };\r\n          window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoCubicRel.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoCubicRel]';\r\n          };\r\n          window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._x1 +\r\n                  ' ' +\r\n                  this._y1 +\r\n                  ' ' +\r\n                  this._x2 +\r\n                  ' ' +\r\n                  this._y2 +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegCurvetoCubicRel.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x1', {\r\n              get: function () {\r\n                  return this._x1;\r\n              },\r\n              set: function (x1) {\r\n                  this._x1 = x1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y1', {\r\n              get: function () {\r\n                  return this._y1;\r\n              },\r\n              set: function (y1) {\r\n                  this._y1 = y1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x2', {\r\n              get: function () {\r\n                  return this._x2;\r\n              },\r\n              set: function (x2) {\r\n                  this._x2 = x2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y2', {\r\n              get: function () {\r\n                  return this._y2;\r\n              },\r\n              set: function (y2) {\r\n                  this._y2 = y2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, 'Q', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._x1 = x1;\r\n              this._y1 = y1;\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoQuadraticAbs]';\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._x1 +\r\n                  ' ' +\r\n                  this._y1 +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x1', {\r\n              get: function () {\r\n                  return this._x1;\r\n              },\r\n              set: function (x1) {\r\n                  this._x1 = x1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y1', {\r\n              get: function () {\r\n                  return this._y1;\r\n              },\r\n              set: function (y1) {\r\n                  this._y1 = y1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, 'q', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._x1 = x1;\r\n              this._y1 = y1;\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoQuadraticRel]';\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._x1 +\r\n                  ' ' +\r\n                  this._y1 +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x1', {\r\n              get: function () {\r\n                  return this._x1;\r\n              },\r\n              set: function (x1) {\r\n                  this._x1 = x1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y1', {\r\n              get: function () {\r\n                  return this._y1;\r\n              },\r\n              set: function (y1) {\r\n                  this._y1 = y1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, 'A', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._r1 = r1;\r\n              this._r2 = r2;\r\n              this._angle = angle;\r\n              this._largeArcFlag = largeArcFlag;\r\n              this._sweepFlag = sweepFlag;\r\n          };\r\n          window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegArcAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegArcAbs]';\r\n          };\r\n          window.SVGPathSegArcAbs.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._r1 +\r\n                  ' ' +\r\n                  this._r2 +\r\n                  ' ' +\r\n                  this._angle +\r\n                  ' ' +\r\n                  (this._largeArcFlag ? '1' : '0') +\r\n                  ' ' +\r\n                  (this._sweepFlag ? '1' : '0') +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegArcAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r1', {\r\n              get: function () {\r\n                  return this._r1;\r\n              },\r\n              set: function (r1) {\r\n                  this._r1 = r1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r2', {\r\n              get: function () {\r\n                  return this._r2;\r\n              },\r\n              set: function (r2) {\r\n                  this._r2 = r2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'angle', {\r\n              get: function () {\r\n                  return this._angle;\r\n              },\r\n              set: function (angle) {\r\n                  this._angle = angle;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'largeArcFlag', {\r\n              get: function () {\r\n                  return this._largeArcFlag;\r\n              },\r\n              set: function (largeArcFlag) {\r\n                  this._largeArcFlag = largeArcFlag;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'sweepFlag', {\r\n              get: function () {\r\n                  return this._sweepFlag;\r\n              },\r\n              set: function (sweepFlag) {\r\n                  this._sweepFlag = sweepFlag;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, 'a', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._r1 = r1;\r\n              this._r2 = r2;\r\n              this._angle = angle;\r\n              this._largeArcFlag = largeArcFlag;\r\n              this._sweepFlag = sweepFlag;\r\n          };\r\n          window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegArcRel.prototype.toString = function () {\r\n              return '[object SVGPathSegArcRel]';\r\n          };\r\n          window.SVGPathSegArcRel.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._r1 +\r\n                  ' ' +\r\n                  this._r2 +\r\n                  ' ' +\r\n                  this._angle +\r\n                  ' ' +\r\n                  (this._largeArcFlag ? '1' : '0') +\r\n                  ' ' +\r\n                  (this._sweepFlag ? '1' : '0') +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegArcRel.prototype.clone = function () {\r\n              return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r1', {\r\n              get: function () {\r\n                  return this._r1;\r\n              },\r\n              set: function (r1) {\r\n                  this._r1 = r1;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r2', {\r\n              get: function () {\r\n                  return this._r2;\r\n              },\r\n              set: function (r2) {\r\n                  this._r2 = r2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'angle', {\r\n              get: function () {\r\n                  return this._angle;\r\n              },\r\n              set: function (angle) {\r\n                  this._angle = angle;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'largeArcFlag', {\r\n              get: function () {\r\n                  return this._largeArcFlag;\r\n              },\r\n              set: function (largeArcFlag) {\r\n                  this._largeArcFlag = largeArcFlag;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegArcRel.prototype, 'sweepFlag', {\r\n              get: function () {\r\n                  return this._sweepFlag;\r\n              },\r\n              set: function (sweepFlag) {\r\n                  this._sweepFlag = sweepFlag;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, 'H', owningPathSegList);\r\n              this._x = x;\r\n          };\r\n          window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegLinetoHorizontalAbs]';\r\n          };\r\n          window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x;\r\n          };\r\n          window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, 'h', owningPathSegList);\r\n              this._x = x;\r\n          };\r\n          window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () {\r\n              return '[object SVGPathSegLinetoHorizontalRel]';\r\n          };\r\n          window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x;\r\n          };\r\n          window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () {\r\n              return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, 'V', owningPathSegList);\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegLinetoVerticalAbs]';\r\n          };\r\n          window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, 'v', owningPathSegList);\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegLinetoVerticalRel.prototype.toString = function () {\r\n              return '[object SVGPathSegLinetoVerticalRel]';\r\n          };\r\n          window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegLinetoVerticalRel.prototype.clone = function () {\r\n              return new window.SVGPathSegLinetoVerticalRel(undefined, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, 'S', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._x2 = x2;\r\n              this._y2 = y2;\r\n          };\r\n          window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoCubicSmoothAbs]';\r\n          };\r\n          window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._x2 +\r\n                  ' ' +\r\n                  this._y2 +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'x2', {\r\n              get: function () {\r\n                  return this._x2;\r\n              },\r\n              set: function (x2) {\r\n                  this._x2 = x2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, 'y2', {\r\n              get: function () {\r\n                  return this._y2;\r\n              },\r\n              set: function (y2) {\r\n                  this._y2 = y2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, 's', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n              this._x2 = x2;\r\n              this._y2 = y2;\r\n          };\r\n          window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoCubicSmoothRel]';\r\n          };\r\n          window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () {\r\n              return (this.pathSegTypeAsLetter +\r\n                  ' ' +\r\n                  this._x2 +\r\n                  ' ' +\r\n                  this._y2 +\r\n                  ' ' +\r\n                  this._x +\r\n                  ' ' +\r\n                  this._y);\r\n          };\r\n          window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'x2', {\r\n              get: function () {\r\n                  return this._x2;\r\n              },\r\n              set: function (x2) {\r\n                  this._x2 = x2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, 'y2', {\r\n              get: function () {\r\n                  return this._y2;\r\n              },\r\n              set: function (y2) {\r\n                  this._y2 = y2;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, 'T', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoQuadraticSmoothAbs]';\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) {\r\n              window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, 't', owningPathSegList);\r\n              this._x = x;\r\n              this._y = y;\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);\r\n          window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () {\r\n              return '[object SVGPathSegCurvetoQuadraticSmoothRel]';\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () {\r\n              return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y;\r\n          };\r\n          window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () {\r\n              return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y);\r\n          };\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, 'x', {\r\n              get: function () {\r\n                  return this._x;\r\n              },\r\n              set: function (x) {\r\n                  this._x = x;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, 'y', {\r\n              get: function () {\r\n                  return this._y;\r\n              },\r\n              set: function (y) {\r\n                  this._y = y;\r\n                  this._segmentChanged();\r\n              },\r\n              enumerable: true\r\n          });\r\n          // Add createSVGPathSeg* functions to window.SVGPathElement.\r\n          // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.\r\n          window.SVGPathElement.prototype.createSVGPathSegClosePath = function () {\r\n              return new window.SVGPathSegClosePath(undefined);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) {\r\n              return new window.SVGPathSegMovetoAbs(undefined, x, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) {\r\n              return new window.SVGPathSegMovetoRel(undefined, x, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) {\r\n              return new window.SVGPathSegLinetoAbs(undefined, x, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) {\r\n              return new window.SVGPathSegLinetoRel(undefined, x, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) {\r\n              return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) {\r\n              return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) {\r\n              return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) {\r\n              return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {\r\n              return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {\r\n              return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) {\r\n              return new window.SVGPathSegLinetoHorizontalAbs(undefined, x);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) {\r\n              return new window.SVGPathSegLinetoHorizontalRel(undefined, x);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) {\r\n              return new window.SVGPathSegLinetoVerticalAbs(undefined, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) {\r\n              return new window.SVGPathSegLinetoVerticalRel(undefined, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) {\r\n              return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) {\r\n              return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) {\r\n              return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y);\r\n          };\r\n          window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) {\r\n              return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y);\r\n          };\r\n          if (!('getPathSegAtLength' in window.SVGPathElement.prototype)) {\r\n              // Add getPathSegAtLength to SVGPathElement.\r\n              // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength\r\n              // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.\r\n              window.SVGPathElement.prototype.getPathSegAtLength = function (distance) {\r\n                  if (distance === undefined || !isFinite(distance))\r\n                      throw 'Invalid arguments.';\r\n                  var measurementElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');\r\n                  measurementElement.setAttribute('d', this.getAttribute('d'));\r\n                  var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1;\r\n                  // If the path is empty, return 0.\r\n                  if (lastPathSegment <= 0)\r\n                      return 0;\r\n                  do {\r\n                      measurementElement.pathSegList.removeItem(lastPathSegment);\r\n                      if (distance > measurementElement.getTotalLength())\r\n                          break;\r\n                      lastPathSegment--;\r\n                  } while (lastPathSegment > 0);\r\n                  return lastPathSegment;\r\n              };\r\n          }\r\n      }\r\n      if (!('SVGPathSegList' in window)) {\r\n          // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList\r\n          window.SVGPathSegList = function (pathElement) {\r\n              this._pathElement = pathElement;\r\n              this._list = this._parsePath(this._pathElement.getAttribute('d'));\r\n              // Use a MutationObserver to catch changes to the path's \"d\" attribute.\r\n              this._mutationObserverConfig = {\r\n                  attributes: true,\r\n                  attributeFilter: ['d']\r\n              };\r\n              this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this));\r\n              this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);\r\n          };\r\n          window.SVGPathSegList.prototype.classname = 'SVGPathSegList';\r\n          Object.defineProperty(window.SVGPathSegList.prototype, 'numberOfItems', {\r\n              get: function () {\r\n                  this._checkPathSynchronizedToList();\r\n                  return this._list.length;\r\n              },\r\n              enumerable: true\r\n          });\r\n          // Add the pathSegList accessors to window.SVGPathElement.\r\n          // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData\r\n          Object.defineProperty(window.SVGPathElement.prototype, 'pathSegList', {\r\n              get: function () {\r\n                  if (!this._pathSegList)\r\n                      this._pathSegList = new window.SVGPathSegList(this);\r\n                  return this._pathSegList;\r\n              },\r\n              enumerable: true\r\n          });\r\n          // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.\r\n          Object.defineProperty(window.SVGPathElement.prototype, 'normalizedPathSegList', {\r\n              get: function () {\r\n                  return this.pathSegList;\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathElement.prototype, 'animatedPathSegList', {\r\n              get: function () {\r\n                  return this.pathSegList;\r\n              },\r\n              enumerable: true\r\n          });\r\n          Object.defineProperty(window.SVGPathElement.prototype, 'animatedNormalizedPathSegList', {\r\n              get: function () {\r\n                  return this.pathSegList;\r\n              },\r\n              enumerable: true\r\n          });\r\n          // Process any pending mutations to the path element and update the list as needed.\r\n          // This should be the first call of all public functions and is needed because\r\n          // MutationObservers are not synchronous so we can have pending asynchronous mutations.\r\n          window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () {\r\n              this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());\r\n          };\r\n          window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) {\r\n              if (!this._pathElement)\r\n                  return;\r\n              var hasPathMutations = false;\r\n              mutationRecords.forEach(function (record) {\r\n                  if (record.attributeName == 'd')\r\n                      hasPathMutations = true;\r\n              });\r\n              if (hasPathMutations)\r\n                  this._list = this._parsePath(this._pathElement.getAttribute('d'));\r\n          };\r\n          // Serialize the list and update the path's 'd' attribute.\r\n          window.SVGPathSegList.prototype._writeListToPath = function () {\r\n              this._pathElementMutationObserver.disconnect();\r\n              this._pathElement.setAttribute('d', window.SVGPathSegList._pathSegArrayAsString(this._list));\r\n              this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);\r\n          };\r\n          // When a path segment changes the list needs to be synchronized back to the path element.\r\n          window.SVGPathSegList.prototype.segmentChanged = function (pathSeg) {\r\n              this._writeListToPath();\r\n          };\r\n          window.SVGPathSegList.prototype.clear = function () {\r\n              this._checkPathSynchronizedToList();\r\n              this._list.forEach(function (pathSeg) {\r\n                  pathSeg._owningPathSegList = null;\r\n              });\r\n              this._list = [];\r\n              this._writeListToPath();\r\n          };\r\n          window.SVGPathSegList.prototype.initialize = function (newItem) {\r\n              this._checkPathSynchronizedToList();\r\n              this._list = [newItem];\r\n              newItem._owningPathSegList = this;\r\n              this._writeListToPath();\r\n              return newItem;\r\n          };\r\n          window.SVGPathSegList.prototype._checkValidIndex = function (index) {\r\n              if (isNaN(index) || index < 0 || index >= this.numberOfItems)\r\n                  throw 'INDEX_SIZE_ERR';\r\n          };\r\n          window.SVGPathSegList.prototype.getItem = function (index) {\r\n              this._checkPathSynchronizedToList();\r\n              this._checkValidIndex(index);\r\n              return this._list[index];\r\n          };\r\n          window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) {\r\n              this._checkPathSynchronizedToList();\r\n              // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.\r\n              if (index > this.numberOfItems)\r\n                  index = this.numberOfItems;\r\n              if (newItem._owningPathSegList) {\r\n                  // SVG2 spec says to make a copy.\r\n                  newItem = newItem.clone();\r\n              }\r\n              this._list.splice(index, 0, newItem);\r\n              newItem._owningPathSegList = this;\r\n              this._writeListToPath();\r\n              return newItem;\r\n          };\r\n          window.SVGPathSegList.prototype.replaceItem = function (newItem, index) {\r\n              this._checkPathSynchronizedToList();\r\n              if (newItem._owningPathSegList) {\r\n                  // SVG2 spec says to make a copy.\r\n                  newItem = newItem.clone();\r\n              }\r\n              this._checkValidIndex(index);\r\n              this._list[index] = newItem;\r\n              newItem._owningPathSegList = this;\r\n              this._writeListToPath();\r\n              return newItem;\r\n          };\r\n          window.SVGPathSegList.prototype.removeItem = function (index) {\r\n              this._checkPathSynchronizedToList();\r\n              this._checkValidIndex(index);\r\n              var item = this._list[index];\r\n              this._list.splice(index, 1);\r\n              this._writeListToPath();\r\n              return item;\r\n          };\r\n          window.SVGPathSegList.prototype.appendItem = function (newItem) {\r\n              this._checkPathSynchronizedToList();\r\n              if (newItem._owningPathSegList) {\r\n                  // SVG2 spec says to make a copy.\r\n                  newItem = newItem.clone();\r\n              }\r\n              this._list.push(newItem);\r\n              newItem._owningPathSegList = this;\r\n              // TODO: Optimize this to just append to the existing attribute.\r\n              this._writeListToPath();\r\n              return newItem;\r\n          };\r\n          window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) {\r\n              var string = '';\r\n              var first = true;\r\n              pathSegArray.forEach(function (pathSeg) {\r\n                  if (first) {\r\n                      first = false;\r\n                      string += pathSeg._asPathString();\r\n                  }\r\n                  else {\r\n                      string += ' ' + pathSeg._asPathString();\r\n                  }\r\n              });\r\n              return string;\r\n          };\r\n          // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.\r\n          window.SVGPathSegList.prototype._parsePath = function (string) {\r\n              if (!string || string.length == 0)\r\n                  return [];\r\n              var owningPathSegList = this;\r\n              var Builder = function () {\r\n                  this.pathSegList = [];\r\n              };\r\n              Builder.prototype.appendSegment = function (pathSeg) {\r\n                  this.pathSegList.push(pathSeg);\r\n              };\r\n              var Source = function (string) {\r\n                  this._string = string;\r\n                  this._currentIndex = 0;\r\n                  this._endIndex = this._string.length;\r\n                  this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;\r\n                  this._skipOptionalSpaces();\r\n              };\r\n              Source.prototype._isCurrentSpace = function () {\r\n                  var character = this._string[this._currentIndex];\r\n                  return (character <= ' ' &&\r\n                      (character == ' ' ||\r\n                          character == '\\n' ||\r\n                          character == '\\t' ||\r\n                          character == '\\r' ||\r\n                          character == '\\f'));\r\n              };\r\n              Source.prototype._skipOptionalSpaces = function () {\r\n                  while (this._currentIndex < this._endIndex && this._isCurrentSpace())\r\n                      this._currentIndex++;\r\n                  return this._currentIndex < this._endIndex;\r\n              };\r\n              Source.prototype._skipOptionalSpacesOrDelimiter = function () {\r\n                  if (this._currentIndex < this._endIndex &&\r\n                      !this._isCurrentSpace() &&\r\n                      this._string.charAt(this._currentIndex) != ',')\r\n                      return false;\r\n                  if (this._skipOptionalSpaces()) {\r\n                      if (this._currentIndex < this._endIndex &&\r\n                          this._string.charAt(this._currentIndex) == ',') {\r\n                          this._currentIndex++;\r\n                          this._skipOptionalSpaces();\r\n                      }\r\n                  }\r\n                  return this._currentIndex < this._endIndex;\r\n              };\r\n              Source.prototype.hasMoreData = function () {\r\n                  return this._currentIndex < this._endIndex;\r\n              };\r\n              Source.prototype.peekSegmentType = function () {\r\n                  var lookahead = this._string[this._currentIndex];\r\n                  return this._pathSegTypeFromChar(lookahead);\r\n              };\r\n              Source.prototype._pathSegTypeFromChar = function (lookahead) {\r\n                  switch (lookahead) {\r\n                      case 'Z':\r\n                      case 'z':\r\n                          return window.SVGPathSeg.PATHSEG_CLOSEPATH;\r\n                      case 'M':\r\n                          return window.SVGPathSeg.PATHSEG_MOVETO_ABS;\r\n                      case 'm':\r\n                          return window.SVGPathSeg.PATHSEG_MOVETO_REL;\r\n                      case 'L':\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_ABS;\r\n                      case 'l':\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_REL;\r\n                      case 'C':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;\r\n                      case 'c':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;\r\n                      case 'Q':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;\r\n                      case 'q':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;\r\n                      case 'A':\r\n                          return window.SVGPathSeg.PATHSEG_ARC_ABS;\r\n                      case 'a':\r\n                          return window.SVGPathSeg.PATHSEG_ARC_REL;\r\n                      case 'H':\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;\r\n                      case 'h':\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;\r\n                      case 'V':\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;\r\n                      case 'v':\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;\r\n                      case 'S':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;\r\n                      case 's':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;\r\n                      case 'T':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;\r\n                      case 't':\r\n                          return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;\r\n                      default:\r\n                          return window.SVGPathSeg.PATHSEG_UNKNOWN;\r\n                  }\r\n              };\r\n              Source.prototype._nextCommandHelper = function (lookahead, previousCommand) {\r\n                  // Check for remaining coordinates in the current command.\r\n                  if ((lookahead == '+' ||\r\n                      lookahead == '-' ||\r\n                      lookahead == '.' ||\r\n                      (lookahead >= '0' && lookahead <= '9')) &&\r\n                      previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) {\r\n                      if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS)\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_ABS;\r\n                      if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL)\r\n                          return window.SVGPathSeg.PATHSEG_LINETO_REL;\r\n                      return previousCommand;\r\n                  }\r\n                  return window.SVGPathSeg.PATHSEG_UNKNOWN;\r\n              };\r\n              Source.prototype.initialCommandIsMoveTo = function () {\r\n                  // If the path is empty it is still valid, so return true.\r\n                  if (!this.hasMoreData())\r\n                      return true;\r\n                  var command = this.peekSegmentType();\r\n                  // Path must start with moveTo.\r\n                  return (command == window.SVGPathSeg.PATHSEG_MOVETO_ABS ||\r\n                      command == window.SVGPathSeg.PATHSEG_MOVETO_REL);\r\n              };\r\n              // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.\r\n              // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF\r\n              Source.prototype._parseNumber = function () {\r\n                  var exponent = 0;\r\n                  var integer = 0;\r\n                  var frac = 1;\r\n                  var decimal = 0;\r\n                  var sign = 1;\r\n                  var expsign = 1;\r\n                  var startIndex = this._currentIndex;\r\n                  this._skipOptionalSpaces();\r\n                  // Read the sign.\r\n                  if (this._currentIndex < this._endIndex &&\r\n                      this._string.charAt(this._currentIndex) == '+')\r\n                      this._currentIndex++;\r\n                  else if (this._currentIndex < this._endIndex &&\r\n                      this._string.charAt(this._currentIndex) == '-') {\r\n                      this._currentIndex++;\r\n                      sign = -1;\r\n                  }\r\n                  if (this._currentIndex == this._endIndex ||\r\n                      ((this._string.charAt(this._currentIndex) < '0' ||\r\n                          this._string.charAt(this._currentIndex) > '9') &&\r\n                          this._string.charAt(this._currentIndex) != '.'))\r\n                      // The first character of a number must be one of [0-9+-.].\r\n                      return undefined;\r\n                  // Read the integer part, build right-to-left.\r\n                  var startIntPartIndex = this._currentIndex;\r\n                  while (this._currentIndex < this._endIndex &&\r\n                      this._string.charAt(this._currentIndex) >= '0' &&\r\n                      this._string.charAt(this._currentIndex) <= '9')\r\n                      this._currentIndex++; // Advance to first non-digit.\r\n                  if (this._currentIndex != startIntPartIndex) {\r\n                      var scanIntPartIndex = this._currentIndex - 1;\r\n                      var multiplier = 1;\r\n                      while (scanIntPartIndex >= startIntPartIndex) {\r\n                          integer +=\r\n                              multiplier * (this._string.charAt(scanIntPartIndex--) - '0');\r\n                          multiplier *= 10;\r\n                      }\r\n                  }\r\n                  // Read the decimals.\r\n                  if (this._currentIndex < this._endIndex &&\r\n                      this._string.charAt(this._currentIndex) == '.') {\r\n                      this._currentIndex++;\r\n                      // There must be a least one digit following the .\r\n                      if (this._currentIndex >= this._endIndex ||\r\n                          this._string.charAt(this._currentIndex) < '0' ||\r\n                          this._string.charAt(this._currentIndex) > '9')\r\n                          return undefined;\r\n                      while (this._currentIndex < this._endIndex &&\r\n                          this._string.charAt(this._currentIndex) >= '0' &&\r\n                          this._string.charAt(this._currentIndex) <= '9') {\r\n                          frac *= 10;\r\n                          decimal += (this._string.charAt(this._currentIndex) - '0') / frac;\r\n                          this._currentIndex += 1;\r\n                      }\r\n                  }\r\n                  // Read the exponent part.\r\n                  if (this._currentIndex != startIndex &&\r\n                      this._currentIndex + 1 < this._endIndex &&\r\n                      (this._string.charAt(this._currentIndex) == 'e' ||\r\n                          this._string.charAt(this._currentIndex) == 'E') &&\r\n                      this._string.charAt(this._currentIndex + 1) != 'x' &&\r\n                      this._string.charAt(this._currentIndex + 1) != 'm') {\r\n                      this._currentIndex++;\r\n                      // Read the sign of the exponent.\r\n                      if (this._string.charAt(this._currentIndex) == '+') {\r\n                          this._currentIndex++;\r\n                      }\r\n                      else if (this._string.charAt(this._currentIndex) == '-') {\r\n                          this._currentIndex++;\r\n                          expsign = -1;\r\n                      }\r\n                      // There must be an exponent.\r\n                      if (this._currentIndex >= this._endIndex ||\r\n                          this._string.charAt(this._currentIndex) < '0' ||\r\n                          this._string.charAt(this._currentIndex) > '9')\r\n                          return undefined;\r\n                      while (this._currentIndex < this._endIndex &&\r\n                          this._string.charAt(this._currentIndex) >= '0' &&\r\n                          this._string.charAt(this._currentIndex) <= '9') {\r\n                          exponent *= 10;\r\n                          exponent += this._string.charAt(this._currentIndex) - '0';\r\n                          this._currentIndex++;\r\n                      }\r\n                  }\r\n                  var number = integer + decimal;\r\n                  number *= sign;\r\n                  if (exponent)\r\n                      number *= Math.pow(10, expsign * exponent);\r\n                  if (startIndex == this._currentIndex)\r\n                      return undefined;\r\n                  this._skipOptionalSpacesOrDelimiter();\r\n                  return number;\r\n              };\r\n              Source.prototype._parseArcFlag = function () {\r\n                  if (this._currentIndex >= this._endIndex)\r\n                      return undefined;\r\n                  var flag = false;\r\n                  var flagChar = this._string.charAt(this._currentIndex++);\r\n                  if (flagChar == '0')\r\n                      flag = false;\r\n                  else if (flagChar == '1')\r\n                      flag = true;\r\n                  else\r\n                      return undefined;\r\n                  this._skipOptionalSpacesOrDelimiter();\r\n                  return flag;\r\n              };\r\n              Source.prototype.parseSegment = function () {\r\n                  var lookahead = this._string[this._currentIndex];\r\n                  var command = this._pathSegTypeFromChar(lookahead);\r\n                  if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {\r\n                      // Possibly an implicit command. Not allowed if this is the first command.\r\n                      if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN)\r\n                          return null;\r\n                      command = this._nextCommandHelper(lookahead, this._previousCommand);\r\n                      if (command == window.SVGPathSeg.PATHSEG_UNKNOWN)\r\n                          return null;\r\n                  }\r\n                  else {\r\n                      this._currentIndex++;\r\n                  }\r\n                  this._previousCommand = command;\r\n                  switch (command) {\r\n                      case window.SVGPathSeg.PATHSEG_MOVETO_REL:\r\n                          return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_MOVETO_ABS:\r\n                          return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_LINETO_REL:\r\n                          return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_LINETO_ABS:\r\n                          return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:\r\n                          return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:\r\n                          return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:\r\n                          return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:\r\n                          return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_CLOSEPATH:\r\n                          this._skipOptionalSpaces();\r\n                          return new window.SVGPathSegClosePath(owningPathSegList);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:\r\n                          var points = {\r\n                              x1: this._parseNumber(),\r\n                              y1: this._parseNumber(),\r\n                              x2: this._parseNumber(),\r\n                              y2: this._parseNumber(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:\r\n                          var points = {\r\n                              x1: this._parseNumber(),\r\n                              y1: this._parseNumber(),\r\n                              x2: this._parseNumber(),\r\n                              y2: this._parseNumber(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:\r\n                          var points = {\r\n                              x2: this._parseNumber(),\r\n                              y2: this._parseNumber(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:\r\n                          var points = {\r\n                              x2: this._parseNumber(),\r\n                              y2: this._parseNumber(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:\r\n                          var points = {\r\n                              x1: this._parseNumber(),\r\n                              y1: this._parseNumber(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:\r\n                          var points = {\r\n                              x1: this._parseNumber(),\r\n                              y1: this._parseNumber(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:\r\n                          return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:\r\n                          return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());\r\n                      case window.SVGPathSeg.PATHSEG_ARC_REL:\r\n                          var points = {\r\n                              x1: this._parseNumber(),\r\n                              y1: this._parseNumber(),\r\n                              arcAngle: this._parseNumber(),\r\n                              arcLarge: this._parseArcFlag(),\r\n                              arcSweep: this._parseArcFlag(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);\r\n                      case window.SVGPathSeg.PATHSEG_ARC_ABS:\r\n                          var points = {\r\n                              x1: this._parseNumber(),\r\n                              y1: this._parseNumber(),\r\n                              arcAngle: this._parseNumber(),\r\n                              arcLarge: this._parseArcFlag(),\r\n                              arcSweep: this._parseArcFlag(),\r\n                              x: this._parseNumber(),\r\n                              y: this._parseNumber()\r\n                          };\r\n                          return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);\r\n                      default:\r\n                          throw 'Unknown path seg type.';\r\n                  }\r\n              };\r\n              var builder = new Builder();\r\n              var source = new Source(string);\r\n              if (!source.initialCommandIsMoveTo())\r\n                  return [];\r\n              while (source.hasMoreData()) {\r\n                  var pathSeg = source.parseSegment();\r\n                  if (!pathSeg)\r\n                      return [];\r\n                  builder.appendSegment(pathSeg);\r\n              }\r\n              return builder.pathSegList;\r\n          };\r\n      }\r\n  })();\r\n  // String.padEnd polyfill for IE11\r\n  //\r\n  // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js\r\n  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd\r\n  if (!String.prototype.padEnd) {\r\n      String.prototype.padEnd = function padEnd(targetLength, padString) {\r\n          targetLength = targetLength >> 0; //floor if number or convert non-number to 0;\r\n          padString = String(typeof padString !== 'undefined' ? padString : ' ');\r\n          if (this.length > targetLength) {\r\n              return String(this);\r\n          }\r\n          else {\r\n              targetLength = targetLength - this.length;\r\n              if (targetLength > padString.length) {\r\n                  padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed\r\n              }\r\n              return String(this) + padString.slice(0, targetLength);\r\n          }\r\n      };\r\n  }\r\n  // Object.assign polyfill for IE11\r\n  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill\r\n  if (typeof Object.assign !== 'function') {\r\n      // Must be writable: true, enumerable: false, configurable: true\r\n      Object.defineProperty(Object, 'assign', {\r\n          value: function assign(target, varArgs) {\r\n              if (target === null || target === undefined) {\r\n                  throw new TypeError('Cannot convert undefined or null to object');\r\n              }\r\n              var to = Object(target);\r\n              for (var index = 1; index < arguments.length; index++) {\r\n                  var nextSource = arguments[index];\r\n                  if (nextSource !== null && nextSource !== undefined) {\r\n                      for (var nextKey in nextSource) {\r\n                          // Avoid bugs when hasOwnProperty is shadowed\r\n                          if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\r\n                              to[nextKey] = nextSource[nextKey];\r\n                          }\r\n                      }\r\n                  }\r\n              }\r\n              return to;\r\n          },\r\n          writable: true,\r\n          configurable: true\r\n      });\r\n  }\r\n  /* jshint ignore:end */\n\n  Chart.prototype.axis = function () { };\r\n  Chart.prototype.axis.labels = function (labels) {\r\n      var $$ = this.internal;\r\n      if (arguments.length) {\r\n          Object.keys(labels).forEach(function (axisId) {\r\n              $$.axis.setLabelText(axisId, labels[axisId]);\r\n          });\r\n          $$.axis.updateLabels();\r\n      }\r\n      // TODO: return some values?\r\n  };\r\n  Chart.prototype.axis.max = function (max) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (arguments.length) {\r\n          if (typeof max === 'object') {\r\n              if (isValue(max.x)) {\r\n                  config.axis_x_max = max.x;\r\n              }\r\n              if (isValue(max.y)) {\r\n                  config.axis_y_max = max.y;\r\n              }\r\n              if (isValue(max.y2)) {\r\n                  config.axis_y2_max = max.y2;\r\n              }\r\n          }\r\n          else {\r\n              config.axis_y_max = config.axis_y2_max = max;\r\n          }\r\n          $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\r\n      }\r\n      else {\r\n          return {\r\n              x: config.axis_x_max,\r\n              y: config.axis_y_max,\r\n              y2: config.axis_y2_max\r\n          };\r\n      }\r\n  };\r\n  Chart.prototype.axis.min = function (min) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (arguments.length) {\r\n          if (typeof min === 'object') {\r\n              if (isValue(min.x)) {\r\n                  config.axis_x_min = min.x;\r\n              }\r\n              if (isValue(min.y)) {\r\n                  config.axis_y_min = min.y;\r\n              }\r\n              if (isValue(min.y2)) {\r\n                  config.axis_y2_min = min.y2;\r\n              }\r\n          }\r\n          else {\r\n              config.axis_y_min = config.axis_y2_min = min;\r\n          }\r\n          $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\r\n      }\r\n      else {\r\n          return {\r\n              x: config.axis_x_min,\r\n              y: config.axis_y_min,\r\n              y2: config.axis_y2_min\r\n          };\r\n      }\r\n  };\r\n  Chart.prototype.axis.range = function (range) {\r\n      if (arguments.length) {\r\n          if (isDefined(range.max)) {\r\n              this.axis.max(range.max);\r\n          }\r\n          if (isDefined(range.min)) {\r\n              this.axis.min(range.min);\r\n          }\r\n      }\r\n      else {\r\n          return {\r\n              max: this.axis.max(),\r\n              min: this.axis.min()\r\n          };\r\n      }\r\n  };\r\n  Chart.prototype.axis.types = function (types) {\r\n      var $$ = this.internal;\r\n      if (types === undefined) {\r\n          return {\r\n              y: $$.config.axis_y_type,\r\n              y2: $$.config.axis_y2_type\r\n          };\r\n      }\r\n      else {\r\n          if (isDefined(types.y)) {\r\n              $$.config.axis_y_type = types.y;\r\n          }\r\n          if (isDefined(types.y2)) {\r\n              $$.config.axis_y2_type = types.y2;\r\n          }\r\n          $$.updateScales();\r\n          $$.redraw();\r\n      }\r\n  };\n\n  Chart.prototype.category = function (i, category) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (arguments.length > 1) {\r\n          config.axis_x_categories[i] = category;\r\n          $$.redraw();\r\n      }\r\n      return config.axis_x_categories[i];\r\n  };\r\n  Chart.prototype.categories = function (categories) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (!arguments.length) {\r\n          return config.axis_x_categories;\r\n      }\r\n      config.axis_x_categories = categories;\r\n      $$.redraw();\r\n      return config.axis_x_categories;\r\n  };\n\n  Chart.prototype.resize = function (size) {\r\n      var $$ = this.internal, config = $$.config;\r\n      config.size_width = size ? size.width : null;\r\n      config.size_height = size ? size.height : null;\r\n      this.flush();\r\n  };\r\n  Chart.prototype.flush = function () {\r\n      var $$ = this.internal;\r\n      $$.updateAndRedraw({\r\n          withLegend: true,\r\n          withTransition: false,\r\n          withTransitionForTransform: false\r\n      });\r\n  };\r\n  Chart.prototype.destroy = function () {\r\n      var $$ = this.internal;\r\n      window.clearInterval($$.intervalForObserveInserted);\r\n      if ($$.resizeTimeout !== undefined) {\r\n          window.clearTimeout($$.resizeTimeout);\r\n      }\r\n      window.removeEventListener('resize', $$.resizeIfElementDisplayed);\r\n      // Removes the inner resize functions\r\n      $$.resizeFunction.remove();\r\n      // Unbinds from the window focus event\r\n      $$.unbindWindowFocus();\r\n      $$.selectChart.classed('c3', false).html('');\r\n      // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen.\r\n      Object.keys($$).forEach(function (key) {\r\n          $$[key] = null;\r\n      });\r\n      return null;\r\n  };\n\n  // TODO: fix\r\n  Chart.prototype.color = function (id) {\r\n      var $$ = this.internal;\r\n      return $$.color(id); // more patterns\r\n  };\n\n  Chart.prototype.data = function (targetIds) {\r\n      var targets = this.internal.data.targets;\r\n      return typeof targetIds === 'undefined'\r\n          ? targets\r\n          : targets.filter(function (t) {\r\n              return [].concat(targetIds).indexOf(t.id) >= 0;\r\n          });\r\n  };\r\n  Chart.prototype.data.shown = function (targetIds) {\r\n      return this.internal.filterTargetsToShow(this.data(targetIds));\r\n  };\r\n  /**\r\n   * Get values of the data loaded in the chart.\r\n   *\r\n   * @param {String|Array} targetId This API returns the value of specified target.\r\n   * @param flat\r\n   * @return {Array} Data values\r\n   */\r\n  Chart.prototype.data.values = function (targetId, flat) {\r\n      if (flat === void 0) { flat = true; }\r\n      var values = null;\r\n      if (targetId) {\r\n          var targets = this.data(targetId);\r\n          if (targets && isArray(targets)) {\r\n              values = targets.reduce(function (ret, v) {\r\n                  var dataValue = v.values.map(function (d) { return d.value; });\r\n                  if (flat) {\r\n                      ret = ret.concat(dataValue);\r\n                  }\r\n                  else {\r\n                      ret.push(dataValue);\r\n                  }\r\n                  return ret;\r\n              }, []);\r\n          }\r\n      }\r\n      return values;\r\n  };\r\n  Chart.prototype.data.names = function (names) {\r\n      this.internal.clearLegendItemTextBoxCache();\r\n      return this.internal.updateDataAttributes('names', names);\r\n  };\r\n  Chart.prototype.data.colors = function (colors) {\r\n      return this.internal.updateDataAttributes('colors', colors);\r\n  };\r\n  Chart.prototype.data.axes = function (axes) {\r\n      return this.internal.updateDataAttributes('axes', axes);\r\n  };\r\n  Chart.prototype.data.stackNormalized = function (normalized) {\r\n      if (normalized === undefined) {\r\n          return this.internal.isStackNormalized();\r\n      }\r\n      this.internal.config.data_stack_normalize = !!normalized;\r\n      this.internal.redraw();\r\n  };\n\n  Chart.prototype.donut = function () { };\r\n  Chart.prototype.donut.padAngle = function (padAngle) {\r\n      if (padAngle === undefined) {\r\n          return this.internal.config.donut_padAngle;\r\n      }\r\n      this.internal.config.donut_padAngle = padAngle;\r\n      this.flush();\r\n  };\n\n  Chart.prototype.flow = function (args) {\r\n      var $$ = this.internal, targets, data, notfoundIds = [], orgDataCount = $$.getMaxDataCount(), dataCount, domain, baseTarget, baseValue, length = 0, tail = 0, diff, to;\r\n      if (args.json) {\r\n          data = $$.convertJsonToData(args.json, args.keys);\r\n      }\r\n      else if (args.rows) {\r\n          data = $$.convertRowsToData(args.rows);\r\n      }\r\n      else if (args.columns) {\r\n          data = $$.convertColumnsToData(args.columns);\r\n      }\r\n      else {\r\n          return;\r\n      }\r\n      targets = $$.convertDataToTargets(data, true);\r\n      // Update/Add data\r\n      $$.data.targets.forEach(function (t) {\r\n          var found = false, i, j;\r\n          for (i = 0; i < targets.length; i++) {\r\n              if (t.id === targets[i].id) {\r\n                  found = true;\r\n                  if (t.values[t.values.length - 1]) {\r\n                      tail = t.values[t.values.length - 1].index + 1;\r\n                  }\r\n                  length = targets[i].values.length;\r\n                  for (j = 0; j < length; j++) {\r\n                      targets[i].values[j].index = tail + j;\r\n                      if (!$$.isTimeSeries()) {\r\n                          targets[i].values[j].x = tail + j;\r\n                      }\r\n                  }\r\n                  t.values = t.values.concat(targets[i].values);\r\n                  targets.splice(i, 1);\r\n                  break;\r\n              }\r\n          }\r\n          if (!found) {\r\n              notfoundIds.push(t.id);\r\n          }\r\n      });\r\n      // Append null for not found targets\r\n      $$.data.targets.forEach(function (t) {\r\n          var i, j;\r\n          for (i = 0; i < notfoundIds.length; i++) {\r\n              if (t.id === notfoundIds[i]) {\r\n                  tail = t.values[t.values.length - 1].index + 1;\r\n                  for (j = 0; j < length; j++) {\r\n                      t.values.push({\r\n                          id: t.id,\r\n                          index: tail + j,\r\n                          x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,\r\n                          value: null\r\n                      });\r\n                  }\r\n              }\r\n          }\r\n      });\r\n      // Generate null values for new target\r\n      if ($$.data.targets.length) {\r\n          targets.forEach(function (t) {\r\n              var i, missing = [];\r\n              for (i = $$.data.targets[0].values[0].index; i < tail; i++) {\r\n                  missing.push({\r\n                      id: t.id,\r\n                      index: i,\r\n                      x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,\r\n                      value: null\r\n                  });\r\n              }\r\n              t.values.forEach(function (v) {\r\n                  v.index += tail;\r\n                  if (!$$.isTimeSeries()) {\r\n                      v.x += tail;\r\n                  }\r\n              });\r\n              t.values = missing.concat(t.values);\r\n          });\r\n      }\r\n      $$.data.targets = $$.data.targets.concat(targets); // add remained\r\n      // check data count because behavior needs to change when it's only one\r\n      dataCount = $$.getMaxDataCount();\r\n      baseTarget = $$.data.targets[0];\r\n      baseValue = baseTarget.values[0];\r\n      // Update length to flow if needed\r\n      if (isDefined(args.to)) {\r\n          length = 0;\r\n          to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to;\r\n          baseTarget.values.forEach(function (v) {\r\n              if (v.x < to) {\r\n                  length++;\r\n              }\r\n          });\r\n      }\r\n      else if (isDefined(args.length)) {\r\n          length = args.length;\r\n      }\r\n      // If only one data, update the domain to flow from left edge of the chart\r\n      if (!orgDataCount) {\r\n          if ($$.isTimeSeries()) {\r\n              if (baseTarget.values.length > 1) {\r\n                  diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x;\r\n              }\r\n              else {\r\n                  diff = baseValue.x - $$.getXDomain($$.data.targets)[0];\r\n              }\r\n          }\r\n          else {\r\n              diff = 1;\r\n          }\r\n          domain = [baseValue.x - diff, baseValue.x];\r\n          $$.updateXDomain(null, true, true, false, domain);\r\n      }\r\n      else if (orgDataCount === 1) {\r\n          if ($$.isTimeSeries()) {\r\n              diff =\r\n                  (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;\r\n              domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];\r\n              $$.updateXDomain(null, true, true, false, domain);\r\n          }\r\n      }\r\n      // Set targets\r\n      $$.updateTargets($$.data.targets);\r\n      // Redraw with new targets\r\n      $$.redraw({\r\n          flow: {\r\n              index: baseValue.index,\r\n              length: length,\r\n              duration: isValue(args.duration)\r\n                  ? args.duration\r\n                  : $$.config.transition_duration,\r\n              done: args.done,\r\n              orgDataCount: orgDataCount\r\n          },\r\n          withLegend: true,\r\n          withTransition: orgDataCount > 1,\r\n          withTrimXDomain: false,\r\n          withUpdateXAxis: true\r\n      });\r\n  };\r\n  ChartInternal.prototype.generateFlow = function (args) {\r\n      var $$ = this, config = $$.config, d3 = $$.d3;\r\n      return function () {\r\n          var targets = args.targets, flow = args.flow, drawBar = args.drawBar, drawLine = args.drawLine, drawArea = args.drawArea, cx = args.cx, cy = args.cy, xv = args.xv, xForText = args.xForText, yForText = args.yForText, duration = args.duration;\r\n          var translateX, scaleX = 1, transform, flowIndex = flow.index, flowLength = flow.length, flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex), flowEnd = $$.getValueOnIndex($$.data.targets[0].values, flowIndex + flowLength), orgDomain = $$.x.domain(), domain, durationForFlow = flow.duration || duration, done = flow.done || function () { }, wait = $$.generateWait();\r\n          var xgrid, xgridLines, mainRegion, mainText, mainBar, mainLine, mainArea, mainCircle;\r\n          // set flag\r\n          $$.flowing = true;\r\n          // remove head data after rendered\r\n          $$.data.targets.forEach(function (d) {\r\n              d.values.splice(0, flowLength);\r\n          });\r\n          // update x domain to generate axis elements for flow\r\n          domain = $$.updateXDomain(targets, true, true);\r\n          // update elements related to x scale\r\n          if ($$.updateXGrid) {\r\n              $$.updateXGrid(true);\r\n          }\r\n          xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid\r\n          xgridLines = $$.xgridLines || d3.selectAll([]);\r\n          mainRegion = $$.mainRegion || d3.selectAll([]);\r\n          mainText = $$.mainText || d3.selectAll([]);\r\n          mainBar = $$.mainBar || d3.selectAll([]);\r\n          mainLine = $$.mainLine || d3.selectAll([]);\r\n          mainArea = $$.mainArea || d3.selectAll([]);\r\n          mainCircle = $$.mainCircle || d3.selectAll([]);\r\n          // generate transform to flow\r\n          if (!flow.orgDataCount) {\r\n              // if empty\r\n              if ($$.data.targets[0].values.length !== 1) {\r\n                  translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);\r\n              }\r\n              else {\r\n                  if ($$.isTimeSeries()) {\r\n                      flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0);\r\n                      flowEnd = $$.getValueOnIndex($$.data.targets[0].values, $$.data.targets[0].values.length - 1);\r\n                      translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);\r\n                  }\r\n                  else {\r\n                      translateX = diffDomain(domain) / 2;\r\n                  }\r\n              }\r\n          }\r\n          else if (flow.orgDataCount === 1 ||\r\n              (flowStart && flowStart.x) === (flowEnd && flowEnd.x)) {\r\n              translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);\r\n          }\r\n          else {\r\n              if ($$.isTimeSeries()) {\r\n                  translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);\r\n              }\r\n              else {\r\n                  translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);\r\n              }\r\n          }\r\n          scaleX = diffDomain(orgDomain) / diffDomain(domain);\r\n          transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)';\r\n          $$.hideXGridFocus();\r\n          var flowTransition = d3\r\n              .transition()\r\n              .ease(d3.easeLinear)\r\n              .duration(durationForFlow);\r\n          wait.add($$.xAxis($$.axes.x, flowTransition));\r\n          wait.add(mainBar.transition(flowTransition).attr('transform', transform));\r\n          wait.add(mainLine.transition(flowTransition).attr('transform', transform));\r\n          wait.add(mainArea.transition(flowTransition).attr('transform', transform));\r\n          wait.add(mainCircle.transition(flowTransition).attr('transform', transform));\r\n          wait.add(mainText.transition(flowTransition).attr('transform', transform));\r\n          wait.add(mainRegion\r\n              .filter($$.isRegionOnX)\r\n              .transition(flowTransition)\r\n              .attr('transform', transform));\r\n          wait.add(xgrid.transition(flowTransition).attr('transform', transform));\r\n          wait.add(xgridLines.transition(flowTransition).attr('transform', transform));\r\n          wait(function () {\r\n              var i, shapes = [], texts = [];\r\n              // remove flowed elements\r\n              if (flowLength) {\r\n                  for (i = 0; i < flowLength; i++) {\r\n                      shapes.push('.' + CLASS.shape + '-' + (flowIndex + i));\r\n                      texts.push('.' + CLASS.text + '-' + (flowIndex + i));\r\n                  }\r\n                  $$.svg\r\n                      .selectAll('.' + CLASS.shapes)\r\n                      .selectAll(shapes)\r\n                      .remove();\r\n                  $$.svg\r\n                      .selectAll('.' + CLASS.texts)\r\n                      .selectAll(texts)\r\n                      .remove();\r\n                  $$.svg.select('.' + CLASS.xgrid).remove();\r\n              }\r\n              // draw again for removing flowed elements and reverting attr\r\n              xgrid\r\n                  .attr('transform', null)\r\n                  .attr('x1', $$.xgridAttr.x1)\r\n                  .attr('x2', $$.xgridAttr.x2)\r\n                  .attr('y1', $$.xgridAttr.y1)\r\n                  .attr('y2', $$.xgridAttr.y2)\r\n                  .style('opacity', $$.xgridAttr.opacity);\r\n              xgridLines.attr('transform', null);\r\n              xgridLines\r\n                  .select('line')\r\n                  .attr('x1', config.axis_rotated ? 0 : xv)\r\n                  .attr('x2', config.axis_rotated ? $$.width : xv);\r\n              xgridLines\r\n                  .select('text')\r\n                  .attr('x', config.axis_rotated ? $$.width : 0)\r\n                  .attr('y', xv);\r\n              mainBar.attr('transform', null).attr('d', drawBar);\r\n              mainLine.attr('transform', null).attr('d', drawLine);\r\n              mainArea.attr('transform', null).attr('d', drawArea);\r\n              mainCircle\r\n                  .attr('transform', null)\r\n                  .attr('cx', cx)\r\n                  .attr('cy', cy);\r\n              mainText\r\n                  .attr('transform', null)\r\n                  .attr('x', xForText)\r\n                  .attr('y', yForText)\r\n                  .style('fill-opacity', $$.opacityForText.bind($$));\r\n              mainRegion.attr('transform', null);\r\n              mainRegion\r\n                  .filter($$.isRegionOnX)\r\n                  .attr('x', $$.regionX.bind($$))\r\n                  .attr('width', $$.regionWidth.bind($$));\r\n              // callback for end of flow\r\n              done();\r\n              $$.flowing = false;\r\n          });\r\n      };\r\n  };\n\n  Chart.prototype.focus = function (targetIds) {\r\n      var $$ = this.internal, candidates;\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      (candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$)))),\r\n          this.revert();\r\n      this.defocus();\r\n      candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false);\r\n      if ($$.hasArcType()) {\r\n          $$.expandArc(targetIds);\r\n      }\r\n      $$.toggleFocusLegend(targetIds, true);\r\n      $$.focusedTargetIds = targetIds;\r\n      $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function (id) {\r\n          return targetIds.indexOf(id) < 0;\r\n      });\r\n  };\r\n  Chart.prototype.defocus = function (targetIds) {\r\n      var $$ = this.internal, candidates;\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      (candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$)))),\r\n          candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true);\r\n      if ($$.hasArcType()) {\r\n          $$.unexpandArc(targetIds);\r\n      }\r\n      $$.toggleFocusLegend(targetIds, false);\r\n      $$.focusedTargetIds = $$.focusedTargetIds.filter(function (id) {\r\n          return targetIds.indexOf(id) < 0;\r\n      });\r\n      $$.defocusedTargetIds = targetIds;\r\n  };\r\n  Chart.prototype.revert = function (targetIds) {\r\n      var $$ = this.internal, candidates;\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets\r\n      candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false);\r\n      if ($$.hasArcType()) {\r\n          $$.unexpandArc(targetIds);\r\n      }\r\n      if ($$.config.legend_show) {\r\n          $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$)));\r\n          $$.legend\r\n              .selectAll($$.selectorLegends(targetIds))\r\n              .filter(function () {\r\n              return $$.d3.select(this).classed(CLASS.legendItemFocused);\r\n          })\r\n              .classed(CLASS.legendItemFocused, false);\r\n      }\r\n      $$.focusedTargetIds = [];\r\n      $$.defocusedTargetIds = [];\r\n  };\n\n  Chart.prototype.xgrids = function (grids) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (!grids) {\r\n          return config.grid_x_lines;\r\n      }\r\n      config.grid_x_lines = grids;\r\n      $$.redrawWithoutRescale();\r\n      return config.grid_x_lines;\r\n  };\r\n  Chart.prototype.xgrids.add = function (grids) {\r\n      var $$ = this.internal;\r\n      return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : []));\r\n  };\r\n  Chart.prototype.xgrids.remove = function (params) {\r\n      // TODO: multiple\r\n      var $$ = this.internal;\r\n      $$.removeGridLines(params, true);\r\n  };\r\n  Chart.prototype.ygrids = function (grids) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (!grids) {\r\n          return config.grid_y_lines;\r\n      }\r\n      config.grid_y_lines = grids;\r\n      $$.redrawWithoutRescale();\r\n      return config.grid_y_lines;\r\n  };\r\n  Chart.prototype.ygrids.add = function (grids) {\r\n      var $$ = this.internal;\r\n      return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : []));\r\n  };\r\n  Chart.prototype.ygrids.remove = function (params) {\r\n      // TODO: multiple\r\n      var $$ = this.internal;\r\n      $$.removeGridLines(params, false);\r\n  };\n\n  Chart.prototype.groups = function (groups) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (isUndefined(groups)) {\r\n          return config.data_groups;\r\n      }\r\n      config.data_groups = groups;\r\n      $$.redraw();\r\n      return config.data_groups;\r\n  };\n\n  Chart.prototype.legend = function () { };\r\n  Chart.prototype.legend.show = function (targetIds) {\r\n      var $$ = this.internal;\r\n      $$.showLegend($$.mapToTargetIds(targetIds));\r\n      $$.updateAndRedraw({ withLegend: true });\r\n  };\r\n  Chart.prototype.legend.hide = function (targetIds) {\r\n      var $$ = this.internal;\r\n      $$.hideLegend($$.mapToTargetIds(targetIds));\r\n      $$.updateAndRedraw({ withLegend: false });\r\n  };\n\n  Chart.prototype.load = function (args) {\r\n      var $$ = this.internal, config = $$.config;\r\n      // update xs if specified\r\n      if (args.xs) {\r\n          $$.addXs(args.xs);\r\n      }\r\n      // update names if exists\r\n      if ('names' in args) {\r\n          Chart.prototype.data.names.bind(this)(args.names);\r\n      }\r\n      // update classes if exists\r\n      if ('classes' in args) {\r\n          Object.keys(args.classes).forEach(function (id) {\r\n              config.data_classes[id] = args.classes[id];\r\n          });\r\n      }\r\n      // update categories if exists\r\n      if ('categories' in args && $$.isCategorized()) {\r\n          config.axis_x_categories = args.categories;\r\n      }\r\n      // update axes if exists\r\n      if ('axes' in args) {\r\n          Object.keys(args.axes).forEach(function (id) {\r\n              config.data_axes[id] = args.axes[id];\r\n          });\r\n      }\r\n      // update colors if exists\r\n      if ('colors' in args) {\r\n          Object.keys(args.colors).forEach(function (id) {\r\n              config.data_colors[id] = args.colors[id];\r\n          });\r\n      }\r\n      // use cache if exists\r\n      if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) {\r\n          $$.load($$.getCaches(args.cacheIds), args.done);\r\n          return;\r\n      }\r\n      // unload if needed\r\n      if (args.unload) {\r\n          // TODO: do not unload if target will load (included in url/rows/columns)\r\n          $$.unload($$.mapToTargetIds(args.unload === true ? null : args.unload), function () {\r\n              $$.loadFromArgs(args);\r\n          });\r\n      }\r\n      else {\r\n          $$.loadFromArgs(args);\r\n      }\r\n  };\r\n  Chart.prototype.unload = function (args) {\r\n      var $$ = this.internal;\r\n      args = args || {};\r\n      if (args instanceof Array) {\r\n          args = { ids: args };\r\n      }\r\n      else if (typeof args === 'string') {\r\n          args = { ids: [args] };\r\n      }\r\n      $$.unload($$.mapToTargetIds(args.ids), function () {\r\n          $$.redraw({\r\n              withUpdateOrgXDomain: true,\r\n              withUpdateXDomain: true,\r\n              withLegend: true\r\n          });\r\n          if (args.done) {\r\n              args.done();\r\n          }\r\n      });\r\n  };\n\n  Chart.prototype.pie = function () { };\r\n  Chart.prototype.pie.padAngle = function (padAngle) {\r\n      if (padAngle === undefined) {\r\n          return this.internal.config.pie_padAngle;\r\n      }\r\n      this.internal.config.pie_padAngle = padAngle;\r\n      this.flush();\r\n  };\n\n  Chart.prototype.regions = function (regions) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (!regions) {\r\n          return config.regions;\r\n      }\r\n      config.regions = regions;\r\n      $$.redrawWithoutRescale();\r\n      return config.regions;\r\n  };\r\n  Chart.prototype.regions.add = function (regions) {\r\n      var $$ = this.internal, config = $$.config;\r\n      if (!regions) {\r\n          return config.regions;\r\n      }\r\n      config.regions = config.regions.concat(regions);\r\n      $$.redrawWithoutRescale();\r\n      return config.regions;\r\n  };\r\n  Chart.prototype.regions.remove = function (options) {\r\n      var $$ = this.internal, config = $$.config, duration, classes, regions;\r\n      options = options || {};\r\n      duration = getOption(options, 'duration', config.transition_duration);\r\n      classes = getOption(options, 'classes', [CLASS.region]);\r\n      regions = $$.main.select('.' + CLASS.regions).selectAll(classes.map(function (c) {\r\n          return '.' + c;\r\n      }));\r\n      (duration ? regions.transition().duration(duration) : regions)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      config.regions = config.regions.filter(function (region) {\r\n          var found = false;\r\n          if (!region['class']) {\r\n              return true;\r\n          }\r\n          region['class'].split(' ').forEach(function (c) {\r\n              if (classes.indexOf(c) >= 0) {\r\n                  found = true;\r\n              }\r\n          });\r\n          return !found;\r\n      });\r\n      return config.regions;\r\n  };\n\n  Chart.prototype.selected = function (targetId) {\r\n      var $$ = this.internal, d3 = $$.d3;\r\n      return $$.main\r\n          .selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId))\r\n          .selectAll('.' + CLASS.shape)\r\n          .filter(function () {\r\n          return d3.select(this).classed(CLASS.SELECTED);\r\n      })\r\n          .nodes()\r\n          .map(function (d) {\r\n          var data = d.__data__;\r\n          return data.data ? data.data : data;\r\n      });\r\n  };\r\n  Chart.prototype.select = function (ids, indices, resetOther) {\r\n      var $$ = this.internal, d3 = $$.d3, config = $$.config;\r\n      if (!config.data_selection_enabled) {\r\n          return;\r\n      }\r\n      $$.main\r\n          .selectAll('.' + CLASS.shapes)\r\n          .selectAll('.' + CLASS.shape)\r\n          .each(function (d, i) {\r\n          var shape = d3.select(this), id = d.data ? d.data.id : d.id, toggle = $$.getToggle(this, d).bind($$), isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, isTargetIndex = !indices || indices.indexOf(i) >= 0, isSelected = shape.classed(CLASS.SELECTED);\r\n          // line/area selection not supported yet\r\n          if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {\r\n              return;\r\n          }\r\n          if (isTargetId && isTargetIndex) {\r\n              if (config.data_selection_isselectable(d) && !isSelected) {\r\n                  toggle(true, shape.classed(CLASS.SELECTED, true), d, i);\r\n              }\r\n          }\r\n          else if (isDefined(resetOther) && resetOther) {\r\n              if (isSelected) {\r\n                  toggle(false, shape.classed(CLASS.SELECTED, false), d, i);\r\n              }\r\n          }\r\n      });\r\n  };\r\n  Chart.prototype.unselect = function (ids, indices) {\r\n      var $$ = this.internal, d3 = $$.d3, config = $$.config;\r\n      if (!config.data_selection_enabled) {\r\n          return;\r\n      }\r\n      $$.main\r\n          .selectAll('.' + CLASS.shapes)\r\n          .selectAll('.' + CLASS.shape)\r\n          .each(function (d, i) {\r\n          var shape = d3.select(this), id = d.data ? d.data.id : d.id, toggle = $$.getToggle(this, d).bind($$), isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0, isTargetIndex = !indices || indices.indexOf(i) >= 0, isSelected = shape.classed(CLASS.SELECTED);\r\n          // line/area selection not supported yet\r\n          if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {\r\n              return;\r\n          }\r\n          if (isTargetId && isTargetIndex) {\r\n              if (config.data_selection_isselectable(d)) {\r\n                  if (isSelected) {\r\n                      toggle(false, shape.classed(CLASS.SELECTED, false), d, i);\r\n                  }\r\n              }\r\n          }\r\n      });\r\n  };\n\n  Chart.prototype.show = function (targetIds, options) {\r\n      var $$ = this.internal, targets;\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      options = options || {};\r\n      $$.removeHiddenTargetIds(targetIds);\r\n      targets = $$.svg.selectAll($$.selectorTargets(targetIds));\r\n      targets\r\n          .transition()\r\n          .style('display', isIE() ? 'block' : 'initial', 'important')\r\n          .style('opacity', 1, 'important')\r\n          .call($$.endall, function () {\r\n          targets.style('opacity', null).style('opacity', 1);\r\n      });\r\n      if (options.withLegend) {\r\n          $$.showLegend(targetIds);\r\n      }\r\n      $$.redraw({\r\n          withUpdateOrgXDomain: true,\r\n          withUpdateXDomain: true,\r\n          withLegend: true\r\n      });\r\n  };\r\n  Chart.prototype.hide = function (targetIds, options) {\r\n      var $$ = this.internal, targets;\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      options = options || {};\r\n      $$.addHiddenTargetIds(targetIds);\r\n      targets = $$.svg.selectAll($$.selectorTargets(targetIds));\r\n      targets\r\n          .transition()\r\n          .style('opacity', 0, 'important')\r\n          .call($$.endall, function () {\r\n          targets.style('opacity', null).style('opacity', 0);\r\n          targets.style('display', 'none');\r\n      });\r\n      if (options.withLegend) {\r\n          $$.hideLegend(targetIds);\r\n      }\r\n      $$.redraw({\r\n          withUpdateOrgXDomain: true,\r\n          withUpdateXDomain: true,\r\n          withLegend: true\r\n      });\r\n  };\r\n  Chart.prototype.toggle = function (targetIds, options) {\r\n      var that = this, $$ = this.internal;\r\n      $$.mapToTargetIds(targetIds).forEach(function (targetId) {\r\n          $$.isTargetToShow(targetId)\r\n              ? that.hide(targetId, options)\r\n              : that.show(targetId, options);\r\n      });\r\n  };\n\n  Chart.prototype.subchart = function () { };\r\n  Chart.prototype.subchart.isShown = function () {\r\n      var $$ = this.internal;\r\n      return $$.config.subchart_show;\r\n  };\r\n  Chart.prototype.subchart.show = function () {\r\n      var $$ = this.internal;\r\n      if ($$.config.subchart_show) {\r\n          return;\r\n      }\r\n      $$.config.subchart_show = true;\r\n      // insert DOM\r\n      $$.initSubchart();\r\n      // update dimensions with sub chart now visible\r\n      $$.updateDimension();\r\n      // insert brush (depends on sizes previously updated)\r\n      $$.initSubchartBrush();\r\n      // attach data\r\n      $$.updateTargetsForSubchart($$.getTargets());\r\n      // reset fade-in state\r\n      $$.mapToIds($$.data.targets).forEach(function (id) {\r\n          $$.withoutFadeIn[id] = false;\r\n      });\r\n      // redraw chart !\r\n      $$.updateAndRedraw();\r\n      // update visible targets !\r\n      $$.showTargets();\r\n  };\r\n  Chart.prototype.subchart.hide = function () {\r\n      var $$ = this.internal;\r\n      if (!$$.config.subchart_show) {\r\n          return;\r\n      }\r\n      $$.config.subchart_show = false;\r\n      // remove DOM\r\n      $$.removeSubchart();\r\n      // re-render chart\r\n      $$.redraw();\r\n  };\n\n  Chart.prototype.tooltip = function () { };\r\n  Chart.prototype.tooltip.show = function (args) {\r\n      var $$ = this.internal, targets, data, mouse = {};\r\n      // determine mouse position on the chart\r\n      if (args.mouse) {\r\n          mouse = args.mouse;\r\n      }\r\n      else {\r\n          // determine focus data\r\n          if (args.data) {\r\n              data = args.data;\r\n          }\r\n          else if (typeof args.x !== 'undefined') {\r\n              if (args.id) {\r\n                  targets = $$.data.targets.filter(function (t) {\r\n                      return t.id === args.id;\r\n                  });\r\n              }\r\n              else {\r\n                  targets = $$.data.targets;\r\n              }\r\n              data = $$.filterByX(targets, args.x).slice(0, 1)[0];\r\n          }\r\n          mouse = data ? $$.getMousePosition(data) : null;\r\n      }\r\n      // emulate mouse events to show\r\n      $$.dispatchEvent('mousemove', mouse);\r\n      $$.config.tooltip_onshow.call($$, data);\r\n  };\r\n  Chart.prototype.tooltip.hide = function () {\r\n      // TODO: get target data by checking the state of focus\r\n      this.internal.dispatchEvent('mouseout', 0);\r\n      this.internal.config.tooltip_onhide.call(this);\r\n  };\n\n  Chart.prototype.transform = function (type, targetIds) {\r\n      var $$ = this.internal, options = ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null;\r\n      $$.transformTo(targetIds, type, options);\r\n  };\r\n  ChartInternal.prototype.transformTo = function (targetIds, type, optionsForRedraw) {\r\n      var $$ = this, withTransitionForAxis = !$$.hasArcType(), options = optionsForRedraw || {\r\n          withTransitionForAxis: withTransitionForAxis\r\n      };\r\n      options.withTransitionForTransform = false;\r\n      $$.transiting = false;\r\n      $$.setTargetType(targetIds, type);\r\n      $$.updateTargets($$.data.targets); // this is needed when transforming to arc\r\n      $$.updateAndRedraw(options);\r\n  };\n\n  Chart.prototype.x = function (x) {\r\n      var $$ = this.internal;\r\n      if (arguments.length) {\r\n          $$.updateTargetX($$.data.targets, x);\r\n          $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\r\n      }\r\n      return $$.data.xs;\r\n  };\r\n  Chart.prototype.xs = function (xs) {\r\n      var $$ = this.internal;\r\n      if (arguments.length) {\r\n          $$.updateTargetXs($$.data.targets, xs);\r\n          $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });\r\n      }\r\n      return $$.data.xs;\r\n  };\n\n  Chart.prototype.zoom = function (domain) {\r\n      var $$ = this.internal;\r\n      if (domain) {\r\n          if ($$.isTimeSeries()) {\r\n              domain = domain.map(function (x) {\r\n                  return $$.parseDate(x);\r\n              });\r\n          }\r\n          if ($$.config.subchart_show) {\r\n              $$.brush.selectionAsValue(domain, true);\r\n          }\r\n          else {\r\n              $$.updateXDomain(null, true, false, false, domain);\r\n              $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false });\r\n          }\r\n          $$.config.zoom_onzoom.call(this, $$.x.orgDomain());\r\n          return domain;\r\n      }\r\n      else {\r\n          return $$.x.domain();\r\n      }\r\n  };\r\n  Chart.prototype.zoom.enable = function (enabled) {\r\n      var $$ = this.internal;\r\n      $$.config.zoom_enabled = enabled;\r\n      $$.updateAndRedraw();\r\n  };\r\n  Chart.prototype.unzoom = function () {\r\n      var $$ = this.internal;\r\n      if ($$.config.subchart_show) {\r\n          $$.brush.clear();\r\n      }\r\n      else {\r\n          $$.updateXDomain(null, true, false, false, $$.subX.domain());\r\n          $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false });\r\n      }\r\n  };\r\n  Chart.prototype.zoom.max = function (max) {\r\n      var $$ = this.internal, config = $$.config, d3 = $$.d3;\r\n      if (max === 0 || max) {\r\n          config.zoom_x_max = d3.max([$$.orgXDomain[1], max]);\r\n      }\r\n      else {\r\n          return config.zoom_x_max;\r\n      }\r\n  };\r\n  Chart.prototype.zoom.min = function (min) {\r\n      var $$ = this.internal, config = $$.config, d3 = $$.d3;\r\n      if (min === 0 || min) {\r\n          config.zoom_x_min = d3.min([$$.orgXDomain[0], min]);\r\n      }\r\n      else {\r\n          return config.zoom_x_min;\r\n      }\r\n  };\r\n  Chart.prototype.zoom.range = function (range) {\r\n      if (arguments.length) {\r\n          if (isDefined(range.max)) {\r\n              this.domain.max(range.max);\r\n          }\r\n          if (isDefined(range.min)) {\r\n              this.domain.min(range.min);\r\n          }\r\n      }\r\n      else {\r\n          return {\r\n              max: this.domain.max(),\r\n              min: this.domain.min()\r\n          };\r\n      }\r\n  };\n\n  ChartInternal.prototype.initPie = function () {\r\n      var $$ = this, d3 = $$.d3;\r\n      $$.pie = d3\r\n          .pie()\r\n          .padAngle(this.getPadAngle.bind(this))\r\n          .value(function (d) {\r\n          return d.values.reduce(function (a, b) {\r\n              return a + b.value;\r\n          }, 0);\r\n      });\r\n      var orderFct = $$.getOrderFunction();\r\n      // we need to reverse the returned order if asc or desc to have the slice in expected order.\r\n      if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) {\r\n          var defaultSort_1 = orderFct;\r\n          orderFct = function (t1, t2) { return defaultSort_1(t1, t2) * -1; };\r\n      }\r\n      $$.pie.sort(orderFct || null);\r\n  };\r\n  ChartInternal.prototype.updateRadius = function () {\r\n      var $$ = this, config = $$.config, w = config.gauge_width || config.donut_width, gaugeArcWidth = $$.filterTargetsToShow($$.data.targets).length *\r\n          $$.config.gauge_arcs_minWidth;\r\n      $$.radiusExpanded =\r\n          (Math.min($$.arcWidth, $$.arcHeight) / 2) * ($$.hasType('gauge') ? 0.85 : 1);\r\n      $$.radius = $$.radiusExpanded * 0.95;\r\n      $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6;\r\n      $$.innerRadius =\r\n          $$.hasType('donut') || $$.hasType('gauge')\r\n              ? $$.radius * $$.innerRadiusRatio\r\n              : 0;\r\n      $$.gaugeArcWidth = w\r\n          ? w\r\n          : gaugeArcWidth <= $$.radius - $$.innerRadius\r\n              ? $$.radius - $$.innerRadius\r\n              : gaugeArcWidth <= $$.radius\r\n                  ? gaugeArcWidth\r\n                  : $$.radius;\r\n  };\r\n  ChartInternal.prototype.getPadAngle = function () {\r\n      if (this.hasType('pie')) {\r\n          return this.config.pie_padAngle || 0;\r\n      }\r\n      else if (this.hasType('donut')) {\r\n          return this.config.donut_padAngle || 0;\r\n      }\r\n      else {\r\n          return 0;\r\n      }\r\n  };\r\n  ChartInternal.prototype.updateArc = function () {\r\n      var $$ = this;\r\n      $$.svgArc = $$.getSvgArc();\r\n      $$.svgArcExpanded = $$.getSvgArcExpanded();\r\n      $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98);\r\n  };\r\n  ChartInternal.prototype.updateAngle = function (d) {\r\n      var $$ = this, config = $$.config, found = false, index = 0, gMin, gMax, gTic, gValue;\r\n      if (!config) {\r\n          return null;\r\n      }\r\n      $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function (t) {\r\n          if (!found && t.data.id === d.data.id) {\r\n              found = true;\r\n              d = t;\r\n              d.index = index;\r\n          }\r\n          index++;\r\n      });\r\n      if (isNaN(d.startAngle)) {\r\n          d.startAngle = 0;\r\n      }\r\n      if (isNaN(d.endAngle)) {\r\n          d.endAngle = d.startAngle;\r\n      }\r\n      if ($$.isGaugeType(d.data)) {\r\n          gMin = config.gauge_min;\r\n          gMax = config.gauge_max;\r\n          gTic = (Math.PI * (config.gauge_fullCircle ? 2 : 1)) / (gMax - gMin);\r\n          gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin;\r\n          d.startAngle = config.gauge_startingAngle;\r\n          d.endAngle = d.startAngle + gTic * gValue;\r\n      }\r\n      return found ? d : null;\r\n  };\r\n  ChartInternal.prototype.getSvgArc = function () {\r\n      var $$ = this, hasGaugeType = $$.hasType('gauge'), singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, arc = $$.d3\r\n          .arc()\r\n          .outerRadius(function (d) {\r\n          return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius;\r\n      })\r\n          .innerRadius(function (d) {\r\n          return hasGaugeType\r\n              ? $$.radius - singleArcWidth * (d.index + 1)\r\n              : $$.innerRadius;\r\n      }), newArc = function (d, withoutUpdate) {\r\n          var updated;\r\n          if (withoutUpdate) {\r\n              return arc(d);\r\n          } // for interpolate\r\n          updated = $$.updateAngle(d);\r\n          return updated ? arc(updated) : 'M 0 0';\r\n      };\r\n      newArc.centroid = arc.centroid;\r\n      return newArc;\r\n  };\r\n  ChartInternal.prototype.getSvgArcExpanded = function (rate) {\r\n      rate = rate || 1;\r\n      var $$ = this, hasGaugeType = $$.hasType('gauge'), singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, expandWidth = Math.min($$.radiusExpanded * rate - $$.radius, singleArcWidth * 0.8 - (1 - rate) * 100), arc = $$.d3\r\n          .arc()\r\n          .outerRadius(function (d) {\r\n          return hasGaugeType\r\n              ? $$.radius - singleArcWidth * d.index + expandWidth\r\n              : $$.radiusExpanded * rate;\r\n      })\r\n          .innerRadius(function (d) {\r\n          return hasGaugeType\r\n              ? $$.radius - singleArcWidth * (d.index + 1)\r\n              : $$.innerRadius;\r\n      });\r\n      return function (d) {\r\n          var updated = $$.updateAngle(d);\r\n          return updated ? arc(updated) : 'M 0 0';\r\n      };\r\n  };\r\n  ChartInternal.prototype.getArc = function (d, withoutUpdate, force) {\r\n      return force || this.isArcType(d.data)\r\n          ? this.svgArc(d, withoutUpdate)\r\n          : 'M 0 0';\r\n  };\r\n  ChartInternal.prototype.transformForArcLabel = function (d) {\r\n      var $$ = this, config = $$.config, updated = $$.updateAngle(d), c, x, y, h, ratio, translate = '', hasGauge = $$.hasType('gauge');\r\n      if (updated && !hasGauge) {\r\n          c = this.svgArc.centroid(updated);\r\n          x = isNaN(c[0]) ? 0 : c[0];\r\n          y = isNaN(c[1]) ? 0 : c[1];\r\n          h = Math.sqrt(x * x + y * y);\r\n          if ($$.hasType('donut') && config.donut_label_ratio) {\r\n              ratio = isFunction(config.donut_label_ratio)\r\n                  ? config.donut_label_ratio(d, $$.radius, h)\r\n                  : config.donut_label_ratio;\r\n          }\r\n          else if ($$.hasType('pie') && config.pie_label_ratio) {\r\n              ratio = isFunction(config.pie_label_ratio)\r\n                  ? config.pie_label_ratio(d, $$.radius, h)\r\n                  : config.pie_label_ratio;\r\n          }\r\n          else {\r\n              ratio =\r\n                  $$.radius && h\r\n                      ? ((36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) *\r\n                          $$.radius) /\r\n                          h\r\n                      : 0;\r\n          }\r\n          translate = 'translate(' + x * ratio + ',' + y * ratio + ')';\r\n      }\r\n      else if (updated &&\r\n          hasGauge &&\r\n          $$.filterTargetsToShow($$.data.targets).length > 1) {\r\n          var y1 = Math.sin(updated.endAngle - Math.PI / 2);\r\n          x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25);\r\n          y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3;\r\n          translate = 'translate(' + x + ',' + y + ')';\r\n      }\r\n      return translate;\r\n  };\r\n  /**\r\n   * @deprecated Use `getRatio('arc', d)` instead.\r\n   */\r\n  ChartInternal.prototype.getArcRatio = function (d) {\r\n      return this.getRatio('arc', d);\r\n  };\r\n  ChartInternal.prototype.convertToArcData = function (d) {\r\n      return this.addName({\r\n          id: d.data.id,\r\n          value: d.value,\r\n          ratio: this.getRatio('arc', d),\r\n          index: d.index\r\n      });\r\n  };\r\n  ChartInternal.prototype.textForArcLabel = function (d) {\r\n      var $$ = this, updated, value, ratio, id, format;\r\n      if (!$$.shouldShowArcLabel()) {\r\n          return '';\r\n      }\r\n      updated = $$.updateAngle(d);\r\n      value = updated ? updated.value : null;\r\n      ratio = $$.getRatio('arc', updated);\r\n      id = d.data.id;\r\n      if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) {\r\n          return '';\r\n      }\r\n      format = $$.getArcLabelFormat();\r\n      return format\r\n          ? format(value, ratio, id)\r\n          : $$.defaultArcValueFormat(value, ratio);\r\n  };\r\n  ChartInternal.prototype.textForGaugeMinMax = function (value, isMax) {\r\n      var $$ = this, format = $$.getGaugeLabelExtents();\r\n      return format ? format(value, isMax) : value;\r\n  };\r\n  ChartInternal.prototype.expandArc = function (targetIds) {\r\n      var $$ = this, interval;\r\n      // MEMO: avoid to cancel transition\r\n      if ($$.transiting) {\r\n          interval = window.setInterval(function () {\r\n              if (!$$.transiting) {\r\n                  window.clearInterval(interval);\r\n                  if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) {\r\n                      $$.expandArc(targetIds);\r\n                  }\r\n              }\r\n          }, 10);\r\n          return;\r\n      }\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      $$.svg\r\n          .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc))\r\n          .each(function (d) {\r\n          if (!$$.shouldExpand(d.data.id)) {\r\n              return;\r\n          }\r\n          $$.d3\r\n              .select(this)\r\n              .selectAll('path')\r\n              .transition()\r\n              .duration($$.expandDuration(d.data.id))\r\n              .attr('d', $$.svgArcExpanded)\r\n              .transition()\r\n              .duration($$.expandDuration(d.data.id) * 2)\r\n              .attr('d', $$.svgArcExpandedSub)\r\n              .each(function (d) {\r\n              if ($$.isDonutType(d.data)) ;\r\n          });\r\n      });\r\n  };\r\n  ChartInternal.prototype.unexpandArc = function (targetIds) {\r\n      var $$ = this;\r\n      if ($$.transiting) {\r\n          return;\r\n      }\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      $$.svg\r\n          .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc))\r\n          .selectAll('path')\r\n          .transition()\r\n          .duration(function (d) {\r\n          return $$.expandDuration(d.data.id);\r\n      })\r\n          .attr('d', $$.svgArc);\r\n      $$.svg.selectAll('.' + CLASS.arc);\r\n  };\r\n  ChartInternal.prototype.expandDuration = function (id) {\r\n      var $$ = this, config = $$.config;\r\n      if ($$.isDonutType(id)) {\r\n          return config.donut_expand_duration;\r\n      }\r\n      else if ($$.isGaugeType(id)) {\r\n          return config.gauge_expand_duration;\r\n      }\r\n      else if ($$.isPieType(id)) {\r\n          return config.pie_expand_duration;\r\n      }\r\n      else {\r\n          return 50;\r\n      }\r\n  };\r\n  ChartInternal.prototype.shouldExpand = function (id) {\r\n      var $$ = this, config = $$.config;\r\n      return (($$.isDonutType(id) && config.donut_expand) ||\r\n          ($$.isGaugeType(id) && config.gauge_expand) ||\r\n          ($$.isPieType(id) && config.pie_expand));\r\n  };\r\n  ChartInternal.prototype.shouldShowArcLabel = function () {\r\n      var $$ = this, config = $$.config, shouldShow = true;\r\n      if ($$.hasType('donut')) {\r\n          shouldShow = config.donut_label_show;\r\n      }\r\n      else if ($$.hasType('pie')) {\r\n          shouldShow = config.pie_label_show;\r\n      }\r\n      // when gauge, always true\r\n      return shouldShow;\r\n  };\r\n  ChartInternal.prototype.meetsArcLabelThreshold = function (ratio) {\r\n      var $$ = this, config = $$.config, threshold = $$.hasType('donut')\r\n          ? config.donut_label_threshold\r\n          : config.pie_label_threshold;\r\n      return ratio >= threshold;\r\n  };\r\n  ChartInternal.prototype.getArcLabelFormat = function () {\r\n      var $$ = this, config = $$.config, format = config.pie_label_format;\r\n      if ($$.hasType('gauge')) {\r\n          format = config.gauge_label_format;\r\n      }\r\n      else if ($$.hasType('donut')) {\r\n          format = config.donut_label_format;\r\n      }\r\n      return format;\r\n  };\r\n  ChartInternal.prototype.getGaugeLabelExtents = function () {\r\n      var $$ = this, config = $$.config;\r\n      return config.gauge_label_extents;\r\n  };\r\n  ChartInternal.prototype.getArcTitle = function () {\r\n      var $$ = this;\r\n      return $$.hasType('donut') ? $$.config.donut_title : '';\r\n  };\r\n  ChartInternal.prototype.updateTargetsForArc = function (targets) {\r\n      var $$ = this, main = $$.main, mainPies, mainPieEnter, classChartArc = $$.classChartArc.bind($$), classArcs = $$.classArcs.bind($$), classFocus = $$.classFocus.bind($$);\r\n      mainPies = main\r\n          .select('.' + CLASS.chartArcs)\r\n          .selectAll('.' + CLASS.chartArc)\r\n          .data($$.pie(targets))\r\n          .attr('class', function (d) {\r\n          return classChartArc(d) + classFocus(d.data);\r\n      });\r\n      mainPieEnter = mainPies\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', classChartArc);\r\n      mainPieEnter.append('g').attr('class', classArcs);\r\n      mainPieEnter\r\n          .append('text')\r\n          .attr('dy', $$.hasType('gauge') ? '-.1em' : '.35em')\r\n          .style('opacity', 0)\r\n          .style('text-anchor', 'middle')\r\n          .style('pointer-events', 'none');\r\n      // MEMO: can not keep same color..., but not bad to update color in redraw\r\n      //mainPieUpdate.exit().remove();\r\n  };\r\n  ChartInternal.prototype.initArc = function () {\r\n      var $$ = this;\r\n      $$.arcs = $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.chartArcs)\r\n          .attr('transform', $$.getTranslate('arc'));\r\n      $$.arcs\r\n          .append('text')\r\n          .attr('class', CLASS.chartArcsTitle)\r\n          .style('text-anchor', 'middle')\r\n          .text($$.getArcTitle());\r\n  };\r\n  ChartInternal.prototype.redrawArc = function (duration, durationForExit, withTransform) {\r\n      var $$ = this, d3 = $$.d3, config = $$.config, main = $$.main, arcs, mainArc, arcLabelLines, mainArcLabelLine, hasGaugeType = $$.hasType('gauge');\r\n      arcs = main\r\n          .selectAll('.' + CLASS.arcs)\r\n          .selectAll('.' + CLASS.arc)\r\n          .data($$.arcData.bind($$));\r\n      mainArc = arcs\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', $$.classArc.bind($$))\r\n          .style('fill', function (d) {\r\n          return $$.color(d.data);\r\n      })\r\n          .style('cursor', function (d) {\r\n          return config.interaction_enabled && config.data_selection_isselectable(d)\r\n              ? 'pointer'\r\n              : null;\r\n      })\r\n          .each(function (d) {\r\n          if ($$.isGaugeType(d.data)) {\r\n              d.startAngle = d.endAngle = config.gauge_startingAngle;\r\n          }\r\n          this._current = d;\r\n      })\r\n          .merge(arcs);\r\n      if (hasGaugeType) {\r\n          arcLabelLines = main\r\n              .selectAll('.' + CLASS.arcs)\r\n              .selectAll('.' + CLASS.arcLabelLine)\r\n              .data($$.arcData.bind($$));\r\n          mainArcLabelLine = arcLabelLines\r\n              .enter()\r\n              .append('rect')\r\n              .attr('class', function (d) {\r\n              return (CLASS.arcLabelLine +\r\n                  ' ' +\r\n                  CLASS.target +\r\n                  ' ' +\r\n                  CLASS.target +\r\n                  '-' +\r\n                  d.data.id);\r\n          })\r\n              .merge(arcLabelLines);\r\n          if ($$.filterTargetsToShow($$.data.targets).length === 1) {\r\n              mainArcLabelLine.style('display', 'none');\r\n          }\r\n          else {\r\n              mainArcLabelLine\r\n                  .style('fill', function (d) {\r\n                  return $$.levelColor\r\n                      ? $$.levelColor(d.data.values.reduce(function (total, item) {\r\n                          return total + item.value;\r\n                      }, 0))\r\n                      : $$.color(d.data);\r\n              })\r\n                  .style('display', config.gauge_labelLine_show ? '' : 'none')\r\n                  .each(function (d) {\r\n                  var lineLength = 0, lineThickness = 2, x = 0, y = 0, transform = '';\r\n                  if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) {\r\n                      var updated = $$.updateAngle(d), innerLineLength = ($$.gaugeArcWidth /\r\n                          $$.filterTargetsToShow($$.data.targets).length) *\r\n                          (updated.index + 1), lineAngle = updated.endAngle - Math.PI / 2, arcInnerRadius = $$.radius - innerLineLength, linePositioningAngle = lineAngle - (arcInnerRadius === 0 ? 0 : 1 / arcInnerRadius);\r\n                      lineLength = $$.radiusExpanded - $$.radius + innerLineLength;\r\n                      x = Math.cos(linePositioningAngle) * arcInnerRadius;\r\n                      y = Math.sin(linePositioningAngle) * arcInnerRadius;\r\n                      transform =\r\n                          'rotate(' +\r\n                              (lineAngle * 180) / Math.PI +\r\n                              ', ' +\r\n                              x +\r\n                              ', ' +\r\n                              y +\r\n                              ')';\r\n                  }\r\n                  d3.select(this)\r\n                      .attr('x', x)\r\n                      .attr('y', y)\r\n                      .attr('width', lineLength)\r\n                      .attr('height', lineThickness)\r\n                      .attr('transform', transform)\r\n                      .style('stroke-dasharray', '0, ' + (lineLength + lineThickness) + ', 0');\r\n              });\r\n          }\r\n      }\r\n      mainArc\r\n          .attr('transform', function (d) {\r\n          return !$$.isGaugeType(d.data) && withTransform ? 'scale(0)' : '';\r\n      })\r\n          .on('mouseover', config.interaction_enabled\r\n          ? function (d) {\r\n              var updated, arcData;\r\n              if ($$.transiting) {\r\n                  // skip while transiting\r\n                  return;\r\n              }\r\n              updated = $$.updateAngle(d);\r\n              if (updated) {\r\n                  arcData = $$.convertToArcData(updated);\r\n                  // transitions\r\n                  $$.expandArc(updated.data.id);\r\n                  $$.api.focus(updated.data.id);\r\n                  $$.toggleFocusLegend(updated.data.id, true);\r\n                  $$.config.data_onmouseover(arcData, this);\r\n              }\r\n          }\r\n          : null)\r\n          .on('mousemove', config.interaction_enabled\r\n          ? function (d) {\r\n              var updated = $$.updateAngle(d), arcData, selectedData;\r\n              if (updated) {\r\n                  (arcData = $$.convertToArcData(updated)),\r\n                      (selectedData = [arcData]);\r\n                  $$.showTooltip(selectedData, this);\r\n              }\r\n          }\r\n          : null)\r\n          .on('mouseout', config.interaction_enabled\r\n          ? function (d) {\r\n              var updated, arcData;\r\n              if ($$.transiting) {\r\n                  // skip while transiting\r\n                  return;\r\n              }\r\n              updated = $$.updateAngle(d);\r\n              if (updated) {\r\n                  arcData = $$.convertToArcData(updated);\r\n                  // transitions\r\n                  $$.unexpandArc(updated.data.id);\r\n                  $$.api.revert();\r\n                  $$.revertLegend();\r\n                  $$.hideTooltip();\r\n                  $$.config.data_onmouseout(arcData, this);\r\n              }\r\n          }\r\n          : null)\r\n          .on('click', config.interaction_enabled\r\n          ? function (d, i) {\r\n              var updated = $$.updateAngle(d), arcData;\r\n              if (updated) {\r\n                  arcData = $$.convertToArcData(updated);\r\n                  if ($$.toggleShape) {\r\n                      $$.toggleShape(this, arcData, i);\r\n                  }\r\n                  $$.config.data_onclick.call($$.api, arcData, this);\r\n              }\r\n          }\r\n          : null)\r\n          .each(function () {\r\n          $$.transiting = true;\r\n      })\r\n          .transition()\r\n          .duration(duration)\r\n          .attrTween('d', function (d) {\r\n          var updated = $$.updateAngle(d), interpolate;\r\n          if (!updated) {\r\n              return function () {\r\n                  return 'M 0 0';\r\n              };\r\n          }\r\n          //                if (this._current === d) {\r\n          //                    this._current = {\r\n          //                        startAngle: Math.PI*2,\r\n          //                        endAngle: Math.PI*2,\r\n          //                    };\r\n          //                }\r\n          if (isNaN(this._current.startAngle)) {\r\n              this._current.startAngle = 0;\r\n          }\r\n          if (isNaN(this._current.endAngle)) {\r\n              this._current.endAngle = this._current.startAngle;\r\n          }\r\n          interpolate = d3.interpolate(this._current, updated);\r\n          this._current = interpolate(0);\r\n          return function (t) {\r\n              // prevents crashing the charts once in transition and chart.destroy() has been called\r\n              if ($$.config === null) {\r\n                  return 'M 0 0';\r\n              }\r\n              var interpolated = interpolate(t);\r\n              interpolated.data = d.data; // data.id will be updated by interporator\r\n              return $$.getArc(interpolated, true);\r\n          };\r\n      })\r\n          .attr('transform', withTransform ? 'scale(1)' : '')\r\n          .style('fill', function (d) {\r\n          return $$.levelColor\r\n              ? $$.levelColor(d.data.values.reduce(function (total, item) {\r\n                  return total + item.value;\r\n              }, 0))\r\n              : $$.color(d.data.id);\r\n      }) // Where gauge reading color would receive customization.\r\n          .call($$.endall, function () {\r\n          $$.transiting = false;\r\n      });\r\n      arcs\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      main\r\n          .selectAll('.' + CLASS.chartArc)\r\n          .select('text')\r\n          .style('opacity', 0)\r\n          .attr('class', function (d) {\r\n          return $$.isGaugeType(d.data) ? CLASS.gaugeValue : '';\r\n      })\r\n          .text($$.textForArcLabel.bind($$))\r\n          .attr('transform', $$.transformForArcLabel.bind($$))\r\n          .style('font-size', function (d) {\r\n          return $$.isGaugeType(d.data) &&\r\n              $$.filterTargetsToShow($$.data.targets).length === 1\r\n              ? Math.round($$.radius / 5) + 'px'\r\n              : '';\r\n      })\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', function (d) {\r\n          return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0;\r\n      });\r\n      main\r\n          .select('.' + CLASS.chartArcsTitle)\r\n          .style('opacity', $$.hasType('donut') || hasGaugeType ? 1 : 0);\r\n      if (hasGaugeType) {\r\n          var index_1 = 0;\r\n          var backgroundArc = $$.arcs\r\n              .select('g.' + CLASS.chartArcsBackground)\r\n              .selectAll('path.' + CLASS.chartArcsBackground)\r\n              .data($$.data.targets);\r\n          backgroundArc\r\n              .enter()\r\n              .append('path')\r\n              .attr('class', function (d, i) {\r\n              return CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i;\r\n          })\r\n              .merge(backgroundArc)\r\n              .attr('d', function (d1) {\r\n              if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) {\r\n                  return 'M 0 0';\r\n              }\r\n              var d = {\r\n                  data: [{ value: config.gauge_max }],\r\n                  startAngle: config.gauge_startingAngle,\r\n                  endAngle: -1 *\r\n                      config.gauge_startingAngle *\r\n                      (config.gauge_fullCircle ? Math.PI : 1),\r\n                  index: index_1++\r\n              };\r\n              return $$.getArc(d, true, true);\r\n          });\r\n          backgroundArc.exit().remove();\r\n          $$.arcs\r\n              .select('.' + CLASS.chartArcsGaugeUnit)\r\n              .attr('dy', '.75em')\r\n              .text(config.gauge_label_show ? config.gauge_units : '');\r\n          $$.arcs\r\n              .select('.' + CLASS.chartArcsGaugeMin)\r\n              .attr('dx', -1 *\r\n              ($$.innerRadius +\r\n                  ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) +\r\n              'px')\r\n              .attr('dy', '1.2em')\r\n              .text(config.gauge_label_show\r\n              ? $$.textForGaugeMinMax(config.gauge_min, false)\r\n              : '');\r\n          $$.arcs\r\n              .select('.' + CLASS.chartArcsGaugeMax)\r\n              .attr('dx', $$.innerRadius +\r\n              ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) +\r\n              'px')\r\n              .attr('dy', '1.2em')\r\n              .text(config.gauge_label_show\r\n              ? $$.textForGaugeMinMax(config.gauge_max, true)\r\n              : '');\r\n      }\r\n  };\r\n  ChartInternal.prototype.initGauge = function () {\r\n      var arcs = this.arcs;\r\n      if (this.hasType('gauge')) {\r\n          arcs.append('g').attr('class', CLASS.chartArcsBackground);\r\n          arcs\r\n              .append('text')\r\n              .attr('class', CLASS.chartArcsGaugeUnit)\r\n              .style('text-anchor', 'middle')\r\n              .style('pointer-events', 'none');\r\n          arcs\r\n              .append('text')\r\n              .attr('class', CLASS.chartArcsGaugeMin)\r\n              .style('text-anchor', 'middle')\r\n              .style('pointer-events', 'none');\r\n          arcs\r\n              .append('text')\r\n              .attr('class', CLASS.chartArcsGaugeMax)\r\n              .style('text-anchor', 'middle')\r\n              .style('pointer-events', 'none');\r\n      }\r\n  };\r\n  ChartInternal.prototype.getGaugeLabelHeight = function () {\r\n      return this.config.gauge_label_show ? 20 : 0;\r\n  };\n\n  /**\r\n   * Store value into cache\r\n   *\r\n   * @param key\r\n   * @param value\r\n   */\r\n  ChartInternal.prototype.addToCache = function (key, value) {\r\n      this.cache[\"$\" + key] = value;\r\n  };\r\n  /**\r\n   * Returns a cached value or undefined\r\n   *\r\n   * @param key\r\n   * @return {*}\r\n   */\r\n  ChartInternal.prototype.getFromCache = function (key) {\r\n      return this.cache[\"$\" + key];\r\n  };\r\n  /**\r\n   * Reset cached data\r\n   */\r\n  ChartInternal.prototype.resetCache = function () {\r\n      var _this = this;\r\n      Object.keys(this.cache)\r\n          .filter(function (key) { return /^\\$/.test(key); })\r\n          .forEach(function (key) {\r\n          delete _this.cache[key];\r\n      });\r\n  };\r\n  // Old API that stores Targets\r\n  ChartInternal.prototype.hasCaches = function (ids) {\r\n      for (var i = 0; i < ids.length; i++) {\r\n          if (!(ids[i] in this.cache)) {\r\n              return false;\r\n          }\r\n      }\r\n      return true;\r\n  };\r\n  ChartInternal.prototype.addCache = function (id, target) {\r\n      this.cache[id] = this.cloneTarget(target);\r\n  };\r\n  ChartInternal.prototype.getCaches = function (ids) {\r\n      var targets = [], i;\r\n      for (i = 0; i < ids.length; i++) {\r\n          if (ids[i] in this.cache) {\r\n              targets.push(this.cloneTarget(this.cache[ids[i]]));\r\n          }\r\n      }\r\n      return targets;\r\n  };\n\n  ChartInternal.prototype.categoryName = function (i) {\r\n      var config = this.config;\r\n      return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i;\r\n  };\n\n  ChartInternal.prototype.generateTargetClass = function (targetId) {\r\n      return targetId || targetId === 0 ? ('-' + targetId).replace(/\\s/g, '-') : '';\r\n  };\r\n  ChartInternal.prototype.generateClass = function (prefix, targetId) {\r\n      return ' ' + prefix + ' ' + prefix + this.generateTargetClass(targetId);\r\n  };\r\n  ChartInternal.prototype.classText = function (d) {\r\n      return this.generateClass(CLASS.text, d.index);\r\n  };\r\n  ChartInternal.prototype.classTexts = function (d) {\r\n      return this.generateClass(CLASS.texts, d.id);\r\n  };\r\n  ChartInternal.prototype.classShape = function (d) {\r\n      return this.generateClass(CLASS.shape, d.index);\r\n  };\r\n  ChartInternal.prototype.classShapes = function (d) {\r\n      return this.generateClass(CLASS.shapes, d.id);\r\n  };\r\n  ChartInternal.prototype.classLine = function (d) {\r\n      return this.classShape(d) + this.generateClass(CLASS.line, d.id);\r\n  };\r\n  ChartInternal.prototype.classLines = function (d) {\r\n      return this.classShapes(d) + this.generateClass(CLASS.lines, d.id);\r\n  };\r\n  ChartInternal.prototype.classCircle = function (d) {\r\n      return this.classShape(d) + this.generateClass(CLASS.circle, d.index);\r\n  };\r\n  ChartInternal.prototype.classCircles = function (d) {\r\n      return this.classShapes(d) + this.generateClass(CLASS.circles, d.id);\r\n  };\r\n  ChartInternal.prototype.classBar = function (d) {\r\n      return this.classShape(d) + this.generateClass(CLASS.bar, d.index);\r\n  };\r\n  ChartInternal.prototype.classBars = function (d) {\r\n      return this.classShapes(d) + this.generateClass(CLASS.bars, d.id);\r\n  };\r\n  ChartInternal.prototype.classArc = function (d) {\r\n      return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id);\r\n  };\r\n  ChartInternal.prototype.classArcs = function (d) {\r\n      return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id);\r\n  };\r\n  ChartInternal.prototype.classArea = function (d) {\r\n      return this.classShape(d) + this.generateClass(CLASS.area, d.id);\r\n  };\r\n  ChartInternal.prototype.classAreas = function (d) {\r\n      return this.classShapes(d) + this.generateClass(CLASS.areas, d.id);\r\n  };\r\n  ChartInternal.prototype.classRegion = function (d, i) {\r\n      return (this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : ''));\r\n  };\r\n  ChartInternal.prototype.classEvent = function (d) {\r\n      return this.generateClass(CLASS.eventRect, d.index);\r\n  };\r\n  ChartInternal.prototype.classTarget = function (id) {\r\n      var $$ = this;\r\n      var additionalClassSuffix = $$.config.data_classes[id], additionalClass = '';\r\n      if (additionalClassSuffix) {\r\n          additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix;\r\n      }\r\n      return $$.generateClass(CLASS.target, id) + additionalClass;\r\n  };\r\n  ChartInternal.prototype.classFocus = function (d) {\r\n      return this.classFocused(d) + this.classDefocused(d);\r\n  };\r\n  ChartInternal.prototype.classFocused = function (d) {\r\n      return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '');\r\n  };\r\n  ChartInternal.prototype.classDefocused = function (d) {\r\n      return (' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : ''));\r\n  };\r\n  ChartInternal.prototype.classChartText = function (d) {\r\n      return CLASS.chartText + this.classTarget(d.id);\r\n  };\r\n  ChartInternal.prototype.classChartLine = function (d) {\r\n      return CLASS.chartLine + this.classTarget(d.id);\r\n  };\r\n  ChartInternal.prototype.classChartBar = function (d) {\r\n      return CLASS.chartBar + this.classTarget(d.id);\r\n  };\r\n  ChartInternal.prototype.classChartArc = function (d) {\r\n      return CLASS.chartArc + this.classTarget(d.data.id);\r\n  };\r\n  ChartInternal.prototype.getTargetSelectorSuffix = function (targetId) {\r\n      var targetClass = this.generateTargetClass(targetId);\r\n      if (window.CSS && window.CSS.escape) {\r\n          return window.CSS.escape(targetClass);\r\n      }\r\n      // fallback on imperfect method for old browsers (does not handles unicode)\r\n      return targetClass.replace(/([?!@#$%^&*()=+,.<>'\":;\\[\\]\\/|~`{}\\\\])/g, '\\\\$1');\r\n  };\r\n  ChartInternal.prototype.selectorTarget = function (id, prefix) {\r\n      return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id);\r\n  };\r\n  ChartInternal.prototype.selectorTargets = function (ids, prefix) {\r\n      var $$ = this;\r\n      ids = ids || [];\r\n      return ids.length\r\n          ? ids.map(function (id) {\r\n              return $$.selectorTarget(id, prefix);\r\n          })\r\n          : null;\r\n  };\r\n  ChartInternal.prototype.selectorLegend = function (id) {\r\n      return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id);\r\n  };\r\n  ChartInternal.prototype.selectorLegends = function (ids) {\r\n      var $$ = this;\r\n      return ids && ids.length\r\n          ? ids.map(function (id) {\r\n              return $$.selectorLegend(id);\r\n          })\r\n          : null;\r\n  };\n\n  ChartInternal.prototype.getClipPath = function (id) {\r\n      return 'url(' + (isIE(9) ? '' : document.URL.split('#')[0]) + '#' + id + ')';\r\n  };\r\n  ChartInternal.prototype.appendClip = function (parent, id) {\r\n      return parent\r\n          .append('clipPath')\r\n          .attr('id', id)\r\n          .append('rect');\r\n  };\r\n  ChartInternal.prototype.getAxisClipX = function (forHorizontal) {\r\n      // axis line width + padding for left\r\n      var left = Math.max(30, this.margin.left);\r\n      return forHorizontal ? -(1 + left) : -(left - 1);\r\n  };\r\n  ChartInternal.prototype.getAxisClipY = function (forHorizontal) {\r\n      return forHorizontal ? -20 : -this.margin.top;\r\n  };\r\n  ChartInternal.prototype.getXAxisClipX = function () {\r\n      var $$ = this;\r\n      return $$.getAxisClipX(!$$.config.axis_rotated);\r\n  };\r\n  ChartInternal.prototype.getXAxisClipY = function () {\r\n      var $$ = this;\r\n      return $$.getAxisClipY(!$$.config.axis_rotated);\r\n  };\r\n  ChartInternal.prototype.getYAxisClipX = function () {\r\n      var $$ = this;\r\n      return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated);\r\n  };\r\n  ChartInternal.prototype.getYAxisClipY = function () {\r\n      var $$ = this;\r\n      return $$.getAxisClipY($$.config.axis_rotated);\r\n  };\r\n  ChartInternal.prototype.getAxisClipWidth = function (forHorizontal) {\r\n      var $$ = this, left = Math.max(30, $$.margin.left), right = Math.max(30, $$.margin.right);\r\n      // width + axis line width + padding for left/right\r\n      return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20;\r\n  };\r\n  ChartInternal.prototype.getAxisClipHeight = function (forHorizontal) {\r\n      // less than 20 is not enough to show the axis label 'outer' without legend\r\n      return ((forHorizontal ? this.margin.bottom : this.margin.top + this.height) + 20);\r\n  };\r\n  ChartInternal.prototype.getXAxisClipWidth = function () {\r\n      var $$ = this;\r\n      return $$.getAxisClipWidth(!$$.config.axis_rotated);\r\n  };\r\n  ChartInternal.prototype.getXAxisClipHeight = function () {\r\n      var $$ = this;\r\n      return $$.getAxisClipHeight(!$$.config.axis_rotated);\r\n  };\r\n  ChartInternal.prototype.getYAxisClipWidth = function () {\r\n      var $$ = this;\r\n      return ($$.getAxisClipWidth($$.config.axis_rotated) +\r\n          ($$.config.axis_y_inner ? 20 : 0));\r\n  };\r\n  ChartInternal.prototype.getYAxisClipHeight = function () {\r\n      var $$ = this;\r\n      return $$.getAxisClipHeight($$.config.axis_rotated);\r\n  };\n\n  ChartInternal.prototype.generateColor = function () {\r\n      var $$ = this, config = $$.config, d3 = $$.d3, colors = config.data_colors, pattern = notEmpty(config.color_pattern)\r\n          ? config.color_pattern\r\n          : d3.schemeCategory10, callback = config.data_color, ids = [];\r\n      return function (d) {\r\n          var id = d.id || (d.data && d.data.id) || d, color;\r\n          // if callback function is provided\r\n          if (colors[id] instanceof Function) {\r\n              color = colors[id](d);\r\n          }\r\n          // if specified, choose that color\r\n          else if (colors[id]) {\r\n              color = colors[id];\r\n          }\r\n          // if not specified, choose from pattern\r\n          else {\r\n              if (ids.indexOf(id) < 0) {\r\n                  ids.push(id);\r\n              }\r\n              color = pattern[ids.indexOf(id) % pattern.length];\r\n              colors[id] = color;\r\n          }\r\n          return callback instanceof Function ? callback(color, d) : color;\r\n      };\r\n  };\r\n  ChartInternal.prototype.generateLevelColor = function () {\r\n      var $$ = this, config = $$.config, colors = config.color_pattern, threshold = config.color_threshold, asValue = threshold.unit === 'value', values = threshold.values && threshold.values.length ? threshold.values : [], max = threshold.max || 100;\r\n      return notEmpty(threshold) && notEmpty(colors)\r\n          ? function (value) {\r\n              var i, v, color = colors[colors.length - 1];\r\n              for (i = 0; i < values.length; i++) {\r\n                  v = asValue ? value : (value * 100) / max;\r\n                  if (v < values[i]) {\r\n                      color = colors[i];\r\n                      break;\r\n                  }\r\n              }\r\n              return color;\r\n          }\r\n          : null;\r\n  };\n\n  ChartInternal.prototype.getDefaultConfig = function () {\r\n      var config = {\r\n          bindto: '#chart',\r\n          svg_classname: undefined,\r\n          size_width: undefined,\r\n          size_height: undefined,\r\n          padding_left: undefined,\r\n          padding_right: undefined,\r\n          padding_top: undefined,\r\n          padding_bottom: undefined,\r\n          resize_auto: true,\r\n          zoom_enabled: false,\r\n          zoom_initialRange: undefined,\r\n          zoom_type: 'scroll',\r\n          zoom_disableDefaultBehavior: false,\r\n          zoom_privileged: false,\r\n          zoom_rescale: false,\r\n          zoom_onzoom: function () { },\r\n          zoom_onzoomstart: function () { },\r\n          zoom_onzoomend: function () { },\r\n          zoom_x_min: undefined,\r\n          zoom_x_max: undefined,\r\n          interaction_brighten: true,\r\n          interaction_enabled: true,\r\n          onmouseover: function () { },\r\n          onmouseout: function () { },\r\n          onresize: function () { },\r\n          onresized: function () { },\r\n          oninit: function () { },\r\n          onrendered: function () { },\r\n          transition_duration: 350,\r\n          data_epochs: 'epochs',\r\n          data_x: undefined,\r\n          data_xs: {},\r\n          data_xFormat: '%Y-%m-%d',\r\n          data_xLocaltime: true,\r\n          data_xSort: true,\r\n          data_idConverter: function (id) {\r\n              return id;\r\n          },\r\n          data_names: {},\r\n          data_classes: {},\r\n          data_groups: [],\r\n          data_axes: {},\r\n          data_type: undefined,\r\n          data_types: {},\r\n          data_labels: {},\r\n          data_order: 'desc',\r\n          data_regions: {},\r\n          data_color: undefined,\r\n          data_colors: {},\r\n          data_hide: false,\r\n          data_filter: undefined,\r\n          data_selection_enabled: false,\r\n          data_selection_grouped: false,\r\n          data_selection_isselectable: function () {\r\n              return true;\r\n          },\r\n          data_selection_multiple: true,\r\n          data_selection_draggable: false,\r\n          data_stack_normalize: false,\r\n          data_onclick: function () { },\r\n          data_onmouseover: function () { },\r\n          data_onmouseout: function () { },\r\n          data_onselected: function () { },\r\n          data_onunselected: function () { },\r\n          data_url: undefined,\r\n          data_headers: undefined,\r\n          data_json: undefined,\r\n          data_rows: undefined,\r\n          data_columns: undefined,\r\n          data_mimeType: undefined,\r\n          data_keys: undefined,\r\n          // configuration for no plot-able data supplied.\r\n          data_empty_label_text: '',\r\n          // subchart\r\n          subchart_show: false,\r\n          subchart_size_height: 60,\r\n          subchart_axis_x_show: true,\r\n          subchart_onbrush: function () { },\r\n          // color\r\n          color_pattern: [],\r\n          color_threshold: {},\r\n          // legend\r\n          legend_show: true,\r\n          legend_hide: false,\r\n          legend_position: 'bottom',\r\n          legend_inset_anchor: 'top-left',\r\n          legend_inset_x: 10,\r\n          legend_inset_y: 0,\r\n          legend_inset_step: undefined,\r\n          legend_item_onclick: undefined,\r\n          legend_item_onmouseover: undefined,\r\n          legend_item_onmouseout: undefined,\r\n          legend_equally: false,\r\n          legend_padding: 0,\r\n          legend_item_tile_width: 10,\r\n          legend_item_tile_height: 10,\r\n          // axis\r\n          axis_rotated: false,\r\n          axis_x_show: true,\r\n          axis_x_type: 'indexed',\r\n          axis_x_localtime: true,\r\n          axis_x_categories: [],\r\n          axis_x_tick_centered: false,\r\n          axis_x_tick_format: undefined,\r\n          axis_x_tick_culling: {},\r\n          axis_x_tick_culling_max: 10,\r\n          axis_x_tick_count: undefined,\r\n          axis_x_tick_fit: true,\r\n          axis_x_tick_values: null,\r\n          axis_x_tick_rotate: 0,\r\n          axis_x_tick_outer: true,\r\n          axis_x_tick_multiline: true,\r\n          axis_x_tick_multilineMax: 0,\r\n          axis_x_tick_width: null,\r\n          axis_x_max: undefined,\r\n          axis_x_min: undefined,\r\n          axis_x_padding: {},\r\n          axis_x_height: undefined,\r\n          axis_x_selection: undefined,\r\n          axis_x_label: {},\r\n          axis_x_inner: undefined,\r\n          axis_y_show: true,\r\n          axis_y_type: 'linear',\r\n          axis_y_max: undefined,\r\n          axis_y_min: undefined,\r\n          axis_y_inverted: false,\r\n          axis_y_center: undefined,\r\n          axis_y_inner: undefined,\r\n          axis_y_label: {},\r\n          axis_y_tick_format: undefined,\r\n          axis_y_tick_outer: true,\r\n          axis_y_tick_values: null,\r\n          axis_y_tick_rotate: 0,\r\n          axis_y_tick_count: undefined,\r\n          axis_y_tick_time_type: undefined,\r\n          axis_y_tick_time_interval: undefined,\r\n          axis_y_padding: {},\r\n          axis_y_default: undefined,\r\n          axis_y2_show: false,\r\n          axis_y2_type: 'linear',\r\n          axis_y2_max: undefined,\r\n          axis_y2_min: undefined,\r\n          axis_y2_inverted: false,\r\n          axis_y2_center: undefined,\r\n          axis_y2_inner: undefined,\r\n          axis_y2_label: {},\r\n          axis_y2_tick_format: undefined,\r\n          axis_y2_tick_outer: true,\r\n          axis_y2_tick_values: null,\r\n          axis_y2_tick_count: undefined,\r\n          axis_y2_padding: {},\r\n          axis_y2_default: undefined,\r\n          // grid\r\n          grid_x_show: false,\r\n          grid_x_type: 'tick',\r\n          grid_x_lines: [],\r\n          grid_y_show: false,\r\n          // not used\r\n          // grid_y_type: 'tick',\r\n          grid_y_lines: [],\r\n          grid_y_ticks: 10,\r\n          grid_focus_show: true,\r\n          grid_lines_front: true,\r\n          // point - point of each data\r\n          point_show: true,\r\n          point_r: 2.5,\r\n          point_sensitivity: 10,\r\n          point_focus_expand_enabled: true,\r\n          point_focus_expand_r: undefined,\r\n          point_select_r: undefined,\r\n          // line\r\n          line_connectNull: false,\r\n          line_step_type: 'step',\r\n          // bar\r\n          bar_width: undefined,\r\n          bar_width_ratio: 0.6,\r\n          bar_width_max: undefined,\r\n          bar_zerobased: true,\r\n          bar_space: 0,\r\n          // area\r\n          area_zerobased: true,\r\n          area_above: false,\r\n          // pie\r\n          pie_label_show: true,\r\n          pie_label_format: undefined,\r\n          pie_label_threshold: 0.05,\r\n          pie_label_ratio: undefined,\r\n          pie_expand: {},\r\n          pie_expand_duration: 50,\r\n          pie_padAngle: 0,\r\n          // gauge\r\n          gauge_fullCircle: false,\r\n          gauge_label_show: true,\r\n          gauge_labelLine_show: true,\r\n          gauge_label_format: undefined,\r\n          gauge_min: 0,\r\n          gauge_max: 100,\r\n          gauge_startingAngle: (-1 * Math.PI) / 2,\r\n          gauge_label_extents: undefined,\r\n          gauge_units: undefined,\r\n          gauge_width: undefined,\r\n          gauge_arcs_minWidth: 5,\r\n          gauge_expand: {},\r\n          gauge_expand_duration: 50,\r\n          // donut\r\n          donut_label_show: true,\r\n          donut_label_format: undefined,\r\n          donut_label_threshold: 0.05,\r\n          donut_label_ratio: undefined,\r\n          donut_width: undefined,\r\n          donut_title: '',\r\n          donut_expand: {},\r\n          donut_expand_duration: 50,\r\n          donut_padAngle: 0,\r\n          // spline\r\n          spline_interpolation_type: 'cardinal',\r\n          // stanford\r\n          stanford_lines: [],\r\n          stanford_regions: [],\r\n          stanford_texts: [],\r\n          stanford_scaleMin: undefined,\r\n          stanford_scaleMax: undefined,\r\n          stanford_scaleWidth: undefined,\r\n          stanford_scaleFormat: undefined,\r\n          stanford_scaleValues: undefined,\r\n          stanford_colors: undefined,\r\n          stanford_padding: {\r\n              top: 0,\r\n              right: 0,\r\n              bottom: 0,\r\n              left: 0\r\n          },\r\n          // region - region to change style\r\n          regions: [],\r\n          // tooltip - show when mouseover on each data\r\n          tooltip_show: true,\r\n          tooltip_grouped: true,\r\n          tooltip_order: undefined,\r\n          tooltip_format_title: undefined,\r\n          tooltip_format_name: undefined,\r\n          tooltip_format_value: undefined,\r\n          tooltip_horizontal: undefined,\r\n          tooltip_position: undefined,\r\n          tooltip_contents: function (d, defaultTitleFormat, defaultValueFormat, color) {\r\n              return this.getTooltipContent\r\n                  ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color)\r\n                  : '';\r\n          },\r\n          tooltip_init_show: false,\r\n          tooltip_init_x: 0,\r\n          tooltip_init_position: { top: '0px', left: '50px' },\r\n          tooltip_onshow: function () { },\r\n          tooltip_onhide: function () { },\r\n          // title\r\n          title_text: undefined,\r\n          title_padding: {\r\n              top: 0,\r\n              right: 0,\r\n              bottom: 0,\r\n              left: 0\r\n          },\r\n          title_position: 'top-center'\r\n      };\r\n      Object.keys(this.additionalConfig).forEach(function (key) {\r\n          config[key] = this.additionalConfig[key];\r\n      }, this);\r\n      return config;\r\n  };\r\n  ChartInternal.prototype.additionalConfig = {};\r\n  ChartInternal.prototype.loadConfig = function (config) {\r\n      var this_config = this.config, target, keys, read;\r\n      function find() {\r\n          var key = keys.shift();\r\n          //        console.log(\"key =>\", key, \", target =>\", target);\r\n          if (key && target && typeof target === 'object' && key in target) {\r\n              target = target[key];\r\n              return find();\r\n          }\r\n          else if (!key) {\r\n              return target;\r\n          }\r\n          else {\r\n              return undefined;\r\n          }\r\n      }\r\n      Object.keys(this_config).forEach(function (key) {\r\n          target = config;\r\n          keys = key.split('_');\r\n          read = find();\r\n          //        console.log(\"CONFIG : \", key, read);\r\n          if (isDefined(read)) {\r\n              this_config[key] = read;\r\n          }\r\n      });\r\n  };\n\n  ChartInternal.prototype.convertUrlToData = function (url, mimeType, headers, keys, done) {\r\n      var $$ = this, type = mimeType ? mimeType : 'csv', f, converter;\r\n      if (type === 'json') {\r\n          f = $$.d3.json;\r\n          converter = $$.convertJsonToData;\r\n      }\r\n      else if (type === 'tsv') {\r\n          f = $$.d3.tsv;\r\n          converter = $$.convertXsvToData;\r\n      }\r\n      else {\r\n          f = $$.d3.csv;\r\n          converter = $$.convertXsvToData;\r\n      }\r\n      f(url, headers)\r\n          .then(function (data) {\r\n          done.call($$, converter.call($$, data, keys));\r\n      })\r\n          .catch(function (error) {\r\n          throw error;\r\n      });\r\n  };\r\n  ChartInternal.prototype.convertXsvToData = function (xsv) {\r\n      var keys = xsv.columns, rows = xsv;\r\n      if (rows.length === 0) {\r\n          return {\r\n              keys: keys,\r\n              rows: [keys.reduce(function (row, key) {\r\n                      var _a;\r\n                      return Object.assign(row, (_a = {}, _a[key] = null, _a));\r\n                  }, {})]\r\n          };\r\n      }\r\n      else {\r\n          // [].concat() is to convert result into a plain array otherwise\r\n          // test is not happy because rows have properties.\r\n          return { keys: keys, rows: [].concat(xsv) };\r\n      }\r\n  };\r\n  ChartInternal.prototype.convertJsonToData = function (json, keys) {\r\n      var $$ = this, new_rows = [], targetKeys, data;\r\n      if (keys) {\r\n          // when keys specified, json would be an array that includes objects\r\n          if (keys.x) {\r\n              targetKeys = keys.value.concat(keys.x);\r\n              $$.config.data_x = keys.x;\r\n          }\r\n          else {\r\n              targetKeys = keys.value;\r\n          }\r\n          new_rows.push(targetKeys);\r\n          json.forEach(function (o) {\r\n              var new_row = [];\r\n              targetKeys.forEach(function (key) {\r\n                  // convert undefined to null because undefined data will be removed in convertDataToTargets()\r\n                  var v = $$.findValueInJson(o, key);\r\n                  if (isUndefined(v)) {\r\n                      v = null;\r\n                  }\r\n                  new_row.push(v);\r\n              });\r\n              new_rows.push(new_row);\r\n          });\r\n          data = $$.convertRowsToData(new_rows);\r\n      }\r\n      else {\r\n          Object.keys(json).forEach(function (key) {\r\n              new_rows.push([key].concat(json[key]));\r\n          });\r\n          data = $$.convertColumnsToData(new_rows);\r\n      }\r\n      return data;\r\n  };\r\n  /**\r\n   * Finds value from the given nested object by the given path.\r\n   * If it's not found, then this returns undefined.\r\n   * @param {Object} object the object\r\n   * @param {string} path the path\r\n   */\r\n  ChartInternal.prototype.findValueInJson = function (object, path) {\r\n      if (path in object) {\r\n          // If object has a key that contains . or [], return the key's value\r\n          // instead of searching for an inner object.\r\n          // See https://github.com/c3js/c3/issues/1691 for details.\r\n          return object[path];\r\n      }\r\n      path = path.replace(/\\[(\\w+)\\]/g, '.$1'); // convert indexes to properties (replace [] with .)\r\n      path = path.replace(/^\\./, ''); // strip a leading dot\r\n      var pathArray = path.split('.');\r\n      for (var i = 0; i < pathArray.length; ++i) {\r\n          var k = pathArray[i];\r\n          if (k in object) {\r\n              object = object[k];\r\n          }\r\n          else {\r\n              return;\r\n          }\r\n      }\r\n      return object;\r\n  };\r\n  /**\r\n   * Converts the rows to normalized data.\r\n   * @param {any[][]} rows The row data\r\n   * @return {Object}\r\n   */\r\n  ChartInternal.prototype.convertRowsToData = function (rows) {\r\n      var newRows = [];\r\n      var keys = rows[0];\r\n      for (var i = 1; i < rows.length; i++) {\r\n          var newRow = {};\r\n          for (var j = 0; j < rows[i].length; j++) {\r\n              if (isUndefined(rows[i][j])) {\r\n                  throw new Error('Source data is missing a component at (' + i + ',' + j + ')!');\r\n              }\r\n              newRow[keys[j]] = rows[i][j];\r\n          }\r\n          newRows.push(newRow);\r\n      }\r\n      return { keys: keys, rows: newRows };\r\n  };\r\n  /**\r\n   * Converts the columns to normalized data.\r\n   * @param {any[][]} columns The column data\r\n   * @return {Object}\r\n   */\r\n  ChartInternal.prototype.convertColumnsToData = function (columns) {\r\n      var newRows = [];\r\n      var keys = [];\r\n      for (var i = 0; i < columns.length; i++) {\r\n          var key = columns[i][0];\r\n          for (var j = 1; j < columns[i].length; j++) {\r\n              if (isUndefined(newRows[j - 1])) {\r\n                  newRows[j - 1] = {};\r\n              }\r\n              if (isUndefined(columns[i][j])) {\r\n                  throw new Error('Source data is missing a component at (' + i + ',' + j + ')!');\r\n              }\r\n              newRows[j - 1][key] = columns[i][j];\r\n          }\r\n          keys.push(key);\r\n      }\r\n      return { keys: keys, rows: newRows };\r\n  };\r\n  /**\r\n   * Converts the data format into the target format.\r\n   * @param {!Object} data\r\n   * @param {!Array} data.keys Ordered list of target IDs.\r\n   * @param {!Array} data.rows Rows of data to convert.\r\n   * @param {boolean} appendXs True to append to $$.data.xs, False to replace.\r\n   * @return {!Array}\r\n   */\r\n  ChartInternal.prototype.convertDataToTargets = function (data, appendXs) {\r\n      var $$ = this, config = $$.config, targets, ids, xs, keys, epochs;\r\n      // handles format where keys are not orderly provided\r\n      if (isArray(data)) {\r\n          keys = Object.keys(data[0]);\r\n      }\r\n      else {\r\n          keys = data.keys;\r\n          data = data.rows;\r\n      }\r\n      xs = keys.filter($$.isX, $$);\r\n      if (!$$.isStanfordGraphType()) {\r\n          ids = keys.filter($$.isNotX, $$);\r\n      }\r\n      else {\r\n          epochs = keys.filter($$.isEpochs, $$);\r\n          ids = keys.filter($$.isNotXAndNotEpochs, $$);\r\n          if (xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) {\r\n              throw new Error(\"You must define the 'x' key name and the 'epochs' for Stanford Diagrams\");\r\n          }\r\n      }\r\n      // save x for update data by load when custom x and c3.x API\r\n      ids.forEach(function (id) {\r\n          var xKey = $$.getXKey(id);\r\n          if ($$.isCustomX() || $$.isTimeSeries()) {\r\n              // if included in input data\r\n              if (xs.indexOf(xKey) >= 0) {\r\n                  $$.data.xs[id] = (appendXs && $$.data.xs[id]\r\n                      ? $$.data.xs[id]\r\n                      : []).concat(data\r\n                      .map(function (d) {\r\n                      return d[xKey];\r\n                  })\r\n                      .filter(isValue)\r\n                      .map(function (rawX, i) {\r\n                      return $$.generateTargetX(rawX, id, i);\r\n                  }));\r\n              }\r\n              // if not included in input data, find from preloaded data of other id's x\r\n              else if (config.data_x) {\r\n                  $$.data.xs[id] = $$.getOtherTargetXs();\r\n              }\r\n              // if not included in input data, find from preloaded data\r\n              else if (notEmpty(config.data_xs)) {\r\n                  $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets);\r\n              }\r\n              // MEMO: if no x included, use same x of current will be used\r\n          }\r\n          else {\r\n              $$.data.xs[id] = data.map(function (d, i) {\r\n                  return i;\r\n              });\r\n          }\r\n      });\r\n      // check x is defined\r\n      ids.forEach(function (id) {\r\n          if (!$$.data.xs[id]) {\r\n              throw new Error('x is not defined for id = \"' + id + '\".');\r\n          }\r\n      });\r\n      // convert to target\r\n      targets = ids.map(function (id, index) {\r\n          var convertedId = config.data_idConverter(id);\r\n          return {\r\n              id: convertedId,\r\n              id_org: id,\r\n              values: data\r\n                  .map(function (d, i) {\r\n                  var xKey = $$.getXKey(id), rawX = d[xKey], value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null, x, returnData;\r\n                  // use x as categories if custom x and categorized\r\n                  if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) {\r\n                      if (index === 0 && i === 0) {\r\n                          config.axis_x_categories = [];\r\n                      }\r\n                      x = config.axis_x_categories.indexOf(rawX);\r\n                      if (x === -1) {\r\n                          x = config.axis_x_categories.length;\r\n                          config.axis_x_categories.push(rawX);\r\n                      }\r\n                  }\r\n                  else {\r\n                      x = $$.generateTargetX(rawX, id, i);\r\n                  }\r\n                  // mark as x = undefined if value is undefined and filter to remove after mapped\r\n                  if (isUndefined(d[id]) || $$.data.xs[id].length <= i) {\r\n                      x = undefined;\r\n                  }\r\n                  returnData = { x: x, value: value, id: convertedId };\r\n                  if ($$.isStanfordGraphType()) {\r\n                      returnData.epochs = d[epochs];\r\n                  }\r\n                  return returnData;\r\n              })\r\n                  .filter(function (v) {\r\n                  return isDefined(v.x);\r\n              })\r\n          };\r\n      });\r\n      // finish targets\r\n      targets.forEach(function (t) {\r\n          var i;\r\n          // sort values by its x\r\n          if (config.data_xSort) {\r\n              t.values = t.values.sort(function (v1, v2) {\r\n                  var x1 = v1.x || v1.x === 0 ? v1.x : Infinity, x2 = v2.x || v2.x === 0 ? v2.x : Infinity;\r\n                  return x1 - x2;\r\n              });\r\n          }\r\n          // indexing each value\r\n          i = 0;\r\n          t.values.forEach(function (v) {\r\n              v.index = i++;\r\n          });\r\n          // this needs to be sorted because its index and value.index is identical\r\n          $$.data.xs[t.id].sort(function (v1, v2) {\r\n              return v1 - v2;\r\n          });\r\n      });\r\n      // cache information about values\r\n      $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets);\r\n      $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets);\r\n      // set target types\r\n      if (config.data_type) {\r\n          $$.setTargetType($$.mapToIds(targets).filter(function (id) {\r\n              return !(id in config.data_types);\r\n          }), config.data_type);\r\n      }\r\n      // cache as original id keyed\r\n      targets.forEach(function (d) {\r\n          $$.addCache(d.id_org, d);\r\n      });\r\n      return targets;\r\n  };\n\n  ChartInternal.prototype.isEpochs = function (key) {\r\n      var $$ = this, config = $$.config;\r\n      return config.data_epochs && key === config.data_epochs;\r\n  };\r\n  ChartInternal.prototype.isX = function (key) {\r\n      var $$ = this, config = $$.config;\r\n      return ((config.data_x && key === config.data_x) ||\r\n          (notEmpty(config.data_xs) && hasValue(config.data_xs, key)));\r\n  };\r\n  ChartInternal.prototype.isNotX = function (key) {\r\n      return !this.isX(key);\r\n  };\r\n  ChartInternal.prototype.isNotXAndNotEpochs = function (key) {\r\n      return !this.isX(key) && !this.isEpochs(key);\r\n  };\r\n  /**\r\n   * Returns whether the normalized stack option is enabled or not.\r\n   *\r\n   * To be enabled it must also have data.groups defined.\r\n   *\r\n   * @return {boolean}\r\n   */\r\n  ChartInternal.prototype.isStackNormalized = function () {\r\n      return this.config.data_stack_normalize && this.config.data_groups.length > 0;\r\n  };\r\n  /**\r\n   * Returns whether the axis is normalized or not.\r\n   *\r\n   * An axis is normalized as long as one of its associated target\r\n   * is normalized.\r\n   *\r\n   * @param axisId Axis ID (y or y2)\r\n   * @return {Boolean}\r\n   */\r\n  ChartInternal.prototype.isAxisNormalized = function (axisId) {\r\n      var $$ = this;\r\n      if (!$$.isStackNormalized()) {\r\n          // shortcut\r\n          return false;\r\n      }\r\n      return $$.data.targets\r\n          .filter(function (target) { return $$.axis.getId(target.id) === axisId; })\r\n          .some(function (target) { return $$.isTargetNormalized(target.id); });\r\n  };\r\n  /**\r\n   * Returns whether the values for this target ID is normalized or not.\r\n   *\r\n   * To be normalized the option needs to be enabled and target needs\r\n   * to be defined in `data.groups`.\r\n   *\r\n   * @param targetId ID of the target\r\n   * @return {Boolean} True if the target is normalized, false otherwise.\r\n   */\r\n  ChartInternal.prototype.isTargetNormalized = function (targetId) {\r\n      var $$ = this;\r\n      return ($$.isStackNormalized() &&\r\n          $$.config.data_groups.some(function (group) { return group.includes(targetId); }));\r\n  };\r\n  ChartInternal.prototype.getXKey = function (id) {\r\n      var $$ = this, config = $$.config;\r\n      return config.data_x\r\n          ? config.data_x\r\n          : notEmpty(config.data_xs)\r\n              ? config.data_xs[id]\r\n              : null;\r\n  };\r\n  /**\r\n   * Get sum of visible data per index for given axis.\r\n   *\r\n   * Expect axisId to be either 'y' or 'y2'.\r\n   *\r\n   * @private\r\n   * @param axisId Compute sum for data associated to given axis.\r\n   * @return {Array}\r\n   */\r\n  ChartInternal.prototype.getTotalPerIndex = function (axisId) {\r\n      var $$ = this;\r\n      if (!$$.isStackNormalized()) {\r\n          return null;\r\n      }\r\n      var cached = $$.getFromCache('getTotalPerIndex');\r\n      if (cached !== undefined) {\r\n          return cached[axisId];\r\n      }\r\n      var sum = { y: [], y2: [] };\r\n      $$.data.targets\r\n          // keep only target that are normalized\r\n          .filter(function (target) { return $$.isTargetNormalized(target.id); })\r\n          // keep only target that are visible\r\n          .filter(function (target) { return $$.isTargetToShow(target.id); })\r\n          // compute sum per axis\r\n          .forEach(function (target) {\r\n          var sumByAxis = sum[$$.axis.getId(target.id)];\r\n          target.values.forEach(function (v, i) {\r\n              if (!sumByAxis[i]) {\r\n                  sumByAxis[i] = 0;\r\n              }\r\n              sumByAxis[i] += isNumber(v.value) ? v.value : 0;\r\n          });\r\n      });\r\n      $$.addToCache('getTotalPerIndex', sum);\r\n      return sum[axisId];\r\n  };\r\n  /**\r\n   * Get sum of visible data.\r\n   *\r\n   * Should be used for normalised data only since all values\r\n   * are expected to be positive.\r\n   *\r\n   * @private\r\n   * @return {Number}\r\n   */\r\n  ChartInternal.prototype.getTotalDataSum = function () {\r\n      var $$ = this;\r\n      var cached = $$.getFromCache('getTotalDataSum');\r\n      if (cached !== undefined) {\r\n          return cached;\r\n      }\r\n      var totalDataSum = flattenArray($$.data.targets\r\n          .filter(function (target) { return $$.isTargetToShow(target.id); })\r\n          .map(function (target) { return target.values; }))\r\n          .map(function (d) { return d.value; })\r\n          .reduce(function (p, c) { return p + c; }, 0);\r\n      $$.addToCache('getTotalDataSum', totalDataSum);\r\n      return totalDataSum;\r\n  };\r\n  ChartInternal.prototype.getXValuesOfXKey = function (key, targets) {\r\n      var $$ = this, xValues, ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : [];\r\n      ids.forEach(function (id) {\r\n          if ($$.getXKey(id) === key) {\r\n              xValues = $$.data.xs[id];\r\n          }\r\n      });\r\n      return xValues;\r\n  };\r\n  ChartInternal.prototype.getXValue = function (id, i) {\r\n      var $$ = this;\r\n      return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i])\r\n          ? $$.data.xs[id][i]\r\n          : i;\r\n  };\r\n  ChartInternal.prototype.getOtherTargetXs = function () {\r\n      var $$ = this, idsForX = Object.keys($$.data.xs);\r\n      return idsForX.length ? $$.data.xs[idsForX[0]] : null;\r\n  };\r\n  ChartInternal.prototype.getOtherTargetX = function (index) {\r\n      var xs = this.getOtherTargetXs();\r\n      return xs && index < xs.length ? xs[index] : null;\r\n  };\r\n  ChartInternal.prototype.addXs = function (xs) {\r\n      var $$ = this;\r\n      Object.keys(xs).forEach(function (id) {\r\n          $$.config.data_xs[id] = xs[id];\r\n      });\r\n  };\r\n  ChartInternal.prototype.addName = function (data) {\r\n      var $$ = this, name;\r\n      if (data) {\r\n          name = $$.config.data_names[data.id];\r\n          data.name = name !== undefined ? name : data.id;\r\n      }\r\n      return data;\r\n  };\r\n  ChartInternal.prototype.getValueOnIndex = function (values, index) {\r\n      var valueOnIndex = values.filter(function (v) {\r\n          return v.index === index;\r\n      });\r\n      return valueOnIndex.length ? valueOnIndex[0] : null;\r\n  };\r\n  ChartInternal.prototype.updateTargetX = function (targets, x) {\r\n      var $$ = this;\r\n      targets.forEach(function (t) {\r\n          t.values.forEach(function (v, i) {\r\n              v.x = $$.generateTargetX(x[i], t.id, i);\r\n          });\r\n          $$.data.xs[t.id] = x;\r\n      });\r\n  };\r\n  ChartInternal.prototype.updateTargetXs = function (targets, xs) {\r\n      var $$ = this;\r\n      targets.forEach(function (t) {\r\n          if (xs[t.id]) {\r\n              $$.updateTargetX([t], xs[t.id]);\r\n          }\r\n      });\r\n  };\r\n  ChartInternal.prototype.generateTargetX = function (rawX, id, index) {\r\n      var $$ = this, x;\r\n      if ($$.isTimeSeries()) {\r\n          x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index));\r\n      }\r\n      else if ($$.isCustomX() && !$$.isCategorized()) {\r\n          x = isValue(rawX) ? +rawX : $$.getXValue(id, index);\r\n      }\r\n      else {\r\n          x = index;\r\n      }\r\n      return x;\r\n  };\r\n  ChartInternal.prototype.cloneTarget = function (target) {\r\n      return {\r\n          id: target.id,\r\n          id_org: target.id_org,\r\n          values: target.values.map(function (d) {\r\n              return {\r\n                  x: d.x,\r\n                  value: d.value,\r\n                  id: d.id\r\n              };\r\n          })\r\n      };\r\n  };\r\n  ChartInternal.prototype.getMaxDataCount = function () {\r\n      var $$ = this;\r\n      return $$.d3.max($$.data.targets, function (t) {\r\n          return t.values.length;\r\n      });\r\n  };\r\n  ChartInternal.prototype.mapToIds = function (targets) {\r\n      return targets.map(function (d) {\r\n          return d.id;\r\n      });\r\n  };\r\n  ChartInternal.prototype.mapToTargetIds = function (ids) {\r\n      var $$ = this;\r\n      return ids ? [].concat(ids) : $$.mapToIds($$.data.targets);\r\n  };\r\n  ChartInternal.prototype.hasTarget = function (targets, id) {\r\n      var ids = this.mapToIds(targets), i;\r\n      for (i = 0; i < ids.length; i++) {\r\n          if (ids[i] === id) {\r\n              return true;\r\n          }\r\n      }\r\n      return false;\r\n  };\r\n  ChartInternal.prototype.isTargetToShow = function (targetId) {\r\n      return this.hiddenTargetIds.indexOf(targetId) < 0;\r\n  };\r\n  ChartInternal.prototype.isLegendToShow = function (targetId) {\r\n      return this.hiddenLegendIds.indexOf(targetId) < 0;\r\n  };\r\n  /**\r\n   * Returns only visible targets.\r\n   *\r\n   * This is the same as calling {@link filterTargetsToShow} on $$.data.targets.\r\n   *\r\n   * @return {Array}\r\n   */\r\n  ChartInternal.prototype.getTargetsToShow = function () {\r\n      var $$ = this;\r\n      return $$.filterTargetsToShow($$.data.targets);\r\n  };\r\n  ChartInternal.prototype.filterTargetsToShow = function (targets) {\r\n      var $$ = this;\r\n      return targets.filter(function (t) {\r\n          return $$.isTargetToShow(t.id);\r\n      });\r\n  };\r\n  /**\r\n   * @return {Array} Returns all the targets attached to the chart, visible or not\r\n   */\r\n  ChartInternal.prototype.getTargets = function () {\r\n      var $$ = this;\r\n      return $$.data.targets;\r\n  };\r\n  ChartInternal.prototype.mapTargetsToUniqueXs = function (targets) {\r\n      var $$ = this;\r\n      var xs = $$.d3\r\n          .set($$.d3.merge(targets.map(function (t) {\r\n          return t.values.map(function (v) {\r\n              return +v.x;\r\n          });\r\n      })))\r\n          .values();\r\n      xs = $$.isTimeSeries()\r\n          ? xs.map(function (x) {\r\n              return new Date(+x);\r\n          })\r\n          : xs.map(function (x) {\r\n              return +x;\r\n          });\r\n      return xs.sort(function (a, b) {\r\n          return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\r\n      });\r\n  };\r\n  ChartInternal.prototype.addHiddenTargetIds = function (targetIds) {\r\n      targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);\r\n      for (var i = 0; i < targetIds.length; i++) {\r\n          if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) {\r\n              this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]);\r\n          }\r\n      }\r\n      this.resetCache();\r\n  };\r\n  ChartInternal.prototype.removeHiddenTargetIds = function (targetIds) {\r\n      this.hiddenTargetIds = this.hiddenTargetIds.filter(function (id) {\r\n          return targetIds.indexOf(id) < 0;\r\n      });\r\n      this.resetCache();\r\n  };\r\n  ChartInternal.prototype.addHiddenLegendIds = function (targetIds) {\r\n      targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);\r\n      for (var i = 0; i < targetIds.length; i++) {\r\n          if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) {\r\n              this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]);\r\n          }\r\n      }\r\n  };\r\n  ChartInternal.prototype.removeHiddenLegendIds = function (targetIds) {\r\n      this.hiddenLegendIds = this.hiddenLegendIds.filter(function (id) {\r\n          return targetIds.indexOf(id) < 0;\r\n      });\r\n  };\r\n  ChartInternal.prototype.getValuesAsIdKeyed = function (targets) {\r\n      var ys = {};\r\n      targets.forEach(function (t) {\r\n          ys[t.id] = [];\r\n          t.values.forEach(function (v) {\r\n              ys[t.id].push(v.value);\r\n          });\r\n      });\r\n      return ys;\r\n  };\r\n  ChartInternal.prototype.checkValueInTargets = function (targets, checker) {\r\n      var ids = Object.keys(targets), i, j, values;\r\n      for (i = 0; i < ids.length; i++) {\r\n          values = targets[ids[i]].values;\r\n          for (j = 0; j < values.length; j++) {\r\n              if (checker(values[j].value)) {\r\n                  return true;\r\n              }\r\n          }\r\n      }\r\n      return false;\r\n  };\r\n  ChartInternal.prototype.hasNegativeValueInTargets = function (targets) {\r\n      return this.checkValueInTargets(targets, function (v) {\r\n          return v < 0;\r\n      });\r\n  };\r\n  ChartInternal.prototype.hasPositiveValueInTargets = function (targets) {\r\n      return this.checkValueInTargets(targets, function (v) {\r\n          return v > 0;\r\n      });\r\n  };\r\n  ChartInternal.prototype.isOrderDesc = function () {\r\n      var config = this.config;\r\n      return (typeof config.data_order === 'string' &&\r\n          config.data_order.toLowerCase() === 'desc');\r\n  };\r\n  ChartInternal.prototype.isOrderAsc = function () {\r\n      var config = this.config;\r\n      return (typeof config.data_order === 'string' &&\r\n          config.data_order.toLowerCase() === 'asc');\r\n  };\r\n  ChartInternal.prototype.getOrderFunction = function () {\r\n      var $$ = this, config = $$.config, orderAsc = $$.isOrderAsc(), orderDesc = $$.isOrderDesc();\r\n      if (orderAsc || orderDesc) {\r\n          var reducer = function (p, c) {\r\n              return p + Math.abs(c.value);\r\n          };\r\n          return function (t1, t2) {\r\n              var t1Sum = t1.values.reduce(reducer, 0), t2Sum = t2.values.reduce(reducer, 0);\r\n              return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum;\r\n          };\r\n      }\r\n      else if (isFunction(config.data_order)) {\r\n          return config.data_order;\r\n      }\r\n      else if (isArray(config.data_order)) {\r\n          var order = config.data_order;\r\n          return function (t1, t2) {\r\n              return order.indexOf(t1.id) - order.indexOf(t2.id);\r\n          };\r\n      }\r\n  };\r\n  ChartInternal.prototype.orderTargets = function (targets) {\r\n      var fct = this.getOrderFunction();\r\n      if (fct) {\r\n          targets.sort(fct);\r\n      }\r\n      return targets;\r\n  };\r\n  /**\r\n   * Returns all the values from the given targets at the given index.\r\n   *\r\n   * @param {Array} targets\r\n   * @param {Number} index\r\n   * @return {Array}\r\n   */\r\n  ChartInternal.prototype.filterByIndex = function (targets, index) {\r\n      return this.d3.merge(targets.map(function (t) { return t.values.filter(function (v) { return v.index === index; }); }));\r\n  };\r\n  ChartInternal.prototype.filterByX = function (targets, x) {\r\n      return this.d3\r\n          .merge(targets.map(function (t) {\r\n          return t.values;\r\n      }))\r\n          .filter(function (v) {\r\n          return v.x - x === 0;\r\n      });\r\n  };\r\n  ChartInternal.prototype.filterRemoveNull = function (data) {\r\n      return data.filter(function (d) {\r\n          return isValue(d.value);\r\n      });\r\n  };\r\n  ChartInternal.prototype.filterByXDomain = function (targets, xDomain) {\r\n      return targets.map(function (t) {\r\n          return {\r\n              id: t.id,\r\n              id_org: t.id_org,\r\n              values: t.values.filter(function (v) {\r\n                  return xDomain[0] <= v.x && v.x <= xDomain[1];\r\n              })\r\n          };\r\n      });\r\n  };\r\n  ChartInternal.prototype.hasDataLabel = function () {\r\n      var config = this.config;\r\n      if (typeof config.data_labels === 'boolean' && config.data_labels) {\r\n          return true;\r\n      }\r\n      else if (typeof config.data_labels === 'object' &&\r\n          notEmpty(config.data_labels)) {\r\n          return true;\r\n      }\r\n      return false;\r\n  };\r\n  ChartInternal.prototype.getDataLabelLength = function (min, max, key) {\r\n      var $$ = this, lengths = [0, 0], paddingCoef = 1.3;\r\n      $$.selectChart\r\n          .select('svg')\r\n          .selectAll('.dummy')\r\n          .data([min, max])\r\n          .enter()\r\n          .append('text')\r\n          .text(function (d) {\r\n          return $$.dataLabelFormat(d.id)(d);\r\n      })\r\n          .each(function (d, i) {\r\n          lengths[i] = getBBox(this)[key] * paddingCoef;\r\n      })\r\n          .remove();\r\n      return lengths;\r\n  };\r\n  /**\r\n   * Returns true if the given data point is not arc type, otherwise false.\r\n   * @param {Object} d The data point\r\n   * @return {boolean}\r\n   */\r\n  ChartInternal.prototype.isNoneArc = function (d) {\r\n      return this.hasTarget(this.data.targets, d.id);\r\n  };\r\n  /**\r\n   * Returns true if the given data point is arc type, otherwise false.\r\n   * @param {Object} d The data point\r\n   * @return {boolean}\r\n   */\r\n  ChartInternal.prototype.isArc = function (d) {\r\n      return 'data' in d && this.hasTarget(this.data.targets, d.data.id);\r\n  };\r\n  /**\r\n   * Find the closest point from the given pos among the given targets or\r\n   * undefined if none satisfies conditions.\r\n   *\r\n   * @param {Array} targets\r\n   * @param {Array} pos An [x,y] coordinate\r\n   * @return {Object|undefined}\r\n   */\r\n  ChartInternal.prototype.findClosestFromTargets = function (targets, pos) {\r\n      var $$ = this;\r\n      // for each target, find the closest point\r\n      var candidates = targets\r\n          .map(function (t) {\r\n          return $$.findClosest(t.values, pos, $$.config.tooltip_horizontal\r\n              ? $$.horizontalDistance.bind($$)\r\n              : $$.dist.bind($$), $$.config.point_sensitivity);\r\n      })\r\n          .filter(function (v) { return v; });\r\n      // returns the closest of candidates\r\n      if (candidates.length === 0) {\r\n          return undefined;\r\n      }\r\n      else if (candidates.length === 1) {\r\n          return candidates[0];\r\n      }\r\n      else {\r\n          return $$.findClosest(candidates, pos, $$.dist.bind($$));\r\n      }\r\n  };\r\n  /**\r\n   * Find the closest point from the x value or undefined if none satisfies conditions.\r\n   *\r\n   * @param {Array} targets\r\n   * @param {Array} x A value on X axis\r\n   * @return {Object|undefined}\r\n   */\r\n  ChartInternal.prototype.findClosestFromTargetsByX = function (targets, x) {\r\n      var closest;\r\n      var diff;\r\n      targets.forEach(function (t) {\r\n          t.values.forEach(function (d) {\r\n              var newDiff = Math.abs(x - d.x);\r\n              if (diff === undefined || newDiff < diff) {\r\n                  closest = d;\r\n                  diff = newDiff;\r\n              }\r\n          });\r\n      });\r\n      return closest;\r\n  };\r\n  /**\r\n   * Using given compute distance method, returns the closest data point from the\r\n   * given position.\r\n   *\r\n   * Giving optionally a minimum distance to satisfy.\r\n   *\r\n   * @param {Array} dataPoints List of DataPoints\r\n   * @param {Array} pos An [x,y] coordinate\r\n   * @param {Function} computeDist Function to compute distance between 2 points\r\n   * @param {Number} minDist Minimal distance to satisfy\r\n   * @return {Object|undefined} Closest data point\r\n   */\r\n  ChartInternal.prototype.findClosest = function (dataPoints, pos, computeDist, minDist) {\r\n      if (minDist === void 0) { minDist = Infinity; }\r\n      var $$ = this;\r\n      var closest;\r\n      // find closest bar\r\n      dataPoints\r\n          .filter(function (v) { return v && $$.isBarType(v.id); })\r\n          .forEach(function (v) {\r\n          if (!closest) {\r\n              var shape = $$.main\r\n                  .select('.' +\r\n                  CLASS.bars +\r\n                  $$.getTargetSelectorSuffix(v.id) +\r\n                  ' .' +\r\n                  CLASS.bar +\r\n                  '-' +\r\n                  v.index)\r\n                  .node();\r\n              if ($$.isWithinBar(pos, shape)) {\r\n                  closest = v;\r\n              }\r\n          }\r\n      });\r\n      // find closest point from non-bar\r\n      dataPoints\r\n          .filter(function (v) { return v && !$$.isBarType(v.id); })\r\n          .forEach(function (v) {\r\n          var d = computeDist(v, pos);\r\n          if (d < minDist) {\r\n              minDist = d;\r\n              closest = v;\r\n          }\r\n      });\r\n      return closest;\r\n  };\r\n  ChartInternal.prototype.dist = function (data, pos) {\r\n      var $$ = this, config = $$.config, xIndex = config.axis_rotated ? 1 : 0, yIndex = config.axis_rotated ? 0 : 1, y = $$.circleY(data, data.index), x = $$.x(data.x);\r\n      return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2));\r\n  };\r\n  ChartInternal.prototype.horizontalDistance = function (data, pos) {\r\n      var $$ = this, config = $$.config, xIndex = config.axis_rotated ? 1 : 0, x = $$.x(data.x);\r\n      return Math.abs(x - pos[xIndex]);\r\n  };\r\n  ChartInternal.prototype.convertValuesToStep = function (values) {\r\n      var converted = [].concat(values), i;\r\n      if (!this.isCategorized()) {\r\n          return values;\r\n      }\r\n      for (i = values.length + 1; 0 < i; i--) {\r\n          converted[i] = converted[i - 1];\r\n      }\r\n      converted[0] = {\r\n          x: converted[0].x - 1,\r\n          value: converted[0].value,\r\n          id: converted[0].id\r\n      };\r\n      converted[values.length + 1] = {\r\n          x: converted[values.length].x + 1,\r\n          value: converted[values.length].value,\r\n          id: converted[values.length].id\r\n      };\r\n      return converted;\r\n  };\r\n  /**\r\n   * Get ratio value\r\n   *\r\n   * @param {String} type Ratio for given type\r\n   * @param {Object} d Data value object\r\n   * @param {Boolean} asPercent Convert the return as percent or not\r\n   * @return {Number} Ratio value\r\n   * @private\r\n   */\r\n  ChartInternal.prototype.getRatio = function (type, d, asPercent) {\r\n      if (asPercent === void 0) { asPercent = false; }\r\n      var $$ = this;\r\n      var api = $$.api;\r\n      var ratio = 0;\r\n      if (d && api.data.shown.call(api).length) {\r\n          ratio = d.ratio || d.value;\r\n          if (type === 'arc') {\r\n              if ($$.hasType('gauge')) {\r\n                  ratio =\r\n                      (d.endAngle - d.startAngle) /\r\n                          (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1));\r\n              }\r\n              else {\r\n                  var total = $$.getTotalDataSum();\r\n                  ratio = d.value / total;\r\n              }\r\n          }\r\n          else if (type === 'index') {\r\n              var total = $$.getTotalPerIndex($$.axis.getId(d.id));\r\n              d.ratio =\r\n                  isNumber(d.value) && total && total[d.index] > 0\r\n                      ? d.value / total[d.index]\r\n                      : 0;\r\n              ratio = d.ratio;\r\n          }\r\n      }\r\n      return asPercent && ratio ? ratio * 100 : ratio;\r\n  };\r\n  ChartInternal.prototype.updateDataAttributes = function (name, attrs) {\r\n      var $$ = this, config = $$.config, current = config['data_' + name];\r\n      if (typeof attrs === 'undefined') {\r\n          return current;\r\n      }\r\n      Object.keys(attrs).forEach(function (id) {\r\n          current[id] = attrs[id];\r\n      });\r\n      $$.redraw({\r\n          withLegend: true\r\n      });\r\n      return current;\r\n  };\n\n  ChartInternal.prototype.load = function (targets, args) {\r\n      var $$ = this;\r\n      if (targets) {\r\n          // filter loading targets if needed\r\n          if (args.filter) {\r\n              targets = targets.filter(args.filter);\r\n          }\r\n          // set type if args.types || args.type specified\r\n          if (args.type || args.types) {\r\n              targets.forEach(function (t) {\r\n                  var type = args.types && args.types[t.id] ? args.types[t.id] : args.type;\r\n                  $$.setTargetType(t.id, type);\r\n              });\r\n          }\r\n          // Update/Add data\r\n          $$.data.targets.forEach(function (d) {\r\n              for (var i = 0; i < targets.length; i++) {\r\n                  if (d.id === targets[i].id) {\r\n                      d.values = targets[i].values;\r\n                      targets.splice(i, 1);\r\n                      break;\r\n                  }\r\n              }\r\n          });\r\n          $$.data.targets = $$.data.targets.concat(targets); // add remained\r\n      }\r\n      // Set targets\r\n      $$.updateTargets($$.data.targets);\r\n      // Redraw with new targets\r\n      $$.redraw({\r\n          withUpdateOrgXDomain: true,\r\n          withUpdateXDomain: true,\r\n          withLegend: true\r\n      });\r\n      if (args.done) {\r\n          args.done();\r\n      }\r\n  };\r\n  ChartInternal.prototype.loadFromArgs = function (args) {\r\n      var $$ = this;\r\n      $$.resetCache();\r\n      if (args.data) {\r\n          $$.load($$.convertDataToTargets(args.data), args);\r\n      }\r\n      else if (args.url) {\r\n          $$.convertUrlToData(args.url, args.mimeType, args.headers, args.keys, function (data) {\r\n              $$.load($$.convertDataToTargets(data), args);\r\n          });\r\n      }\r\n      else if (args.json) {\r\n          $$.load($$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), args);\r\n      }\r\n      else if (args.rows) {\r\n          $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args);\r\n      }\r\n      else if (args.columns) {\r\n          $$.load($$.convertDataToTargets($$.convertColumnsToData(args.columns)), args);\r\n      }\r\n      else {\r\n          $$.load(null, args);\r\n      }\r\n  };\r\n  ChartInternal.prototype.unload = function (targetIds, done) {\r\n      var $$ = this;\r\n      $$.resetCache();\r\n      if (!done) {\r\n          done = function () { };\r\n      }\r\n      // filter existing target\r\n      targetIds = targetIds.filter(function (id) {\r\n          return $$.hasTarget($$.data.targets, id);\r\n      });\r\n      // If no target, call done and return\r\n      if (!targetIds || targetIds.length === 0) {\r\n          done();\r\n          return;\r\n      }\r\n      $$.svg\r\n          .selectAll(targetIds.map(function (id) {\r\n          return $$.selectorTarget(id);\r\n      }))\r\n          .transition()\r\n          .style('opacity', 0)\r\n          .remove()\r\n          .call($$.endall, done);\r\n      targetIds.forEach(function (id) {\r\n          // Reset fadein for future load\r\n          $$.withoutFadeIn[id] = false;\r\n          // Remove target's elements\r\n          if ($$.legend) {\r\n              $$.legend\r\n                  .selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id))\r\n                  .remove();\r\n          }\r\n          // Remove target\r\n          $$.data.targets = $$.data.targets.filter(function (t) {\r\n              return t.id !== id;\r\n          });\r\n      });\r\n  };\n\n  ChartInternal.prototype.getYDomainMin = function (targets) {\r\n      var $$ = this, config = $$.config, ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets), j, k, baseId, idsInGroup, id, hasNegativeValue;\r\n      if (config.data_groups.length > 0) {\r\n          hasNegativeValue = $$.hasNegativeValueInTargets(targets);\r\n          for (j = 0; j < config.data_groups.length; j++) {\r\n              // Determine baseId\r\n              idsInGroup = config.data_groups[j].filter(function (id) {\r\n                  return ids.indexOf(id) >= 0;\r\n              });\r\n              if (idsInGroup.length === 0) {\r\n                  continue;\r\n              }\r\n              baseId = idsInGroup[0];\r\n              // Consider negative values\r\n              if (hasNegativeValue && ys[baseId]) {\r\n                  ys[baseId].forEach(function (v, i) {\r\n                      ys[baseId][i] = v < 0 ? v : 0;\r\n                  });\r\n              }\r\n              // Compute min\r\n              for (k = 1; k < idsInGroup.length; k++) {\r\n                  id = idsInGroup[k];\r\n                  if (!ys[id]) {\r\n                      continue;\r\n                  }\r\n                  ys[id].forEach(function (v, i) {\r\n                      if ($$.axis.getId(id) === $$.axis.getId(baseId) &&\r\n                          ys[baseId] &&\r\n                          !(hasNegativeValue && +v > 0)) {\r\n                          ys[baseId][i] += +v;\r\n                      }\r\n                  });\r\n              }\r\n          }\r\n      }\r\n      return $$.d3.min(Object.keys(ys).map(function (key) {\r\n          return $$.d3.min(ys[key]);\r\n      }));\r\n  };\r\n  ChartInternal.prototype.getYDomainMax = function (targets) {\r\n      var $$ = this, config = $$.config, ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets), j, k, baseId, idsInGroup, id, hasPositiveValue;\r\n      if (config.data_groups.length > 0) {\r\n          hasPositiveValue = $$.hasPositiveValueInTargets(targets);\r\n          for (j = 0; j < config.data_groups.length; j++) {\r\n              // Determine baseId\r\n              idsInGroup = config.data_groups[j].filter(function (id) {\r\n                  return ids.indexOf(id) >= 0;\r\n              });\r\n              if (idsInGroup.length === 0) {\r\n                  continue;\r\n              }\r\n              baseId = idsInGroup[0];\r\n              // Consider positive values\r\n              if (hasPositiveValue && ys[baseId]) {\r\n                  ys[baseId].forEach(function (v, i) {\r\n                      ys[baseId][i] = v > 0 ? v : 0;\r\n                  });\r\n              }\r\n              // Compute max\r\n              for (k = 1; k < idsInGroup.length; k++) {\r\n                  id = idsInGroup[k];\r\n                  if (!ys[id]) {\r\n                      continue;\r\n                  }\r\n                  ys[id].forEach(function (v, i) {\r\n                      if ($$.axis.getId(id) === $$.axis.getId(baseId) &&\r\n                          ys[baseId] &&\r\n                          !(hasPositiveValue && +v < 0)) {\r\n                          ys[baseId][i] += +v;\r\n                      }\r\n                  });\r\n              }\r\n          }\r\n      }\r\n      return $$.d3.max(Object.keys(ys).map(function (key) {\r\n          return $$.d3.max(ys[key]);\r\n      }));\r\n  };\r\n  ChartInternal.prototype.getYDomain = function (targets, axisId, xDomain) {\r\n      var $$ = this, config = $$.config;\r\n      if ($$.isAxisNormalized(axisId)) {\r\n          return [0, 100];\r\n      }\r\n      var targetsByAxisId = targets.filter(function (t) {\r\n          return $$.axis.getId(t.id) === axisId;\r\n      }), yTargets = xDomain\r\n          ? $$.filterByXDomain(targetsByAxisId, xDomain)\r\n          : targetsByAxisId, yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min, yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max, yDomainMin = $$.getYDomainMin(yTargets), yDomainMax = $$.getYDomainMax(yTargets), domain, domainLength, padding_top, padding_bottom, center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center, yDomainAbs, lengths, diff, ratio, isAllPositive, isAllNegative, isZeroBased = ($$.hasType('bar', yTargets) && config.bar_zerobased) ||\r\n          ($$.hasType('area', yTargets) && config.area_zerobased), isInverted = axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted, showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated, showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated;\r\n      // MEMO: avoid inverting domain unexpectedly\r\n      yDomainMin = isValue(yMin)\r\n          ? yMin\r\n          : isValue(yMax)\r\n              ? yDomainMin < yMax\r\n                  ? yDomainMin\r\n                  : yMax - 10\r\n              : yDomainMin;\r\n      yDomainMax = isValue(yMax)\r\n          ? yMax\r\n          : isValue(yMin)\r\n              ? yMin < yDomainMax\r\n                  ? yDomainMax\r\n                  : yMin + 10\r\n              : yDomainMax;\r\n      if (yTargets.length === 0) {\r\n          // use current domain if target of axisId is none\r\n          return axisId === 'y2' ? $$.y2.domain() : $$.y.domain();\r\n      }\r\n      if (isNaN(yDomainMin)) {\r\n          // set minimum to zero when not number\r\n          yDomainMin = 0;\r\n      }\r\n      if (isNaN(yDomainMax)) {\r\n          // set maximum to have same value as yDomainMin\r\n          yDomainMax = yDomainMin;\r\n      }\r\n      if (yDomainMin === yDomainMax) {\r\n          yDomainMin < 0 ? (yDomainMax = 0) : (yDomainMin = 0);\r\n      }\r\n      isAllPositive = yDomainMin >= 0 && yDomainMax >= 0;\r\n      isAllNegative = yDomainMin <= 0 && yDomainMax <= 0;\r\n      // Cancel zerobased if axis_*_min / axis_*_max specified\r\n      if ((isValue(yMin) && isAllPositive) || (isValue(yMax) && isAllNegative)) {\r\n          isZeroBased = false;\r\n      }\r\n      // Bar/Area chart should be 0-based if all positive|negative\r\n      if (isZeroBased) {\r\n          if (isAllPositive) {\r\n              yDomainMin = 0;\r\n          }\r\n          if (isAllNegative) {\r\n              yDomainMax = 0;\r\n          }\r\n      }\r\n      domainLength = Math.abs(yDomainMax - yDomainMin);\r\n      padding_top = padding_bottom = domainLength * 0.1;\r\n      if (typeof center !== 'undefined') {\r\n          yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax));\r\n          yDomainMax = center + yDomainAbs;\r\n          yDomainMin = center - yDomainAbs;\r\n      }\r\n      // add padding for data label\r\n      if (showHorizontalDataLabel) {\r\n          lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width');\r\n          diff = diffDomain($$.y.range());\r\n          ratio = [lengths[0] / diff, lengths[1] / diff];\r\n          padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1]));\r\n          padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1]));\r\n      }\r\n      else if (showVerticalDataLabel) {\r\n          lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height');\r\n          var pixelsToAxisPadding = $$.getY(config[\"axis_\" + axisId + \"_type\"], \r\n          // input domain as pixels\r\n          [0, config.axis_rotated ? $$.width : $$.height], \r\n          // output range as axis padding\r\n          [0, domainLength]);\r\n          padding_top += pixelsToAxisPadding(lengths[1]);\r\n          padding_bottom += pixelsToAxisPadding(lengths[0]);\r\n      }\r\n      if (axisId === 'y' && notEmpty(config.axis_y_padding)) {\r\n          padding_top = $$.axis.getPadding(config.axis_y_padding, 'top', padding_top, domainLength);\r\n          padding_bottom = $$.axis.getPadding(config.axis_y_padding, 'bottom', padding_bottom, domainLength);\r\n      }\r\n      if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) {\r\n          padding_top = $$.axis.getPadding(config.axis_y2_padding, 'top', padding_top, domainLength);\r\n          padding_bottom = $$.axis.getPadding(config.axis_y2_padding, 'bottom', padding_bottom, domainLength);\r\n      }\r\n      // Bar/Area chart should be 0-based if all positive|negative\r\n      if (isZeroBased) {\r\n          if (isAllPositive) {\r\n              padding_bottom = yDomainMin;\r\n          }\r\n          if (isAllNegative) {\r\n              padding_top = -yDomainMax;\r\n          }\r\n      }\r\n      domain = [yDomainMin - padding_bottom, yDomainMax + padding_top];\r\n      return isInverted ? domain.reverse() : domain;\r\n  };\r\n  ChartInternal.prototype.getXDomainMin = function (targets) {\r\n      var $$ = this, config = $$.config;\r\n      return isDefined(config.axis_x_min)\r\n          ? $$.isTimeSeries()\r\n              ? this.parseDate(config.axis_x_min)\r\n              : config.axis_x_min\r\n          : $$.d3.min(targets, function (t) {\r\n              return $$.d3.min(t.values, function (v) {\r\n                  return v.x;\r\n              });\r\n          });\r\n  };\r\n  ChartInternal.prototype.getXDomainMax = function (targets) {\r\n      var $$ = this, config = $$.config;\r\n      return isDefined(config.axis_x_max)\r\n          ? $$.isTimeSeries()\r\n              ? this.parseDate(config.axis_x_max)\r\n              : config.axis_x_max\r\n          : $$.d3.max(targets, function (t) {\r\n              return $$.d3.max(t.values, function (v) {\r\n                  return v.x;\r\n              });\r\n          });\r\n  };\r\n  ChartInternal.prototype.getXDomainPadding = function (domain) {\r\n      var $$ = this, config = $$.config, diff = domain[1] - domain[0], maxDataCount, padding, paddingLeft, paddingRight;\r\n      if ($$.isCategorized()) {\r\n          padding = 0;\r\n      }\r\n      else if ($$.hasType('bar')) {\r\n          maxDataCount = $$.getMaxDataCount();\r\n          padding = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : 0.5;\r\n      }\r\n      else {\r\n          padding = diff * 0.01;\r\n      }\r\n      if (typeof config.axis_x_padding === 'object' &&\r\n          notEmpty(config.axis_x_padding)) {\r\n          paddingLeft = isValue(config.axis_x_padding.left)\r\n              ? config.axis_x_padding.left\r\n              : padding;\r\n          paddingRight = isValue(config.axis_x_padding.right)\r\n              ? config.axis_x_padding.right\r\n              : padding;\r\n      }\r\n      else if (typeof config.axis_x_padding === 'number') {\r\n          paddingLeft = paddingRight = config.axis_x_padding;\r\n      }\r\n      else {\r\n          paddingLeft = paddingRight = padding;\r\n      }\r\n      return { left: paddingLeft, right: paddingRight };\r\n  };\r\n  ChartInternal.prototype.getXDomain = function (targets) {\r\n      var $$ = this, xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)], firstX = xDomain[0], lastX = xDomain[1], padding = $$.getXDomainPadding(xDomain), min = 0, max = 0;\r\n      // show center of x domain if min and max are the same\r\n      if (firstX - lastX === 0 && !$$.isCategorized()) {\r\n          if ($$.isTimeSeries()) {\r\n              firstX = new Date(firstX.getTime() * 0.5);\r\n              lastX = new Date(lastX.getTime() * 1.5);\r\n          }\r\n          else {\r\n              firstX = firstX === 0 ? 1 : firstX * 0.5;\r\n              lastX = lastX === 0 ? -1 : lastX * 1.5;\r\n          }\r\n      }\r\n      if (firstX || firstX === 0) {\r\n          min = $$.isTimeSeries()\r\n              ? new Date(firstX.getTime() - padding.left)\r\n              : firstX - padding.left;\r\n      }\r\n      if (lastX || lastX === 0) {\r\n          max = $$.isTimeSeries()\r\n              ? new Date(lastX.getTime() + padding.right)\r\n              : lastX + padding.right;\r\n      }\r\n      return [min, max];\r\n  };\r\n  ChartInternal.prototype.updateXDomain = function (targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) {\r\n      var $$ = this, config = $$.config;\r\n      if (withUpdateOrgXDomain) {\r\n          $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets)));\r\n          $$.orgXDomain = $$.x.domain();\r\n          if (config.zoom_enabled) {\r\n              $$.zoom.update();\r\n          }\r\n          $$.subX.domain($$.x.domain());\r\n          if ($$.brush) {\r\n              $$.brush.updateScale($$.subX);\r\n          }\r\n      }\r\n      if (withUpdateXDomain) {\r\n          $$.x.domain(domain\r\n              ? domain\r\n              : !$$.brush || $$.brush.empty()\r\n                  ? $$.orgXDomain\r\n                  : $$.brush.selectionAsValue());\r\n      }\r\n      // Trim domain when too big by zoom mousemove event\r\n      if (withTrim) {\r\n          $$.x.domain($$.trimXDomain($$.x.orgDomain()));\r\n      }\r\n      return $$.x.domain();\r\n  };\r\n  ChartInternal.prototype.trimXDomain = function (domain) {\r\n      var zoomDomain = this.getZoomDomain(), min = zoomDomain[0], max = zoomDomain[1];\r\n      if (domain[0] <= min) {\r\n          domain[1] = +domain[1] + (min - domain[0]);\r\n          domain[0] = min;\r\n      }\r\n      if (max <= domain[1]) {\r\n          domain[0] = +domain[0] - (domain[1] - max);\r\n          domain[1] = max;\r\n      }\r\n      return domain;\r\n  };\n\n  ChartInternal.prototype.drag = function (mouse) {\r\n      var $$ = this, config = $$.config, main = $$.main, d3 = $$.d3;\r\n      var sx, sy, mx, my, minX, maxX, minY, maxY;\r\n      if ($$.hasArcType()) {\r\n          return;\r\n      }\r\n      if (!config.data_selection_enabled) {\r\n          return;\r\n      } // do nothing if not selectable\r\n      if (!config.data_selection_multiple) {\r\n          return;\r\n      } // skip when single selection because drag is used for multiple selection\r\n      sx = $$.dragStart[0];\r\n      sy = $$.dragStart[1];\r\n      mx = mouse[0];\r\n      my = mouse[1];\r\n      minX = Math.min(sx, mx);\r\n      maxX = Math.max(sx, mx);\r\n      minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my);\r\n      maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my);\r\n      main\r\n          .select('.' + CLASS.dragarea)\r\n          .attr('x', minX)\r\n          .attr('y', minY)\r\n          .attr('width', maxX - minX)\r\n          .attr('height', maxY - minY);\r\n      // TODO: binary search when multiple xs\r\n      main\r\n          .selectAll('.' + CLASS.shapes)\r\n          .selectAll('.' + CLASS.shape)\r\n          .each(function (d, i) {\r\n          if (!config.data_selection_isselectable(d)) {\r\n              return;\r\n          }\r\n          var shape = d3.select(this), isSelected = shape.classed(CLASS.SELECTED), isIncluded = shape.classed(CLASS.INCLUDED), _x, _y, _w, _h, toggle, isWithin = false, box;\r\n          if (shape.classed(CLASS.circle)) {\r\n              _x = shape.attr('cx') * 1;\r\n              _y = shape.attr('cy') * 1;\r\n              toggle = $$.togglePoint;\r\n              isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY;\r\n          }\r\n          else if (shape.classed(CLASS.bar)) {\r\n              box = getPathBox(this);\r\n              _x = box.x;\r\n              _y = box.y;\r\n              _w = box.width;\r\n              _h = box.height;\r\n              toggle = $$.togglePath;\r\n              isWithin =\r\n                  !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY);\r\n          }\r\n          else {\r\n              // line/area selection not supported yet\r\n              return;\r\n          }\r\n          if (isWithin ^ isIncluded) {\r\n              shape.classed(CLASS.INCLUDED, !isIncluded);\r\n              // TODO: included/unincluded callback here\r\n              shape.classed(CLASS.SELECTED, !isSelected);\r\n              toggle.call($$, !isSelected, shape, d, i);\r\n          }\r\n      });\r\n  };\r\n  ChartInternal.prototype.dragstart = function (mouse) {\r\n      var $$ = this, config = $$.config;\r\n      if ($$.hasArcType()) {\r\n          return;\r\n      }\r\n      if (!config.data_selection_enabled) {\r\n          return;\r\n      } // do nothing if not selectable\r\n      $$.dragStart = mouse;\r\n      $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('rect')\r\n          .attr('class', CLASS.dragarea)\r\n          .style('opacity', 0.1);\r\n      $$.dragging = true;\r\n  };\r\n  ChartInternal.prototype.dragend = function () {\r\n      var $$ = this, config = $$.config;\r\n      if ($$.hasArcType()) {\r\n          return;\r\n      }\r\n      if (!config.data_selection_enabled) {\r\n          return;\r\n      } // do nothing if not selectable\r\n      $$.main\r\n          .select('.' + CLASS.dragarea)\r\n          .transition()\r\n          .duration(100)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      $$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false);\r\n      $$.dragging = false;\r\n  };\n\n  ChartInternal.prototype.getYFormat = function (forArc) {\r\n      var $$ = this, formatForY = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat, formatForY2 = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format;\r\n      return function (v, ratio, id) {\r\n          var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY;\r\n          return format.call($$, v, ratio);\r\n      };\r\n  };\r\n  ChartInternal.prototype.yFormat = function (v) {\r\n      var $$ = this, config = $$.config, format = config.axis_y_tick_format\r\n          ? config.axis_y_tick_format\r\n          : $$.defaultValueFormat;\r\n      return format(v);\r\n  };\r\n  ChartInternal.prototype.y2Format = function (v) {\r\n      var $$ = this, config = $$.config, format = config.axis_y2_tick_format\r\n          ? config.axis_y2_tick_format\r\n          : $$.defaultValueFormat;\r\n      return format(v);\r\n  };\r\n  ChartInternal.prototype.defaultValueFormat = function (v) {\r\n      return isValue(v) ? +v : '';\r\n  };\r\n  ChartInternal.prototype.defaultArcValueFormat = function (v, ratio) {\r\n      return (ratio * 100).toFixed(1) + '%';\r\n  };\r\n  ChartInternal.prototype.dataLabelFormat = function (targetId) {\r\n      var $$ = this, data_labels = $$.config.data_labels, format, defaultFormat = function (v) {\r\n          return isValue(v) ? +v : '';\r\n      };\r\n      // find format according to axis id\r\n      if (typeof data_labels.format === 'function') {\r\n          format = data_labels.format;\r\n      }\r\n      else if (typeof data_labels.format === 'object') {\r\n          if (data_labels.format[targetId]) {\r\n              format =\r\n                  data_labels.format[targetId] === true\r\n                      ? defaultFormat\r\n                      : data_labels.format[targetId];\r\n          }\r\n          else {\r\n              format = function () {\r\n                  return '';\r\n              };\r\n          }\r\n      }\r\n      else {\r\n          format = defaultFormat;\r\n      }\r\n      return format;\r\n  };\n\n  ChartInternal.prototype.initGrid = function () {\r\n      var $$ = this, config = $$.config, d3 = $$.d3;\r\n      $$.grid = $$.main\r\n          .append('g')\r\n          .attr('clip-path', $$.clipPathForGrid)\r\n          .attr('class', CLASS.grid);\r\n      if (config.grid_x_show) {\r\n          $$.grid.append('g').attr('class', CLASS.xgrids);\r\n      }\r\n      if (config.grid_y_show) {\r\n          $$.grid.append('g').attr('class', CLASS.ygrids);\r\n      }\r\n      if (config.grid_focus_show) {\r\n          $$.grid\r\n              .append('g')\r\n              .attr('class', CLASS.xgridFocus)\r\n              .append('line')\r\n              .attr('class', CLASS.xgridFocus);\r\n      }\r\n      $$.xgrid = d3.selectAll([]);\r\n      if (!config.grid_lines_front) {\r\n          $$.initGridLines();\r\n      }\r\n  };\r\n  ChartInternal.prototype.initGridLines = function () {\r\n      var $$ = this, d3 = $$.d3;\r\n      $$.gridLines = $$.main\r\n          .append('g')\r\n          .attr('clip-path', $$.clipPathForGrid)\r\n          .attr('class', CLASS.grid + ' ' + CLASS.gridLines);\r\n      $$.gridLines.append('g').attr('class', CLASS.xgridLines);\r\n      $$.gridLines.append('g').attr('class', CLASS.ygridLines);\r\n      $$.xgridLines = d3.selectAll([]);\r\n  };\r\n  ChartInternal.prototype.updateXGrid = function (withoutUpdate) {\r\n      var $$ = this, config = $$.config, d3 = $$.d3, xgridData = $$.generateGridData(config.grid_x_type, $$.x), tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0;\r\n      $$.xgridAttr = config.axis_rotated\r\n          ? {\r\n              x1: 0,\r\n              x2: $$.width,\r\n              y1: function (d) {\r\n                  return $$.x(d) - tickOffset;\r\n              },\r\n              y2: function (d) {\r\n                  return $$.x(d) - tickOffset;\r\n              }\r\n          }\r\n          : {\r\n              x1: function (d) {\r\n                  return $$.x(d) + tickOffset;\r\n              },\r\n              x2: function (d) {\r\n                  return $$.x(d) + tickOffset;\r\n              },\r\n              y1: 0,\r\n              y2: $$.height\r\n          };\r\n      $$.xgridAttr.opacity = function () {\r\n          var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1');\r\n          return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1;\r\n      };\r\n      var xgrid = $$.main\r\n          .select('.' + CLASS.xgrids)\r\n          .selectAll('.' + CLASS.xgrid)\r\n          .data(xgridData);\r\n      var xgridEnter = xgrid\r\n          .enter()\r\n          .append('line')\r\n          .attr('class', CLASS.xgrid)\r\n          .attr('x1', $$.xgridAttr.x1)\r\n          .attr('x2', $$.xgridAttr.x2)\r\n          .attr('y1', $$.xgridAttr.y1)\r\n          .attr('y2', $$.xgridAttr.y2)\r\n          .style('opacity', 0);\r\n      $$.xgrid = xgridEnter.merge(xgrid);\r\n      if (!withoutUpdate) {\r\n          $$.xgrid\r\n              .attr('x1', $$.xgridAttr.x1)\r\n              .attr('x2', $$.xgridAttr.x2)\r\n              .attr('y1', $$.xgridAttr.y1)\r\n              .attr('y2', $$.xgridAttr.y2)\r\n              .style('opacity', $$.xgridAttr.opacity);\r\n      }\r\n      xgrid.exit().remove();\r\n  };\r\n  ChartInternal.prototype.updateYGrid = function () {\r\n      var $$ = this, config = $$.config, gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks);\r\n      var ygrid = $$.main\r\n          .select('.' + CLASS.ygrids)\r\n          .selectAll('.' + CLASS.ygrid)\r\n          .data(gridValues);\r\n      var ygridEnter = ygrid\r\n          .enter()\r\n          .append('line')\r\n          // TODO: x1, x2, y1, y2, opacity need to be set here maybe\r\n          .attr('class', CLASS.ygrid);\r\n      $$.ygrid = ygridEnter.merge(ygrid);\r\n      $$.ygrid\r\n          .attr('x1', config.axis_rotated ? $$.y : 0)\r\n          .attr('x2', config.axis_rotated ? $$.y : $$.width)\r\n          .attr('y1', config.axis_rotated ? 0 : $$.y)\r\n          .attr('y2', config.axis_rotated ? $$.height : $$.y);\r\n      ygrid.exit().remove();\r\n      $$.smoothLines($$.ygrid, 'grid');\r\n  };\r\n  ChartInternal.prototype.gridTextAnchor = function (d) {\r\n      return d.position ? d.position : 'end';\r\n  };\r\n  ChartInternal.prototype.gridTextDx = function (d) {\r\n      return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4;\r\n  };\r\n  ChartInternal.prototype.xGridTextX = function (d) {\r\n      return d.position === 'start'\r\n          ? -this.height\r\n          : d.position === 'middle'\r\n              ? -this.height / 2\r\n              : 0;\r\n  };\r\n  ChartInternal.prototype.yGridTextX = function (d) {\r\n      return d.position === 'start'\r\n          ? 0\r\n          : d.position === 'middle'\r\n              ? this.width / 2\r\n              : this.width;\r\n  };\r\n  ChartInternal.prototype.updateGrid = function (duration) {\r\n      var $$ = this, main = $$.main, config = $$.config, xgridLine, xgridLineEnter, ygridLine, ygridLineEnter, xv = $$.xv.bind($$), yv = $$.yv.bind($$), xGridTextX = $$.xGridTextX.bind($$), yGridTextX = $$.yGridTextX.bind($$);\r\n      // hide if arc type\r\n      $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');\r\n      main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden');\r\n      if (config.grid_x_show) {\r\n          $$.updateXGrid();\r\n      }\r\n      xgridLine = main\r\n          .select('.' + CLASS.xgridLines)\r\n          .selectAll('.' + CLASS.xgridLine)\r\n          .data(config.grid_x_lines);\r\n      // enter\r\n      xgridLineEnter = xgridLine\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', function (d) {\r\n          return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : '');\r\n      });\r\n      xgridLineEnter\r\n          .append('line')\r\n          .attr('x1', config.axis_rotated ? 0 : xv)\r\n          .attr('x2', config.axis_rotated ? $$.width : xv)\r\n          .attr('y1', config.axis_rotated ? xv : 0)\r\n          .attr('y2', config.axis_rotated ? xv : $$.height)\r\n          .style('opacity', 0);\r\n      xgridLineEnter\r\n          .append('text')\r\n          .attr('text-anchor', $$.gridTextAnchor)\r\n          .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\r\n          .attr('x', config.axis_rotated ? yGridTextX : xGridTextX)\r\n          .attr('y', xv)\r\n          .attr('dx', $$.gridTextDx)\r\n          .attr('dy', -5)\r\n          .style('opacity', 0);\r\n      // udpate\r\n      $$.xgridLines = xgridLineEnter.merge(xgridLine);\r\n      // done in d3.transition() of the end of this function\r\n      // exit\r\n      xgridLine\r\n          .exit()\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      // Y-Grid\r\n      if (config.grid_y_show) {\r\n          $$.updateYGrid();\r\n      }\r\n      ygridLine = main\r\n          .select('.' + CLASS.ygridLines)\r\n          .selectAll('.' + CLASS.ygridLine)\r\n          .data(config.grid_y_lines);\r\n      // enter\r\n      ygridLineEnter = ygridLine\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', function (d) {\r\n          return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : '');\r\n      });\r\n      ygridLineEnter\r\n          .append('line')\r\n          .attr('x1', config.axis_rotated ? yv : 0)\r\n          .attr('x2', config.axis_rotated ? yv : $$.width)\r\n          .attr('y1', config.axis_rotated ? 0 : yv)\r\n          .attr('y2', config.axis_rotated ? $$.height : yv)\r\n          .style('opacity', 0);\r\n      ygridLineEnter\r\n          .append('text')\r\n          .attr('text-anchor', $$.gridTextAnchor)\r\n          .attr('transform', config.axis_rotated ? 'rotate(-90)' : '')\r\n          .attr('x', config.axis_rotated ? xGridTextX : yGridTextX)\r\n          .attr('y', yv)\r\n          .attr('dx', $$.gridTextDx)\r\n          .attr('dy', -5)\r\n          .style('opacity', 0);\r\n      // update\r\n      $$.ygridLines = ygridLineEnter.merge(ygridLine);\r\n      $$.ygridLines\r\n          .select('line')\r\n          .transition()\r\n          .duration(duration)\r\n          .attr('x1', config.axis_rotated ? yv : 0)\r\n          .attr('x2', config.axis_rotated ? yv : $$.width)\r\n          .attr('y1', config.axis_rotated ? 0 : yv)\r\n          .attr('y2', config.axis_rotated ? $$.height : yv)\r\n          .style('opacity', 1);\r\n      $$.ygridLines\r\n          .select('text')\r\n          .transition()\r\n          .duration(duration)\r\n          .attr('x', config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$))\r\n          .attr('y', yv)\r\n          .text(function (d) {\r\n          return d.text;\r\n      })\r\n          .style('opacity', 1);\r\n      // exit\r\n      ygridLine\r\n          .exit()\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n  };\r\n  ChartInternal.prototype.redrawGrid = function (withTransition, transition) {\r\n      var $$ = this, config = $$.config, xv = $$.xv.bind($$), lines = $$.xgridLines.select('line'), texts = $$.xgridLines.select('text');\r\n      return [\r\n          (withTransition ? lines.transition(transition) : lines)\r\n              .attr('x1', config.axis_rotated ? 0 : xv)\r\n              .attr('x2', config.axis_rotated ? $$.width : xv)\r\n              .attr('y1', config.axis_rotated ? xv : 0)\r\n              .attr('y2', config.axis_rotated ? xv : $$.height)\r\n              .style('opacity', 1),\r\n          (withTransition ? texts.transition(transition) : texts)\r\n              .attr('x', config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$))\r\n              .attr('y', xv)\r\n              .text(function (d) {\r\n              return d.text;\r\n          })\r\n              .style('opacity', 1)\r\n      ];\r\n  };\r\n  ChartInternal.prototype.showXGridFocus = function (selectedData) {\r\n      var $$ = this, config = $$.config, dataToShow = selectedData.filter(function (d) {\r\n          return d && isValue(d.value);\r\n      }), focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus), xx = $$.xx.bind($$);\r\n      if (!config.tooltip_show) {\r\n          return;\r\n      }\r\n      // Hide when stanford plot exists\r\n      if ($$.hasType('stanford') || $$.hasArcType()) {\r\n          return;\r\n      }\r\n      focusEl\r\n          .style('visibility', 'visible')\r\n          .data([dataToShow[0]])\r\n          .attr(config.axis_rotated ? 'y1' : 'x1', xx)\r\n          .attr(config.axis_rotated ? 'y2' : 'x2', xx);\r\n      $$.smoothLines(focusEl, 'grid');\r\n  };\r\n  ChartInternal.prototype.hideXGridFocus = function () {\r\n      this.main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden');\r\n  };\r\n  ChartInternal.prototype.updateXgridFocus = function () {\r\n      var $$ = this, config = $$.config;\r\n      $$.main\r\n          .select('line.' + CLASS.xgridFocus)\r\n          .attr('x1', config.axis_rotated ? 0 : -10)\r\n          .attr('x2', config.axis_rotated ? $$.width : -10)\r\n          .attr('y1', config.axis_rotated ? -10 : 0)\r\n          .attr('y2', config.axis_rotated ? -10 : $$.height);\r\n  };\r\n  ChartInternal.prototype.generateGridData = function (type, scale) {\r\n      var $$ = this, gridData = [], xDomain, firstYear, lastYear, i, tickNum = $$.main\r\n          .select('.' + CLASS.axisX)\r\n          .selectAll('.tick')\r\n          .size();\r\n      if (type === 'year') {\r\n          xDomain = $$.getXDomain();\r\n          firstYear = xDomain[0].getFullYear();\r\n          lastYear = xDomain[1].getFullYear();\r\n          for (i = firstYear; i <= lastYear; i++) {\r\n              gridData.push(new Date(i + '-01-01 00:00:00'));\r\n          }\r\n      }\r\n      else {\r\n          gridData = scale.ticks(10);\r\n          if (gridData.length > tickNum) {\r\n              // use only int\r\n              gridData = gridData.filter(function (d) {\r\n                  return ('' + d).indexOf('.') < 0;\r\n              });\r\n          }\r\n      }\r\n      return gridData;\r\n  };\r\n  ChartInternal.prototype.getGridFilterToRemove = function (params) {\r\n      return params\r\n          ? function (line) {\r\n              var found = false;\r\n              [].concat(params).forEach(function (param) {\r\n                  if (('value' in param && line.value === param.value) ||\r\n                      ('class' in param && line['class'] === param['class'])) {\r\n                      found = true;\r\n                  }\r\n              });\r\n              return found;\r\n          }\r\n          : function () {\r\n              return true;\r\n          };\r\n  };\r\n  ChartInternal.prototype.removeGridLines = function (params, forX) {\r\n      var $$ = this, config = $$.config, toRemove = $$.getGridFilterToRemove(params), toShow = function (line) {\r\n          return !toRemove(line);\r\n      }, classLines = forX ? CLASS.xgridLines : CLASS.ygridLines, classLine = forX ? CLASS.xgridLine : CLASS.ygridLine;\r\n      $$.main\r\n          .select('.' + classLines)\r\n          .selectAll('.' + classLine)\r\n          .filter(toRemove)\r\n          .transition()\r\n          .duration(config.transition_duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      if (forX) {\r\n          config.grid_x_lines = config.grid_x_lines.filter(toShow);\r\n      }\r\n      else {\r\n          config.grid_y_lines = config.grid_y_lines.filter(toShow);\r\n      }\r\n  };\n\n  ChartInternal.prototype.initEventRect = function () {\r\n      var $$ = this, config = $$.config;\r\n      $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.eventRects)\r\n          .style('fill-opacity', 0);\r\n      $$.eventRect = $$.main\r\n          .select('.' + CLASS.eventRects)\r\n          .append('rect')\r\n          .attr('class', CLASS.eventRect);\r\n      // event rect handle zoom event as well\r\n      if (config.zoom_enabled && $$.zoom) {\r\n          $$.eventRect.call($$.zoom).on('dblclick.zoom', null);\r\n          if (config.zoom_initialRange) {\r\n              // WORKAROUND: Add transition to apply transform immediately when no subchart\r\n              $$.eventRect\r\n                  .transition()\r\n                  .duration(0)\r\n                  .call($$.zoom.transform, $$.zoomTransform(config.zoom_initialRange));\r\n          }\r\n      }\r\n  };\r\n  ChartInternal.prototype.redrawEventRect = function () {\r\n      var $$ = this, d3 = $$.d3, config = $$.config;\r\n      function mouseout() {\r\n          $$.svg.select('.' + CLASS.eventRect).style('cursor', null);\r\n          $$.hideXGridFocus();\r\n          $$.hideTooltip();\r\n          $$.unexpandCircles();\r\n          $$.unexpandBars();\r\n      }\r\n      var isHoveringDataPoint = function (mouse, closest) {\r\n          return closest &&\r\n              ($$.isBarType(closest.id) ||\r\n                  $$.dist(closest, mouse) < config.point_sensitivity);\r\n      };\r\n      var withName = function (d) { return (d ? $$.addName(Object.assign({}, d)) : null); };\r\n      // rects for mouseover\r\n      $$.main\r\n          .select('.' + CLASS.eventRects)\r\n          .style('cursor', config.zoom_enabled\r\n          ? config.axis_rotated\r\n              ? 'ns-resize'\r\n              : 'ew-resize'\r\n          : null);\r\n      $$.eventRect\r\n          .attr('x', 0)\r\n          .attr('y', 0)\r\n          .attr('width', $$.width)\r\n          .attr('height', $$.height)\r\n          .on('mouseout', config.interaction_enabled\r\n          ? function () {\r\n              if (!config) {\r\n                  return;\r\n              } // chart is destroyed\r\n              if ($$.hasArcType()) {\r\n                  return;\r\n              }\r\n              if ($$.mouseover) {\r\n                  config.data_onmouseout.call($$.api, $$.mouseover);\r\n                  $$.mouseover = undefined;\r\n              }\r\n              mouseout();\r\n          }\r\n          : null)\r\n          .on('mousemove', config.interaction_enabled\r\n          ? function () {\r\n              // do nothing when dragging\r\n              if ($$.dragging) {\r\n                  return;\r\n              }\r\n              var targetsToShow = $$.getTargetsToShow();\r\n              // do nothing if arc type\r\n              if ($$.hasArcType(targetsToShow)) {\r\n                  return;\r\n              }\r\n              var mouse = d3.mouse(this);\r\n              var closest = withName($$.findClosestFromTargets(targetsToShow, mouse));\r\n              var isMouseCloseToDataPoint = isHoveringDataPoint(mouse, closest);\r\n              // ensure onmouseout is always called if mousemove switch between 2 targets\r\n              if ($$.mouseover &&\r\n                  (!closest ||\r\n                      closest.id !== $$.mouseover.id ||\r\n                      closest.index !== $$.mouseover.index)) {\r\n                  config.data_onmouseout.call($$.api, $$.mouseover);\r\n                  $$.mouseover = undefined;\r\n              }\r\n              if (closest && !$$.mouseover) {\r\n                  config.data_onmouseover.call($$.api, closest);\r\n                  $$.mouseover = closest;\r\n              }\r\n              // show cursor as pointer if we're hovering a data point close enough\r\n              $$.svg\r\n                  .select('.' + CLASS.eventRect)\r\n                  .style('cursor', isMouseCloseToDataPoint ? 'pointer' : null);\r\n              // if tooltip not grouped, we want to display only data from closest data point\r\n              var showSingleDataPoint = !config.tooltip_grouped || $$.hasType('stanford', targetsToShow);\r\n              // find data to highlight\r\n              var selectedData;\r\n              if (showSingleDataPoint) {\r\n                  if (closest) {\r\n                      selectedData = [closest];\r\n                  }\r\n              }\r\n              else {\r\n                  var closestByX = void 0;\r\n                  if (closest) {\r\n                      // reuse closest value\r\n                      closestByX = closest;\r\n                  }\r\n                  else {\r\n                      // try to find the closest value by X values from the mouse position\r\n                      var mouseX = config.axis_rotated ? mouse[1] : mouse[0];\r\n                      closestByX = $$.findClosestFromTargetsByX(targetsToShow, $$.x.invert(mouseX));\r\n                  }\r\n                  // highlight all data for this 'x' value\r\n                  if (closestByX) {\r\n                      selectedData = $$.filterByX(targetsToShow, closestByX.x);\r\n                  }\r\n              }\r\n              // ensure we have data to show\r\n              if (!selectedData || selectedData.length === 0) {\r\n                  return mouseout();\r\n              }\r\n              // inject names for each point\r\n              selectedData = selectedData.map(withName);\r\n              // show tooltip\r\n              $$.showTooltip(selectedData, this);\r\n              // expand points\r\n              if (config.point_focus_expand_enabled) {\r\n                  $$.unexpandCircles();\r\n                  selectedData.forEach(function (d) {\r\n                      $$.expandCircles(d.index, d.id, false);\r\n                  });\r\n              }\r\n              // expand bars\r\n              $$.unexpandBars();\r\n              selectedData.forEach(function (d) {\r\n                  $$.expandBars(d.index, d.id, false);\r\n              });\r\n              // Show xgrid focus line\r\n              $$.showXGridFocus(selectedData);\r\n          }\r\n          : null)\r\n          .on('click', config.interaction_enabled\r\n          ? function () {\r\n              var targetsToShow = $$.getTargetsToShow();\r\n              if ($$.hasArcType(targetsToShow)) {\r\n                  return;\r\n              }\r\n              var mouse = d3.mouse(this);\r\n              var closest = withName($$.findClosestFromTargets(targetsToShow, mouse));\r\n              if (!isHoveringDataPoint(mouse, closest)) {\r\n                  return;\r\n              }\r\n              // select if selection enabled\r\n              var sameXData;\r\n              if (!config.data_selection_grouped || $$.isStanfordType(closest)) {\r\n                  sameXData = [closest];\r\n              }\r\n              else {\r\n                  sameXData = $$.filterByX(targetsToShow, closest.x);\r\n              }\r\n              // toggle selected state\r\n              sameXData.forEach(function (d) {\r\n                  $$.main\r\n                      .selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id))\r\n                      .selectAll('.' + CLASS.shape + '-' + d.index)\r\n                      .each(function () {\r\n                      if (config.data_selection_grouped ||\r\n                          $$.isWithinShape(this, d)) {\r\n                          $$.toggleShape(this, d, d.index);\r\n                      }\r\n                  });\r\n              });\r\n              // call data_onclick on the closest data point\r\n              if (closest) {\r\n                  var shape = $$.main\r\n                      .selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id))\r\n                      .select('.' + CLASS.shape + '-' + closest.index);\r\n                  config.data_onclick.call($$.api, closest, shape.node());\r\n              }\r\n          }\r\n          : null)\r\n          .call(config.interaction_enabled && config.data_selection_draggable && $$.drag\r\n          ? d3\r\n              .drag()\r\n              .on('drag', function () {\r\n              $$.drag(d3.mouse(this));\r\n          })\r\n              .on('start', function () {\r\n              $$.dragstart(d3.mouse(this));\r\n          })\r\n              .on('end', function () {\r\n              $$.dragend();\r\n          })\r\n          : function () { });\r\n  };\r\n  ChartInternal.prototype.getMousePosition = function (data) {\r\n      var $$ = this;\r\n      return [$$.x(data.x), $$.getYScale(data.id)(data.value)];\r\n  };\r\n  ChartInternal.prototype.dispatchEvent = function (type, mouse) {\r\n      var $$ = this, selector = '.' + CLASS.eventRect, eventRect = $$.main.select(selector).node(), box = eventRect.getBoundingClientRect(), x = box.left + (mouse ? mouse[0] : 0), y = box.top + (mouse ? mouse[1] : 0), event = document.createEvent('MouseEvents');\r\n      event.initMouseEvent(type, true, true, window, 0, x, y, x, y, false, false, false, false, 0, null);\r\n      eventRect.dispatchEvent(event);\r\n  };\n\n  ChartInternal.prototype.initLegend = function () {\r\n      var $$ = this;\r\n      $$.legendItemTextBox = {};\r\n      $$.legendHasRendered = false;\r\n      $$.legend = $$.svg.append('g').attr('transform', $$.getTranslate('legend'));\r\n      if (!$$.config.legend_show) {\r\n          $$.legend.style('visibility', 'hidden');\r\n          $$.hiddenLegendIds = $$.mapToIds($$.data.targets);\r\n          return;\r\n      }\r\n      // MEMO: call here to update legend box and tranlate for all\r\n      // MEMO: translate will be updated by this, so transform not needed in updateLegend()\r\n      $$.updateLegendWithDefaults();\r\n  };\r\n  ChartInternal.prototype.updateLegendWithDefaults = function () {\r\n      var $$ = this;\r\n      $$.updateLegend($$.mapToIds($$.data.targets), {\r\n          withTransform: false,\r\n          withTransitionForTransform: false,\r\n          withTransition: false\r\n      });\r\n  };\r\n  ChartInternal.prototype.updateSizeForLegend = function (legendHeight, legendWidth) {\r\n      var $$ = this, config = $$.config, insetLegendPosition = {\r\n          top: $$.isLegendTop\r\n              ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5\r\n              : $$.currentHeight -\r\n                  legendHeight -\r\n                  $$.getCurrentPaddingBottom() -\r\n                  config.legend_inset_y,\r\n          left: $$.isLegendLeft\r\n              ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5\r\n              : $$.currentWidth -\r\n                  legendWidth -\r\n                  $$.getCurrentPaddingRight() -\r\n                  config.legend_inset_x +\r\n                  0.5\r\n      };\r\n      $$.margin3 = {\r\n          top: $$.isLegendRight\r\n              ? 0\r\n              : $$.isLegendInset\r\n                  ? insetLegendPosition.top\r\n                  : $$.currentHeight - legendHeight,\r\n          right: NaN,\r\n          bottom: 0,\r\n          left: $$.isLegendRight\r\n              ? $$.currentWidth - legendWidth\r\n              : $$.isLegendInset\r\n                  ? insetLegendPosition.left\r\n                  : 0\r\n      };\r\n  };\r\n  ChartInternal.prototype.transformLegend = function (withTransition) {\r\n      var $$ = this;\r\n      (withTransition ? $$.legend.transition() : $$.legend).attr('transform', $$.getTranslate('legend'));\r\n  };\r\n  ChartInternal.prototype.updateLegendStep = function (step) {\r\n      this.legendStep = step;\r\n  };\r\n  ChartInternal.prototype.updateLegendItemWidth = function (w) {\r\n      this.legendItemWidth = w;\r\n  };\r\n  ChartInternal.prototype.updateLegendItemHeight = function (h) {\r\n      this.legendItemHeight = h;\r\n  };\r\n  ChartInternal.prototype.getLegendWidth = function () {\r\n      var $$ = this;\r\n      return $$.config.legend_show\r\n          ? $$.isLegendRight || $$.isLegendInset\r\n              ? $$.legendItemWidth * ($$.legendStep + 1)\r\n              : $$.currentWidth\r\n          : 0;\r\n  };\r\n  ChartInternal.prototype.getLegendHeight = function () {\r\n      var $$ = this, h = 0;\r\n      if ($$.config.legend_show) {\r\n          if ($$.isLegendRight) {\r\n              h = $$.currentHeight;\r\n          }\r\n          else {\r\n              h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1);\r\n          }\r\n      }\r\n      return h;\r\n  };\r\n  ChartInternal.prototype.opacityForLegend = function (legendItem) {\r\n      return legendItem.classed(CLASS.legendItemHidden) ? null : 1;\r\n  };\r\n  ChartInternal.prototype.opacityForUnfocusedLegend = function (legendItem) {\r\n      return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3;\r\n  };\r\n  ChartInternal.prototype.toggleFocusLegend = function (targetIds, focus) {\r\n      var $$ = this;\r\n      targetIds = $$.mapToTargetIds(targetIds);\r\n      $$.legend\r\n          .selectAll('.' + CLASS.legendItem)\r\n          .filter(function (id) {\r\n          return targetIds.indexOf(id) >= 0;\r\n      })\r\n          .classed(CLASS.legendItemFocused, focus)\r\n          .transition()\r\n          .duration(100)\r\n          .style('opacity', function () {\r\n          var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend;\r\n          return opacity.call($$, $$.d3.select(this));\r\n      });\r\n  };\r\n  ChartInternal.prototype.revertLegend = function () {\r\n      var $$ = this, d3 = $$.d3;\r\n      $$.legend\r\n          .selectAll('.' + CLASS.legendItem)\r\n          .classed(CLASS.legendItemFocused, false)\r\n          .transition()\r\n          .duration(100)\r\n          .style('opacity', function () {\r\n          return $$.opacityForLegend(d3.select(this));\r\n      });\r\n  };\r\n  ChartInternal.prototype.showLegend = function (targetIds) {\r\n      var $$ = this, config = $$.config;\r\n      if (!config.legend_show) {\r\n          config.legend_show = true;\r\n          $$.legend.style('visibility', 'visible');\r\n          if (!$$.legendHasRendered) {\r\n              $$.updateLegendWithDefaults();\r\n          }\r\n      }\r\n      $$.removeHiddenLegendIds(targetIds);\r\n      $$.legend\r\n          .selectAll($$.selectorLegends(targetIds))\r\n          .style('visibility', 'visible')\r\n          .transition()\r\n          .style('opacity', function () {\r\n          return $$.opacityForLegend($$.d3.select(this));\r\n      });\r\n  };\r\n  ChartInternal.prototype.hideLegend = function (targetIds) {\r\n      var $$ = this, config = $$.config;\r\n      if (config.legend_show && isEmpty(targetIds)) {\r\n          config.legend_show = false;\r\n          $$.legend.style('visibility', 'hidden');\r\n      }\r\n      $$.addHiddenLegendIds(targetIds);\r\n      $$.legend\r\n          .selectAll($$.selectorLegends(targetIds))\r\n          .style('opacity', 0)\r\n          .style('visibility', 'hidden');\r\n  };\r\n  ChartInternal.prototype.clearLegendItemTextBoxCache = function () {\r\n      this.legendItemTextBox = {};\r\n  };\r\n  ChartInternal.prototype.updateLegend = function (targetIds, options, transitions) {\r\n      var $$ = this, config = $$.config;\r\n      var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect, x1ForLegendTile, x2ForLegendTile, yForLegendTile;\r\n      var paddingTop = 4, paddingRight = 10, maxWidth = 0, maxHeight = 0, posMin = 10, tileWidth = config.legend_item_tile_width + 5;\r\n      var l, totalLength = 0, offsets = {}, widths = {}, heights = {}, margins = [0], steps = {}, step = 0;\r\n      var withTransition, withTransitionForTransform;\r\n      var texts, rects, tiles, background;\r\n      // Skip elements when their name is set to null\r\n      targetIds = targetIds.filter(function (id) {\r\n          return !isDefined(config.data_names[id]) || config.data_names[id] !== null;\r\n      });\r\n      options = options || {};\r\n      withTransition = getOption(options, 'withTransition', true);\r\n      withTransitionForTransform = getOption(options, 'withTransitionForTransform', true);\r\n      function getTextBox(textElement, id) {\r\n          if (!$$.legendItemTextBox[id]) {\r\n              $$.legendItemTextBox[id] = $$.getTextRect(textElement.textContent, CLASS.legendItem, textElement);\r\n          }\r\n          return $$.legendItemTextBox[id];\r\n      }\r\n      function updatePositions(textElement, id, index) {\r\n          var reset = index === 0, isLast = index === targetIds.length - 1, box = getTextBox(textElement, id), itemWidth = box.width +\r\n              tileWidth +\r\n              (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) +\r\n              config.legend_padding, itemHeight = box.height + paddingTop, itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth, areaLength = $$.isLegendRight || $$.isLegendInset\r\n              ? $$.getLegendHeight()\r\n              : $$.getLegendWidth(), margin, maxLength;\r\n          // MEMO: care about condifion of step, totalLength\r\n          function updateValues(id, withoutStep) {\r\n              if (!withoutStep) {\r\n                  margin = (areaLength - totalLength - itemLength) / 2;\r\n                  if (margin < posMin) {\r\n                      margin = (areaLength - itemLength) / 2;\r\n                      totalLength = 0;\r\n                      step++;\r\n                  }\r\n              }\r\n              steps[id] = step;\r\n              margins[step] = $$.isLegendInset ? 10 : margin;\r\n              offsets[id] = totalLength;\r\n              totalLength += itemLength;\r\n          }\r\n          if (reset) {\r\n              totalLength = 0;\r\n              step = 0;\r\n              maxWidth = 0;\r\n              maxHeight = 0;\r\n          }\r\n          if (config.legend_show && !$$.isLegendToShow(id)) {\r\n              widths[id] = heights[id] = steps[id] = offsets[id] = 0;\r\n              return;\r\n          }\r\n          widths[id] = itemWidth;\r\n          heights[id] = itemHeight;\r\n          if (!maxWidth || itemWidth >= maxWidth) {\r\n              maxWidth = itemWidth;\r\n          }\r\n          if (!maxHeight || itemHeight >= maxHeight) {\r\n              maxHeight = itemHeight;\r\n          }\r\n          maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth;\r\n          if (config.legend_equally) {\r\n              Object.keys(widths).forEach(function (id) {\r\n                  widths[id] = maxWidth;\r\n              });\r\n              Object.keys(heights).forEach(function (id) {\r\n                  heights[id] = maxHeight;\r\n              });\r\n              margin = (areaLength - maxLength * targetIds.length) / 2;\r\n              if (margin < posMin) {\r\n                  totalLength = 0;\r\n                  step = 0;\r\n                  targetIds.forEach(function (id) {\r\n                      updateValues(id);\r\n                  });\r\n              }\r\n              else {\r\n                  updateValues(id, true);\r\n              }\r\n          }\r\n          else {\r\n              updateValues(id);\r\n          }\r\n      }\r\n      if ($$.isLegendInset) {\r\n          step = config.legend_inset_step\r\n              ? config.legend_inset_step\r\n              : targetIds.length;\r\n          $$.updateLegendStep(step);\r\n      }\r\n      if ($$.isLegendRight) {\r\n          xForLegend = function (id) {\r\n              return maxWidth * steps[id];\r\n          };\r\n          yForLegend = function (id) {\r\n              return margins[steps[id]] + offsets[id];\r\n          };\r\n      }\r\n      else if ($$.isLegendInset) {\r\n          xForLegend = function (id) {\r\n              return maxWidth * steps[id] + 10;\r\n          };\r\n          yForLegend = function (id) {\r\n              return margins[steps[id]] + offsets[id];\r\n          };\r\n      }\r\n      else {\r\n          xForLegend = function (id) {\r\n              return margins[steps[id]] + offsets[id];\r\n          };\r\n          yForLegend = function (id) {\r\n              return maxHeight * steps[id];\r\n          };\r\n      }\r\n      xForLegendText = function (id, i) {\r\n          return xForLegend(id, i) + 4 + config.legend_item_tile_width;\r\n      };\r\n      yForLegendText = function (id, i) {\r\n          return yForLegend(id, i) + 9;\r\n      };\r\n      xForLegendRect = function (id, i) {\r\n          return xForLegend(id, i);\r\n      };\r\n      yForLegendRect = function (id, i) {\r\n          return yForLegend(id, i) - 5;\r\n      };\r\n      x1ForLegendTile = function (id, i) {\r\n          return xForLegend(id, i) - 2;\r\n      };\r\n      x2ForLegendTile = function (id, i) {\r\n          return xForLegend(id, i) - 2 + config.legend_item_tile_width;\r\n      };\r\n      yForLegendTile = function (id, i) {\r\n          return yForLegend(id, i) + 4;\r\n      };\r\n      // Define g for legend area\r\n      l = $$.legend\r\n          .selectAll('.' + CLASS.legendItem)\r\n          .data(targetIds)\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', function (id) {\r\n          return $$.generateClass(CLASS.legendItem, id);\r\n      })\r\n          .style('visibility', function (id) {\r\n          return $$.isLegendToShow(id) ? 'visible' : 'hidden';\r\n      })\r\n          .style('cursor', function () {\r\n          return config.interaction_enabled ? 'pointer' : 'auto';\r\n      })\r\n          .on('click', config.interaction_enabled\r\n          ? function (id) {\r\n              if (config.legend_item_onclick) {\r\n                  config.legend_item_onclick.call($$, id);\r\n              }\r\n              else {\r\n                  if ($$.d3.event.altKey) {\r\n                      $$.api.hide();\r\n                      $$.api.show(id);\r\n                  }\r\n                  else {\r\n                      $$.api.toggle(id);\r\n                      $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert();\r\n                  }\r\n              }\r\n          }\r\n          : null)\r\n          .on('mouseover', config.interaction_enabled\r\n          ? function (id) {\r\n              if (config.legend_item_onmouseover) {\r\n                  config.legend_item_onmouseover.call($$, id);\r\n              }\r\n              else {\r\n                  $$.d3.select(this).classed(CLASS.legendItemFocused, true);\r\n                  if (!$$.transiting && $$.isTargetToShow(id)) {\r\n                      $$.api.focus(id);\r\n                  }\r\n              }\r\n          }\r\n          : null)\r\n          .on('mouseout', config.interaction_enabled\r\n          ? function (id) {\r\n              if (config.legend_item_onmouseout) {\r\n                  config.legend_item_onmouseout.call($$, id);\r\n              }\r\n              else {\r\n                  $$.d3.select(this).classed(CLASS.legendItemFocused, false);\r\n                  $$.api.revert();\r\n              }\r\n          }\r\n          : null);\r\n      l.append('text')\r\n          .text(function (id) {\r\n          return isDefined(config.data_names[id]) ? config.data_names[id] : id;\r\n      })\r\n          .each(function (id, i) {\r\n          updatePositions(this, id, i);\r\n      })\r\n          .style('pointer-events', 'none')\r\n          .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200)\r\n          .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText);\r\n      l.append('rect')\r\n          .attr('class', CLASS.legendItemEvent)\r\n          .style('fill-opacity', 0)\r\n          .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200)\r\n          .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect);\r\n      l.append('line')\r\n          .attr('class', CLASS.legendItemTile)\r\n          .style('stroke', $$.color)\r\n          .style('pointer-events', 'none')\r\n          .attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200)\r\n          .attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile)\r\n          .attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200)\r\n          .attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile)\r\n          .attr('stroke-width', config.legend_item_tile_height);\r\n      // Set background for inset legend\r\n      background = $$.legend.select('.' + CLASS.legendBackground + ' rect');\r\n      if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) {\r\n          background = $$.legend\r\n              .insert('g', '.' + CLASS.legendItem)\r\n              .attr('class', CLASS.legendBackground)\r\n              .append('rect');\r\n      }\r\n      texts = $$.legend\r\n          .selectAll('text')\r\n          .data(targetIds)\r\n          .text(function (id) {\r\n          return isDefined(config.data_names[id]) ? config.data_names[id] : id;\r\n      }) // MEMO: needed for update\r\n          .each(function (id, i) {\r\n          updatePositions(this, id, i);\r\n      });\r\n      (withTransition ? texts.transition() : texts)\r\n          .attr('x', xForLegendText)\r\n          .attr('y', yForLegendText);\r\n      rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent).data(targetIds);\r\n      (withTransition ? rects.transition() : rects)\r\n          .attr('width', function (id) {\r\n          return widths[id];\r\n      })\r\n          .attr('height', function (id) {\r\n          return heights[id];\r\n      })\r\n          .attr('x', xForLegendRect)\r\n          .attr('y', yForLegendRect);\r\n      tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile).data(targetIds);\r\n      (withTransition ? tiles.transition() : tiles)\r\n          .style('stroke', $$.levelColor\r\n          ? function (id) {\r\n              return $$.levelColor($$.cache[id].values.reduce(function (total, item) {\r\n                  return total + item.value;\r\n              }, 0));\r\n          }\r\n          : $$.color)\r\n          .attr('x1', x1ForLegendTile)\r\n          .attr('y1', yForLegendTile)\r\n          .attr('x2', x2ForLegendTile)\r\n          .attr('y2', yForLegendTile);\r\n      if (background) {\r\n          (withTransition ? background.transition() : background)\r\n              .attr('height', $$.getLegendHeight() - 12)\r\n              .attr('width', maxWidth * (step + 1) + 10);\r\n      }\r\n      // toggle legend state\r\n      $$.legend\r\n          .selectAll('.' + CLASS.legendItem)\r\n          .classed(CLASS.legendItemHidden, function (id) {\r\n          return !$$.isTargetToShow(id);\r\n      });\r\n      // Update all to reflect change of legend\r\n      $$.updateLegendItemWidth(maxWidth);\r\n      $$.updateLegendItemHeight(maxHeight);\r\n      $$.updateLegendStep(step);\r\n      // Update size and scale\r\n      $$.updateSizes();\r\n      $$.updateScales();\r\n      $$.updateSvgSize();\r\n      // Update g positions\r\n      $$.transformAll(withTransitionForTransform, transitions);\r\n      $$.legendHasRendered = true;\r\n  };\n\n  ChartInternal.prototype.initRegion = function () {\r\n      var $$ = this;\r\n      $$.region = $$.main\r\n          .append('g')\r\n          .attr('clip-path', $$.clipPath)\r\n          .attr('class', CLASS.regions);\r\n  };\r\n  ChartInternal.prototype.updateRegion = function (duration) {\r\n      var $$ = this, config = $$.config;\r\n      // hide if arc type\r\n      $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');\r\n      var mainRegion = $$.main\r\n          .select('.' + CLASS.regions)\r\n          .selectAll('.' + CLASS.region)\r\n          .data(config.regions);\r\n      var g = mainRegion.enter().append('g');\r\n      g.append('rect')\r\n          .attr('x', $$.regionX.bind($$))\r\n          .attr('y', $$.regionY.bind($$))\r\n          .attr('width', $$.regionWidth.bind($$))\r\n          .attr('height', $$.regionHeight.bind($$))\r\n          .style('fill-opacity', function (d) {\r\n          return isValue(d.opacity) ? d.opacity : 0.1;\r\n      });\r\n      g.append('text').text($$.labelRegion.bind($$));\r\n      $$.mainRegion = g.merge(mainRegion).attr('class', $$.classRegion.bind($$));\r\n      mainRegion\r\n          .exit()\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n  };\r\n  ChartInternal.prototype.redrawRegion = function (withTransition, transition) {\r\n      var $$ = this, regions = $$.mainRegion, regionLabels = $$.mainRegion.selectAll('text');\r\n      return [\r\n          (withTransition ? regions.transition(transition) : regions)\r\n              .attr('x', $$.regionX.bind($$))\r\n              .attr('y', $$.regionY.bind($$))\r\n              .attr('width', $$.regionWidth.bind($$))\r\n              .attr('height', $$.regionHeight.bind($$))\r\n              .style('fill-opacity', function (d) {\r\n              return isValue(d.opacity) ? d.opacity : 0.1;\r\n          }),\r\n          (withTransition ? regionLabels.transition(transition) : regionLabels)\r\n              .attr('x', $$.labelOffsetX.bind($$))\r\n              .attr('y', $$.labelOffsetY.bind($$))\r\n              .attr('transform', $$.labelTransform.bind($$))\r\n              .attr('style', 'text-anchor: left;')\r\n      ];\r\n  };\r\n  ChartInternal.prototype.regionX = function (d) {\r\n      var $$ = this, config = $$.config, xPos, yScale = d.axis === 'y' ? $$.y : $$.y2;\r\n      if (d.axis === 'y' || d.axis === 'y2') {\r\n          xPos = config.axis_rotated ? ('start' in d ? yScale(d.start) : 0) : 0;\r\n      }\r\n      else {\r\n          xPos = config.axis_rotated\r\n              ? 0\r\n              : 'start' in d\r\n                  ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start)\r\n                  : 0;\r\n      }\r\n      return xPos;\r\n  };\r\n  ChartInternal.prototype.regionY = function (d) {\r\n      var $$ = this, config = $$.config, yPos, yScale = d.axis === 'y' ? $$.y : $$.y2;\r\n      if (d.axis === 'y' || d.axis === 'y2') {\r\n          yPos = config.axis_rotated ? 0 : 'end' in d ? yScale(d.end) : 0;\r\n      }\r\n      else {\r\n          yPos = config.axis_rotated\r\n              ? 'start' in d\r\n                  ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start)\r\n                  : 0\r\n              : 0;\r\n      }\r\n      return yPos;\r\n  };\r\n  ChartInternal.prototype.regionWidth = function (d) {\r\n      var $$ = this, config = $$.config, start = $$.regionX(d), end, yScale = d.axis === 'y' ? $$.y : $$.y2;\r\n      if (d.axis === 'y' || d.axis === 'y2') {\r\n          end = config.axis_rotated\r\n              ? 'end' in d\r\n                  ? yScale(d.end)\r\n                  : $$.width\r\n              : $$.width;\r\n      }\r\n      else {\r\n          end = config.axis_rotated\r\n              ? $$.width\r\n              : 'end' in d\r\n                  ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end)\r\n                  : $$.width;\r\n      }\r\n      return end < start ? 0 : end - start;\r\n  };\r\n  ChartInternal.prototype.regionHeight = function (d) {\r\n      var $$ = this, config = $$.config, start = this.regionY(d), end, yScale = d.axis === 'y' ? $$.y : $$.y2;\r\n      if (d.axis === 'y' || d.axis === 'y2') {\r\n          end = config.axis_rotated\r\n              ? $$.height\r\n              : 'start' in d\r\n                  ? yScale(d.start)\r\n                  : $$.height;\r\n      }\r\n      else {\r\n          end = config.axis_rotated\r\n              ? 'end' in d\r\n                  ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end)\r\n                  : $$.height\r\n              : $$.height;\r\n      }\r\n      return end < start ? 0 : end - start;\r\n  };\r\n  ChartInternal.prototype.isRegionOnX = function (d) {\r\n      return !d.axis || d.axis === 'x';\r\n  };\r\n  ChartInternal.prototype.labelRegion = function (d) {\r\n      return 'label' in d ? d.label : '';\r\n  };\r\n  ChartInternal.prototype.labelTransform = function (d) {\r\n      return 'vertical' in d && d.vertical ? 'rotate(90)' : '';\r\n  };\r\n  ChartInternal.prototype.labelOffsetX = function (d) {\r\n      var paddingX = 'paddingX' in d ? d.paddingX : 3;\r\n      var paddingY = 'paddingY' in d ? d.paddingY : 3;\r\n      return 'vertical' in d && d.vertical\r\n          ? this.regionY(d) + paddingY\r\n          : this.regionX(d) + paddingX;\r\n  };\r\n  ChartInternal.prototype.labelOffsetY = function (d) {\r\n      var paddingX = 'paddingX' in d ? d.paddingX : 3;\r\n      var paddingY = 'paddingY' in d ? d.paddingY : 3;\r\n      return 'vertical' in d && d.vertical\r\n          ? -(this.regionX(d) + paddingX)\r\n          : this.regionY(d) + 10 + paddingY;\r\n  };\n\n  function c3LogScale(d3, linearScale, logScale) {\r\n      var PROJECTION = [0.01, 10];\r\n      if (!linearScale) {\r\n          linearScale = d3.scaleLinear();\r\n          linearScale.range(PROJECTION);\r\n      }\r\n      if (!logScale) {\r\n          logScale = d3.scaleLog();\r\n          logScale.domain(PROJECTION);\r\n          logScale.nice();\r\n      }\r\n      // copied from https://github.com/compute-io/logspace\r\n      function logspace(a, b, len) {\r\n          var arr, end, tmp, d;\r\n          if (arguments.length < 3) {\r\n              len = 10;\r\n          }\r\n          else {\r\n              if (len === 0) {\r\n                  return [];\r\n              }\r\n          }\r\n          // Calculate the increment:\r\n          end = len - 1;\r\n          d = (b - a) / end;\r\n          // Build the output array...\r\n          arr = new Array(len);\r\n          tmp = a;\r\n          arr[0] = Math.pow(10, tmp);\r\n          for (var i = 1; i < end; i++) {\r\n              tmp += d;\r\n              arr[i] = Math.pow(10, tmp);\r\n          }\r\n          arr[end] = Math.pow(10, b);\r\n          return arr;\r\n      }\r\n      function scale(x) {\r\n          return logScale(linearScale(x));\r\n      }\r\n      scale.domain = function (x) {\r\n          if (!arguments.length) {\r\n              return linearScale.domain();\r\n          }\r\n          linearScale.domain(x);\r\n          return scale;\r\n      };\r\n      scale.range = function (x) {\r\n          if (!arguments.length) {\r\n              return logScale.range();\r\n          }\r\n          logScale.range(x);\r\n          return scale;\r\n      };\r\n      scale.ticks = function (m) {\r\n          return logspace(-2, 1, m || 10).map(function (v) {\r\n              return linearScale.invert(v);\r\n          });\r\n      };\r\n      scale.copy = function () {\r\n          return c3LogScale(d3, linearScale.copy(), logScale.copy());\r\n      };\r\n      return scale;\r\n  }\r\n  ChartInternal.prototype.getScale = function (min, max, forTimeseries) {\r\n      return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([\r\n          min,\r\n          max\r\n      ]);\r\n  };\r\n  ChartInternal.prototype.getX = function (min, max, domain, offset) {\r\n      var $$ = this, scale = $$.getScale(min, max, $$.isTimeSeries()), _scale = domain ? scale.domain(domain) : scale, key;\r\n      // Define customized scale if categorized axis\r\n      if ($$.isCategorized()) {\r\n          offset =\r\n              offset ||\r\n                  function () {\r\n                      return 0;\r\n                  };\r\n          scale = function (d, raw) {\r\n              var v = _scale(d) + offset(d);\r\n              return raw ? v : Math.ceil(v);\r\n          };\r\n      }\r\n      else {\r\n          scale = function (d, raw) {\r\n              var v = _scale(d);\r\n              return raw ? v : Math.ceil(v);\r\n          };\r\n      }\r\n      // define functions\r\n      for (key in _scale) {\r\n          scale[key] = _scale[key];\r\n      }\r\n      scale.orgDomain = function () {\r\n          return _scale.domain();\r\n      };\r\n      // define custom domain() for categorized axis\r\n      if ($$.isCategorized()) {\r\n          scale.domain = function (domain) {\r\n              if (!arguments.length) {\r\n                  domain = this.orgDomain();\r\n                  return [domain[0], domain[1] + 1];\r\n              }\r\n              _scale.domain(domain);\r\n              return scale;\r\n          };\r\n      }\r\n      return scale;\r\n  };\r\n  /**\r\n   * Creates and configures a D3 scale instance for the given type.\r\n   *\r\n   * By defaults it returns a Linear scale.\r\n   *\r\n   * @param {String} type Type of d3-scale to create. Type can be 'linear', 'time', 'timeseries' or 'log'.\r\n   * @param {Array} domain The scale domain such as [from, to]\r\n   * @param {Array} range The scale's range such as [from, to]\r\n   *\r\n   * @return A d3-scale instance\r\n   */\r\n  ChartInternal.prototype.getY = function (type, domain, range) {\r\n      var scale;\r\n      if (type === 'timeseries' || type === 'time') {\r\n          scale = this.d3.scaleTime();\r\n      }\r\n      else if (type === 'log') {\r\n          scale = c3LogScale(this.d3);\r\n      }\r\n      else if (type === 'linear' || type === undefined) {\r\n          scale = this.d3.scaleLinear();\r\n      }\r\n      else {\r\n          throw new Error(\"Invalid Y axis type: \\\"\" + type + \"\\\"\");\r\n      }\r\n      if (domain) {\r\n          scale.domain(domain);\r\n      }\r\n      if (range) {\r\n          scale.range(range);\r\n      }\r\n      return scale;\r\n  };\r\n  ChartInternal.prototype.getYScale = function (id) {\r\n      return this.axis.getId(id) === 'y2' ? this.y2 : this.y;\r\n  };\r\n  ChartInternal.prototype.getSubYScale = function (id) {\r\n      return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY;\r\n  };\r\n  ChartInternal.prototype.updateScales = function () {\r\n      var $$ = this, config = $$.config, forInit = !$$.x;\r\n      // update edges\r\n      $$.xMin = config.axis_rotated ? 1 : 0;\r\n      $$.xMax = config.axis_rotated ? $$.height : $$.width;\r\n      $$.yMin = config.axis_rotated ? 0 : $$.height;\r\n      $$.yMax = config.axis_rotated ? $$.width : 1;\r\n      $$.subXMin = $$.xMin;\r\n      $$.subXMax = $$.xMax;\r\n      $$.subYMin = config.axis_rotated ? 0 : $$.height2;\r\n      $$.subYMax = config.axis_rotated ? $$.width2 : 1;\r\n      // update scales\r\n      $$.x = $$.getX($$.xMin, $$.xMax, forInit ? undefined : $$.x.orgDomain(), function () {\r\n          return $$.xAxis.tickOffset();\r\n      });\r\n      $$.y = $$.getY(config.axis_y_type, forInit ? config.axis_y_default : $$.y.domain(), [$$.yMin, $$.yMax]);\r\n      $$.y2 = $$.getY(config.axis_y2_type, forInit ? config.axis_y2_default : $$.y2.domain(), [$$.yMin, $$.yMax]);\r\n      $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function (d) {\r\n          return d % 1 ? 0 : $$.subXAxis.tickOffset();\r\n      });\r\n      $$.subY = $$.getY(config.axis_y_type, forInit ? config.axis_y_default : $$.subY.domain(), [$$.subYMin, $$.subYMax]);\r\n      $$.subY2 = $$.getY(config.axis_y2_type, forInit ? config.axis_y2_default : $$.subY2.domain(), [$$.subYMin, $$.subYMax]);\r\n      // update axes\r\n      $$.xAxisTickFormat = $$.axis.getXAxisTickFormat();\r\n      $$.xAxisTickValues = $$.axis.getXAxisTickValues();\r\n      $$.yAxisTickValues = $$.axis.getYAxisTickValues();\r\n      $$.y2AxisTickValues = $$.axis.getY2AxisTickValues();\r\n      $$.xAxis = $$.axis.getXAxis($$.x, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);\r\n      $$.subXAxis = $$.axis.getXAxis($$.subX, $$.subXOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);\r\n      $$.yAxis = $$.axis.getYAxis('y', $$.y, $$.yOrient, $$.yAxisTickValues, config.axis_y_tick_outer);\r\n      $$.y2Axis = $$.axis.getYAxis('y2', $$.y2, $$.y2Orient, $$.y2AxisTickValues, config.axis_y2_tick_outer);\r\n      // Set initialized scales to brush and zoom\r\n      if (!forInit) {\r\n          if ($$.brush) {\r\n              $$.brush.updateScale($$.subX);\r\n          }\r\n      }\r\n      // update for arc\r\n      if ($$.updateArc) {\r\n          $$.updateArc();\r\n      }\r\n  };\n\n  ChartInternal.prototype.selectPoint = function (target, d, i) {\r\n      var $$ = this, config = $$.config, cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$), cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$), r = $$.pointSelectR.bind($$);\r\n      config.data_onselected.call($$.api, d, target.node());\r\n      // add selected-circle on low layer g\r\n      $$.main\r\n          .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id))\r\n          .selectAll('.' + CLASS.selectedCircle + '-' + i)\r\n          .data([d])\r\n          .enter()\r\n          .append('circle')\r\n          .attr('class', function () {\r\n          return $$.generateClass(CLASS.selectedCircle, i);\r\n      })\r\n          .attr('cx', cx)\r\n          .attr('cy', cy)\r\n          .attr('stroke', function () {\r\n          return $$.color(d);\r\n      })\r\n          .attr('r', function (d) {\r\n          return $$.pointSelectR(d) * 1.4;\r\n      })\r\n          .transition()\r\n          .duration(100)\r\n          .attr('r', r);\r\n  };\r\n  ChartInternal.prototype.unselectPoint = function (target, d, i) {\r\n      var $$ = this;\r\n      $$.config.data_onunselected.call($$.api, d, target.node());\r\n      // remove selected-circle from low layer g\r\n      $$.main\r\n          .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id))\r\n          .selectAll('.' + CLASS.selectedCircle + '-' + i)\r\n          .transition()\r\n          .duration(100)\r\n          .attr('r', 0)\r\n          .remove();\r\n  };\r\n  ChartInternal.prototype.togglePoint = function (selected, target, d, i) {\r\n      selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i);\r\n  };\r\n  ChartInternal.prototype.selectPath = function (target, d) {\r\n      var $$ = this;\r\n      $$.config.data_onselected.call($$, d, target.node());\r\n      if ($$.config.interaction_brighten) {\r\n          target\r\n              .transition()\r\n              .duration(100)\r\n              .style('fill', function () {\r\n              return $$.d3.rgb($$.color(d)).brighter(0.75);\r\n          });\r\n      }\r\n  };\r\n  ChartInternal.prototype.unselectPath = function (target, d) {\r\n      var $$ = this;\r\n      $$.config.data_onunselected.call($$, d, target.node());\r\n      if ($$.config.interaction_brighten) {\r\n          target\r\n              .transition()\r\n              .duration(100)\r\n              .style('fill', function () {\r\n              return $$.color(d);\r\n          });\r\n      }\r\n  };\r\n  ChartInternal.prototype.togglePath = function (selected, target, d, i) {\r\n      selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i);\r\n  };\r\n  ChartInternal.prototype.getToggle = function (that, d) {\r\n      var $$ = this, toggle;\r\n      if (that.nodeName === 'circle') {\r\n          if ($$.isStepType(d)) {\r\n              // circle is hidden in step chart, so treat as within the click area\r\n              toggle = function () { }; // TODO: how to select step chart?\r\n          }\r\n          else {\r\n              toggle = $$.togglePoint;\r\n          }\r\n      }\r\n      else if (that.nodeName === 'path') {\r\n          toggle = $$.togglePath;\r\n      }\r\n      return toggle;\r\n  };\r\n  ChartInternal.prototype.toggleShape = function (that, d, i) {\r\n      var $$ = this, d3 = $$.d3, config = $$.config, shape = d3.select(that), isSelected = shape.classed(CLASS.SELECTED), toggle = $$.getToggle(that, d).bind($$);\r\n      if (config.data_selection_enabled && config.data_selection_isselectable(d)) {\r\n          if (!config.data_selection_multiple) {\r\n              $$.main\r\n                  .selectAll('.' +\r\n                  CLASS.shapes +\r\n                  (config.data_selection_grouped\r\n                      ? $$.getTargetSelectorSuffix(d.id)\r\n                      : ''))\r\n                  .selectAll('.' + CLASS.shape)\r\n                  .each(function (d, i) {\r\n                  var shape = d3.select(this);\r\n                  if (shape.classed(CLASS.SELECTED)) {\r\n                      toggle(false, shape.classed(CLASS.SELECTED, false), d, i);\r\n                  }\r\n              });\r\n          }\r\n          shape.classed(CLASS.SELECTED, !isSelected);\r\n          toggle(!isSelected, shape, d, i);\r\n      }\r\n  };\n\n  ChartInternal.prototype.initBar = function () {\r\n      var $$ = this;\r\n      $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.chartBars);\r\n  };\r\n  ChartInternal.prototype.updateTargetsForBar = function (targets) {\r\n      var $$ = this, config = $$.config, mainBars, mainBarEnter, classChartBar = $$.classChartBar.bind($$), classBars = $$.classBars.bind($$), classFocus = $$.classFocus.bind($$);\r\n      mainBars = $$.main\r\n          .select('.' + CLASS.chartBars)\r\n          .selectAll('.' + CLASS.chartBar)\r\n          .data(targets)\r\n          .attr('class', function (d) {\r\n          return classChartBar(d) + classFocus(d);\r\n      });\r\n      mainBarEnter = mainBars\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', classChartBar)\r\n          .style('pointer-events', 'none');\r\n      // Bars for each data\r\n      mainBarEnter\r\n          .append('g')\r\n          .attr('class', classBars)\r\n          .style('cursor', function (d) {\r\n          return config.data_selection_isselectable(d) ? 'pointer' : null;\r\n      });\r\n  };\r\n  ChartInternal.prototype.updateBar = function (durationForExit) {\r\n      var $$ = this, barData = $$.barData.bind($$), classBar = $$.classBar.bind($$), initialOpacity = $$.initialOpacity.bind($$), color = function (d) {\r\n          return $$.color(d.id);\r\n      };\r\n      var mainBar = $$.main\r\n          .selectAll('.' + CLASS.bars)\r\n          .selectAll('.' + CLASS.bar)\r\n          .data(barData);\r\n      var mainBarEnter = mainBar\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', classBar)\r\n          .style('stroke', color)\r\n          .style('fill', color);\r\n      $$.mainBar = mainBarEnter.merge(mainBar).style('opacity', initialOpacity);\r\n      mainBar\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0);\r\n  };\r\n  ChartInternal.prototype.redrawBar = function (drawBar, withTransition, transition) {\r\n      var $$ = this;\r\n      return [\r\n          (withTransition ? this.mainBar.transition(transition) : this.mainBar)\r\n              .attr('d', drawBar)\r\n              .style('stroke', this.color)\r\n              .style('fill', this.color)\r\n              .style('opacity', function (d) { return ($$.isTargetToShow(d.id) ? 1 : 0); })\r\n      ];\r\n  };\r\n  ChartInternal.prototype.getBarW = function (axis, barTargetsNum) {\r\n      var $$ = this, config = $$.config, w = typeof config.bar_width === 'number'\r\n          ? config.bar_width\r\n          : barTargetsNum\r\n              ? (axis.tickInterval() * config.bar_width_ratio) / barTargetsNum\r\n              : 0;\r\n      return config.bar_width_max && w > config.bar_width_max\r\n          ? config.bar_width_max\r\n          : w;\r\n  };\r\n  ChartInternal.prototype.getBars = function (i, id) {\r\n      var $$ = this;\r\n      return (id\r\n          ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id))\r\n          : $$.main).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''));\r\n  };\r\n  ChartInternal.prototype.expandBars = function (i, id, reset) {\r\n      var $$ = this;\r\n      if (reset) {\r\n          $$.unexpandBars();\r\n      }\r\n      $$.getBars(i, id).classed(CLASS.EXPANDED, true);\r\n  };\r\n  ChartInternal.prototype.unexpandBars = function (i) {\r\n      var $$ = this;\r\n      $$.getBars(i).classed(CLASS.EXPANDED, false);\r\n  };\r\n  ChartInternal.prototype.generateDrawBar = function (barIndices, isSub) {\r\n      var $$ = this, config = $$.config, getPoints = $$.generateGetBarPoints(barIndices, isSub);\r\n      return function (d, i) {\r\n          // 4 points that make a bar\r\n          var points = getPoints(d, i);\r\n          // switch points if axis is rotated, not applicable for sub chart\r\n          var indexX = config.axis_rotated ? 1 : 0;\r\n          var indexY = config.axis_rotated ? 0 : 1;\r\n          var path = 'M ' +\r\n              points[0][indexX] +\r\n              ',' +\r\n              points[0][indexY] +\r\n              ' ' +\r\n              'L' +\r\n              points[1][indexX] +\r\n              ',' +\r\n              points[1][indexY] +\r\n              ' ' +\r\n              'L' +\r\n              points[2][indexX] +\r\n              ',' +\r\n              points[2][indexY] +\r\n              ' ' +\r\n              'L' +\r\n              points[3][indexX] +\r\n              ',' +\r\n              points[3][indexY] +\r\n              ' ' +\r\n              'z';\r\n          return path;\r\n      };\r\n  };\r\n  ChartInternal.prototype.generateGetBarPoints = function (barIndices, isSub) {\r\n      var $$ = this, axis = isSub ? $$.subXAxis : $$.xAxis, barTargetsNum = barIndices.__max__ + 1, barW = $$.getBarW(axis, barTargetsNum), barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub), barY = $$.getShapeY(!!isSub), barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub), barSpaceOffset = barW * ($$.config.bar_space / 2), yScale = isSub ? $$.getSubYScale : $$.getYScale;\r\n      return function (d, i) {\r\n          var y0 = yScale.call($$, d.id)(0), offset = barOffset(d, i) || y0, // offset is for stacked bar chart\r\n          posX = barX(d), posY = barY(d);\r\n          // fix posY not to overflow opposite quadrant\r\n          if ($$.config.axis_rotated) {\r\n              if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\r\n                  posY = y0;\r\n              }\r\n          }\r\n          posY -= y0 - offset;\r\n          // 4 points that make a bar\r\n          return [\r\n              [posX + barSpaceOffset, offset],\r\n              [posX + barSpaceOffset, posY],\r\n              [posX + barW - barSpaceOffset, posY],\r\n              [posX + barW - barSpaceOffset, offset]\r\n          ];\r\n      };\r\n  };\r\n  /**\r\n   * Returns whether the data point is within the given bar shape.\r\n   *\r\n   * @param mouse\r\n   * @param barShape\r\n   * @return {boolean}\r\n   */\r\n  ChartInternal.prototype.isWithinBar = function (mouse, barShape) {\r\n      return isWithinBox(mouse, getBBox(barShape), 2);\r\n  };\n\n  ChartInternal.prototype.getShapeIndices = function (typeFilter) {\r\n      var $$ = this, config = $$.config, indices = {}, i = 0, j, k;\r\n      $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) {\r\n          for (j = 0; j < config.data_groups.length; j++) {\r\n              if (config.data_groups[j].indexOf(d.id) < 0) {\r\n                  continue;\r\n              }\r\n              for (k = 0; k < config.data_groups[j].length; k++) {\r\n                  if (config.data_groups[j][k] in indices) {\r\n                      indices[d.id] = indices[config.data_groups[j][k]];\r\n                      break;\r\n                  }\r\n              }\r\n          }\r\n          if (isUndefined(indices[d.id])) {\r\n              indices[d.id] = i++;\r\n          }\r\n      });\r\n      indices.__max__ = i - 1;\r\n      return indices;\r\n  };\r\n  ChartInternal.prototype.getShapeX = function (offset, targetsNum, indices, isSub) {\r\n      var $$ = this, scale = isSub ? $$.subX : $$.x;\r\n      return function (d) {\r\n          var index = d.id in indices ? indices[d.id] : 0;\r\n          return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0;\r\n      };\r\n  };\r\n  ChartInternal.prototype.getShapeY = function (isSub) {\r\n      var $$ = this;\r\n      return function (d) {\r\n          var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id);\r\n          return scale($$.isTargetNormalized(d.id) ? $$.getRatio('index', d, true) : d.value);\r\n      };\r\n  };\r\n  ChartInternal.prototype.getShapeOffset = function (typeFilter, indices, isSub) {\r\n      var $$ = this, targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))), targetIds = targets.map(function (t) {\r\n          return t.id;\r\n      });\r\n      return function (d, i) {\r\n          var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id), y0 = scale(0), offset = y0;\r\n          targets.forEach(function (t) {\r\n              var rowValues = $$.isStepType(d)\r\n                  ? $$.convertValuesToStep(t.values)\r\n                  : t.values;\r\n              var isTargetNormalized = $$.isTargetNormalized(d.id);\r\n              var values = rowValues.map(function (v) {\r\n                  return isTargetNormalized ? $$.getRatio('index', v, true) : v.value;\r\n              });\r\n              if (t.id === d.id || indices[t.id] !== indices[d.id]) {\r\n                  return;\r\n              }\r\n              if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) {\r\n                  // check if the x values line up\r\n                  if (isUndefined(rowValues[i]) || +rowValues[i].x !== +d.x) {\r\n                      // \"+\" for timeseries\r\n                      // if not, try to find the value that does line up\r\n                      i = -1;\r\n                      rowValues.forEach(function (v, j) {\r\n                          var x1 = v.x.constructor === Date ? +v.x : v.x;\r\n                          var x2 = d.x.constructor === Date ? +d.x : d.x;\r\n                          if (x1 === x2) {\r\n                              i = j;\r\n                          }\r\n                      });\r\n                  }\r\n                  if (i in rowValues && rowValues[i].value * d.value >= 0) {\r\n                      offset += scale(values[i]) - y0;\r\n                  }\r\n              }\r\n          });\r\n          return offset;\r\n      };\r\n  };\r\n  ChartInternal.prototype.isWithinShape = function (that, d) {\r\n      var $$ = this, shape = $$.d3.select(that), isWithin;\r\n      if (!$$.isTargetToShow(d.id)) {\r\n          isWithin = false;\r\n      }\r\n      else if (that.nodeName === 'circle') {\r\n          isWithin = $$.isStepType(d)\r\n              ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value))\r\n              : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5);\r\n      }\r\n      else if (that.nodeName === 'path') {\r\n          isWithin = shape.classed(CLASS.bar)\r\n              ? $$.isWithinBar($$.d3.mouse(that), that)\r\n              : true;\r\n      }\r\n      return isWithin;\r\n  };\r\n  ChartInternal.prototype.getInterpolate = function (d) {\r\n      var $$ = this, d3 = $$.d3, types = {\r\n          linear: d3.curveLinear,\r\n          'linear-closed': d3.curveLinearClosed,\r\n          basis: d3.curveBasis,\r\n          'basis-open': d3.curveBasisOpen,\r\n          'basis-closed': d3.curveBasisClosed,\r\n          bundle: d3.curveBundle,\r\n          cardinal: d3.curveCardinal,\r\n          'cardinal-open': d3.curveCardinalOpen,\r\n          'cardinal-closed': d3.curveCardinalClosed,\r\n          monotone: d3.curveMonotoneX,\r\n          step: d3.curveStep,\r\n          'step-before': d3.curveStepBefore,\r\n          'step-after': d3.curveStepAfter\r\n      }, type;\r\n      if ($$.isSplineType(d)) {\r\n          type = types[$$.config.spline_interpolation_type] || types.cardinal;\r\n      }\r\n      else if ($$.isStepType(d)) {\r\n          type = types[$$.config.line_step_type];\r\n      }\r\n      else {\r\n          type = types.linear;\r\n      }\r\n      return type;\r\n  };\n\n  ChartInternal.prototype.initLine = function () {\r\n      var $$ = this;\r\n      $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.chartLines);\r\n  };\r\n  ChartInternal.prototype.updateTargetsForLine = function (targets) {\r\n      var $$ = this, config = $$.config, mainLines, mainLineEnter, classChartLine = $$.classChartLine.bind($$), classLines = $$.classLines.bind($$), classAreas = $$.classAreas.bind($$), classCircles = $$.classCircles.bind($$), classFocus = $$.classFocus.bind($$);\r\n      mainLines = $$.main\r\n          .select('.' + CLASS.chartLines)\r\n          .selectAll('.' + CLASS.chartLine)\r\n          .data(targets)\r\n          .attr('class', function (d) {\r\n          return classChartLine(d) + classFocus(d);\r\n      });\r\n      mainLineEnter = mainLines\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', classChartLine)\r\n          .style('opacity', 0)\r\n          .style('pointer-events', 'none');\r\n      // Lines for each data\r\n      mainLineEnter.append('g').attr('class', classLines);\r\n      // Areas\r\n      mainLineEnter.append('g').attr('class', classAreas);\r\n      // Circles for each data point on lines\r\n      mainLineEnter.append('g').attr('class', function (d) {\r\n          return $$.generateClass(CLASS.selectedCircles, d.id);\r\n      });\r\n      mainLineEnter\r\n          .append('g')\r\n          .attr('class', classCircles)\r\n          .style('cursor', function (d) {\r\n          return config.data_selection_isselectable(d) ? 'pointer' : null;\r\n      });\r\n      // Update date for selected circles\r\n      targets.forEach(function (t) {\r\n          $$.main\r\n              .selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id))\r\n              .selectAll('.' + CLASS.selectedCircle)\r\n              .each(function (d) {\r\n              d.value = t.values[d.index].value;\r\n          });\r\n      });\r\n      // MEMO: can not keep same color...\r\n      //mainLineUpdate.exit().remove();\r\n  };\r\n  ChartInternal.prototype.updateLine = function (durationForExit) {\r\n      var $$ = this;\r\n      var mainLine = $$.main\r\n          .selectAll('.' + CLASS.lines)\r\n          .selectAll('.' + CLASS.line)\r\n          .data($$.lineData.bind($$));\r\n      var mainLineEnter = mainLine\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', $$.classLine.bind($$))\r\n          .style('stroke', $$.color);\r\n      $$.mainLine = mainLineEnter\r\n          .merge(mainLine)\r\n          .style('opacity', $$.initialOpacity.bind($$))\r\n          .style('shape-rendering', function (d) {\r\n          return $$.isStepType(d) ? 'crispEdges' : '';\r\n      })\r\n          .attr('transform', null);\r\n      mainLine\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0);\r\n  };\r\n  ChartInternal.prototype.redrawLine = function (drawLine, withTransition, transition) {\r\n      return [\r\n          (withTransition ? this.mainLine.transition(transition) : this.mainLine)\r\n              .attr('d', drawLine)\r\n              .style('stroke', this.color)\r\n              .style('opacity', 1)\r\n      ];\r\n  };\r\n  ChartInternal.prototype.generateDrawLine = function (lineIndices, isSub) {\r\n      var $$ = this, config = $$.config, line = $$.d3.line(), getPoints = $$.generateGetLinePoints(lineIndices, isSub), yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, xValue = function (d) {\r\n          return (isSub ? $$.subxx : $$.xx).call($$, d);\r\n      }, yValue = function (d, i) {\r\n          return config.data_groups.length > 0\r\n              ? getPoints(d, i)[0][1]\r\n              : yScaleGetter.call($$, d.id)(d.value);\r\n      };\r\n      line = config.axis_rotated\r\n          ? line.x(yValue).y(xValue)\r\n          : line.x(xValue).y(yValue);\r\n      if (!config.line_connectNull) {\r\n          line = line.defined(function (d) {\r\n              return d.value != null;\r\n          });\r\n      }\r\n      return function (d) {\r\n          var values = config.line_connectNull\r\n              ? $$.filterRemoveNull(d.values)\r\n              : d.values, x = isSub ? $$.subX : $$.x, y = yScaleGetter.call($$, d.id), x0 = 0, y0 = 0, path;\r\n          if ($$.isLineType(d)) {\r\n              if (config.data_regions[d.id]) {\r\n                  path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]);\r\n              }\r\n              else {\r\n                  if ($$.isStepType(d)) {\r\n                      values = $$.convertValuesToStep(values);\r\n                  }\r\n                  path = line.curve($$.getInterpolate(d))(values);\r\n              }\r\n          }\r\n          else {\r\n              if (values[0]) {\r\n                  x0 = x(values[0].x);\r\n                  y0 = y(values[0].value);\r\n              }\r\n              path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0;\r\n          }\r\n          return path ? path : 'M 0 0';\r\n      };\r\n  };\r\n  ChartInternal.prototype.generateGetLinePoints = function (lineIndices, isSub) {\r\n      // partial duplication of generateGetBarPoints\r\n      var $$ = this, config = $$.config, lineTargetsNum = lineIndices.__max__ + 1, x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub), y = $$.getShapeY(!!isSub), lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub), yScale = isSub ? $$.getSubYScale : $$.getYScale;\r\n      return function (d, i) {\r\n          var y0 = yScale.call($$, d.id)(0), offset = lineOffset(d, i) || y0, // offset is for stacked area chart\r\n          posX = x(d), posY = y(d);\r\n          // fix posY not to overflow opposite quadrant\r\n          if (config.axis_rotated) {\r\n              if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\r\n                  posY = y0;\r\n              }\r\n          }\r\n          // 1 point that marks the line position\r\n          return [\r\n              [posX, posY - (y0 - offset)],\r\n              [posX, posY - (y0 - offset)],\r\n              [posX, posY - (y0 - offset)],\r\n              [posX, posY - (y0 - offset)] // needed for compatibility\r\n          ];\r\n      };\r\n  };\r\n  ChartInternal.prototype.lineWithRegions = function (d, x, y, _regions) {\r\n      var $$ = this, config = $$.config, prev = -1, i, j, s = 'M', sWithRegion, xp, yp, dx, dy, dd, diff, diffx2, xOffset = $$.isCategorized() ? 0.5 : 0, xValue, yValue, regions = [];\r\n      function isWithinRegions(x, regions) {\r\n          var i;\r\n          for (i = 0; i < regions.length; i++) {\r\n              if (regions[i].start < x && x <= regions[i].end) {\r\n                  return true;\r\n              }\r\n          }\r\n          return false;\r\n      }\r\n      // Check start/end of regions\r\n      if (isDefined(_regions)) {\r\n          for (i = 0; i < _regions.length; i++) {\r\n              regions[i] = {};\r\n              if (isUndefined(_regions[i].start)) {\r\n                  regions[i].start = d[0].x;\r\n              }\r\n              else {\r\n                  regions[i].start = $$.isTimeSeries()\r\n                      ? $$.parseDate(_regions[i].start)\r\n                      : _regions[i].start;\r\n              }\r\n              if (isUndefined(_regions[i].end)) {\r\n                  regions[i].end = d[d.length - 1].x;\r\n              }\r\n              else {\r\n                  regions[i].end = $$.isTimeSeries()\r\n                      ? $$.parseDate(_regions[i].end)\r\n                      : _regions[i].end;\r\n              }\r\n          }\r\n      }\r\n      // Set scales\r\n      xValue = config.axis_rotated\r\n          ? function (d) {\r\n              return y(d.value);\r\n          }\r\n          : function (d) {\r\n              return x(d.x);\r\n          };\r\n      yValue = config.axis_rotated\r\n          ? function (d) {\r\n              return x(d.x);\r\n          }\r\n          : function (d) {\r\n              return y(d.value);\r\n          };\r\n      // Define svg generator function for region\r\n      function generateM(points) {\r\n          return ('M' +\r\n              points[0][0] +\r\n              ' ' +\r\n              points[0][1] +\r\n              ' ' +\r\n              points[1][0] +\r\n              ' ' +\r\n              points[1][1]);\r\n      }\r\n      if ($$.isTimeSeries()) {\r\n          sWithRegion = function (d0, d1, j, diff) {\r\n              var x0 = d0.x.getTime(), x_diff = d1.x - d0.x, xv0 = new Date(x0 + x_diff * j), xv1 = new Date(x0 + x_diff * (j + diff)), points;\r\n              if (config.axis_rotated) {\r\n                  points = [\r\n                      [y(yp(j)), x(xv0)],\r\n                      [y(yp(j + diff)), x(xv1)]\r\n                  ];\r\n              }\r\n              else {\r\n                  points = [\r\n                      [x(xv0), y(yp(j))],\r\n                      [x(xv1), y(yp(j + diff))]\r\n                  ];\r\n              }\r\n              return generateM(points);\r\n          };\r\n      }\r\n      else {\r\n          sWithRegion = function (d0, d1, j, diff) {\r\n              var points;\r\n              if (config.axis_rotated) {\r\n                  points = [\r\n                      [y(yp(j), true), x(xp(j))],\r\n                      [y(yp(j + diff), true), x(xp(j + diff))]\r\n                  ];\r\n              }\r\n              else {\r\n                  points = [\r\n                      [x(xp(j), true), y(yp(j))],\r\n                      [x(xp(j + diff), true), y(yp(j + diff))]\r\n                  ];\r\n              }\r\n              return generateM(points);\r\n          };\r\n      }\r\n      // Generate\r\n      for (i = 0; i < d.length; i++) {\r\n          // Draw as normal\r\n          if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) {\r\n              s += ' ' + xValue(d[i]) + ' ' + yValue(d[i]);\r\n          }\r\n          // Draw with region // TODO: Fix for horizotal charts\r\n          else {\r\n              xp = $$.getScale(d[i - 1].x + xOffset, d[i].x + xOffset, $$.isTimeSeries());\r\n              yp = $$.getScale(d[i - 1].value, d[i].value);\r\n              dx = x(d[i].x) - x(d[i - 1].x);\r\n              dy = y(d[i].value) - y(d[i - 1].value);\r\n              dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));\r\n              diff = 2 / dd;\r\n              diffx2 = diff * 2;\r\n              for (j = diff; j <= 1; j += diffx2) {\r\n                  s += sWithRegion(d[i - 1], d[i], j, diff);\r\n              }\r\n          }\r\n          prev = d[i].x;\r\n      }\r\n      return s;\r\n  };\r\n  ChartInternal.prototype.updateArea = function (durationForExit) {\r\n      var $$ = this, d3 = $$.d3;\r\n      var mainArea = $$.main\r\n          .selectAll('.' + CLASS.areas)\r\n          .selectAll('.' + CLASS.area)\r\n          .data($$.lineData.bind($$));\r\n      var mainAreaEnter = mainArea\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', $$.classArea.bind($$))\r\n          .style('fill', $$.color)\r\n          .style('opacity', function () {\r\n          $$.orgAreaOpacity = +d3.select(this).style('opacity');\r\n          return 0;\r\n      });\r\n      $$.mainArea = mainAreaEnter\r\n          .merge(mainArea)\r\n          .style('opacity', $$.orgAreaOpacity);\r\n      mainArea\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0);\r\n  };\r\n  ChartInternal.prototype.redrawArea = function (drawArea, withTransition, transition) {\r\n      return [\r\n          (withTransition ? this.mainArea.transition(transition) : this.mainArea)\r\n              .attr('d', drawArea)\r\n              .style('fill', this.color)\r\n              .style('opacity', this.orgAreaOpacity)\r\n      ];\r\n  };\r\n  ChartInternal.prototype.generateDrawArea = function (areaIndices, isSub) {\r\n      var $$ = this, config = $$.config, area = $$.d3.area(), getPoints = $$.generateGetAreaPoints(areaIndices, isSub), yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale, xValue = function (d) {\r\n          return (isSub ? $$.subxx : $$.xx).call($$, d);\r\n      }, value0 = function (d, i) {\r\n          return config.data_groups.length > 0\r\n              ? getPoints(d, i)[0][1]\r\n              : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id));\r\n      }, value1 = function (d, i) {\r\n          return config.data_groups.length > 0\r\n              ? getPoints(d, i)[1][1]\r\n              : yScaleGetter.call($$, d.id)(d.value);\r\n      };\r\n      area = config.axis_rotated\r\n          ? area\r\n              .x0(value0)\r\n              .x1(value1)\r\n              .y(xValue)\r\n          : area\r\n              .x(xValue)\r\n              .y0(config.area_above ? 0 : value0)\r\n              .y1(value1);\r\n      if (!config.line_connectNull) {\r\n          area = area.defined(function (d) {\r\n              return d.value !== null;\r\n          });\r\n      }\r\n      return function (d) {\r\n          var values = config.line_connectNull\r\n              ? $$.filterRemoveNull(d.values)\r\n              : d.values, x0 = 0, y0 = 0, path;\r\n          if ($$.isAreaType(d)) {\r\n              if ($$.isStepType(d)) {\r\n                  values = $$.convertValuesToStep(values);\r\n              }\r\n              path = area.curve($$.getInterpolate(d))(values);\r\n          }\r\n          else {\r\n              if (values[0]) {\r\n                  x0 = $$.x(values[0].x);\r\n                  y0 = $$.getYScale(d.id)(values[0].value);\r\n              }\r\n              path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0;\r\n          }\r\n          return path ? path : 'M 0 0';\r\n      };\r\n  };\r\n  ChartInternal.prototype.getAreaBaseValue = function () {\r\n      return 0;\r\n  };\r\n  ChartInternal.prototype.generateGetAreaPoints = function (areaIndices, isSub) {\r\n      // partial duplication of generateGetBarPoints\r\n      var $$ = this, config = $$.config, areaTargetsNum = areaIndices.__max__ + 1, x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub), y = $$.getShapeY(!!isSub), areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub), yScale = isSub ? $$.getSubYScale : $$.getYScale;\r\n      return function (d, i) {\r\n          var y0 = yScale.call($$, d.id)(0), offset = areaOffset(d, i) || y0, // offset is for stacked area chart\r\n          posX = x(d), posY = y(d);\r\n          // fix posY not to overflow opposite quadrant\r\n          if (config.axis_rotated) {\r\n              if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\r\n                  posY = y0;\r\n              }\r\n          }\r\n          // 1 point that marks the area position\r\n          return [\r\n              [posX, offset],\r\n              [posX, posY - (y0 - offset)],\r\n              [posX, posY - (y0 - offset)],\r\n              [posX, offset] // needed for compatibility\r\n          ];\r\n      };\r\n  };\r\n  ChartInternal.prototype.updateCircle = function (cx, cy) {\r\n      var $$ = this;\r\n      var mainCircle = $$.main\r\n          .selectAll('.' + CLASS.circles)\r\n          .selectAll('.' + CLASS.circle)\r\n          .data($$.lineOrScatterOrStanfordData.bind($$));\r\n      var mainCircleEnter = mainCircle\r\n          .enter()\r\n          .append('circle')\r\n          .attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '')\r\n          .attr('class', $$.classCircle.bind($$))\r\n          .attr('cx', cx)\r\n          .attr('cy', cy)\r\n          .attr('r', $$.pointR.bind($$))\r\n          .style('color', $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color);\r\n      $$.mainCircle = mainCircleEnter\r\n          .merge(mainCircle)\r\n          .style('opacity', $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$));\r\n      mainCircle.exit().style('opacity', 0);\r\n  };\r\n  ChartInternal.prototype.redrawCircle = function (cx, cy, withTransition, transition) {\r\n      var $$ = this, selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle);\r\n      return [\r\n          (withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle)\r\n              .style('opacity', this.opacityForCircle.bind($$))\r\n              .style('color', $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color)\r\n              .attr('cx', cx)\r\n              .attr('cy', cy),\r\n          (withTransition ? selectedCircles.transition(transition) : selectedCircles)\r\n              .attr('cx', cx)\r\n              .attr('cy', cy)\r\n      ];\r\n  };\r\n  ChartInternal.prototype.circleX = function (d) {\r\n      return d.x || d.x === 0 ? this.x(d.x) : null;\r\n  };\r\n  ChartInternal.prototype.updateCircleY = function () {\r\n      var $$ = this, lineIndices, getPoints;\r\n      if ($$.config.data_groups.length > 0) {\r\n          (lineIndices = $$.getShapeIndices($$.isLineType)),\r\n              (getPoints = $$.generateGetLinePoints(lineIndices));\r\n          $$.circleY = function (d, i) {\r\n              return getPoints(d, i)[0][1];\r\n          };\r\n      }\r\n      else {\r\n          $$.circleY = function (d) {\r\n              return $$.getYScale(d.id)(d.value);\r\n          };\r\n      }\r\n  };\r\n  ChartInternal.prototype.getCircles = function (i, id) {\r\n      var $$ = this;\r\n      return (id\r\n          ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id))\r\n          : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''));\r\n  };\r\n  ChartInternal.prototype.expandCircles = function (i, id, reset) {\r\n      var $$ = this, r = $$.pointExpandedR.bind($$);\r\n      if (reset) {\r\n          $$.unexpandCircles();\r\n      }\r\n      $$.getCircles(i, id)\r\n          .classed(CLASS.EXPANDED, true)\r\n          .attr('r', r);\r\n  };\r\n  ChartInternal.prototype.unexpandCircles = function (i) {\r\n      var $$ = this, r = $$.pointR.bind($$);\r\n      $$.getCircles(i)\r\n          .filter(function () {\r\n          return $$.d3.select(this).classed(CLASS.EXPANDED);\r\n      })\r\n          .classed(CLASS.EXPANDED, false)\r\n          .attr('r', r);\r\n  };\r\n  ChartInternal.prototype.pointR = function (d) {\r\n      var $$ = this, config = $$.config;\r\n      return $$.isStepType(d)\r\n          ? 0\r\n          : isFunction(config.point_r)\r\n              ? config.point_r(d)\r\n              : config.point_r;\r\n  };\r\n  ChartInternal.prototype.pointExpandedR = function (d) {\r\n      var $$ = this, config = $$.config;\r\n      if (config.point_focus_expand_enabled) {\r\n          return isFunction(config.point_focus_expand_r)\r\n              ? config.point_focus_expand_r(d)\r\n              : config.point_focus_expand_r\r\n                  ? config.point_focus_expand_r\r\n                  : $$.pointR(d) * 1.75;\r\n      }\r\n      else {\r\n          return $$.pointR(d);\r\n      }\r\n  };\r\n  ChartInternal.prototype.pointSelectR = function (d) {\r\n      var $$ = this, config = $$.config;\r\n      return isFunction(config.point_select_r)\r\n          ? config.point_select_r(d)\r\n          : config.point_select_r\r\n              ? config.point_select_r\r\n              : $$.pointR(d) * 4;\r\n  };\r\n  ChartInternal.prototype.isWithinCircle = function (that, r) {\r\n      var d3 = this.d3, mouse = d3.mouse(that), d3_this = d3.select(that), cx = +d3_this.attr('cx'), cy = +d3_this.attr('cy');\r\n      return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r;\r\n  };\r\n  ChartInternal.prototype.isWithinStep = function (that, y) {\r\n      return Math.abs(y - this.d3.mouse(that)[1]) < 30;\r\n  };\n\n  ChartInternal.prototype.getCurrentWidth = function () {\r\n      var $$ = this, config = $$.config;\r\n      return config.size_width ? config.size_width : $$.getParentWidth();\r\n  };\r\n  ChartInternal.prototype.getCurrentHeight = function () {\r\n      var $$ = this, config = $$.config, h = config.size_height ? config.size_height : $$.getParentHeight();\r\n      return h > 0\r\n          ? h\r\n          : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1);\r\n  };\r\n  ChartInternal.prototype.getCurrentPaddingTop = function () {\r\n      var $$ = this, config = $$.config, padding = isValue(config.padding_top) ? config.padding_top : 0;\r\n      if ($$.title && $$.title.node()) {\r\n          padding += $$.getTitlePadding();\r\n      }\r\n      return padding;\r\n  };\r\n  ChartInternal.prototype.getCurrentPaddingBottom = function () {\r\n      var config = this.config;\r\n      return isValue(config.padding_bottom) ? config.padding_bottom : 0;\r\n  };\r\n  ChartInternal.prototype.getCurrentPaddingLeft = function (withoutRecompute) {\r\n      var $$ = this, config = $$.config;\r\n      if (isValue(config.padding_left)) {\r\n          return config.padding_left;\r\n      }\r\n      else if (config.axis_rotated) {\r\n          return !config.axis_x_show || config.axis_x_inner\r\n              ? 1\r\n              : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40);\r\n      }\r\n      else if (!config.axis_y_show || config.axis_y_inner) {\r\n          // && !config.axis_rotated\r\n          return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1;\r\n      }\r\n      else {\r\n          return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute));\r\n      }\r\n  };\r\n  ChartInternal.prototype.getCurrentPaddingRight = function () {\r\n      var $$ = this, config = $$.config, padding = 0, defaultPadding = 10, legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0;\r\n      if (isValue(config.padding_right)) {\r\n          padding = config.padding_right + 1; // 1 is needed not to hide tick line\r\n      }\r\n      else if (config.axis_rotated) {\r\n          padding = defaultPadding + legendWidthOnRight;\r\n      }\r\n      else if (!config.axis_y2_show || config.axis_y2_inner) {\r\n          // && !config.axis_rotated\r\n          padding =\r\n              2 +\r\n                  legendWidthOnRight +\r\n                  ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0);\r\n      }\r\n      else {\r\n          padding = ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight;\r\n      }\r\n      if ($$.colorScale && $$.colorScale.node()) {\r\n          padding += $$.getColorScalePadding();\r\n      }\r\n      return padding;\r\n  };\r\n  ChartInternal.prototype.getParentRectValue = function (key) {\r\n      var parent = this.selectChart.node(), v;\r\n      while (parent && parent.tagName !== 'BODY') {\r\n          try {\r\n              v = parent.getBoundingClientRect()[key];\r\n          }\r\n          catch (e) {\r\n              if (key === 'width') {\r\n                  // In IE in certain cases getBoundingClientRect\r\n                  // will cause an \"unspecified error\"\r\n                  v = parent.offsetWidth;\r\n              }\r\n          }\r\n          if (v) {\r\n              break;\r\n          }\r\n          parent = parent.parentNode;\r\n      }\r\n      return v;\r\n  };\r\n  ChartInternal.prototype.getParentWidth = function () {\r\n      return this.getParentRectValue('width');\r\n  };\r\n  ChartInternal.prototype.getParentHeight = function () {\r\n      var h = this.selectChart.style('height');\r\n      return h.indexOf('px') > 0 ? +h.replace('px', '') : 0;\r\n  };\r\n  ChartInternal.prototype.getSvgLeft = function (withoutRecompute) {\r\n      var $$ = this, config = $$.config, hasLeftAxisRect = config.axis_rotated || (!config.axis_rotated && !config.axis_y_inner), leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY, leftAxis = $$.main.select('.' + leftAxisClass).node(), svgRect = leftAxis && hasLeftAxisRect\r\n          ? leftAxis.getBoundingClientRect()\r\n          : { right: 0 }, chartRect = $$.selectChart.node().getBoundingClientRect(), hasArc = $$.hasArcType(), svgLeft = svgRect.right -\r\n          chartRect.left -\r\n          (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute));\r\n      return svgLeft > 0 ? svgLeft : 0;\r\n  };\r\n  ChartInternal.prototype.getAxisWidthByAxisId = function (id, withoutRecompute) {\r\n      var $$ = this, position = $$.axis.getLabelPositionById(id);\r\n      return ($$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40));\r\n  };\r\n  ChartInternal.prototype.getHorizontalAxisHeight = function (axisId, isSubchart) {\r\n      var $$ = this, config = $$.config, h = 30;\r\n      if (axisId === 'x' && !(isDefined(isSubchart) && isSubchart ? config.subchart_axis_x_show : config.axis_x_show)) {\r\n          return 8;\r\n      }\r\n      if (axisId === 'x' && config.axis_x_height) {\r\n          return config.axis_x_height;\r\n      }\r\n      if (axisId === 'y' && !config.axis_y_show) {\r\n          return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1;\r\n      }\r\n      if (axisId === 'y2' && !config.axis_y2_show) {\r\n          return $$.rotated_padding_top;\r\n      }\r\n      // Calculate x axis height when tick rotated\r\n      if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {\r\n          h =\r\n              30 +\r\n                  $$.axis.getMaxTickWidth(axisId) *\r\n                      Math.cos((Math.PI * (90 - Math.abs(config.axis_x_tick_rotate))) / 180);\r\n      }\r\n      // Calculate y axis height when tick rotated\r\n      if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) {\r\n          h =\r\n              30 +\r\n                  $$.axis.getMaxTickWidth(axisId) *\r\n                      Math.cos((Math.PI * (90 - Math.abs(config.axis_y_tick_rotate))) / 180);\r\n      }\r\n      return (h +\r\n          ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) +\r\n          (axisId === 'y2' ? -10 : 0));\r\n  };\n\n  ChartInternal.prototype.initBrush = function (scale) {\r\n      var $$ = this, d3 = $$.d3;\r\n      // TODO: dynamically change brushY/brushX according to axis_rotated.\r\n      $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX())\r\n          .on('brush', function () {\r\n          var event = d3.event.sourceEvent;\r\n          if (event && event.type === 'zoom') {\r\n              return;\r\n          }\r\n          $$.redrawForBrush();\r\n      })\r\n          .on('end', function () {\r\n          var event = d3.event.sourceEvent;\r\n          if (event && event.type === 'zoom') {\r\n              return;\r\n          }\r\n          if ($$.brush.empty() && event && event.type !== 'end') {\r\n              $$.brush.clear();\r\n          }\r\n      });\r\n      $$.brush.updateExtent = function () {\r\n          var range = this.scale.range(), extent;\r\n          if ($$.config.axis_rotated) {\r\n              extent = [\r\n                  [0, range[0]],\r\n                  [$$.width2, range[1]]\r\n              ];\r\n          }\r\n          else {\r\n              extent = [\r\n                  [range[0], 0],\r\n                  [range[1], $$.height2]\r\n              ];\r\n          }\r\n          this.extent(extent);\r\n          return this;\r\n      };\r\n      $$.brush.updateScale = function (scale) {\r\n          this.scale = scale;\r\n          return this;\r\n      };\r\n      $$.brush.update = function (scale) {\r\n          this.updateScale(scale || $$.subX).updateExtent();\r\n          $$.context.select('.' + CLASS.brush).call(this);\r\n      };\r\n      $$.brush.clear = function () {\r\n          $$.context.select('.' + CLASS.brush).call($$.brush.move, null);\r\n      };\r\n      $$.brush.selection = function () {\r\n          return d3.brushSelection($$.context.select('.' + CLASS.brush).node());\r\n      };\r\n      $$.brush.selectionAsValue = function (selectionAsValue, withTransition) {\r\n          var selection, brush;\r\n          if (selectionAsValue) {\r\n              if ($$.context) {\r\n                  selection = [\r\n                      this.scale(selectionAsValue[0]),\r\n                      this.scale(selectionAsValue[1])\r\n                  ];\r\n                  brush = $$.context.select('.' + CLASS.brush);\r\n                  if (withTransition) {\r\n                      brush = brush.transition();\r\n                  }\r\n                  $$.brush.move(brush, selection);\r\n              }\r\n              return [];\r\n          }\r\n          selection = $$.brush.selection() || [0, 0];\r\n          return [this.scale.invert(selection[0]), this.scale.invert(selection[1])];\r\n      };\r\n      $$.brush.empty = function () {\r\n          var selection = $$.brush.selection();\r\n          return !selection || selection[0] === selection[1];\r\n      };\r\n      return $$.brush.updateScale(scale);\r\n  };\r\n  ChartInternal.prototype.initSubchart = function () {\r\n      var $$ = this, config = $$.config, context = ($$.context = $$.svg\r\n          .append('g')\r\n          .attr('transform', $$.getTranslate('context')));\r\n      // set style\r\n      context.style('visibility', 'visible');\r\n      // Define g for chart area\r\n      context\r\n          .append('g')\r\n          .attr('clip-path', $$.clipPathForSubchart)\r\n          .attr('class', CLASS.chart);\r\n      // Define g for bar chart area\r\n      context\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.chartBars);\r\n      // Define g for line chart area\r\n      context\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.chartLines);\r\n      // Add extent rect for Brush\r\n      context\r\n          .append('g')\r\n          .attr('clip-path', $$.clipPath)\r\n          .attr('class', CLASS.brush);\r\n      // ATTENTION: This must be called AFTER chart added\r\n      // Add Axis\r\n      $$.axes.subx = context\r\n          .append('g')\r\n          .attr('class', CLASS.axisX)\r\n          .attr('transform', $$.getTranslate('subx'))\r\n          .attr('clip-path', config.axis_rotated ? '' : $$.clipPathForXAxis)\r\n          .style('visibility', config.subchart_axis_x_show ? 'visible' : 'hidden');\r\n  };\r\n  ChartInternal.prototype.initSubchartBrush = function () {\r\n      var $$ = this;\r\n      // Add extent rect for Brush\r\n      $$.initBrush($$.subX).updateExtent();\r\n      $$.context.select('.' + CLASS.brush).call($$.brush);\r\n  };\r\n  ChartInternal.prototype.updateTargetsForSubchart = function (targets) {\r\n      var $$ = this, context = $$.context, config = $$.config, contextLineEnter, contextLine, contextBarEnter, contextBar, classChartBar = $$.classChartBar.bind($$), classBars = $$.classBars.bind($$), classChartLine = $$.classChartLine.bind($$), classLines = $$.classLines.bind($$), classAreas = $$.classAreas.bind($$);\r\n      //-- Bar --//\r\n      contextBar = context\r\n          .select('.' + CLASS.chartBars)\r\n          .selectAll('.' + CLASS.chartBar)\r\n          .data(targets);\r\n      contextBarEnter = contextBar\r\n          .enter()\r\n          .append('g')\r\n          .style('opacity', 0);\r\n      contextBarEnter.merge(contextBar).attr('class', classChartBar);\r\n      // Bars for each data\r\n      contextBarEnter.append('g').attr('class', classBars);\r\n      //-- Line --//\r\n      contextLine = context\r\n          .select('.' + CLASS.chartLines)\r\n          .selectAll('.' + CLASS.chartLine)\r\n          .data(targets);\r\n      contextLineEnter = contextLine\r\n          .enter()\r\n          .append('g')\r\n          .style('opacity', 0);\r\n      contextLineEnter.merge(contextLine).attr('class', classChartLine);\r\n      // Lines for each data\r\n      contextLineEnter.append('g').attr('class', classLines);\r\n      // Area\r\n      contextLineEnter.append('g').attr('class', classAreas);\r\n      //-- Brush --//\r\n      context\r\n          .selectAll('.' + CLASS.brush + ' rect')\r\n          .attr(config.axis_rotated ? 'width' : 'height', config.axis_rotated ? $$.width2 : $$.height2);\r\n  };\r\n  ChartInternal.prototype.updateBarForSubchart = function (durationForExit) {\r\n      var $$ = this;\r\n      var contextBar = $$.context\r\n          .selectAll('.' + CLASS.bars)\r\n          .selectAll('.' + CLASS.bar)\r\n          .data($$.barData.bind($$));\r\n      var contextBarEnter = contextBar\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', $$.classBar.bind($$))\r\n          .style('stroke', 'none')\r\n          .style('fill', $$.color);\r\n      contextBar\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      $$.contextBar = contextBarEnter\r\n          .merge(contextBar)\r\n          .style('opacity', $$.initialOpacity.bind($$));\r\n  };\r\n  ChartInternal.prototype.redrawBarForSubchart = function (drawBarOnSub, withTransition, duration) {\r\n      (withTransition\r\n          ? this.contextBar.transition(Math.random().toString()).duration(duration)\r\n          : this.contextBar)\r\n          .attr('d', drawBarOnSub)\r\n          .style('opacity', 1);\r\n  };\r\n  ChartInternal.prototype.updateLineForSubchart = function (durationForExit) {\r\n      var $$ = this;\r\n      var contextLine = $$.context\r\n          .selectAll('.' + CLASS.lines)\r\n          .selectAll('.' + CLASS.line)\r\n          .data($$.lineData.bind($$));\r\n      var contextLineEnter = contextLine\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', $$.classLine.bind($$))\r\n          .style('stroke', $$.color);\r\n      contextLine\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      $$.contextLine = contextLineEnter\r\n          .merge(contextLine)\r\n          .style('opacity', $$.initialOpacity.bind($$));\r\n  };\r\n  ChartInternal.prototype.redrawLineForSubchart = function (drawLineOnSub, withTransition, duration) {\r\n      (withTransition\r\n          ? this.contextLine.transition(Math.random().toString()).duration(duration)\r\n          : this.contextLine)\r\n          .attr('d', drawLineOnSub)\r\n          .style('opacity', 1);\r\n  };\r\n  ChartInternal.prototype.updateAreaForSubchart = function (durationForExit) {\r\n      var $$ = this, d3 = $$.d3;\r\n      var contextArea = $$.context\r\n          .selectAll('.' + CLASS.areas)\r\n          .selectAll('.' + CLASS.area)\r\n          .data($$.lineData.bind($$));\r\n      var contextAreaEnter = contextArea\r\n          .enter()\r\n          .append('path')\r\n          .attr('class', $$.classArea.bind($$))\r\n          .style('fill', $$.color)\r\n          .style('opacity', function () {\r\n          $$.orgAreaOpacity = +d3.select(this).style('opacity');\r\n          return 0;\r\n      });\r\n      contextArea\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      $$.contextArea = contextAreaEnter.merge(contextArea).style('opacity', 0);\r\n  };\r\n  ChartInternal.prototype.redrawAreaForSubchart = function (drawAreaOnSub, withTransition, duration) {\r\n      (withTransition\r\n          ? this.contextArea.transition(Math.random().toString()).duration(duration)\r\n          : this.contextArea)\r\n          .attr('d', drawAreaOnSub)\r\n          .style('fill', this.color)\r\n          .style('opacity', this.orgAreaOpacity);\r\n  };\r\n  ChartInternal.prototype.redrawSubchart = function (withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices) {\r\n      var $$ = this, d3 = $$.d3, drawAreaOnSub, drawBarOnSub, drawLineOnSub;\r\n      // reflect main chart to extent on subchart if zoomed\r\n      if (d3.event && d3.event.type === 'zoom') {\r\n          $$.brush.selectionAsValue($$.x.orgDomain());\r\n      }\r\n      // update subchart elements if needed\r\n      if (withSubchart) {\r\n          // extent rect\r\n          if (!$$.brush.empty()) {\r\n              $$.brush.selectionAsValue($$.x.orgDomain());\r\n          }\r\n          // setup drawer - MEMO: this must be called after axis updated\r\n          drawAreaOnSub = $$.generateDrawArea(areaIndices, true);\r\n          drawBarOnSub = $$.generateDrawBar(barIndices, true);\r\n          drawLineOnSub = $$.generateDrawLine(lineIndices, true);\r\n          $$.updateBarForSubchart(duration);\r\n          $$.updateLineForSubchart(duration);\r\n          $$.updateAreaForSubchart(duration);\r\n          $$.redrawBarForSubchart(drawBarOnSub, duration, duration);\r\n          $$.redrawLineForSubchart(drawLineOnSub, duration, duration);\r\n          $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration);\r\n      }\r\n  };\r\n  ChartInternal.prototype.redrawForBrush = function () {\r\n      var $$ = this, x = $$.x, d3 = $$.d3, s;\r\n      $$.redraw({\r\n          withTransition: false,\r\n          withY: $$.config.zoom_rescale,\r\n          withSubchart: false,\r\n          withUpdateXDomain: true,\r\n          withEventRect: false,\r\n          withDimension: false\r\n      });\r\n      // update zoom transation binded to event rect\r\n      s = d3.event.selection || $$.brush.scale.range();\r\n      $$.main\r\n          .select('.' + CLASS.eventRect)\r\n          .call($$.zoom.transform, d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0));\r\n      $$.config.subchart_onbrush.call($$.api, x.orgDomain());\r\n  };\r\n  ChartInternal.prototype.transformContext = function (withTransition, transitions) {\r\n      var $$ = this, subXAxis;\r\n      if (transitions && transitions.axisSubX) {\r\n          subXAxis = transitions.axisSubX;\r\n      }\r\n      else {\r\n          subXAxis = $$.context.select('.' + CLASS.axisX);\r\n          if (withTransition) {\r\n              subXAxis = subXAxis.transition();\r\n          }\r\n      }\r\n      $$.context.attr('transform', $$.getTranslate('context'));\r\n      subXAxis.attr('transform', $$.getTranslate('subx'));\r\n  };\r\n  ChartInternal.prototype.getDefaultSelection = function () {\r\n      var $$ = this, config = $$.config, selection = isFunction(config.axis_x_selection)\r\n          ? config.axis_x_selection($$.getXDomain($$.data.targets))\r\n          : config.axis_x_selection;\r\n      if ($$.isTimeSeries()) {\r\n          selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])];\r\n      }\r\n      return selection;\r\n  };\r\n  ChartInternal.prototype.removeSubchart = function () {\r\n      var $$ = this;\r\n      $$.brush = null;\r\n      $$.context.remove();\r\n      $$.context = null;\r\n  };\n\n  ChartInternal.prototype.initText = function () {\r\n      var $$ = this;\r\n      $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.chartTexts);\r\n      $$.mainText = $$.d3.selectAll([]);\r\n  };\r\n  ChartInternal.prototype.updateTargetsForText = function (targets) {\r\n      var $$ = this, classChartText = $$.classChartText.bind($$), classTexts = $$.classTexts.bind($$), classFocus = $$.classFocus.bind($$);\r\n      var mainText = $$.main\r\n          .select('.' + CLASS.chartTexts)\r\n          .selectAll('.' + CLASS.chartText)\r\n          .data(targets);\r\n      var mainTextEnter = mainText\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', classChartText)\r\n          .style('opacity', 0)\r\n          .style('pointer-events', 'none');\r\n      mainTextEnter.append('g').attr('class', classTexts);\r\n      mainTextEnter.merge(mainText).attr('class', function (d) {\r\n          return classChartText(d) + classFocus(d);\r\n      });\r\n  };\r\n  ChartInternal.prototype.updateText = function (xForText, yForText, durationForExit) {\r\n      var $$ = this, config = $$.config, barOrLineData = $$.barOrLineData.bind($$), classText = $$.classText.bind($$);\r\n      var mainText = $$.main\r\n          .selectAll('.' + CLASS.texts)\r\n          .selectAll('.' + CLASS.text)\r\n          .data(barOrLineData);\r\n      var mainTextEnter = mainText\r\n          .enter()\r\n          .append('text')\r\n          .attr('class', classText)\r\n          .attr('text-anchor', function (d) {\r\n          return config.axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle';\r\n      })\r\n          .style('stroke', 'none')\r\n          .attr('x', xForText)\r\n          .attr('y', yForText)\r\n          .style('fill', function (d) {\r\n          return $$.color(d);\r\n      })\r\n          .style('fill-opacity', 0);\r\n      $$.mainText = mainTextEnter.merge(mainText).text(function (d, i, j) {\r\n          return $$.dataLabelFormat(d.id)(d.value, d.id, i, j);\r\n      });\r\n      mainText\r\n          .exit()\r\n          .transition()\r\n          .duration(durationForExit)\r\n          .style('fill-opacity', 0)\r\n          .remove();\r\n  };\r\n  ChartInternal.prototype.redrawText = function (xForText, yForText, forFlow, withTransition, transition) {\r\n      return [\r\n          (withTransition ? this.mainText.transition(transition) : this.mainText)\r\n              .attr('x', xForText)\r\n              .attr('y', yForText)\r\n              .style('fill', this.color)\r\n              .style('fill-opacity', forFlow ? 0 : this.opacityForText.bind(this))\r\n      ];\r\n  };\r\n  ChartInternal.prototype.getTextRect = function (text, cls, element) {\r\n      var dummy = this.d3\r\n          .select('body')\r\n          .append('div')\r\n          .classed('c3', true), svg = dummy\r\n          .append('svg')\r\n          .style('visibility', 'hidden')\r\n          .style('position', 'fixed')\r\n          .style('top', 0)\r\n          .style('left', 0), font = this.d3.select(element).style('font'), rect;\r\n      svg\r\n          .selectAll('.dummy')\r\n          .data([text])\r\n          .enter()\r\n          .append('text')\r\n          .classed(cls ? cls : '', true)\r\n          .style('font', font)\r\n          .text(text)\r\n          .each(function () {\r\n          rect = getBBox(this);\r\n      });\r\n      dummy.remove();\r\n      return rect;\r\n  };\r\n  ChartInternal.prototype.generateXYForText = function (areaIndices, barIndices, lineIndices, forX) {\r\n      var $$ = this, getAreaPoints = $$.generateGetAreaPoints(areaIndices, false), getBarPoints = $$.generateGetBarPoints(barIndices, false), getLinePoints = $$.generateGetLinePoints(lineIndices, false), getter = forX ? $$.getXForText : $$.getYForText;\r\n      return function (d, i) {\r\n          var getPoints = $$.isAreaType(d)\r\n              ? getAreaPoints\r\n              : $$.isBarType(d)\r\n                  ? getBarPoints\r\n                  : getLinePoints;\r\n          return getter.call($$, getPoints(d, i), d, this);\r\n      };\r\n  };\r\n  ChartInternal.prototype.getXForText = function (points, d, textElement) {\r\n      var $$ = this, box = getBBox(textElement), xPos, padding;\r\n      if ($$.config.axis_rotated) {\r\n          padding = $$.isBarType(d) ? 4 : 6;\r\n          xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1);\r\n      }\r\n      else {\r\n          xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0];\r\n      }\r\n      // show labels regardless of the domain if value is null\r\n      if (d.value === null) {\r\n          if (xPos > $$.width) {\r\n              xPos = $$.width - box.width;\r\n          }\r\n          else if (xPos < 0) {\r\n              xPos = 4;\r\n          }\r\n      }\r\n      return xPos;\r\n  };\r\n  ChartInternal.prototype.getYForText = function (points, d, textElement) {\r\n      var $$ = this, box = getBBox(textElement), yPos;\r\n      if ($$.config.axis_rotated) {\r\n          yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2;\r\n      }\r\n      else {\r\n          yPos = points[2][1];\r\n          if (d.value < 0 || (d.value === 0 && !$$.hasPositiveValue)) {\r\n              yPos += box.height;\r\n              if ($$.isBarType(d) && $$.isSafari()) {\r\n                  yPos -= 3;\r\n              }\r\n              else if (!$$.isBarType(d) && $$.isChrome()) {\r\n                  yPos += 3;\r\n              }\r\n          }\r\n          else {\r\n              yPos += $$.isBarType(d) ? -3 : -6;\r\n          }\r\n      }\r\n      // show labels regardless of the domain if value is null\r\n      if (d.value === null && !$$.config.axis_rotated) {\r\n          if (yPos < box.height) {\r\n              yPos = box.height;\r\n          }\r\n          else if (yPos > this.height) {\r\n              yPos = this.height - 4;\r\n          }\r\n      }\r\n      return yPos;\r\n  };\n\n  ChartInternal.prototype.initTitle = function () {\r\n      var $$ = this;\r\n      $$.title = $$.svg\r\n          .append('text')\r\n          .text($$.config.title_text)\r\n          .attr('class', $$.CLASS.title);\r\n  };\r\n  ChartInternal.prototype.redrawTitle = function () {\r\n      var $$ = this;\r\n      $$.title.attr('x', $$.xForTitle.bind($$)).attr('y', $$.yForTitle.bind($$));\r\n  };\r\n  ChartInternal.prototype.xForTitle = function () {\r\n      var $$ = this, config = $$.config, position = config.title_position || 'left', x;\r\n      if (position.indexOf('right') >= 0) {\r\n          x =\r\n              $$.currentWidth -\r\n                  $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width -\r\n                  config.title_padding.right;\r\n      }\r\n      else if (position.indexOf('center') >= 0) {\r\n          x = Math.max(($$.currentWidth -\r\n              $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width) /\r\n              2, 0);\r\n      }\r\n      else {\r\n          // left\r\n          x = config.title_padding.left;\r\n      }\r\n      return x;\r\n  };\r\n  ChartInternal.prototype.yForTitle = function () {\r\n      var $$ = this;\r\n      return ($$.config.title_padding.top +\r\n          $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node())\r\n              .height);\r\n  };\r\n  ChartInternal.prototype.getTitlePadding = function () {\r\n      var $$ = this;\r\n      return $$.yForTitle() + $$.config.title_padding.bottom;\r\n  };\n\n  function powerOfTen(d) {\r\n      return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1;\r\n  }\r\n  ChartInternal.prototype.drawColorScale = function () {\r\n      var $$ = this, d3 = $$.d3, config = $$.config, target = $$.data.targets[0], barWidth, barHeight, axis, points, legendAxis, axisScale, inverseScale, height;\r\n      barWidth = !isNaN(config.stanford_scaleWidth)\r\n          ? config.stanford_scaleWidth\r\n          : 20;\r\n      barHeight = 5;\r\n      if (barHeight < 0 || barWidth < 0) {\r\n          throw Error(\"Colorscale's barheight and barwidth must be greater than 0.\");\r\n      }\r\n      height =\r\n          $$.height - config.stanford_padding.bottom - config.stanford_padding.top;\r\n      points = d3.range(config.stanford_padding.bottom, height, barHeight);\r\n      inverseScale = d3\r\n          .scaleSequential(target.colors)\r\n          .domain([points[points.length - 1], points[0]]);\r\n      if ($$.colorScale) {\r\n          $$.colorScale.remove();\r\n      }\r\n      $$.colorScale = $$.svg\r\n          .append('g')\r\n          .attr('width', 50)\r\n          .attr('height', height)\r\n          .attr('class', CLASS.colorScale);\r\n      $$.colorScale\r\n          .append('g')\r\n          .attr('transform', \"translate(0, \" + config.stanford_padding.top + \")\")\r\n          .selectAll('bars')\r\n          .data(points)\r\n          .enter()\r\n          .append('rect')\r\n          .attr('y', function (d, i) { return i * barHeight; })\r\n          .attr('x', 0)\r\n          .attr('width', barWidth)\r\n          .attr('height', barHeight)\r\n          .attr('fill', function (d) {\r\n          return inverseScale(d);\r\n      });\r\n      // Legend Axis\r\n      axisScale = d3\r\n          .scaleLog()\r\n          .domain([target.minEpochs, target.maxEpochs])\r\n          .range([\r\n          points[0] +\r\n              config.stanford_padding.top +\r\n              points[points.length - 1] +\r\n              barHeight -\r\n              1,\r\n          points[0] + config.stanford_padding.top\r\n      ]);\r\n      legendAxis = d3.axisRight(axisScale);\r\n      if (config.stanford_scaleFormat === 'pow10') {\r\n          legendAxis.tickValues([1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]);\r\n      }\r\n      else if (isFunction(config.stanford_scaleFormat)) {\r\n          legendAxis.tickFormat(config.stanford_scaleFormat);\r\n      }\r\n      else {\r\n          legendAxis.tickFormat(d3.format('d'));\r\n      }\r\n      if (isFunction(config.stanford_scaleValues)) {\r\n          legendAxis.tickValues(config.stanford_scaleValues(target.minEpochs, target.maxEpochs));\r\n      }\r\n      // Draw Axis\r\n      axis = $$.colorScale\r\n          .append('g')\r\n          .attr('class', 'legend axis')\r\n          .attr('transform', \"translate(\" + barWidth + \",0)\")\r\n          .call(legendAxis);\r\n      if (config.stanford_scaleFormat === 'pow10') {\r\n          axis\r\n              .selectAll('.tick text')\r\n              .text(null)\r\n              .filter(powerOfTen)\r\n              .text(10)\r\n              .append('tspan')\r\n              .attr('dy', '-.7em') // https://bl.ocks.org/mbostock/6738229\r\n              .text(function (d) {\r\n              return Math.round(Math.log(d) / Math.LN10);\r\n          });\r\n      }\r\n      $$.colorScale.attr('transform', \"translate(\" + ($$.currentWidth - $$.xForColorScale()) + \", 0)\");\r\n  };\r\n  ChartInternal.prototype.xForColorScale = function () {\r\n      var $$ = this;\r\n      return $$.config.stanford_padding.right + getBBox($$.colorScale.node()).width;\r\n  };\r\n  ChartInternal.prototype.getColorScalePadding = function () {\r\n      var $$ = this;\r\n      return $$.xForColorScale() + $$.config.stanford_padding.left + 20;\r\n  };\n\n  ChartInternal.prototype.isStanfordGraphType = function () {\r\n      var $$ = this;\r\n      return $$.config.data_type === 'stanford';\r\n  };\r\n  ChartInternal.prototype.initStanfordData = function () {\r\n      var $$ = this, d3 = $$.d3, config = $$.config, target = $$.data.targets[0], epochs, maxEpochs, minEpochs;\r\n      // Make larger values appear on top\r\n      target.values.sort(compareEpochs);\r\n      // Get array of epochs\r\n      epochs = target.values.map(function (a) { return a.epochs; });\r\n      minEpochs = !isNaN(config.stanford_scaleMin)\r\n          ? config.stanford_scaleMin\r\n          : d3.min(epochs);\r\n      maxEpochs = !isNaN(config.stanford_scaleMax)\r\n          ? config.stanford_scaleMax\r\n          : d3.max(epochs);\r\n      if (minEpochs > maxEpochs) {\r\n          throw Error('Number of minEpochs has to be smaller than maxEpochs');\r\n      }\r\n      target.colors = isFunction(config.stanford_colors)\r\n          ? config.stanford_colors\r\n          : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5));\r\n      target.colorscale = d3\r\n          .scaleSequentialLog(target.colors)\r\n          .domain([minEpochs, maxEpochs]);\r\n      target.minEpochs = minEpochs;\r\n      target.maxEpochs = maxEpochs;\r\n  };\r\n  ChartInternal.prototype.getStanfordPointColor = function (d) {\r\n      var $$ = this, target = $$.data.targets[0];\r\n      return target.colorscale(d.epochs);\r\n  };\r\n  // http://jsfiddle.net/Xotic750/KtzLq/\r\n  ChartInternal.prototype.getCentroid = function (points) {\r\n      var area = getRegionArea(points);\r\n      var x = 0, y = 0, i, j, f, point1, point2;\r\n      for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {\r\n          point1 = points[i];\r\n          point2 = points[j];\r\n          f = point1.x * point2.y - point2.x * point1.y;\r\n          x += (point1.x + point2.x) * f;\r\n          y += (point1.y + point2.y) * f;\r\n      }\r\n      f = area * 6;\r\n      return {\r\n          x: x / f,\r\n          y: y / f\r\n      };\r\n  };\r\n  ChartInternal.prototype.getStanfordTooltipTitle = function (d) {\r\n      var $$ = this, labelX = $$.axis.getLabelText('x'), labelY = $$.axis.getLabelText('y');\r\n      return \"\\n      <tr><th>\" + (labelX ? sanitise(labelX) : 'x') + \"</th><th class='value'>\" + d.x + \"</th></tr>\\n      <tr><th>\" + (labelY ? sanitise(labelY) : 'y') + \"</th><th class='value'>\" + d.value + \"</th></tr>\\n    \";\r\n  };\r\n  ChartInternal.prototype.countEpochsInRegion = function (region) {\r\n      var $$ = this, target = $$.data.targets[0], total, count;\r\n      total = target.values.reduce(function (accumulator, currentValue) { return accumulator + Number(currentValue.epochs); }, 0);\r\n      count = target.values.reduce(function (accumulator, currentValue) {\r\n          if (pointInRegion(currentValue, region)) {\r\n              return accumulator + Number(currentValue.epochs);\r\n          }\r\n          return accumulator;\r\n      }, 0);\r\n      return {\r\n          value: count,\r\n          percentage: count !== 0 ? ((count / total) * 100).toFixed(1) : 0\r\n      };\r\n  };\r\n  var getRegionArea = function (points) {\r\n      // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript\r\n      var area = 0, i, j, point1, point2;\r\n      for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {\r\n          point1 = points[i];\r\n          point2 = points[j];\r\n          area += point1.x * point2.y;\r\n          area -= point1.y * point2.x;\r\n      }\r\n      area /= 2;\r\n      return area;\r\n  };\r\n  var pointInRegion = function (point, region) {\r\n      // thanks to: http://bl.ocks.org/bycoffe/5575904\r\n      // ray-casting algorithm based on\r\n      // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html\r\n      var xi, yi, yj, xj, intersect, x = point.x, y = point.value, inside = false;\r\n      for (var i = 0, j = region.length - 1; i < region.length; j = i++) {\r\n          xi = region[i].x;\r\n          yi = region[i].y;\r\n          xj = region[j].x;\r\n          yj = region[j].y;\r\n          intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;\r\n          if (intersect) {\r\n              inside = !inside;\r\n          }\r\n      }\r\n      return inside;\r\n  };\r\n  var compareEpochs = function (a, b) {\r\n      if (a.epochs < b.epochs) {\r\n          return -1;\r\n      }\r\n      if (a.epochs > b.epochs) {\r\n          return 1;\r\n      }\r\n      return 0;\r\n  };\n\n  ChartInternal.prototype.initStanfordElements = function () {\r\n      var $$ = this;\r\n      // Avoid blocking eventRect\r\n      $$.stanfordElements = $$.main\r\n          .select('.' + CLASS.chart)\r\n          .append('g')\r\n          .attr('class', CLASS.stanfordElements);\r\n      $$.stanfordElements.append('g').attr('class', CLASS.stanfordLines);\r\n      $$.stanfordElements.append('g').attr('class', CLASS.stanfordTexts);\r\n      $$.stanfordElements.append('g').attr('class', CLASS.stanfordRegions);\r\n  };\r\n  ChartInternal.prototype.updateStanfordElements = function (duration) {\r\n      var $$ = this, main = $$.main, config = $$.config, stanfordLine, stanfordLineEnter, stanfordRegion, stanfordRegionEnter, stanfordText, stanfordTextEnter, xvCustom = $$.xvCustom.bind($$), yvCustom = $$.yvCustom.bind($$), countPointsInRegion = $$.countEpochsInRegion.bind($$);\r\n      // Stanford-Lines\r\n      stanfordLine = main\r\n          .select('.' + CLASS.stanfordLines)\r\n          .style('shape-rendering', 'geometricprecision')\r\n          .selectAll('.' + CLASS.stanfordLine)\r\n          .data(config.stanford_lines);\r\n      // enter\r\n      stanfordLineEnter = stanfordLine\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', function (d) {\r\n          return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : '');\r\n      });\r\n      stanfordLineEnter\r\n          .append('line')\r\n          .attr('x1', function (d) {\r\n          return config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1');\r\n      })\r\n          .attr('x2', function (d) {\r\n          return config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2');\r\n      })\r\n          .attr('y1', function (d) {\r\n          return config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1');\r\n      })\r\n          .attr('y2', function (d) {\r\n          return config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2');\r\n      })\r\n          .style('opacity', 0);\r\n      // update\r\n      $$.stanfordLines = stanfordLineEnter.merge(stanfordLine);\r\n      $$.stanfordLines\r\n          .select('line')\r\n          .transition()\r\n          .duration(duration)\r\n          .attr('x1', function (d) {\r\n          return config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1');\r\n      })\r\n          .attr('x2', function (d) {\r\n          return config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2');\r\n      })\r\n          .attr('y1', function (d) {\r\n          return config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1');\r\n      })\r\n          .attr('y2', function (d) {\r\n          return config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2');\r\n      })\r\n          .style('opacity', 1);\r\n      // exit\r\n      stanfordLine\r\n          .exit()\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      // Stanford-Text\r\n      stanfordText = main\r\n          .select('.' + CLASS.stanfordTexts)\r\n          .selectAll('.' + CLASS.stanfordText)\r\n          .data(config.stanford_texts);\r\n      // enter\r\n      stanfordTextEnter = stanfordText\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', function (d) {\r\n          return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : '');\r\n      });\r\n      stanfordTextEnter\r\n          .append('text')\r\n          .attr('x', function (d) { return (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')); })\r\n          .attr('y', function (d) { return (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')); })\r\n          .style('opacity', 0);\r\n      // update\r\n      $$.stanfordTexts = stanfordTextEnter.merge(stanfordText);\r\n      $$.stanfordTexts\r\n          .select('text')\r\n          .transition()\r\n          .duration(duration)\r\n          .attr('x', function (d) { return (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')); })\r\n          .attr('y', function (d) { return (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')); })\r\n          .text(function (d) {\r\n          return d.content;\r\n      })\r\n          .style('opacity', 1);\r\n      // exit\r\n      stanfordText\r\n          .exit()\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n      // Stanford-Regions\r\n      stanfordRegion = main\r\n          .select('.' + CLASS.stanfordRegions)\r\n          .selectAll('.' + CLASS.stanfordRegion)\r\n          .data(config.stanford_regions);\r\n      // enter\r\n      stanfordRegionEnter = stanfordRegion\r\n          .enter()\r\n          .append('g')\r\n          .attr('class', function (d) {\r\n          return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : '');\r\n      });\r\n      stanfordRegionEnter\r\n          .append('polygon')\r\n          .attr('points', function (d) {\r\n          return d.points\r\n              .map(function (value) {\r\n              return [\r\n                  config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'),\r\n                  config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')\r\n              ].join(',');\r\n          })\r\n              .join(' ');\r\n      })\r\n          .style('opacity', 0);\r\n      stanfordRegionEnter\r\n          .append('text')\r\n          .attr('x', function (d) { return $$.getCentroid(d.points).x; })\r\n          .attr('y', function (d) { return $$.getCentroid(d.points).y; })\r\n          .style('opacity', 0);\r\n      // update\r\n      $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion);\r\n      $$.stanfordRegions\r\n          .select('polygon')\r\n          .transition()\r\n          .duration(duration)\r\n          .attr('points', function (d) {\r\n          return d.points\r\n              .map(function (value) {\r\n              return [\r\n                  config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'),\r\n                  config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')\r\n              ].join(',');\r\n          })\r\n              .join(' ');\r\n      })\r\n          .style('opacity', function (d) {\r\n          return d.opacity ? d.opacity : 0.2;\r\n      });\r\n      $$.stanfordRegions\r\n          .select('text')\r\n          .transition()\r\n          .duration(duration)\r\n          .attr('x', function (d) {\r\n          return config.axis_rotated\r\n              ? yvCustom($$.getCentroid(d.points), 'y')\r\n              : xvCustom($$.getCentroid(d.points), 'x');\r\n      })\r\n          .attr('y', function (d) {\r\n          return config.axis_rotated\r\n              ? xvCustom($$.getCentroid(d.points), 'x')\r\n              : yvCustom($$.getCentroid(d.points), 'y');\r\n      })\r\n          .text(function (d) {\r\n          if (d.text) {\r\n              var value, percentage, temp;\r\n              if ($$.isStanfordGraphType()) {\r\n                  temp = countPointsInRegion(d.points);\r\n                  value = temp.value;\r\n                  percentage = temp.percentage;\r\n              }\r\n              return d.text(value, percentage);\r\n          }\r\n          return '';\r\n      })\r\n          .attr('text-anchor', 'middle')\r\n          .attr('dominant-baseline', 'middle')\r\n          .style('opacity', 1);\r\n      // exit\r\n      stanfordRegion\r\n          .exit()\r\n          .transition()\r\n          .duration(duration)\r\n          .style('opacity', 0)\r\n          .remove();\r\n  };\n\n  ChartInternal.prototype.initTooltip = function () {\r\n      var $$ = this, config = $$.config, i;\r\n      $$.tooltip = $$.selectChart\r\n          .style('position', 'relative')\r\n          .append('div')\r\n          .attr('class', CLASS.tooltipContainer)\r\n          .style('position', 'absolute')\r\n          .style('pointer-events', 'none')\r\n          .style('display', 'none');\r\n      // Show tooltip if needed\r\n      if (config.tooltip_init_show) {\r\n          if ($$.isTimeSeries() && isString(config.tooltip_init_x)) {\r\n              config.tooltip_init_x = $$.parseDate(config.tooltip_init_x);\r\n              for (i = 0; i < $$.data.targets[0].values.length; i++) {\r\n                  if ($$.data.targets[0].values[i].x - config.tooltip_init_x === 0) {\r\n                      break;\r\n                  }\r\n              }\r\n              config.tooltip_init_x = i;\r\n          }\r\n          $$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) {\r\n              return $$.addName(d.values[config.tooltip_init_x]);\r\n          }), $$.axis.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color));\r\n          $$.tooltip\r\n              .style('top', config.tooltip_init_position.top)\r\n              .style('left', config.tooltip_init_position.left)\r\n              .style('display', 'block');\r\n      }\r\n  };\r\n  ChartInternal.prototype.getTooltipSortFunction = function () {\r\n      var $$ = this, config = $$.config;\r\n      if (config.data_groups.length === 0 || config.tooltip_order !== undefined) {\r\n          // if data are not grouped or if an order is specified\r\n          // for the tooltip values we sort them by their values\r\n          var order = config.tooltip_order;\r\n          if (order === undefined) {\r\n              order = config.data_order;\r\n          }\r\n          var valueOf = function (obj) {\r\n              return obj ? obj.value : null;\r\n          };\r\n          // if data are not grouped, we sort them by their value\r\n          if (isString(order) && order.toLowerCase() === 'asc') {\r\n              return function (a, b) {\r\n                  return valueOf(a) - valueOf(b);\r\n              };\r\n          }\r\n          else if (isString(order) && order.toLowerCase() === 'desc') {\r\n              return function (a, b) {\r\n                  return valueOf(b) - valueOf(a);\r\n              };\r\n          }\r\n          else if (isFunction(order)) {\r\n              // if the function is from data_order we need\r\n              // to wrap the returned function in order to format\r\n              // the sorted value to the expected format\r\n              var sortFunction = order;\r\n              if (config.tooltip_order === undefined) {\r\n                  sortFunction = function (a, b) {\r\n                      return order(a\r\n                          ? {\r\n                              id: a.id,\r\n                              values: [a]\r\n                          }\r\n                          : null, b\r\n                          ? {\r\n                              id: b.id,\r\n                              values: [b]\r\n                          }\r\n                          : null);\r\n                  };\r\n              }\r\n              return sortFunction;\r\n          }\r\n          else if (isArray(order)) {\r\n              return function (a, b) {\r\n                  return order.indexOf(a.id) - order.indexOf(b.id);\r\n              };\r\n          }\r\n      }\r\n      else {\r\n          // if data are grouped, we follow the order of grouped targets\r\n          var ids = $$.orderTargets($$.data.targets).map(function (i) {\r\n              return i.id;\r\n          });\r\n          // if it was either asc or desc we need to invert the order\r\n          // returned by orderTargets\r\n          if ($$.isOrderAsc() || $$.isOrderDesc()) {\r\n              ids = ids.reverse();\r\n          }\r\n          return function (a, b) {\r\n              return ids.indexOf(a.id) - ids.indexOf(b.id);\r\n          };\r\n      }\r\n  };\r\n  ChartInternal.prototype.getTooltipContent = function (d, defaultTitleFormat, defaultValueFormat, color) {\r\n      var $$ = this, config = $$.config, titleFormat = config.tooltip_format_title || defaultTitleFormat, nameFormat = config.tooltip_format_name ||\r\n          function (name) {\r\n              return name;\r\n          }, text, i, title, value, name, bgcolor;\r\n      var valueFormat = config.tooltip_format_value;\r\n      if (!valueFormat) {\r\n          valueFormat = $$.isTargetNormalized(d.id)\r\n              ? function (v, ratio) { return (ratio * 100).toFixed(2) + \"%\"; }\r\n              : defaultValueFormat;\r\n      }\r\n      var tooltipSortFunction = this.getTooltipSortFunction();\r\n      if (tooltipSortFunction) {\r\n          d.sort(tooltipSortFunction);\r\n      }\r\n      for (i = 0; i < d.length; i++) {\r\n          if (!(d[i] && (d[i].value || d[i].value === 0))) {\r\n              continue;\r\n          }\r\n          if ($$.isStanfordGraphType()) {\r\n              // Custom tooltip for stanford plots\r\n              if (!text) {\r\n                  title = $$.getStanfordTooltipTitle(d[i]);\r\n                  text = \"<table class='\" + $$.CLASS.tooltip + \"'>\" + title;\r\n              }\r\n              bgcolor = $$.getStanfordPointColor(d[i]);\r\n              name = sanitise(config.data_epochs); // Epochs key name\r\n              value = d[i].epochs;\r\n          }\r\n          else {\r\n              // Regular tooltip\r\n              if (!text) {\r\n                  title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x);\r\n                  text =\r\n                      \"<table class='\" +\r\n                          $$.CLASS.tooltip +\r\n                          \"'>\" +\r\n                          (title || title === 0\r\n                              ? \"<tr><th colspan='2'>\" + title + '</th></tr>'\r\n                              : '');\r\n              }\r\n              value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d));\r\n              if (value !== undefined) {\r\n                  // Skip elements when their name is set to null\r\n                  if (d[i].name === null) {\r\n                      continue;\r\n                  }\r\n                  name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index));\r\n                  bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);\r\n              }\r\n          }\r\n          if (value !== undefined) {\r\n              text +=\r\n                  \"<tr class='\" +\r\n                      $$.CLASS.tooltipName +\r\n                      '-' +\r\n                      $$.getTargetSelectorSuffix(d[i].id) +\r\n                      \"'>\";\r\n              text +=\r\n                  \"<td class='name'><span style='background-color:\" +\r\n                      bgcolor +\r\n                      \"'></span>\" +\r\n                      name +\r\n                      '</td>';\r\n              text += \"<td class='value'>\" + value + '</td>';\r\n              text += '</tr>';\r\n          }\r\n      }\r\n      return text + '</table>';\r\n  };\r\n  ChartInternal.prototype.tooltipPosition = function (dataToShow, tWidth, tHeight, element) {\r\n      var $$ = this, config = $$.config, d3 = $$.d3;\r\n      var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight;\r\n      var forArc = $$.hasArcType(), mouse = d3.mouse(element);\r\n      // Determin tooltip position\r\n      if (forArc) {\r\n          tooltipLeft =\r\n              ($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2 + mouse[0];\r\n          tooltipTop =\r\n              ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20;\r\n      }\r\n      else {\r\n          svgLeft = $$.getSvgLeft(true);\r\n          if (config.axis_rotated) {\r\n              tooltipLeft = svgLeft + mouse[0] + 100;\r\n              tooltipRight = tooltipLeft + tWidth;\r\n              chartRight = $$.currentWidth - $$.getCurrentPaddingRight();\r\n              tooltipTop = $$.x(dataToShow[0].x) + 20;\r\n          }\r\n          else {\r\n              tooltipLeft =\r\n                  svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20;\r\n              tooltipRight = tooltipLeft + tWidth;\r\n              chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight();\r\n              tooltipTop = mouse[1] + 15;\r\n          }\r\n          if (tooltipRight > chartRight) {\r\n              // 20 is needed for Firefox to keep tooltip width\r\n              tooltipLeft -= tooltipRight - chartRight + 20;\r\n          }\r\n          if (tooltipTop + tHeight > $$.currentHeight) {\r\n              tooltipTop -= tHeight + 30;\r\n          }\r\n      }\r\n      if (tooltipTop < 0) {\r\n          tooltipTop = 0;\r\n      }\r\n      return {\r\n          top: tooltipTop,\r\n          left: tooltipLeft\r\n      };\r\n  };\r\n  ChartInternal.prototype.showTooltip = function (selectedData, element) {\r\n      var $$ = this, config = $$.config;\r\n      var tWidth, tHeight, position;\r\n      var forArc = $$.hasArcType(), dataToShow = selectedData.filter(function (d) {\r\n          return d && isValue(d.value);\r\n      }), positionFunction = config.tooltip_position || ChartInternal.prototype.tooltipPosition;\r\n      if (dataToShow.length === 0 || !config.tooltip_show) {\r\n          $$.hideTooltip();\r\n          return;\r\n      }\r\n      $$.tooltip\r\n          .html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color))\r\n          .style('display', 'block');\r\n      // Get tooltip dimensions\r\n      tWidth = $$.tooltip.property('offsetWidth');\r\n      tHeight = $$.tooltip.property('offsetHeight');\r\n      position = positionFunction.call(this, dataToShow, tWidth, tHeight, element);\r\n      // Set tooltip\r\n      $$.tooltip\r\n          .style('top', position.top + 'px')\r\n          .style('left', position.left + 'px');\r\n  };\r\n  ChartInternal.prototype.hideTooltip = function () {\r\n      this.tooltip.style('display', 'none');\r\n  };\n\n  ChartInternal.prototype.setTargetType = function (targetIds, type) {\r\n      var $$ = this, config = $$.config;\r\n      $$.mapToTargetIds(targetIds).forEach(function (id) {\r\n          $$.withoutFadeIn[id] = type === config.data_types[id];\r\n          config.data_types[id] = type;\r\n      });\r\n      if (!targetIds) {\r\n          config.data_type = type;\r\n      }\r\n  };\r\n  ChartInternal.prototype.hasType = function (type, targets) {\r\n      var $$ = this, types = $$.config.data_types, has = false;\r\n      targets = targets || $$.data.targets;\r\n      if (targets && targets.length) {\r\n          targets.forEach(function (target) {\r\n              var t = types[target.id];\r\n              if ((t && t.indexOf(type) >= 0) || (!t && type === 'line')) {\r\n                  has = true;\r\n              }\r\n          });\r\n      }\r\n      else if (Object.keys(types).length) {\r\n          Object.keys(types).forEach(function (id) {\r\n              if (types[id] === type) {\r\n                  has = true;\r\n              }\r\n          });\r\n      }\r\n      else {\r\n          has = $$.config.data_type === type;\r\n      }\r\n      return has;\r\n  };\r\n  ChartInternal.prototype.hasArcType = function (targets) {\r\n      return (this.hasType('pie', targets) ||\r\n          this.hasType('donut', targets) ||\r\n          this.hasType('gauge', targets));\r\n  };\r\n  ChartInternal.prototype.isLineType = function (d) {\r\n      var config = this.config, id = isString(d) ? d : d.id;\r\n      return (!config.data_types[id] ||\r\n          ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(config.data_types[id]) >= 0);\r\n  };\r\n  ChartInternal.prototype.isStepType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0;\r\n  };\r\n  ChartInternal.prototype.isSplineType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0;\r\n  };\r\n  ChartInternal.prototype.isAreaType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return (['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >=\r\n          0);\r\n  };\r\n  ChartInternal.prototype.isBarType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return this.config.data_types[id] === 'bar';\r\n  };\r\n  ChartInternal.prototype.isScatterType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return this.config.data_types[id] === 'scatter';\r\n  };\r\n  ChartInternal.prototype.isStanfordType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return this.config.data_types[id] === 'stanford';\r\n  };\r\n  ChartInternal.prototype.isPieType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return this.config.data_types[id] === 'pie';\r\n  };\r\n  ChartInternal.prototype.isGaugeType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return this.config.data_types[id] === 'gauge';\r\n  };\r\n  ChartInternal.prototype.isDonutType = function (d) {\r\n      var id = isString(d) ? d : d.id;\r\n      return this.config.data_types[id] === 'donut';\r\n  };\r\n  ChartInternal.prototype.isArcType = function (d) {\r\n      return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d);\r\n  };\r\n  ChartInternal.prototype.lineData = function (d) {\r\n      return this.isLineType(d) ? [d] : [];\r\n  };\r\n  ChartInternal.prototype.arcData = function (d) {\r\n      return this.isArcType(d.data) ? [d] : [];\r\n  };\r\n  /* not used\r\n   function scatterData(d) {\r\n   return isScatterType(d) ? d.values : [];\r\n   }\r\n   */\r\n  ChartInternal.prototype.barData = function (d) {\r\n      return this.isBarType(d) ? d.values : [];\r\n  };\r\n  ChartInternal.prototype.lineOrScatterOrStanfordData = function (d) {\r\n      return this.isLineType(d) || this.isScatterType(d) || this.isStanfordType(d)\r\n          ? d.values\r\n          : [];\r\n  };\r\n  ChartInternal.prototype.barOrLineData = function (d) {\r\n      return this.isBarType(d) || this.isLineType(d) ? d.values : [];\r\n  };\n\n  ChartInternal.prototype.isSafari = function () {\r\n      var ua = window.navigator.userAgent;\r\n      return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0;\r\n  };\r\n  ChartInternal.prototype.isChrome = function () {\r\n      var ua = window.navigator.userAgent;\r\n      return ua.indexOf('Chrome') >= 0;\r\n  };\n\n  ChartInternal.prototype.initZoom = function () {\r\n      var $$ = this, d3 = $$.d3, config = $$.config, startEvent;\r\n      $$.zoom = d3\r\n          .zoom()\r\n          .on('start', function () {\r\n          if (config.zoom_type !== 'scroll') {\r\n              return;\r\n          }\r\n          var e = d3.event.sourceEvent;\r\n          if (e && e.type === 'brush') {\r\n              return;\r\n          }\r\n          startEvent = e;\r\n          config.zoom_onzoomstart.call($$.api, e);\r\n      })\r\n          .on('zoom', function () {\r\n          if (config.zoom_type !== 'scroll') {\r\n              return;\r\n          }\r\n          var e = d3.event.sourceEvent;\r\n          if (e && e.type === 'brush') {\r\n              return;\r\n          }\r\n          $$.redrawForZoom();\r\n          config.zoom_onzoom.call($$.api, $$.x.orgDomain());\r\n      })\r\n          .on('end', function () {\r\n          if (config.zoom_type !== 'scroll') {\r\n              return;\r\n          }\r\n          var e = d3.event.sourceEvent;\r\n          if (e && e.type === 'brush') {\r\n              return;\r\n          }\r\n          // if click, do nothing. otherwise, click interaction will be canceled.\r\n          if (e &&\r\n              startEvent.clientX === e.clientX &&\r\n              startEvent.clientY === e.clientY) {\r\n              return;\r\n          }\r\n          config.zoom_onzoomend.call($$.api, $$.x.orgDomain());\r\n      });\r\n      $$.zoom.updateDomain = function () {\r\n          if (d3.event && d3.event.transform) {\r\n              if (config.axis_rotated && config.zoom_type === 'scroll' && d3.event.sourceEvent.type === 'mousemove') {\r\n                  // we're moving the mouse in a rotated chart with zoom = \"scroll\", so we need rescaleY (i.e. vertical)\r\n                  $$.x.domain(d3.event.transform.rescaleY($$.subX).domain());\r\n              }\r\n              else {\r\n                  $$.x.domain(d3.event.transform.rescaleX($$.subX).domain());\r\n              }\r\n          }\r\n          return this;\r\n      };\r\n      $$.zoom.updateExtent = function () {\r\n          this.scaleExtent([1, Infinity])\r\n              .translateExtent([\r\n              [0, 0],\r\n              [$$.width, $$.height]\r\n          ])\r\n              .extent([\r\n              [0, 0],\r\n              [$$.width, $$.height]\r\n          ]);\r\n          return this;\r\n      };\r\n      $$.zoom.update = function () {\r\n          return this.updateExtent().updateDomain();\r\n      };\r\n      return $$.zoom.updateExtent();\r\n  };\r\n  ChartInternal.prototype.zoomTransform = function (range) {\r\n      var $$ = this, s = [$$.x(range[0]), $$.x(range[1])];\r\n      return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0);\r\n  };\r\n  ChartInternal.prototype.initDragZoom = function () {\r\n      var $$ = this;\r\n      var d3 = $$.d3;\r\n      var config = $$.config;\r\n      var context = ($$.context = $$.svg);\r\n      var brushXPos = $$.margin.left + 20.5;\r\n      var brushYPos = $$.margin.top + 0.5;\r\n      if (!(config.zoom_type === 'drag' && config.zoom_enabled)) {\r\n          return;\r\n      }\r\n      var getZoomedDomain = function (selection) {\r\n          return selection && selection.map(function (x) { return $$.x.invert(x); });\r\n      };\r\n      var brush = ($$.dragZoomBrush = d3\r\n          .brushX()\r\n          .on('start', function () {\r\n          $$.api.unzoom();\r\n          $$.svg.select('.' + CLASS.dragZoom).classed('disabled', false);\r\n          config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent);\r\n      })\r\n          .on('brush', function () {\r\n          config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection));\r\n      })\r\n          .on('end', function () {\r\n          if (d3.event.selection == null) {\r\n              return;\r\n          }\r\n          var zoomedDomain = getZoomedDomain(d3.event.selection);\r\n          if (!config.zoom_disableDefaultBehavior) {\r\n              $$.api.zoom(zoomedDomain);\r\n          }\r\n          $$.svg.select('.' + CLASS.dragZoom).classed('disabled', true);\r\n          config.zoom_onzoomend.call($$.api, zoomedDomain);\r\n      }));\r\n      context\r\n          .append('g')\r\n          .classed(CLASS.dragZoom, true)\r\n          .attr('clip-path', $$.clipPath)\r\n          .attr('transform', 'translate(' + brushXPos + ',' + brushYPos + ')')\r\n          .call(brush);\r\n  };\r\n  ChartInternal.prototype.getZoomDomain = function () {\r\n      var $$ = this, config = $$.config, d3 = $$.d3, min = d3.min([$$.orgXDomain[0], config.zoom_x_min]), max = d3.max([$$.orgXDomain[1], config.zoom_x_max]);\r\n      return [min, max];\r\n  };\r\n  ChartInternal.prototype.redrawForZoom = function () {\r\n      var $$ = this, d3 = $$.d3, config = $$.config, zoom = $$.zoom, x = $$.x;\r\n      if (!config.zoom_enabled) {\r\n          return;\r\n      }\r\n      if ($$.filterTargetsToShow($$.data.targets).length === 0) {\r\n          return;\r\n      }\r\n      zoom.update();\r\n      if (config.zoom_disableDefaultBehavior) {\r\n          return;\r\n      }\r\n      if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) {\r\n          x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]);\r\n      }\r\n      $$.redraw({\r\n          withTransition: false,\r\n          withY: config.zoom_rescale,\r\n          withSubchart: false,\r\n          withEventRect: false,\r\n          withDimension: false\r\n      });\r\n      if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') {\r\n          $$.cancelClick = true;\r\n      }\r\n  };\n\n  return c3;\n\n})));\n"
  },
  {
    "path": "docs/js/gettingstarted.js",
    "content": "c3.generate({\n    bindto: '#chart2_1',\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ]\n    }\n});\n\nc3.generate({\n    bindto: '#chart3_1',\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ],\n        axes: {\n            data2: 'y2'\n        }\n    },\n    axis: {\n        y2: {\n            show: true\n        }\n    }\n});\n\nc3.generate({\n    bindto: '#chart3_2',\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ],\n        axes: {\n            data2: 'y2'\n        }\n    },\n    axis: {\n        y: {\n            label: {\n                text: 'Y Label',\n                position: 'outer-middle'\n            }\n        },\n        y2: {\n            show: true,\n            label: {\n                text: 'Y2 Label',\n                position: 'outer-middle'\n            }\n        }\n    }\n});\n\nc3.generate({\n    bindto: '#chart3_3',\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ],\n        axes: {\n            data2: 'y2'\n        },\n        types: {\n            data2: 'bar'\n        }\n    },\n    axis: {\n        y: {\n            label: {\n                text: 'Y Label',\n                position: 'outer-middle'\n            }\n        },\n        y2: {\n            show: true,\n            label: {\n                text: 'Y2 Label',\n                position: 'outer-middle'\n            }\n        }\n    }\n});\n\nc3.generate({\n    bindto: '#chart3_4',\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ],\n        axes: {\n            data2: 'y2'\n        },\n        types: {\n            data2: 'bar'\n        }\n    },\n    axis: {\n        y: {\n            label: {\n                text: 'Y Label',\n                position: 'outer-middle'\n            },\n            tick: {\n                format: d3.format(\"$,\")\n            }\n        },\n        y2: {\n            show: true,\n            label: {\n                text: 'Y2 Label',\n                position: 'outer-middle'\n            }\n        }\n    }\n});\n\nvar chart4_1 = c3.generate({\n    bindto: '#chart4_1',\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ]\n    }\n});\n\nfunction example4_1() {\n    chart4_1.load({\n        columns: [\n            ['data1', 300, 100, 250, 150, 300, 150, 500],\n            ['data2', 100, 200, 150, 50, 100, 250],\n            ['data3', 600, 700, 350, 450, 800, 550]\n        ]\n    });\n}\n\nvar chart4_2 = c3.generate({\n    bindto: '#chart4_2',\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25],\n            ['data3', 600, 700, 350, 450, 800, 550]\n        ]\n    }\n});\n\nfunction example4_2() {\n    chart4_2.unload({\n        ids: ['data2', 'data3']\n    });\n}\n\nvar chart4_3 = c3.generate({\n    bindto: '#chart4_3',\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25],\n            ['data3', 600, 700, 350, 450, 800, 550]\n        ]\n    }\n});\n\nfunction example4_3_1() {\n    chart4_3.show(['data2', 'data3']);\n}\nfunction example4_3_2() {\n    chart4_3.hide(['data2', 'data3']);\n}\n\nc3.generate({\n    bindto: '#chart5_1',\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25],\n            ['data3', 600, 700, 350, 450, 800, 550]\n        ]\n    }\n});\n"
  },
  {
    "path": "docs/js/highlight.pack.js",
    "content": "var hljs=new function(){function l(o){return o.replace(/&/gm,\"&amp;\").replace(/</gm,\"&lt;\").replace(/>/gm,\"&gt;\")}function b(p){for(var o=p.firstChild;o;o=o.nextSibling){if(o.nodeName==\"CODE\"){return o}if(!(o.nodeType==3&&o.nodeValue.match(/\\s+/))){break}}}function h(p,o){return Array.prototype.map.call(p.childNodes,function(q){if(q.nodeType==3){return o?q.nodeValue.replace(/\\n/g,\"\"):q.nodeValue}if(q.nodeName==\"BR\"){return\"\\n\"}return h(q,o)}).join(\"\")}function a(q){var p=(q.className+\" \"+q.parentNode.className).split(/\\s+/);p=p.map(function(r){return r.replace(/^language-/,\"\")});for(var o=0;o<p.length;o++){if(e[p[o]]||p[o]==\"no-highlight\"){return p[o]}}}function c(q){var o=[];(function p(r,s){for(var t=r.firstChild;t;t=t.nextSibling){if(t.nodeType==3){s+=t.nodeValue.length}else{if(t.nodeName==\"BR\"){s+=1}else{if(t.nodeType==1){o.push({event:\"start\",offset:s,node:t});s=p(t,s);o.push({event:\"stop\",offset:s,node:t})}}}}return s})(q,0);return o}function j(x,v,w){var p=0;var y=\"\";var r=[];function t(){if(x.length&&v.length){if(x[0].offset!=v[0].offset){return(x[0].offset<v[0].offset)?x:v}else{return v[0].event==\"start\"?x:v}}else{return x.length?x:v}}function s(A){function z(B){return\" \"+B.nodeName+'=\"'+l(B.value)+'\"'}return\"<\"+A.nodeName+Array.prototype.map.call(A.attributes,z).join(\"\")+\">\"}while(x.length||v.length){var u=t().splice(0,1)[0];y+=l(w.substr(p,u.offset-p));p=u.offset;if(u.event==\"start\"){y+=s(u.node);r.push(u.node)}else{if(u.event==\"stop\"){var o,q=r.length;do{q--;o=r[q];y+=(\"</\"+o.nodeName.toLowerCase()+\">\")}while(o!=u.node);r.splice(q,1);while(q<r.length){y+=s(r[q]);q++}}}}return y+l(w.substr(p))}function f(q){function o(s,r){return RegExp(s,\"m\"+(q.cI?\"i\":\"\")+(r?\"g\":\"\"))}function p(y,w){if(y.compiled){return}y.compiled=true;var s=[];if(y.k){var r={};function z(A,t){t.split(\" \").forEach(function(B){var C=B.split(\"|\");r[C[0]]=[A,C[1]?Number(C[1]):1];s.push(C[0])})}y.lR=o(y.l||hljs.IR,true);if(typeof y.k==\"string\"){z(\"keyword\",y.k)}else{for(var x in y.k){if(!y.k.hasOwnProperty(x)){continue}z(x,y.k[x])}}y.k=r}if(w){if(y.bWK){y.b=\"\\\\b(\"+s.join(\"|\")+\")\\\\s\"}y.bR=o(y.b?y.b:\"\\\\B|\\\\b\");if(!y.e&&!y.eW){y.e=\"\\\\B|\\\\b\"}if(y.e){y.eR=o(y.e)}y.tE=y.e||\"\";if(y.eW&&w.tE){y.tE+=(y.e?\"|\":\"\")+w.tE}}if(y.i){y.iR=o(y.i)}if(y.r===undefined){y.r=1}if(!y.c){y.c=[]}for(var v=0;v<y.c.length;v++){if(y.c[v]==\"self\"){y.c[v]=y}p(y.c[v],y)}if(y.starts){p(y.starts,w)}var u=[];for(var v=0;v<y.c.length;v++){u.push(y.c[v].b)}if(y.tE){u.push(y.tE)}if(y.i){u.push(y.i)}y.t=u.length?o(u.join(\"|\"),true):{exec:function(t){return null}}}p(q)}function d(D,E){function o(r,M){for(var L=0;L<M.c.length;L++){var K=M.c[L].bR.exec(r);if(K&&K.index==0){return M.c[L]}}}function s(K,r){if(K.e&&K.eR.test(r)){return K}if(K.eW){return s(K.parent,r)}}function t(r,K){return K.i&&K.iR.test(r)}function y(L,r){var K=F.cI?r[0].toLowerCase():r[0];return L.k.hasOwnProperty(K)&&L.k[K]}function G(){var K=l(w);if(!A.k){return K}var r=\"\";var N=0;A.lR.lastIndex=0;var L=A.lR.exec(K);while(L){r+=K.substr(N,L.index-N);var M=y(A,L);if(M){v+=M[1];r+='<span class=\"'+M[0]+'\">'+L[0]+\"</span>\"}else{r+=L[0]}N=A.lR.lastIndex;L=A.lR.exec(K)}return r+K.substr(N)}function z(){if(A.sL&&!e[A.sL]){return l(w)}var r=A.sL?d(A.sL,w):g(w);if(A.r>0){v+=r.keyword_count;B+=r.r}return'<span class=\"'+r.language+'\">'+r.value+\"</span>\"}function J(){return A.sL!==undefined?z():G()}function I(L,r){var K=L.cN?'<span class=\"'+L.cN+'\">':\"\";if(L.rB){x+=K;w=\"\"}else{if(L.eB){x+=l(r)+K;w=\"\"}else{x+=K;w=r}}A=Object.create(L,{parent:{value:A}});B+=L.r}function C(K,r){w+=K;if(r===undefined){x+=J();return 0}var L=o(r,A);if(L){x+=J();I(L,r);return L.rB?0:r.length}var M=s(A,r);if(M){if(!(M.rE||M.eE)){w+=r}x+=J();do{if(A.cN){x+=\"</span>\"}A=A.parent}while(A!=M.parent);if(M.eE){x+=l(r)}w=\"\";if(M.starts){I(M.starts,\"\")}return M.rE?0:r.length}if(t(r,A)){throw\"Illegal\"}w+=r;return r.length||1}var F=e[D];f(F);var A=F;var w=\"\";var B=0;var v=0;var x=\"\";try{var u,q,p=0;while(true){A.t.lastIndex=p;u=A.t.exec(E);if(!u){break}q=C(E.substr(p,u.index-p),u[0]);p=u.index+q}C(E.substr(p));return{r:B,keyword_count:v,value:x,language:D}}catch(H){if(H==\"Illegal\"){return{r:0,keyword_count:0,value:l(E)}}else{throw H}}}function g(s){var o={keyword_count:0,r:0,value:l(s)};var q=o;for(var p in e){if(!e.hasOwnProperty(p)){continue}var r=d(p,s);r.language=p;if(r.keyword_count+r.r>q.keyword_count+q.r){q=r}if(r.keyword_count+r.r>o.keyword_count+o.r){q=o;o=r}}if(q.language){o.second_best=q}return o}function i(q,p,o){if(p){q=q.replace(/^((<[^>]+>|\\t)+)/gm,function(r,v,u,t){return v.replace(/\\t/g,p)})}if(o){q=q.replace(/\\n/g,\"<br>\")}return q}function m(r,u,p){var v=h(r,p);var t=a(r);if(t==\"no-highlight\"){return}var w=t?d(t,v):g(v);t=w.language;var o=c(r);if(o.length){var q=document.createElement(\"pre\");q.innerHTML=w.value;w.value=j(o,c(q),v)}w.value=i(w.value,u,p);var s=r.className;if(!s.match(\"(\\\\s|^)(language-)?\"+t+\"(\\\\s|$)\")){s=s?(s+\" \"+t):t}r.innerHTML=w.value;r.className=s;r.result={language:t,kw:w.keyword_count,re:w.r};if(w.second_best){r.second_best={language:w.second_best.language,kw:w.second_best.keyword_count,re:w.second_best.r}}}function n(){if(n.called){return}n.called=true;Array.prototype.map.call(document.getElementsByTagName(\"pre\"),b).filter(Boolean).forEach(function(o){m(o,hljs.tabReplace)})}function k(){window.addEventListener(\"DOMContentLoaded\",n,false);window.addEventListener(\"load\",n,false)}var e={};this.LANGUAGES=e;this.highlight=d;this.highlightAuto=g;this.fixMarkup=i;this.highlightBlock=m;this.initHighlighting=n;this.initHighlightingOnLoad=k;this.IR=\"[a-zA-Z][a-zA-Z0-9_]*\";this.UIR=\"[a-zA-Z_][a-zA-Z0-9_]*\";this.NR=\"\\\\b\\\\d+(\\\\.\\\\d+)?\";this.CNR=\"(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)\";this.BNR=\"\\\\b(0b[01]+)\";this.RSR=\"!|!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|\\\\.|-|-=|/|/=|:|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\\\?|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~\";this.BE={b:\"\\\\\\\\[\\\\s\\\\S]\",r:0};this.ASM={cN:\"string\",b:\"'\",e:\"'\",i:\"\\\\n\",c:[this.BE],r:0};this.QSM={cN:\"string\",b:'\"',e:'\"',i:\"\\\\n\",c:[this.BE],r:0};this.CLCM={cN:\"comment\",b:\"//\",e:\"$\"};this.CBLCLM={cN:\"comment\",b:\"/\\\\*\",e:\"\\\\*/\"};this.HCM={cN:\"comment\",b:\"#\",e:\"$\"};this.NM={cN:\"number\",b:this.NR,r:0};this.CNM={cN:\"number\",b:this.CNR,r:0};this.BNM={cN:\"number\",b:this.BNR,r:0};this.inherit=function(q,r){var o={};for(var p in q){o[p]=q[p]}if(r){for(var p in r){o[p]=r[p]}}return o}}();hljs.LANGUAGES.javascript=function(a){return{k:{keyword:\"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const\",literal:\"true false null undefined NaN Infinity\"},c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{b:\"(\"+a.RSR+\"|\\\\b(case|return|throw)\\\\b)\\\\s*\",k:\"return throw case\",c:[a.CLCM,a.CBLCLM,{cN:\"regexp\",b:\"/\",e:\"/[gim]*\",i:\"\\\\n\",c:[{b:\"\\\\\\\\/\"}]},{b:\"<\",e:\">;\",sL:\"xml\"}],r:0},{cN:\"function\",bWK:true,e:\"{\",k:\"function\",c:[{cN:\"title\",b:\"[A-Za-z$_][0-9A-Za-z$_]*\"},{cN:\"params\",b:\"\\\\(\",e:\"\\\\)\",c:[a.CLCM,a.CBLCLM],i:\"[\\\"'\\\\(]\"}],i:\"\\\\[|%\"}]}}(hljs);"
  },
  {
    "path": "docs/js/index.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250, 50, 100, 250]\n        ],\n        selection: {\n            enabled: true\n        }\n    }\n});\n\nvar defaultMessage = $('#message').html(), currentIndex = 0, timer, duration = 1500, demos = [\n    function () {\n        chart.load({\n            columns: [['data2', 100, 30, 200, 320, 50, 150, 230, 80, 150]]\n        })\n        setMessage('Load data2');\n    },\n    function () {\n        chart.load({\n            columns: [['data3', 70, 90, 170, 220, 100, 110, 130, 40, 50]]\n        })\n        setMessage('Load data3');\n    },\n    function () {\n        chart.select(['data1'], [2]);\n        setMessage('Select point for index 2 of data1');\n    },\n    function () {\n        chart.select(['data1'], [4,6]);\n        setMessage('Select point for index 4,6 of data1');\n    },\n    function () {\n        chart.unselect();\n        setMessage('Unselect points');\n    },\n    function () {\n        chart.focus('data2');\n        setMessage('Focus on data2');\n    },\n    function () {\n        chart.focus('data3');\n        setMessage('Focus on data3');\n    },\n    function () {\n        chart.revert();\n        setMessage('Defocus');\n    },\n    function () {\n        chart.load({\n            columns: [['data1', 300, 230, 400, 520, 230, 250, 330, 280, 250]]\n        })\n        setMessage('Update data1');\n    },\n    function () {\n        chart.load({\n            columns: [['data2', 30, 50, 90, 120, 40, 50, 80, 70, 50]]\n        })\n        setMessage('Update data2');\n    },\n    function () {\n        chart.regions([{start:1,end:3}]);\n        setMessage('Add region from 1 to 3');\n        },\n    function () {\n        chart.regions.add([{start:6}]);\n        setMessage('Add region from 6 to end');\n    },\n    function () {\n        chart.regions([]);\n        setMessage('Clear regions');\n    },\n    function () {\n        chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);\n        setMessage('Add x grid lines for 1, 4');\n    },\n    function () {\n        chart.ygrids.add([{value: 450, text:'Label 450'}]);\n        setMessage('Add y grid lines for 450');\n    },\n    function () {\n        chart.xgrids.remove({value: 1});\n        chart.xgrids.remove({value: 4});\n        setMessage('Remove grid lines for 1, 4');\n    },\n    function () {\n        chart.ygrids.remove({value: 450});\n        setMessage('Remove grid line for 450');\n    },\n    function () {\n        chart.transform('bar');\n        setMessage('Show as bar chart');\n    },\n    function () {\n        chart.groups([['data2','data3']]);\n        setMessage('Grouping data2 and data3');\n    },\n    function () {\n        chart.groups([['data1', 'data2', 'data3']]);\n        setMessage('Grouping data1, data2 and data3');\n    },\n    function () {\n        chart.groups([['data2', 'data3']]);\n        chart.transform('line', 'data1');\n        setMessage('Show data1 as line');\n    },\n    function () {\n        chart.unload({\n            ids: 'data3'\n        });\n        setMessage('Unload data3');\n    },\n    function () {\n        chart.unload({\n            ids: 'data2'\n        });\n        setMessage('Unload data2');\n    },\n    function () {\n        chart.flow({\n            columns: [\n                ['data1', 390, 400, 200, 500]\n            ],\n            duration: 1000,\n        });\n        setMessage('Flow 4 data');\n    },\n    function () {\n        // wait for end of transition for flow\n    },\n    function () {\n        chart.flow({\n            columns: [\n                ['data1', 190, 230]\n            ],\n        });\n        setMessage('Flow 2 data');\n    },\n    function () {\n        // wait for end of transition for flow\n    },\n    function () {\n        chart.transform('line', ['data1', 'data2', 'data3']);\n        chart.groups([['data1'], ['data2'], ['data3']]);\n        chart.load({\n            columns: [['data1', 30, 200, 100, 400, 150, 250, 50, 100, 250]]\n        })\n        setMessage('Starting Demo..');\n    }\n];\n\nfunction setMessage(message) {\n    document.getElementById('message').innerHTML = '<a id=\"demoMessage\" class=\"button small secondary\" onclick=\"stopDemo();\" title=\"Stop Demo\" onclick=\"stopDemo();\">'+message+'</button>';\n//        $('#demoMessage').tooltip('toggle');\n}\n\nfunction startDemo() {\n    setMessage('Starting Demo..');\n    timer = setInterval(function(){\n        if (currentIndex == demos.length) currentIndex = 0;\n        demos[currentIndex++]();\n    }, duration);\n}\n\nfunction stopDemo() {\n    clearInterval(timer);\n    document.getElementById('message').innerHTML = defaultMessage;\n}\n"
  },
  {
    "path": "docs/js/main.js",
    "content": "\n"
  },
  {
    "path": "docs/js/plugins.js",
    "content": "// Avoid `console` errors in browsers that lack a console.\nif (!(window.console && console.log)) {\n    (function() {\n        var noop = function() {};\n        var methods = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'markTimeline', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'];\n        var length = methods.length;\n        var console = window.console = {};\n        while (length--) {\n            console[methods[length]] = noop;\n        }\n    }());\n}\n\n// Place any jQuery/helper plugins in here.\n"
  },
  {
    "path": "docs/js/samples/api_axis_label.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ],\n        axes: {\n            data1: 'y',\n            data2: 'y2'\n        }\n    },\n    axis: {\n        y: {\n            label: 'Y Axis Label'\n        },\n        y2: {\n            show: true,\n            label: 'Y2 Axis Label'\n        }\n    }\n});\n\nsetTimeout(function () {\n    chart.axis.labels({y2: 'New Y2 Axis Label'});\n}, 1000);\n\nsetTimeout(function () {\n    chart.axis.labels({y: 'New Y Axis Label', y2: 'New Y2 Axis Label Again'});\n}, 2000);\n"
  },
  {
    "path": "docs/js/samples/api_axis_range.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ],\n        axes: {\n            data1: 'y',\n            data2: 'y2'\n        }\n    },\n    axis: {\n        y2: {\n            show: true,\n        }\n    }\n});\n\nsetTimeout(function () {\n    chart.axis.max(500);\n}, 1000);\n\nsetTimeout(function () {\n    chart.axis.min(-500);\n}, 2000);\n\nsetTimeout(function () {\n    chart.axis.max({y: 600, y2: 100});\n}, 3000);\n\nsetTimeout(function () {\n    chart.axis.min({y: -600, y2: -100});\n}, 4000);\n\nsetTimeout(function () {\n    chart.axis.range({max: 1000, min: -1000});\n}, 5000);\n\nsetTimeout(function () {\n    chart.axis.range({max: {y: 600, y2: 100}, min: {y: -100, y2: 0}});\n}, 6000);\n\nsetTimeout(function () {\n    chart.axis.max({x: 10});\n}, 7000);\n\nsetTimeout(function () {\n    chart.axis.min({x: -10});\n}, 8000);\n\nsetTimeout(function () {\n    chart.axis.range({max: {x: 5}, min: {x: 0}});\n}, 9000);\n"
  },
  {
    "path": "docs/js/samples/api_data_color.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n            ['data2', 200, 130, 90, 240, 130, 220],\n            ['data3', 300, 200, 160, 400, 250, 250]\n        ],\n        type: 'bar',\n        colors: {\n            data1: '#ff0000',\n            data2: '#00ff00',\n            data3: '#0000ff'\n        },\n        labels: true\n    }\n});\n\nsetTimeout(function () {\n    chart.data.colors({\n        data1: d3.rgb('#ff0000').darker(1),\n        data2: d3.rgb('#00ff00').darker(1),\n        data3: d3.rgb('#0000ff').darker(1),\n    });\n}, 1000);\n\nsetTimeout(function () {\n    chart.data.colors({\n        data1: d3.rgb('#ff0000').darker(2),\n        data2: d3.rgb('#00ff00').darker(2),\n        data3: d3.rgb('#0000ff').darker(2),\n    });\n}, 2000);\n"
  },
  {
    "path": "docs/js/samples/api_data_name.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ],\n        names: {\n            data1: 'Name 1',\n            data2: 'Name 2'\n        }\n    }\n});\n\nsetTimeout(function () {\n    chart.data.names({data1: 'New name for data1', data2: 'New name for data2'});\n}, 1000);\n\nsetTimeout(function () {\n    chart.data.names({data1: 'New name for data1 again'});\n}, 2000);\n\n"
  },
  {
    "path": "docs/js/samples/api_flow.js",
    "content": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        columns: [\n            ['x', '2012-12-29', '2012-12-30', '2012-12-31'],\n            ['data1', 230, 300, 330],\n            ['data2', 190, 230, 200],\n            ['data3', 90, 130, 180],\n        ]\n    },\n    axis: {\n        x: {\n            type: 'timeseries',\n            tick: {\n                format: '%m/%d',\n            }\n        }\n    }\n});\n\nsetTimeout(function () {\n    chart.flow({\n        columns: [\n            ['x', '2013-01-11', '2013-01-21'],\n            ['data1', 500, 200],\n            ['data2', 100, 300],\n            ['data3', 200, 120],\n        ],\n        duration: 1500,\n        done: function () {\n            chart.flow({\n                columns: [\n                    ['x', '2013-02-11', '2013-02-12', '2013-02-13', '2013-02-14'],\n                    ['data1', 200, 300, 100, 250],\n                    ['data2', 100, 90, 40, 120],\n                    ['data3', 100, 100, 300, 500]\n                ],\n                length: 0,\n                duration: 1500,\n                done: function () {\n                    chart.flow({\n                        columns: [\n                            ['x', '2013-03-01', '2013-03-02'],\n                            ['data1', 200, 300],\n                            ['data2', 150, 250],\n                            ['data3', 100, 100]\n                        ],\n                        length: 2,\n                        duration: 1500,\n                        done: function () {\n                            chart.flow({\n                                columns: [\n                                    ['x', '2013-03-21', '2013-04-01'],\n                                    ['data1', 500, 200],\n                                    ['data2', 100, 150],\n                                    ['data3', 200, 400]\n                                ],\n                                to: '2013-03-01',\n                                duration: 1500,\n                            });\n                        }\n                    });\n                }\n            });\n        },\n    });\n}, 1000);\n"
  },
  {
    "path": "docs/js/samples/api_grid_x.js",
    "content": "var chart = c3.generate({\n    bindto: '#chart',\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n    }\n});\n\nsetTimeout(function () {\n    chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);\n}, 1000);\n\nsetTimeout(function () {\n    chart.xgrids([{value: 2, text:'Label 2'}]);\n}, 2000);\n\nsetTimeout(function () {\n    chart.xgrids.add([{value: 3, text:'Label 3', class:'hoge'}]);\n}, 3000);\n\nsetTimeout(function () {\n    chart.xgrids.remove({value:2});\n}, 4000);\n\nsetTimeout(function () {\n    chart.xgrids.remove({class:'hoge'});\n}, 5000);\n\nsetTimeout(function () {\n    chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);\n}, 6000);\n\nsetTimeout(function () {\n    chart.xgrids.remove();\n}, 7000);\n"
  },
  {
    "path": "docs/js/samples/api_resize.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ]\n    }\n});\n\nsetTimeout(function () {\n    chart.resize({height:100, width:300})\n}, 1000);\n\nsetTimeout(function () {\n    chart.resize({height:200})\n}, 2000);\n\nsetTimeout(function () {\n    chart.resize();\n}, 3000);"
  },
  {
    "path": "docs/js/samples/axes_label.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250],\n            ['sample2', 130, 300, 200, 500, 250, 350]\n        ],\n        axes: {\n            sample2: 'y2'\n        }\n    },\n    axis: {\n        x: {\n            label: 'X Label'\n        },\n        y: {\n            label: 'Y Label'\n        },\n        y2: {\n            show: true,\n            label: 'Y2 Label'\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_label_position.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample1', 30, 200, 100, 400, 150, 250],\n            ['sample2', 430, 300, 500, 400, 650, 250]\n        ],\n        axes: {\n            sample1: 'y',\n            sample2: 'y2'\n        }\n    },\n    axis: {\n        x: {\n            label: {\n                text: 'X Label',\n                position: 'outer-center'\n                // inner-right : default\n                // inner-center\n                // inner-left\n                // outer-right\n                // outer-center\n                // outer-left\n            }\n        },\n        y: {\n            label: {\n                text: 'Y Label',\n                position: 'outer-middle'\n                // inner-top : default\n                // inner-middle\n                // inner-bottom\n                // outer-top\n                // outer-middle\n                // outer-bottom\n            }\n        },\n        y2: {\n            show: true,\n            label: {\n                text: 'Y2 Label',\n                position: 'outer-middle'\n                // inner-top : default\n                // inner-middle\n                // inner-bottom\n                // outer-top\n                // outer-middle\n                // outer-bottom\n            }\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_rotated.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ],\n        types: {\n            data1: 'bar',\n        }\n    },\n    axis: {\n        rotated: true\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_x_localtime.js",
    "content": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        xFormat: '%Y',\n        columns: [\n//            ['x', '2012-12-31', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05'],\n            ['x', '2010', '2011', '2012', '2013', '2014', '2015'],\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 340, 200, 500, 250, 350]\n        ]\n    },\n    axis: {\n        x: {\n            type: 'timeseries',\n            // if true, treat x value as localtime (Default)\n            // if false, convert to UTC internally\n            localtime: false,\n            tick: {\n                format: '%Y-%m-%d %H:%M:%S'\n            }\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_x_tick_count.js",
    "content": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        columns: [\n            ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06', '2013-01-07', '2013-01-08', '2013-01-09', '2013-01-10', '2013-01-11', '2013-01-12'],\n            ['sample', 30, 200, 100, 400, 150, 250, 30, 200, 100, 400, 150, 250]\n        ]\n    },\n    axis: {\n        x: {\n            type: 'timeseries',\n            tick: {\n                count: 4,\n                format: '%Y-%m-%d'\n            }\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_x_tick_culling.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250, 30, 200, 100, 400, 150, 250, 30, 200, 100, 400, 150, 250, 200, 100, 400, 150, 250]\n        ]\n    },\n    axis: {\n        x: {\n            type: 'category',\n            tick: {\n                culling: {\n                    max: 4 // the number of tick texts will be adjusted to less than this value\n                }\n                // for normal axis, default on\n                // for category axis, default off\n            }\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_x_tick_fit.js",
    "content": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        columns: [\n            ['x', '2013-10-31', '2013-12-31', '2014-01-31', '2014-02-28'],\n            ['sample', 30, 100, 400, 150],\n        ]\n    },\n    axis : {\n        x : {\n            type : 'timeseries',\n            tick: {\n                fit: true,\n                format: \"%e %b %y\"\n            }\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_x_tick_format.js",
    "content": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        columns: [\n            ['x', '2010-01-01', '2011-01-01', '2012-01-01', '2013-01-01', '2014-01-01', '2015-01-01'],\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n    },\n    axis : {\n        x : {\n            type : 'timeseries',\n            tick: {\n                format: function (x) { return x.getFullYear(); }\n              //format: '%Y' // format string is also available for timeseries data\n            }\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_x_tick_rotate.js",
    "content": "var chart = c3.generate({\n    data: {\n        x : 'x',\n        columns: [\n            ['x', 'www.somesitename1.com', 'www.somesitename2.com', 'www.somesitename3.com', 'www.somesitename4.com', 'www.somesitename5.com', 'www.somesitename6.com', 'www.somesitename7.com', 'www.somesitename8.com', 'www.somesitename9.com', 'www.somesitename10.com', 'www.somesitename11.com', 'www.somesitename12.com'],\n            ['pv', 90, 100, 140, 200, 100, 400, 90, 100, 140, 200, 100, 400],\n        ],\n        type: 'bar'\n    },\n    axis: {\n        x: {\n            type: 'category',\n            tick: {\n                rotate: 75,\n                multiline: false\n            },\n            height: 130\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_x_tick_values.js",
    "content": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        columns: [\n            ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06', '2013-01-07', '2013-01-08', '2013-01-09', '2013-01-10', '2013-01-11', '2013-01-12'],\n            ['sample', 30, 200, 100, 400, 150, 250, 30, 200, 100, 400, 150, 250]\n        ]\n    },\n    axis: {\n        x: {\n            type: 'timeseries',\n            tick: {\n                // this also works for non timeseries data\n                values: ['2013-01-05', '2013-01-10']\n            }\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_y2.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ],\n        axes: {\n            data1: 'y',\n            data2: 'y2'\n        }\n    },\n    axis: {\n        y2: {\n            show: true\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_y_padding.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ],\n        axes: {\n            data1: 'y',\n            data2: 'y2'\n        }\n    },\n    axis: {\n        y: {\n            padding: {top: 200, bottom: 0}\n        },\n        y2: {\n            padding: {top: 100, bottom: 100},\n            show: true\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_y_range.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n    },\n    axis: {\n        y: {\n            max: 400,\n            min: -400,\n            // Range includes padding, set 0 if no padding needed\n            // padding: {top:0, bottom:0}\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/axes_y_tick_format.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 2500]\n        ]\n    },\n    axis : {\n        y : {\n            tick: {\n                format: d3.format(\"$,\")\n//                format: function (d) { return \"$\" + d; }\n            }\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/categorized.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250, 50, 100, 250]\n        ]\n    },\n    axis: {\n        x: {\n            type: 'category',\n            categories: ['cat1', 'cat2', 'cat3', 'cat4', 'cat5', 'cat6', 'cat7', 'cat8', 'cat9']\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/chart_area.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 300, 350, 300, 0, 0, 0],\n            ['data2', 130, 100, 140, 200, 150, 50]\n        ],\n        types: {\n            data1: 'area',\n            data2: 'area-spline'\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/chart_area_stacked.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 300, 350, 300, 0, 0, 120],\n            ['data2', 130, 100, 140, 200, 150, 50]\n        ],\n        types: {\n            data1: 'area-spline',\n            data2: 'area-spline'\n            // 'line', 'spline', 'step', 'area', 'area-step' are also available to stack\n        },\n        groups: [['data1', 'data2']]\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/chart_bar.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 140, 200, 150, 50]\n        ],\n        type: 'bar'\n    },\n    bar: {\n        width: {\n            ratio: 0.5 // this makes bar width 50% of length between ticks\n        }\n        // or\n        //width: 100 // this makes bar width 100px\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['data3', 130, -150, 200, 300, -200, 100]\n        ]\n    });\n}, 1000);"
  },
  {
    "path": "docs/js/samples/chart_bar_stacked.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', -30, 200, 200, 400, -150, 250],\n            ['data2', 130, 100, -100, 200, -150, 50],\n            ['data3', -230, 200, 200, -300, 250, 250]\n        ],\n        type: 'bar',\n        groups: [\n            ['data1', 'data2']\n        ]\n    },\n    grid: {\n        y: {\n            lines: [{value:0}]\n        }\n    }\n});\n\nsetTimeout(function () {\n    chart.groups([['data1', 'data2', 'data3']])\n}, 1000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [['data4', 100, -50, 150, 200, -300, -100]]\n    });\n}, 1500);\n\nsetTimeout(function () {\n    chart.groups([['data1', 'data2', 'data3', 'data4']])\n}, 2000);\n"
  },
  {
    "path": "docs/js/samples/chart_combination.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n            ['data2', 200, 130, 90, 240, 130, 220],\n            ['data3', 300, 200, 160, 400, 250, 250],\n            ['data4', 200, 130, 90, 240, 130, 220],\n            ['data5', 130, 120, 150, 140, 160, 150],\n            ['data6', 90, 70, 20, 50, 60, 120],\n        ],\n        type: 'bar',\n        types: {\n            data3: 'spline',\n            data4: 'line',\n            data6: 'area',\n        },\n        groups: [\n            ['data1','data2']\n        ]\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/chart_donut.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30],\n            ['data2', 120],\n        ],\n        type : 'donut',\n        onclick: function (d, i) { console.log(\"onclick\", d, i); },\n        onmouseover: function (d, i) { console.log(\"onmouseover\", d, i); },\n        onmouseout: function (d, i) { console.log(\"onmouseout\", d, i); }\n    },\n    donut: {\n        title: \"Iris Petal Width\"\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            [\"setosa\", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],\n            [\"versicolor\", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],\n            [\"virginica\", 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8],\n        ]\n    });\n}, 1500);\n\nsetTimeout(function () {\n    chart.unload({\n        ids: 'data1'\n    });\n    chart.unload({\n        ids: 'data2'\n    });\n}, 2500);\n"
  },
  {
    "path": "docs/js/samples/chart_gauge.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data', 91.4]\n        ],\n        type: 'gauge',\n        onclick: function (d, i) { console.log(\"onclick\", d, i); },\n        onmouseover: function (d, i) { console.log(\"onmouseover\", d, i); },\n        onmouseout: function (d, i) { console.log(\"onmouseout\", d, i); }\n    },\n    gauge: {\n//        label: {\n//            format: function(value, ratio) {\n//                return value;\n//            },\n//            show: false // to turn off the min/max labels.\n//        },\n//    min: 0, // 0 is default, //can handle negative min e.g. vacuum / voltage / current flow / rate of change\n//    max: 100, // 100 is default\n//    units: ' %',\n//    width: 39 // for adjusting arc thickness\n    },\n    color: {\n        pattern: ['#FF0000', '#F97600', '#F6C600', '#60B044'], // the three color levels for the percentage values.\n        threshold: {\n//            unit: 'value', // percentage is default\n//            max: 200, // 100 is default\n            values: [30, 60, 90, 100]\n        }\n    },\n    size: {\n        height: 180\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        columns: [['data', 10]]\n    });\n}, 1000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [['data', 50]]\n    });\n}, 2000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [['data', 70]]\n    });\n}, 3000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [['data', 0]]\n    });\n}, 4000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [['data', 100]]\n    });\n}, 5000);\n"
  },
  {
    "path": "docs/js/samples/chart_pie.js",
    "content": "var chart = c3.generate({\n    data: {\n        // iris data from R\n        columns: [\n            ['data1', 30],\n            ['data2', 120],\n        ],\n        type : 'pie',\n        onclick: function (d, i) { console.log(\"onclick\", d, i); },\n        onmouseover: function (d, i) { console.log(\"onmouseover\", d, i); },\n        onmouseout: function (d, i) { console.log(\"onmouseout\", d, i); }\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            [\"setosa\", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],\n            [\"versicolor\", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],\n            [\"virginica\", 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8],\n        ]\n    });\n}, 1500);\n\nsetTimeout(function () {\n    chart.unload({\n        ids: 'data1'\n    });\n    chart.unload({\n        ids: 'data2'\n    });\n}, 2500);\n"
  },
  {
    "path": "docs/js/samples/chart_scatter.js",
    "content": "var chart = c3.generate({\n    data: {\n        xs: {\n            setosa: 'setosa_x',\n            versicolor: 'versicolor_x',\n        },\n        // iris data from R\n        columns: [\n            [\"setosa_x\", 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.4, 3.0, 3.0, 4.0, 4.4, 3.9, 3.5, 3.8, 3.8, 3.4, 3.7, 3.6, 3.3, 3.4, 3.0, 3.4, 3.5, 3.4, 3.2, 3.1, 3.4, 4.1, 4.2, 3.1, 3.2, 3.5, 3.6, 3.0, 3.4, 3.5, 2.3, 3.2, 3.5, 3.8, 3.0, 3.8, 3.2, 3.7, 3.3],\n            [\"versicolor_x\", 3.2, 3.2, 3.1, 2.3, 2.8, 2.8, 3.3, 2.4, 2.9, 2.7, 2.0, 3.0, 2.2, 2.9, 2.9, 3.1, 3.0, 2.7, 2.2, 2.5, 3.2, 2.8, 2.5, 2.8, 2.9, 3.0, 2.8, 3.0, 2.9, 2.6, 2.4, 2.4, 2.7, 2.7, 3.0, 3.4, 3.1, 2.3, 3.0, 2.5, 2.6, 3.0, 2.6, 2.3, 2.7, 3.0, 2.9, 2.9, 2.5, 2.8],\n            [\"setosa\", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],\n            [\"versicolor\", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],\n        ],\n        type: 'scatter'\n    },\n    axis: {\n        x: {\n            label: 'Sepal.Width',\n            tick: {\n                fit: false\n            }\n        },\n        y: {\n            label: 'Petal.Width'\n        }\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        xs: {\n            virginica: 'virginica_x'\n        },\n        columns: [\n            [\"virginica_x\", 3.3, 2.7, 3.0, 2.9, 3.0, 3.0, 2.5, 2.9, 2.5, 3.6, 3.2, 2.7, 3.0, 2.5, 2.8, 3.2, 3.0, 3.8, 2.6, 2.2, 3.2, 2.8, 2.8, 2.7, 3.3, 3.2, 2.8, 3.0, 2.8, 3.0, 2.8, 3.8, 2.8, 2.8, 2.6, 3.0, 3.4, 3.1, 3.0, 3.1, 3.1, 3.1, 2.7, 3.2, 3.3, 3.0, 2.5, 3.0, 3.4, 3.0],\n            [\"virginica\", 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8],\n        ]\n    });\n}, 1000);\n\nsetTimeout(function () {\n    chart.unload({\n        ids: 'setosa'\n    });\n}, 2000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            [\"virginica\", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],\n        ]\n    });\n}, 3000);\n"
  },
  {
    "path": "docs/js/samples/chart_spline.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 140, 200, 150, 50]\n        ],\n        type: 'spline'\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/chart_stanford.js",
    "content": "// More samples available at:\n// - htdocs/samples/chart_stanford.html\n// - htdocs/samples/chart_stanford_custom_elements.html\n\nvar chart = c3.generate({\n    data: {\n        x: 'HPE',\n        epochs: 'Epochs',\n        columns: [\n            ['HPE', 2.5, 2.5, 2.5, 2.5, 2.5, 3, 3, 3, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5.5, 5.5, 5.5, 2, 2.5, 2.5, 3, 3, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 4, 4, 4, 4, 4, 4.5, 4.5, 4.5, 4.5, 4.5, 5, 5, 5, 5, 5, 5, 5.5, 5.5, 2.5, 3, 3, 3.5, 3.5, 3.5, 3.5, 4, 4, 4, 4, 4, 4.5, 4.5, 4.5, 5, 5, 5, 5, 5, 5, 5.5, 5.5, 5.5, 5.5, 2.5, 2.5, 2.5, 3, 3.5, 3.5, 3.5, 3.5, 3.5, 4, 4.5, 4.5, 4.5, 4.5, 4.5, 5, 5, 5, 5.5, 2, 3.5, 3.5, 3.5, 3.5, 3.5, 4, 4.5, 4.5, 4.5, 4.5, 5, 2, 2, 3, 3, 3.5, 3.5, 3.5, 3.5, 4, 4, 4, 4, 5, 2, 3, 3, 3.5, 3.5, 3.5, 3.5, 4, 4.5, 5, 5, 5, 5.5, 5.5, 2.5, 3, 3, 3, 3.5, 4, 2.5, 3, 3.5, 4, 4, 4.5, 5, 3.5, 4, 4, 4, 4, 4.5, 3.5, 4, 4.5, 5, 5, 2.5, 3, 3.5, 3.5, 4, 4.5, 4.5, 4, 5, 3, 4, 4, 2, 4.5, 3.5, 2.5, 3.5, 4, 4, 2.5, 2.5, 3, 3, 4, 4.5, 5, 5, 4.5, 2.5, 3, 4, 3, 3.5, 3.5, 4, 2.5, 3.5, 2.5, 3.5, 2.5, 2.5, 3.5, 2.5, 4.5, 3, 4, 2.5, 4.5, 2.5, 4, 4, 2.5, 3, 3.5, 2.5, 3.5, 3.5, 3.5, 2.5, 3.5, 3.5, 4, 4, 3.5, 4, 4, 4],\n            ['HPL', 24.5, 24, 27.5, 56.5, 26.5, 26, 51.5, 50, 39, 39.5, 54, 48.5, 54.5, 53, 52, 13.5, 16.5, 15.5, 14.5, 19, 19.5, 41, 40, 42.5, 40.5, 41.5, 30, 56, 47, 11.5, 11, 12, 14.5, 55, 56.5, 54, 55.5, 56, 48.5, 19, 56, 56.5, 53.5, 51.5, 52, 31.5, 36.5, 38.5, 22, 21, 22.5, 37, 38, 38.5, 11, 55, 14.5, 12.5, 56, 22, 11, 48, 12.5, 14, 17, 13.5, 43, 55.5, 53.5, 10.5, 49.5, 54.5, 51.5, 19.5, 24, 52.5, 49.5, 47, 45.5, 46, 20, 34.5, 37.5, 28, 10, 26.5, 22.5, 13, 18.5, 20, 29, 39.5, 48.5, 50.5, 19.5, 29, 27.5, 52.5, 50.5, 53, 37, 36, 34.5, 20.5, 31.5, 33, 32, 36, 29, 28.5, 31.5, 29, 30, 11.5, 49, 52.5, 20.5, 49.5, 28, 24.5, 53, 50, 23.5, 47.5, 38, 35, 34, 12, 21, 36.5, 51, 12, 58.5, 36.5, 28.5, 51, 50.5, 20, 50, 56, 55, 29.5, 28.5, 23, 17.5, 38.5, 57.5, 29.5, 38.5, 49, 52.5, 34, 11.5, 27, 30, 10, 51.5, 50.5, 18, 20.5, 23, 49, 51, 48, 33.5, 32.5, 27, 28, 25.5, 57.5, 10.5, 52, 29.5, 27.5, 50, 28.5, 51.5, 21.5, 35.5, 49.5, 37.5, 39, 50, 51, 22.5, 58, 20, 25.5, 48.5, 32, 30, 24.5, 23.5, 29.5, 23, 25, 21, 38, 32.5, 12, 22, 37, 55.5, 22, 38, 55.5, 29, 23.5, 21, 12.5, 14, 11.5, 56.5, 21.5, 20.5, 33, 33.5, 27, 13, 10.5, 22.5, 57, 24, 28.5, 28, 10, 37, 56, 37.5, 11, 10.5, 28, 13.5, 26, 11, 27.5, 12, 26.5, 26, 24.5, 24, 25, 25, 25, 11.5, 25.5, 26.5, 26, 25.5, 27.5, 27, 25, 27, 24.5, 26, 26.5, 25.5],\n            ['Epochs', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 22, 23, 23, 23, 24, 24, 24, 24, 25, 28, 29, 29, 36, 38, 39, 43, 44, 47, 50, 54, 54, 59, 62, 62, 70, 70, 81, 84, 85, 86, 88, 89, 93, 94, 95, 106, 110, 111, 115, 170]\n        ],\n        type: 'stanford',\n    },\n    legend: {\n        hide: true\n    },\n    point: {\n        focus: {\n            expand: {\n                r: 5\n            }\n        },\n        r: 2\n    },\n    axis: {\n        x: {\n            show: true,\n            label: {\n                text: 'HPE (m)',\n                position: 'outer-center'\n            },\n            min: 0,\n            max: 61,\n            tick: {\n                values: d3.range(0, 65, 10)\n            },\n            padding: {\n                top: 0,\n                bottom: 0,\n                left: 0,\n                right: 0\n            },\n        },\n        y: {\n            show: true,\n            label: {\n                text: 'HPL (m)',\n                position: 'outer-middle'\n            },\n            min: 0,\n            max: 60,\n            tick: {\n                values: d3.range(0, 65, 10)\n            },\n            padding: {\n                top: 5,\n                bottom: 0,\n                left: 0,\n                right: 0\n            },\n        }\n    },\n    stanford: {\n        scaleMin: 1,\n        scaleMax: 10000,\n        scaleFormat: 'pow10',\n        padding: {\n            top: 15,\n            right: 0,\n            bottom: 0,\n            left: 0\n        }\n    }\n});\n\n"
  },
  {
    "path": "docs/js/samples/chart_step.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 300, 350, 300, 0, 0, 100],\n            ['data2', 130, 100, 140, 200, 150, 50]\n        ],\n        types: {\n            data1: 'step',\n            data2: 'area-step'\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/data_color.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n            ['data2', 200, 130, 90, 240, 130, 220],\n            ['data3', 300, 200, 160, 400, 250, 250]\n        ],\n        type: 'bar',\n        colors: {\n            data1: '#ff0000',\n            data2: '#00ff00',\n            data3: '#0000ff'\n        },\n        color: function (color, d) {\n            // d will be 'id' when called for legends\n            return d.id && d.id === 'data3' ? d3.rgb(color).darker(d.value / 150) : color;\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/data_columned.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n            ['data2', 200, 130, 90, 240, 130, 220],\n            ['data3', 300, 200, 160, 400, 250, 250]\n        ]\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/data_json.js",
    "content": "var chart = c3.generate({\n    data: {\n        json: {\n            data1: [30, 20, 50, 40, 60, 50],\n            data2: [200, 130, 90, 240, 130, 220],\n            data3: [300, 200, 160, 400, 250, 250]\n        }\n    }\n});\n\nsetTimeout(function () {\n    chart = c3.generate({\n        data: {\n            json: [\n                {name: 'www.site1.com', upload: 200, download: 200, total: 400},\n                {name: 'www.site2.com', upload: 100, download: 300, total: 400},\n                {name: 'www.site3.com', upload: 300, download: 200, total: 500},\n                {name: 'www.site4.com', upload: 400, download: 100, total: 500},\n            ],\n            keys: {\n//                x: 'name', // it's possible to specify 'x' when category axis\n                value: ['upload', 'download'],\n            }\n        },\n        axis: {\n            x: {\n//                type: 'category'\n            }\n        }\n    });\n}, 1000);\n\nsetTimeout(function () {\n    chart.load({\n        json: [\n            {name: 'www.site1.com', upload: 800, download: 500, total: 400},\n            {name: 'www.site2.com', upload: 600, download: 600, total: 400},\n            {name: 'www.site3.com', upload: 400, download: 800, total: 500},\n            {name: 'www.site4.com', upload: 400, download: 700, total: 500},\n        ],\n        keys: {\n            value: ['upload', 'download'],\n        }\n    });\n}, 2000);\n"
  },
  {
    "path": "docs/js/samples/data_label.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, -200, -100, 400, 150, 250],\n            ['data2', -50, 150, -150, 150, -50, -150],\n            ['data3', -100, 100, -40, 100, -150, -50]\n        ],\n        groups: [\n            ['data1', 'data2']\n        ],\n        type: 'bar',\n        labels: true\n    },\n    grid: {\n        y: {\n            lines: [{value: 0}]\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/data_label_format.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, -200, -100, 400, 150, 250],\n            ['data2', -50, 150, -150, 150, -50, -150],\n            ['data3', -100, 100, -40, 100, -150, -50]\n        ],\n        groups: [\n            ['data1', 'data2']\n        ],\n        type: 'bar',\n        labels: {\n//            format: function (v, id, i, j) { return \"Default Format\"; },\n            format: {\n                data1: d3.format('$'),\n//                data1: function (v, id, i, j) { return \"Format for data1\"; },\n            }\n        }\n    },\n    grid: {\n        y: {\n            lines: [{value: 0}]\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/data_load.js",
    "content": "var chart = c3.generate({\n    data: {\n        url: '/data/c3_test.csv',\n        type: 'line'\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        url: '/data/c3_test2.csv'\n    });\n}, 1000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['data1', 130, 120, 150, 140, 160, 150],\n            ['data4', 30, 20, 50, 40, 60, 50],\n        ],\n        unload: ['data2', 'data3'],\n    });\n}, 2000);\n\nsetTimeout(function () {\n    chart.load({\n        rows: [\n            ['data2', 'data3'],\n            [120, 300],\n            [160, 240],\n            [200, 290],\n            [160, 230],\n            [130, 300],\n            [220, 320],\n        ],\n        unload: 'data4',\n    });\n}, 3000);\n\nsetTimeout(function () {\n    chart.load({\n        columns:[\n            ['data4', 30, 20, 50, 40, 60, 50,100,200]\n        ],\n        type: 'bar'\n    });\n}, 4000);\n\nsetTimeout(function () {\n    chart.unload({\n        ids: 'data4'\n    });\n}, 5000);\n\nsetTimeout(function () {\n    chart.load({\n        columns:[\n            ['data2', null, 30, 20, 50, 40, 60, 50]\n        ]\n    });\n}, 6000);\n\nsetTimeout(function () {\n    chart.unload();\n}, 7000);\n\nsetTimeout(function () {\n    chart.load({\n        rows: [\n            ['data4', 'data2', 'data3'],\n            [90, 120, 300],\n            [40, 160, 240],\n            [50, 200, 290],\n            [120, 160, 230],\n            [80, 130, 300],\n            [90, 220, 320],\n        ],\n        type: 'bar'\n    });\n}, 8000);\n\nsetTimeout(function () {\n    chart.load({\n        rows: [\n            ['data5', 'data6'],\n            [190, 420],\n            [140, 460],\n            [150, 500],\n            [220, 460],\n            [180, 430],\n            [190, 520],\n        ],\n        type: 'line'\n    });\n}, 9000);\n\nsetTimeout(function () {\n    chart.unload({\n        ids: ['data2', 'data3']\n    });\n}, 10000);\n"
  },
  {
    "path": "docs/js/samples/data_name.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ],\n        names: {\n            data1: 'Name 1',\n            data2: 'Name 2'\n        }\n    }\n});"
  },
  {
    "path": "docs/js/samples/data_number_format_l10n.js",
    "content": "// Locale for Russian (ru_RU)\nvar d3locale = d3.formatDefaultLocale({\n    \"decimal\": \",\",\n    \"thousands\": \"\\u00A0\",\n    \"grouping\": [3],\n    \"currency\": [\"\", \" руб.\"],\n    \"dateTime\": \"%A, %e %B %Y г. %X\",\n    \"date\": \"%d.%m.%Y\",\n    \"time\": \"%H:%M:%S\",\n    \"periods\": [\"AM\", \"PM\"],\n    \"days\": [\"воскресенье\", \"понедельник\", \"вторник\", \"среда\", \"четверг\", \"пятница\", \"суббота\"],\n    \"shortDays\": [\"вс\", \"пн\", \"вт\", \"ср\", \"чт\", \"пт\", \"сб\"],\n    \"months\": [\"января\", \"февраля\", \"марта\", \"апреля\", \"мая\", \"июня\", \"июля\", \"августа\", \"сентября\", \"октября\", \"ноября\", \"декабря\"],\n    \"shortMonths\": [\"янв\", \"фев\", \"мар\", \"апр\", \"май\", \"июн\", \"июл\", \"авг\", \"сен\", \"окт\", \"ноя\", \"дек\"]\n});\n// More about locale settings: https://github.com/mbostock/d3/wiki/Localization\nvar chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30000, 20000, 10000, 40000, 15000, 250000],\n            ['data2', 100.5, 1200.46, 100.1, 40.12, 150.1, 250]\n        ],\n        axes: {\n            data2: 'y2'\n        }\n    },\n    axis : {\n        y : {\n            tick: {\n                format: d3locale.format(\",\")\n            }\n        },\n        y2: {\n            show: true,\n            tick: {\n                format: d3locale.format(\",\")\n            }\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/data_order.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 130, 200, 320, 400, 530, 750],\n            ['data2', -130, 10, 130, 200, 150, 250],\n            ['data3', -130, -50, -10, -200, -250, -150]\n        ],\n        type: 'bar',\n        groups: [\n            ['data1', 'data2', 'data3']\n        ],\n        order: 'desc' // stack order by sum of values descendantly. this is default.\n//      order: 'asc'  // stack order by sum of values ascendantly.\n//      order: null   // stack order by data definition.\n    },\n    grid: {\n        y: {\n            lines: [{value:0}]\n        }\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['data4', 1200, 1300, 1450, 1600, 1520, 1820],\n        ]\n    });\n}, 1000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['data5', 200, 300, 450, 600, 520, 820],\n        ]\n    });\n}, 2000);\n\nsetTimeout(function () {\n    chart.groups([['data1', 'data2', 'data3', 'data4', 'data5']])\n}, 3000);\n"
  },
  {
    "path": "docs/js/samples/data_rowed.js",
    "content": "var chart = c3.generate({\n    data: {\n        rows: [\n            ['data1', 'data2', 'data3'],\n            [90, 120, 300],\n            [40, 160, 240],\n            [50, 200, 290],\n            [120, 160, 230],\n            [80, 130, 300],\n            [90, 220, 320],\n        ]\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/data_stringx.js",
    "content": "var chart = c3.generate({\n    data: {\n        x : 'x',\n        columns: [\n            ['x', 'www.site1.com', 'www.site2.com', 'www.site3.com', 'www.site4.com'],\n            ['download', 30, 200, 100, 400],\n            ['loading', 90, 100, 140, 200],\n        ],\n        groups: [\n            ['download', 'loading']\n        ],\n        type: 'bar'\n    },\n    axis: {\n        x: {\n            type: 'category' // this needed to load string x value\n        }\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['x', 'www.siteA.com', 'www.siteB.com', 'www.siteC.com', 'www.siteD.com'],\n            ['download', 130, 200, 150, 350],\n            ['loading', 190, 180, 190, 140],\n        ],\n    });\n}, 1000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['x', 'www.siteE.com', 'www.siteF.com', 'www.siteG.com'],\n            ['download', 30, 300, 200],\n            ['loading', 90, 130, 240],\n        ],\n    });\n}, 2000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['x', 'www.site1.com', 'www.site2.com', 'www.site3.com', 'www.site4.com'],\n            ['download', 130, 300, 200, 470],\n            ['loading', 190, 130, 240, 340],\n        ],\n    });\n}, 3000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['download', 30, 30, 20, 170],\n            ['loading', 90, 30, 40, 40],\n        ],\n    });\n}, 4000);\n\nsetTimeout(function () {\n    chart.load({\n        url: '/data/c3_string_x.csv'\n    });\n}, 5000);"
  },
  {
    "path": "docs/js/samples/data_url.js",
    "content": "var chart = c3.generate({\n    data: {\n        url: '/data/c3_test.csv'\n    }\n});\n\nsetTimeout(function () {\n    c3.generate({\n        data: {\n            url: '/data/c3_test.json',\n            mimeType: 'json'\n        }\n    });\n}, 1000);"
  },
  {
    "path": "docs/js/samples/data_xformat.js",
    "content": "var chart = c3.generate({\n    data: {\n        x: 'date',\n        xFormat : '%Y%m%d', // default '%Y-%m-%d'\n        columns: [\n            ['date', '20130101', '20130102', '20130103', '20130104', '20130105', '20130106'],\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n    },\n    axis : {\n        x : {\n            type : 'timeseries'\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/grid_x_lines.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n    },\n    grid: {\n        x: {\n            lines: [\n                {value: 1, text: 'Label 1'},\n                {value: 3, text: 'Label 3', position: 'middle'},\n                {value: 4.5, text: 'Lable 4.5', position: 'start'}\n            ]\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/grid_y_lines.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250],\n            ['sample2', 1300, 1200, 1100, 1400, 1500, 1250],\n        ],\n        axes: {\n            sample2: 'y2'\n        }\n    },\n    axis: {\n        y2: {\n            show: true\n        }\n    },\n    grid: {\n        y: {\n            lines: [\n                {value: 50, text: 'Label 50 for y'},\n                {value: 1300, text: 'Label 1300 for y2', axis: 'y2', position: 'start'},\n                {value: 350, text: 'Label 350 for y', position: 'middle'}\n            ]\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/interaction_zoom.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250, 150, 200, 170, 240, 350, 150, 100, 400, 150, 250, 150, 200, 170, 240, 100, 150, 250, 150, 200, 170, 240, 30, 200, 100, 400, 150, 250, 150, 200, 170, 240, 350, 150, 100, 400, 350, 220, 250, 300, 270, 140, 150, 90, 150, 50, 120, 70, 40]\n        ]\n    },\n    zoom: {\n        enabled: true\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/interaction_zoom_by_drag.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250, 150, 200, 170, 240, 350, 150, 100, 400, 150, 250, 150, 200, 170, 240, 100, 150, 250, 150, 200, 170, 240, 30, 200, 100, 400, 150, 250, 150, 200, 170, 240, 350, 150, 100, 400, 350, 220, 250, 300, 270, 140, 150, 90, 150, 50, 120, 70, 40]\n        ]\n    },\n    zoom: {\n        enabled: true,\n        type: 'drag',\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/legend_custom.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 100],\n            ['data2', 300],\n            ['data3', 200]\n        ],\n        type: 'pie'\n    },\n    legend: {\n        show: false\n    }\n});\n\nfunction toggle(id) {\n    chart.toggle(id);\n}\n\nd3.select('.container').insert('div', '.chart').attr('class', 'legend').selectAll('span')\n    .data(['data1', 'data2', 'data3'])\n  .enter().append('span')\n    .attr('data-id', function (id) { return id; })\n    .html(function (id) { return id; })\n    .each(function (id) {\n        d3.select(this).style('background-color', chart.color(id));\n    })\n    .on('mouseover', function (id) {\n        chart.focus(id);\n    })\n    .on('mouseout', function (id) {\n        chart.revert();\n    })\n    .on('click', function (id) {\n        chart.toggle(id);\n    });\n"
  },
  {
    "path": "docs/js/samples/legend_position.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ]\n    },\n    legend: {\n        position: 'right'\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['data3', 130, 150, 200, 300, 200, 100]\n        ]\n    });\n}, 1000);\n\nsetTimeout(function () {\n    chart.unload({\n        ids: 'data1'\n    });\n}, 2000);\n\nsetTimeout(function () {\n    chart.transform('pie');\n}, 3000);\n\nsetTimeout(function () {\n    chart.transform('line');\n}, 4000);\n"
  },
  {
    "path": "docs/js/samples/options_color.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25],\n            ['data3', 130, 220, 140, 200, 250, 450],\n            ['data4', 250, 320, 210, 240, 215, 225],\n            ['data5', 430, 500, 400, 280, 290, 350],\n            ['data6', 100, 120, 310, 340, 415, 225]\n        ]\n    },\n    color: {\n        pattern: ['#1f77b4', '#aec7e8', '#ff7f0e', '#ffbb78', '#2ca02c', '#98df8a', '#d62728', '#ff9896', '#9467bd', '#c5b0d5', '#8c564b', '#c49c94', '#e377c2', '#f7b6d2', '#7f7f7f', '#c7c7c7', '#bcbd22', '#dbdb8d', '#17becf', '#9edae5']\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/options_gridline.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250, 120, 200]\n        ]\n    },\n    grid: {\n        x: {\n            show: true\n        },\n        y: {\n            show: true\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/options_legend.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n    },\n    legend: {\n        show: false\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/options_padding.js",
    "content": "var chart = c3.generate({\n    padding: {\n        top: 40,\n        right: 100,\n        bottom: 40,\n        left: 100,\n    },\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250000000000]\n        ]\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/options_size.js",
    "content": "var chart = c3.generate({\n    size: {\n        height: 240,\n        width: 480\n    },\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/options_subchart.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n    },\n    subchart: {\n        show: true\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/pie_label_format.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30],\n            ['data2', 50]\n        ],\n        type: 'pie'\n    },\n    pie: {\n        label: {\n            format: function (value, ratio, id) {\n                return d3.format('$')(value);\n            }\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/point_show.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ]\n    },\n    point: {\n        show: false\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/region.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250, 400],\n            ['data2', 830, 1200, 1100, 1400, 1150, 1250, 1500],\n        ],\n        axes: {\n            data2: 'y2'\n        }\n    },\n    axis: {\n        y2: {\n            show: true\n        }\n    },\n    regions: [\n        {axis: 'x', end: 1, class: 'regionX'},\n        {axis: 'x', start: 2, end: 4, class: 'regionX'},\n        {axis: 'x', start: 5, class: 'regionX'},\n        {axis: 'y', end: 50, class: 'regionY'},\n        {axis: 'y', start: 80, end: 140, class: 'regionY'},\n        {axis: 'y', start: 400, class: 'regionY'},\n        {axis: 'y2', end: 900, class: 'regionY2'},\n        {axis: 'y2', start: 1150, end: 1250, class: 'regionY2'},\n        {axis: 'y2', start: 1300, class: 'regionY2'},\n    ]\n});\n"
  },
  {
    "path": "docs/js/samples/region_timeseries.js",
    "content": "var chart = c3.generate({\n    data: {\n        x: 'date',\n        columns: [\n            ['date', '2014-01-01', '2014-01-10', '2014-01-20', '2014-01-30', '2014-02-01'],\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n    },\n    axis: {\n        x: {\n            type: 'timeseries'\n        }\n    },\n    regions: [\n        {start: '2014-01-05', end: '2014-01-10'},\n        {start: new Date('2014/01/15'), end: new Date('20 Jan 2014')},\n        {start: 1390575600000, end: 1391007600000} // start => 2014-01-25 00:00:00, end => 2014-01-30 00:00:00\n    ]\n});\n"
  },
  {
    "path": "docs/js/samples/simple.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/simple_multiple.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ]\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['data1', 230, 190, 300, 500, 300, 400]\n        ]\n    });\n}, 1000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['data3', 130, 150, 200, 300, 200, 100]\n        ]\n    });\n}, 1500);\n\nsetTimeout(function () {\n    chart.unload({\n        ids: 'data1'\n    });\n}, 2000);\n"
  },
  {
    "path": "docs/js/samples/simple_regions.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ],\n        regions: {\n            'data1': [{'start':1, 'end':2, 'style':'dashed'},{'start':3}], // currently 'dashed' style only\n            'data2': [{'end':3}]\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/simple_xy.js",
    "content": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        columns: [\n            ['x', 30, 50, 100, 230, 300, 310],\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 300, 200, 300, 250, 450]\n        ]\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['data1', 100, 250, 150, 200, 100, 350]\n        ]\n    });\n}, 1000);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['data3', 80, 150, 100, 180, 80, 150]\n        ]\n    });\n}, 1500);\n\nsetTimeout(function () {\n    chart.unload({\n        ids: 'data2'\n    });\n}, 2000);\n"
  },
  {
    "path": "docs/js/samples/simple_xy_multiple.js",
    "content": "var chart = c3.generate({\n    data: {\n        xs: {\n            'data1': 'x1',\n            'data2': 'x2',\n        },\n        columns: [\n            ['x1', 10, 30, 45, 50, 70, 100],\n            ['x2', 30, 50, 75, 100, 120],\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 20, 180, 240, 100, 190]\n        ]\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/style_grid.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 100, 200, 1000, 900, 500]\n        ]\n    },\n    grid: {\n        x: {\n            lines: [{value: 2}, {value: 4, class: 'grid4', text: 'LABEL 4'}]\n        },\n        y: {\n            lines: [{value: 500}, {value: 800, class: 'grid800', text: 'LABEL 800'}]\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/style_region.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n    },\n    regions: [\n        {start:0, end:1},\n        {start:2, end:4, class:'foo'}\n    ]\n});\n"
  },
  {
    "path": "docs/js/samples/timeseries.js",
    "content": "var chart = c3.generate({\n    data: {\n        x: 'x',\n//        xFormat: '%Y%m%d', // 'xFormat' can be used as custom format of 'x'\n        columns: [\n            ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],\n//            ['x', '20130101', '20130102', '20130103', '20130104', '20130105', '20130106'],\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 340, 200, 500, 250, 350]\n        ]\n    },\n    axis: {\n        x: {\n            type: 'timeseries',\n            tick: {\n                format: '%Y-%m-%d'\n            }\n        }\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['data3', 400, 500, 450, 700, 600, 500]\n        ]\n    });\n}, 1000);\n"
  },
  {
    "path": "docs/js/samples/tooltip_format.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30000, 20000, 10000, 40000, 15000, 250000],\n            ['data2', 100, 200, 100, 40, 150, 250]\n        ],\n        axes: {\n            data2: 'y2'\n        }\n    },\n    axis : {\n        y : {\n            tick: {\n                format: d3.format(\"s\")\n            }\n        },\n        y2: {\n            show: true,\n            tick: {\n                format: d3.format(\"$\")\n            }\n        }\n    },\n    tooltip: {\n        format: {\n            title: function (d) { return 'Data ' + d; },\n            value: function (value, ratio, id) {\n                var format = id === 'data1' ? d3.format(',') : d3.format('$');\n                return format(value);\n            }\n//            value: d3.format(',') // apply this format to both y and y2\n        }\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/tooltip_grouped.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25],\n            ['data3', 500, 320, 210, 340, 215, 125]\n        ]\n    },\n    tooltip: {\n        grouped: false // Default true\n    }\n});"
  },
  {
    "path": "docs/js/samples/tooltip_horizontal.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ]\n    },\n    tooltip: {\n        horizontal: true\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/tooltip_show.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n        ]\n    },\n    tooltip: {\n        show: false\n    }\n});\n"
  },
  {
    "path": "docs/js/samples/transform_area.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 140, 200, 150, 50]\n        ],\n        type: 'bar'\n    }\n});\n\nsetTimeout(function () {\n    chart.transform('area', 'data1');\n}, 1000);\n\nsetTimeout(function () {\n    chart.transform('area', 'data2');\n}, 2000);\n\nsetTimeout(function () {\n    chart.transform('bar');\n}, 3000);\n\nsetTimeout(function () {\n    chart.transform('area');\n}, 4000);"
  },
  {
    "path": "docs/js/samples/transform_areaspline.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 140, 200, 150, 50]\n        ],\n        type: 'bar'\n    }\n});\n\nsetTimeout(function () {\n    chart.transform('area-spline', 'data1');\n}, 1000);\n\nsetTimeout(function () {\n    chart.transform('area-spline', 'data2');\n}, 2000);\n\nsetTimeout(function () {\n    chart.transform('bar');\n}, 3000);\n\nsetTimeout(function () {\n    chart.transform('area-spline');\n}, 4000);\n"
  },
  {
    "path": "docs/js/samples/transform_bar.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 140, 200, 150, 50]\n        ],\n        type: 'line'\n    }\n});\n\nsetTimeout(function () {\n    chart.transform('bar', 'data1');\n}, 1000);\n\nsetTimeout(function () {\n    chart.transform('bar', 'data2');\n}, 2000);\n\nsetTimeout(function () {\n    chart.transform('line');\n}, 3000);\n\nsetTimeout(function () {\n    chart.transform('bar');\n}, 4000);"
  },
  {
    "path": "docs/js/samples/transform_donut.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 140, 200, 150, 50]\n        ]\n    }\n});\n\nsetTimeout(function () {\n    chart.transform('donut');\n}, 1000);\n\nsetTimeout(function () {\n    chart.transform('line');\n}, 2000);\n\nsetTimeout(function () {\n    chart.transform('pie');\n}, 3000);\n\nsetTimeout(function () {\n    chart.transform('donut');\n}, 4000);\n"
  },
  {
    "path": "docs/js/samples/transform_line.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 140, 200, 150, 50]\n        ],\n        type: 'bar'\n    }\n});\n\nsetTimeout(function () {\n    chart.transform('line', 'data1');\n}, 1000);\n\nsetTimeout(function () {\n    chart.transform('line', 'data2');\n}, 2000);\n\nsetTimeout(function () {\n    chart.transform('bar');\n}, 3000);\n\nsetTimeout(function () {\n    chart.transform('line');\n}, 4000);"
  },
  {
    "path": "docs/js/samples/transform_pie.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 140, 200, 150, 50]\n        ]\n    }\n});\n\nsetTimeout(function () {\n    chart.transform('pie');\n}, 1000);\n\nsetTimeout(function () {\n    chart.transform('line');\n}, 2000);\n\nsetTimeout(function () {\n    chart.transform('pie');\n}, 3000);\n"
  },
  {
    "path": "docs/js/samples/transform_scatter.js",
    "content": "var chart = c3.generate({\n    data: {\n        xs: {\n            setosa: 'setosa_x',\n            versicolor: 'versicolor_x',\n        },\n        // iris data from R\n        columns: [\n            [\"setosa_x\", 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.4, 3.0, 3.0, 4.0, 4.4, 3.9, 3.5, 3.8, 3.8, 3.4, 3.7, 3.6, 3.3, 3.4, 3.0, 3.4, 3.5, 3.4, 3.2, 3.1, 3.4, 4.1, 4.2, 3.1, 3.2, 3.5, 3.6, 3.0, 3.4, 3.5, 2.3, 3.2, 3.5, 3.8, 3.0, 3.8, 3.2, 3.7, 3.3],\n            [\"versicolor_x\", 3.2, 3.2, 3.1, 2.3, 2.8, 2.8, 3.3, 2.4, 2.9, 2.7, 2.0, 3.0, 2.2, 2.9, 2.9, 3.1, 3.0, 2.7, 2.2, 2.5, 3.2, 2.8, 2.5, 2.8, 2.9, 3.0, 2.8, 3.0, 2.9, 2.6, 2.4, 2.4, 2.7, 2.7, 3.0, 3.4, 3.1, 2.3, 3.0, 2.5, 2.6, 3.0, 2.6, 2.3, 2.7, 3.0, 2.9, 2.9, 2.5, 2.8],\n            [\"setosa\", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],\n            [\"versicolor\", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],\n        ],\n        type: 'pie'\n    },\n    axis: {\n        x: {\n            label: 'Sepal.Width',\n            tick: {\n                fit: false\n            }\n        },\n        y: {\n            label: 'Petal.Width'\n        }\n    }\n});\n\nsetTimeout(function () {\n    chart.transform('scatter');\n}, 1000);\n\nsetTimeout(function () {\n    chart.transform('pie');\n}, 2000);\n\nsetTimeout(function () {\n    chart.transform('scatter');\n}, 3000)\n"
  },
  {
    "path": "docs/js/samples/transform_spline.js",
    "content": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 140, 200, 150, 50]\n        ],\n        type: 'bar'\n    }\n});\n\nsetTimeout(function () {\n    chart.transform('spline', 'data1');\n}, 1000);\n\nsetTimeout(function () {\n    chart.transform('spline', 'data2');\n}, 2000);\n\nsetTimeout(function () {\n    chart.transform('bar');\n}, 3000);\n\nsetTimeout(function () {\n    chart.transform('spline');\n}, 4000);"
  },
  {
    "path": "docs/js/samples/transition_duration.js",
    "content": "var chart = c3.generate({\n    data: {\n        url: '/data/c3_test.csv'\n    },\n    transition: {\n        duration: 100\n    }\n});\n\nsetTimeout(function () {\n    chart.load({\n        url: '/data/c3_test2.csv'\n    });\n}, 500);\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n            ['data2', 200, 130, 90, 240, 130, 220],\n            ['data3', 300, 200, 160, 400, 250, 250]\n        ]\n    });\n}, 1000);\n\nsetTimeout(function () {\n    chart.load({\n        rows: [\n            ['data1', 'data2', 'data3'],\n            [90, 120, 300],\n            [40, 160, 240],\n            [50, 200, 290],\n            [120, 160, 230],\n            [80, 130, 300],\n            [90, 220, 320],\n        ]\n    });\n}, 1500);\n\nsetTimeout(function () {\n    chart.load({\n        columns:[\n            ['data1', null, 30, 20, 50, 40, 60, 50, 100, 200]\n        ]\n    });\n}, 2000);\n"
  },
  {
    "path": "docs/layouts/layout.haml",
    "content": "!!!\n%html.no-js\n  %head\n    %meta( charset=\"utf-8\" )\n    %meta( http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" )\n    %meta( name=\"description\" content=\"D3 based reusable chart library\" )\n    %meta( name=\"author\" content=\"c3js.org\" )\n    %meta( name=\"viewport\" content=\"width=device-width\" )\n    %link( rel=\"icon\" href=\"/img/favicon.png\" )\n    %title C3.js | D3-based reusable chart library\n\n    -# Place favicon.ico and apple-touch-icon.png in the root directory\n\n    -#= stylesheet_link_tag 'bootstrap.min'\n    = stylesheet_link_tag 'normalize'\n    = stylesheet_link_tag 'foundation.min'\n    = stylesheet_link_tag 'tomorrow'\n    = stylesheet_link_tag 'c3'\n    = stylesheet_link_tag 'style'\n    = stylesheet_link_tag get_css_name(current_page.path)\n\n    :javascript\n      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\n      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n      })(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n      ga('create', 'UA-42896059-3', 'c3js.org');\n      ga('send', 'pageview');\n\n    = javascript_include_tag 'vendor/modernizr-2.6.1.min.js'\n\n  %body.antialiased\n    .sticky\n      %nav.top-bar( data-topbar data-options=\"sticky_on: large\" )\n        %ul.title-area\n          %li.name\n            %h1\n              %a( href=\"/\" ) C3.js | D3-based reusable chart library\n          %li.toggle-topbar.menu-icon\n            %a( href=\"#\" )\n              %span Menu\n        %section.top-bar-section\n          %ul.right\n            %li.has-form\n              %a.button( href=\"/gettingstarted.html\" ) Getting Started\n            %li.divider\n            %li\n              %a( href=\"/examples.html\") Examples\n            %li.divider\n            %li\n              %a( href=\"/reference.html\") Reference\n            %li.divider\n            %li\n              %a( href=\"https://groups.google.com/forum/#!forum/c3js\" target=\"_blank\") Forum\n            %li.divider\n            %li\n              %a( href=\"https://github.com/c3js/c3\" target=\"_blank\") Source\n    = yield\n"
  },
  {
    "path": "docs/reference.html.haml",
    "content": ".container.sidemenu\n  .row\n    .large-3.medium-4.columns.column-menu\n      .side-bar\n        %ul.side-nav\n          %li\n            %strong OPTIONS\n\n          %li Chart\n          = partial :reference_menu_item, locals: { id: 'bindto' }\n          = partial :reference_menu_item, locals: { id: 'size.width' }\n          = partial :reference_menu_item, locals: { id: 'size.height' }\n          = partial :reference_menu_item, locals: { id: 'padding.top' }\n          = partial :reference_menu_item, locals: { id: 'padding.right' }\n          = partial :reference_menu_item, locals: { id: 'padding.bottom' }\n          = partial :reference_menu_item, locals: { id: 'padding.left' }\n          = partial :reference_menu_item, locals: { id: 'color.pattern' }\n          = partial :reference_menu_item, locals: { id: 'color.threshold' }\n          = partial :reference_menu_item, locals: { id: 'interaction.enabled' }\n          = partial :reference_menu_item, locals: { id: 'transition.duration' }\n          = partial :reference_menu_item, locals: { id: 'oninit' }\n          = partial :reference_menu_item, locals: { id: 'onrendered' }\n          = partial :reference_menu_item, locals: { id: 'onmouseover' }\n          = partial :reference_menu_item, locals: { id: 'onmouseout' }\n          = partial :reference_menu_item, locals: { id: 'onresize' }\n          = partial :reference_menu_item, locals: { id: 'onresized' }\n\n          %li Data\n          = partial :reference_menu_item, locals: { id: 'data.url' }\n          = partial :reference_menu_item, locals: { id: 'data.json' }\n          = partial :reference_menu_item, locals: { id: 'data.rows' }\n          = partial :reference_menu_item, locals: { id: 'data.columns' }\n          = partial :reference_menu_item, locals: { id: 'data.mimeType' }\n          = partial :reference_menu_item, locals: { id: 'data.keys' }\n          = partial :reference_menu_item, locals: { id: 'data.x' }\n          = partial :reference_menu_item, locals: { id: 'data.xs' }\n          = partial :reference_menu_item, locals: { id: 'data.xFormat' }\n          = partial :reference_menu_item, locals: { id: 'data.xLocaltime' }\n          = partial :reference_menu_item, locals: { id: 'data.xSort' }\n          -#= partial :reference_menu_item, locals: { id: 'data.idConverter' }\n          = partial :reference_menu_item, locals: { id: 'data.names' }\n          = partial :reference_menu_item, locals: { id: 'data.classes' }\n          = partial :reference_menu_item, locals: { id: 'data.groups' }\n          = partial :reference_menu_item, locals: { id: 'data.axes' }\n          = partial :reference_menu_item, locals: { id: 'data.type' }\n          = partial :reference_menu_item, locals: { id: 'data.types' }\n          = partial :reference_menu_item, locals: { id: 'data.labels' }\n          = partial :reference_menu_item, locals: { id: 'data.labels.format' }\n          = partial :reference_menu_item, locals: { id: 'data.order' }\n          = partial :reference_menu_item, locals: { id: 'data.regions' }\n          = partial :reference_menu_item, locals: { id: 'data.color' }\n          = partial :reference_menu_item, locals: { id: 'data.colors' }\n          = partial :reference_menu_item, locals: { id: 'data.hide' }\n          = partial :reference_menu_item, locals: { id: 'data.empty.label.text' }\n          = partial :reference_menu_item, locals: { id: 'data.selection.enabled' }\n          = partial :reference_menu_item, locals: { id: 'data.selection.grouped' }\n          = partial :reference_menu_item, locals: { id: 'data.selection.multiple' }\n          = partial :reference_menu_item, locals: { id: 'data.selection.draggable' }\n          = partial :reference_menu_item, locals: { id: 'data.selection.isselectable' }\n          = partial :reference_menu_item, locals: { id: 'data.stack.normalize' }\n          = partial :reference_menu_item, locals: { id: 'data.onclick' }\n          = partial :reference_menu_item, locals: { id: 'data.onmouseover' }\n          = partial :reference_menu_item, locals: { id: 'data.onmouseout' }\n          = partial :reference_menu_item, locals: { id: 'data.onselected' }\n          = partial :reference_menu_item, locals: { id: 'data.onunselected' }\n          = partial :reference_menu_item, locals: { id: 'data.ondragstart' }\n          = partial :reference_menu_item, locals: { id: 'data.ondragend' }\n\n          %li Axis\n          = partial :reference_menu_item, locals: { id: 'axis.rotated' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.show' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.type' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.localtime' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.categories' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.tick.centered' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.tick.format' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.tick.culling' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.tick.culling.max' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.tick.count' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.tick.fit' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.tick.values' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.tick.rotate' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.tick.outer' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.tick.multiline' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.tick.multilineMax' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.tick.width' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.max' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.min' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.padding' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.height' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.extent' }\n          = partial :reference_menu_item, locals: { id: 'axis.x.label' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.show' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.inner' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.type' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.max' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.min' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.inverted' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.center' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.label' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.tick.format' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.tick.outer' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.tick.values' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.tick.count' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.tick.time.value' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.tick.time.interval' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.padding' }\n          = partial :reference_menu_item, locals: { id: 'axis.y.default' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.show' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.inner' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.type' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.max' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.min' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.inverted' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.center' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.label' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.tick.format' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.tick.outer' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.tick.values' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.tick.count' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.padding' }\n          = partial :reference_menu_item, locals: { id: 'axis.y2.default' }\n\n          %li Grid\n          = partial :reference_menu_item, locals: { id: 'grid.x.show' }\n          = partial :reference_menu_item, locals: { id: 'grid.x.lines' }\n          = partial :reference_menu_item, locals: { id: 'grid.y.show' }\n          = partial :reference_menu_item, locals: { id: 'grid.y.lines' }\n          = partial :reference_menu_item, locals: { id: 'grid.y.ticks' }\n\n          %li Region\n          = partial :reference_menu_item, locals: { id: 'regions' }\n\n          %li Legend\n          = partial :reference_menu_item, locals: { id: 'legend.show' }\n          = partial :reference_menu_item, locals: { id: 'legend.hide' }\n          = partial :reference_menu_item, locals: { id: 'legend.position' }\n          = partial :reference_menu_item, locals: { id: 'legend.inset' }\n          = partial :reference_menu_item, locals: { id: 'legend.item.onclick' }\n          = partial :reference_menu_item, locals: { id: 'legend.item.onmouseover' }\n          = partial :reference_menu_item, locals: { id: 'legend.item.onmouseout' }\n\n          %li Tooltip\n          = partial :reference_menu_item, locals: { id: 'tooltip.show' }\n          = partial :reference_menu_item, locals: { id: 'tooltip.grouped' }\n          = partial :reference_menu_item, locals: { id: 'tooltip.format.title' }\n          = partial :reference_menu_item, locals: { id: 'tooltip.format.name' }\n          = partial :reference_menu_item, locals: { id: 'tooltip.format.value' }\n          = partial :reference_menu_item, locals: { id: 'tooltip.position' }\n          = partial :reference_menu_item, locals: { id: 'tooltip.contents' }\n          = partial :reference_menu_item, locals: { id: 'tooltip.horizontal' }\n\n          %li Subchart\n          = partial :reference_menu_item, locals: { id: 'subchart.show', experimental: true }\n          = partial :reference_menu_item, locals: { id: 'subchart.size.height', experimental: true }\n          = partial :reference_menu_item, locals: { id: 'subchart.onbrush', experimental: true }\n          = partial :reference_menu_item, locals: { id: 'subchart.axis.x.show', experimental: true }\n\n          %li Zoom\n          = partial :reference_menu_item, locals: { id: 'zoom.enabled', experimental: true }\n          = partial :reference_menu_item, locals: { id: 'zoom.type', experimental: true }\n          = partial :reference_menu_item, locals: { id: 'zoom.rescale', experimental: true }\n          = partial :reference_menu_item, locals: { id: 'zoom.extent', experimental: true }\n          = partial :reference_menu_item, locals: { id: 'zoom.onzoom', experimental: true }\n          = partial :reference_menu_item, locals: { id: 'zoom.onzoomstart', experimental: true }\n          = partial :reference_menu_item, locals: { id: 'zoom.onzoomend', experimental: true }\n          = partial :reference_menu_item, locals: { id: 'zoom.disableDefaultBehavior', experimental: true }\n\n          %li Point\n          = partial :reference_menu_item, locals: { id: 'point.show' }\n          = partial :reference_menu_item, locals: { id: 'point.r' }\n          = partial :reference_menu_item, locals: { id: 'point.focus.expand.enabled' }\n          = partial :reference_menu_item, locals: { id: 'point.focus.expand.r' }\n          = partial :reference_menu_item, locals: { id: 'point.select.r' }\n\n          %li Line\n          = partial :reference_menu_item, locals: { id: 'line.connectNull' }\n          = partial :reference_menu_item, locals: { id: 'line.step.type' }\n\n          %li Area\n          = partial :reference_menu_item, locals: { id: 'area.zerobased' }\n\n          %li Bar\n          = partial :reference_menu_item, locals: { id: 'bar.width' }\n          = partial :reference_menu_item, locals: { id: 'bar.width.ratio' }\n          = partial :reference_menu_item, locals: { id: 'bar.zerobased' }\n\n          %li Pie\n          = partial :reference_menu_item, locals: { id: 'pie.label.show' }\n          = partial :reference_menu_item, locals: { id: 'pie.label.format' }\n          = partial :reference_menu_item, locals: { id: 'pie.label.threshold' }\n          = partial :reference_menu_item, locals: { id: 'pie.expand' }\n          = partial :reference_menu_item, locals: { id: 'pie.padAngle' }\n\n          %li Donut\n          = partial :reference_menu_item, locals: { id: 'donut.label.show' }\n          = partial :reference_menu_item, locals: { id: 'donut.label.format' }\n          = partial :reference_menu_item, locals: { id: 'donut.label.threshold' }\n          = partial :reference_menu_item, locals: { id: 'donut.expand' }\n          = partial :reference_menu_item, locals: { id: 'donut.padAngle' }\n          = partial :reference_menu_item, locals: { id: 'donut.width' }\n          = partial :reference_menu_item, locals: { id: 'donut.title' }\n\n          %li Gauge\n          = partial :reference_menu_item, locals: { id: 'gauge.label.show' }\n          = partial :reference_menu_item, locals: { id: 'gauge.label.format' }\n          = partial :reference_menu_item, locals: { id: 'gauge.expand' }\n          = partial :reference_menu_item, locals: { id: 'gauge.min' }\n          = partial :reference_menu_item, locals: { id: 'gauge.max' }\n          = partial :reference_menu_item, locals: { id: 'gauge.units' }\n          = partial :reference_menu_item, locals: { id: 'gauge.width' }\n\n          %li Spline\n          = partial :reference_menu_item, locals: { id: 'spline.interpolation.type' }\n\n          %li Stanford\n          = partial :reference_menu_item, locals: { id: 'stanford.scaleMin' }\n          = partial :reference_menu_item, locals: { id: 'stanford.scaleMax' }\n          = partial :reference_menu_item, locals: { id: 'stanford.scaleWidth' }\n          = partial :reference_menu_item, locals: { id: 'stanford.scaleFormat' }\n          = partial :reference_menu_item, locals: { id: 'stanford.colors' }\n          = partial :reference_menu_item, locals: { id: 'stanford.padding' }\n          = partial :reference_menu_item, locals: { id: 'stanford.texts' }\n          = partial :reference_menu_item, locals: { id: 'stanford.lines' }\n          = partial :reference_menu_item, locals: { id: 'stanford.regions' }\n\n          %li.margin-medium-top\n            %strong API\n\n          = partial :reference_menu_item, locals: { id: 'api.focus' }\n          = partial :reference_menu_item, locals: { id: 'api.defocus' }\n          = partial :reference_menu_item, locals: { id: 'api.revert' }\n          = partial :reference_menu_item, locals: { id: 'api.show' }\n          = partial :reference_menu_item, locals: { id: 'api.hide' }\n          = partial :reference_menu_item, locals: { id: 'api.toggle' }\n          = partial :reference_menu_item, locals: { id: 'api.load' }\n          = partial :reference_menu_item, locals: { id: 'api.unload' }\n          = partial :reference_menu_item, locals: { id: 'api.flow' }\n          = partial :reference_menu_item, locals: { id: 'api.select' }\n          = partial :reference_menu_item, locals: { id: 'api.unselect' }\n          = partial :reference_menu_item, locals: { id: 'api.selected' }\n          = partial :reference_menu_item, locals: { id: 'api.transform' }\n          = partial :reference_menu_item, locals: { id: 'api.groups' }\n          = partial :reference_menu_item, locals: { id: 'api.xgrids' }\n          = partial :reference_menu_item, locals: { id: 'api.xgrids.add' }\n          = partial :reference_menu_item, locals: { id: 'api.xgrids.remove' }\n          = partial :reference_menu_item, locals: { id: 'api.ygrids' }\n          = partial :reference_menu_item, locals: { id: 'api.ygrids.add' }\n          = partial :reference_menu_item, locals: { id: 'api.ygrids.remove' }\n          = partial :reference_menu_item, locals: { id: 'api.regions' }\n          = partial :reference_menu_item, locals: { id: 'api.regions.add' }\n          = partial :reference_menu_item, locals: { id: 'api.regions.remove' }\n          = partial :reference_menu_item, locals: { id: 'api.data' }\n          = partial :reference_menu_item, locals: { id: 'api.data.shown' }\n          = partial :reference_menu_item, locals: { id: 'api.data.values' }\n          = partial :reference_menu_item, locals: { id: 'api.data.names' }\n          = partial :reference_menu_item, locals: { id: 'api.data.colors' }\n          = partial :reference_menu_item, locals: { id: 'api.data.axes' }\n          = partial :reference_menu_item, locals: { id: 'api.x' }\n          = partial :reference_menu_item, locals: { id: 'api.xs' }\n          = partial :reference_menu_item, locals: { id: 'api.axis.labels' }\n          = partial :reference_menu_item, locals: { id: 'api.axis.min' }\n          = partial :reference_menu_item, locals: { id: 'api.axis.max' }\n          = partial :reference_menu_item, locals: { id: 'api.axis.range' }\n          = partial :reference_menu_item, locals: { id: 'api.axis.types' }\n          = partial :reference_menu_item, locals: { id: 'api.legend.show' }\n          = partial :reference_menu_item, locals: { id: 'api.legend.hide' }\n          = partial :reference_menu_item, locals: { id: 'api.subchart.isShown' }\n          = partial :reference_menu_item, locals: { id: 'api.subchart.show' }\n          = partial :reference_menu_item, locals: { id: 'api.subchart.hide' }\n          = partial :reference_menu_item, locals: { id: 'api.zoom' }\n          = partial :reference_menu_item, locals: { id: 'api.unzoom' }\n          = partial :reference_menu_item, locals: { id: 'api.zoom.enable' }\n          = partial :reference_menu_item, locals: { id: 'api.resize' }\n          = partial :reference_menu_item, locals: { id: 'api.flush' }\n          = partial :reference_menu_item, locals: { id: 'api.destroy' }\n\n          %li.margin-medium-top\n            %strong CLASS\n\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-line' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-lines' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-bar' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-bars' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-text' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-texts' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-arc' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-arcs' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-arcs-title' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-arcs-background' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-arcs-gauge-unit' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-arcs-gauge-max' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-chart-arcs-gauge-min' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-selected-circle' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-selected-circles' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-event-rect' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-event-rects' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-event-rects-single' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-event-rects-multiple' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-zoom-rect' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-brush' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-focused' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-region' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-regions' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-tooltip' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-tooltip-name' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-shape' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-shapes' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-line' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-lines' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-bar' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-bars' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-circle' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-circles' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-arc' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-arcs' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-area' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-areas' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-empty' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-text' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-texts' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-gauge-value' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-grid' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-xgrid' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-xgrids' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-xgrid-line' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-xgrid-lines' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-xgrid-focus' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-ygrid' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-ygrids' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-ygrid-line' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-ygrid-lines' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-stanford-elements' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-stanford-line' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-stanford-lines' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-stanford-region' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-stanford-regions' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-stanford-text' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-stanford-texts' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-axis' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-axis-x' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-axis-x-label' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-axis-y' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-axis-y-label' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-axis-y2' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-axis-y2-label' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-legend-item' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-legend-item-event' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-legend-item-tile' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-legend-item-hidden' }\n          = partial :reference_menu_item, locals: { id: 'class.c3-legend-item-focused' }\n\n\n    .large-9.medium-8.columns.column-content\n      %h2 Options\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'bindto' }\n        %p The CSS selector or the element which the chart will be set to. D3 selection object can be specified. If other chart is set already, it will be replaced with the new one (only one chart can be set in one element).\n        %br\n        %p If this option is not specified, the chart will be generated but not be set. Instead, we can access the element by <span class=\"code\">chart.element</span> and set it by ourselves.\n        %h5 Note:\n        %p When chart is not binded, c3 starts observing if <span class=\"code\">chart.element</span> is binded by <span class=\"code\">MutationObserver</span>. In this case, polyfill is required in IE9 and IE10 because they do not support <span class=\"code\">MutationObserver</span>. On the other hand, if chart always will be binded, polyfill will not be required because <span class=\"code\">MutationObserver</span> will never be called.\n        %h5 Default:\n        <code>#chart</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              bindto: '#myContainer'\n              \\// or element\n              bindto: document.getElementById('myContainer')\n              \\// or D3 selection object\n              bindto: d3.select('#myContainer')\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'size.width' }\n        %p The desired width of the chart element.\n        %br\n        %p If this option is not specified, the width of the chart will be calculated by the size of the parent element it's appended to.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              size: {\n              &nbsp;&nbsp;width: 640\n              }\n        %h5 Note:\n        %p This option should be specified if possible because it can improve its performance because some size calculations will be skipped by an explicit value.\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'size.height' }\n        %p The desired height of the chart element.\n        %br\n        %p If this option is not specified, the height of the chart will be calculated by the size of the parent element it's appended to.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              size: {\n              &nbsp;&nbsp;height: 480\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'padding.top' }\n        %p The padding on the top of the chart.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              padding: {\n              &nbsp;&nbsp;top: 20\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/options_padding.html\" ) Padding for the chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'padding.right' }\n        %p The padding on the right of the chart.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              padding: {\n              &nbsp;&nbsp;right: 20\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/options_padding.html\" ) Padding for the chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'padding.bottom' }\n        %p The padding on the bottom of the chart.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              padding: {\n              &nbsp;&nbsp;bottom: 20\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/options_padding.html\" ) Padding for the chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'padding.left' }\n        %p The padding on the left of the chart.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              padding: {\n              &nbsp;&nbsp;left: 20\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/options_padding.html\" ) Padding for the chart\n        %h5 Note:\n        %p This option should be specified if possible because it can improve its performance because some size calculations will be skipped by an explicit value.\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'color.pattern' }\n        %p Set custom color pattern.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              color: {\n              &nbsp;&nbsp;pattern: ['#1f77b4', '#aec7e8', ...]\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/options_color.html\" ) Custom color pattern\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'color.threshold' }\n        %p not yet\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'interaction.enabled' }\n        %p Indicate if the chart should have interactions.\n        %br\n        %p If <code>false</code> is set, all of interactions (showing/hiding tooltip, selection, mouse events, etc) will be disabled.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              interaction: {\n              &nbsp;&nbsp;enabled: false\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'transition.duration' }\n        %p Set duration of transition (in milliseconds) for chart animation.\n        %h5 Note:\n        %p If <span class=\"code\">0</span> or <span class=\"code\">null</span> set, transition will be skipped. So, this makes initial rendering faster especially in case you have a lot of data.\n        %h5 Default:\n        <code>350</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              transition: {\n              &nbsp;&nbsp;duration: 500\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/transition_duration.html\" ) Change the duration of transition\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'oninit' }\n        %p Set a callback to execute when the chart is initialized.\n        %h5 Default:\n        <code>function () {}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              oninit: function () { ... }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'onrendered' }\n        %p Set a callback which is executed when the chart is rendered. Basically, this callback will be called in each time when the chart is redrawed.\n        %h5 Default:\n        <code>function () {}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              onrendered: function () { ... }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'onmouseover' }\n        %p Set a callback to execute when mouse enters the chart.\n        %h5 Default:\n        <code>function () {}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              onmouseover: function () { ... }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'onmouseout' }\n        %p Set a callback to execute when mouse leaves the chart.\n        %h5 Default:\n        <code>function () {}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              onmouseout: function () { ... }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'onresize' }\n        %p Set a callback to execute when user resizes the screen.\n        %h5 Default:\n        <code>function () {}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              onresize: function () { ... }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'onresized' }\n        %p Set a callback to execute when screen resize finished.\n        %h5 Default:\n        <code>function () {}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              onresized: function () { ... }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.url' }\n        %p Load a CSV or JSON file from a URL. Note that this will not work if loading via the \"file://\" protocol as the most browsers will block XMLHTTPRequests.\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              var chart = c3.generate({\n              &nbsp;&nbsp;data: {\n              &nbsp;&nbsp;&nbsp;&nbsp;url: '/data/c3_test.csv'\n              &nbsp;&nbsp;}\n              });\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.json' }\n        %p Parse a JSON object for data. See also data.keys.\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              var chart = c3.generate({\n              &nbsp;&nbsp;data: {\n              &nbsp;&nbsp;&nbsp;&nbsp;json: [\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{name: 'www.site1.com', upload: 200, download: 200, total: 400},\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{name: 'www.site2.com', upload: 100, download: 300, total: 400},\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{name: 'www.site3.com', upload: 300, download: 200, total: 500},\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{name: 'www.site4.com', upload: 400, download: 100, total: 500}\n              &nbsp;&nbsp;&nbsp;&nbsp;],\n              &nbsp;&nbsp;&nbsp;&nbsp;keys: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// x: 'name', // it's possible to specify 'x' when category axis\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: ['upload', 'download']\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;},\n              &nbsp;&nbsp;axis: {\n              &nbsp;&nbsp;&nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// type: 'category'\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              });\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.rows' }\n        %p Load data from a multidimensional array, with the first element containing the data names, the following containing related data in that order.\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              rows: [\n              &nbsp;&nbsp;['data1', 'data2', 'data3'],\n              &nbsp;&nbsp;[90, 120, 300],\n              &nbsp;&nbsp;[40, 160, 240],\n              &nbsp;&nbsp;[50, 200, 290],\n              &nbsp;&nbsp;[120, 160, 230],\n              &nbsp;&nbsp;[80, 130, 300],\n              &nbsp;&nbsp;[90, 220, 320]\n              ]\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.columns' }\n        %p Load data from a multidimensional array, with each element containing an array consisting of a datum name and associated data values.\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              columns: [\n              &nbsp;&nbsp;['data1', 30, 20, 50, 40, 60, 50],\n              &nbsp;&nbsp;['data2', 200, 130, 90, 240, 130, 220],\n              &nbsp;&nbsp;['data3', 300, 200, 160, 400, 250, 250]\n              ]\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.mimeType' }\n        %p Used if loading JSON via data.url:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              {data: {mimeType: 'json'}}\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.keys' }\n        %p Choose which JSON object keys correspond to desired data.\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              var chart = c3.generate({\n              &nbsp;&nbsp;data: {\n              &nbsp;&nbsp;&nbsp;&nbsp;json: [\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{name: 'www.site1.com', upload: 200, download: 200, total: 400},\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{name: 'www.site2.com', upload: 100, download: 300, total: 400},\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{name: 'www.site3.com', upload: 300, download: 200, total: 500},\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{name: 'www.site4.com', upload: 400, download: 100, total: 500}\n              &nbsp;&nbsp;&nbsp;&nbsp;],\n              &nbsp;&nbsp;&nbsp;&nbsp;keys: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// x: 'name', // it's possible to specify 'x' when category axis\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value: ['upload', 'download']\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;},\n              &nbsp;&nbsp;axis: {\n              &nbsp;&nbsp;&nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// type: 'category'\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              });\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.x' }\n        %p Specify the key of x values in the data.\n        %br\n        %p We can show the data with non-index x values by this option. This option is required when the type of x axis is timeseries. If this option is set on category axis, the values of the data on the key will be used for category names.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;x: 'date'\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/simple_xy.html\") XY Chart\n          %li\n            %a( href=\"/samples/timeseries.html\" ) Timeseries Chart\n          %li\n            %a( href=\"/samples/data_stringx.html\" ) Category Names\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.xs' }\n        %p Specify the keys of the x values for each data.\n        %br\n        %p This option can be used if we want to show the data that has different x values.\n        %h5 Default:\n        <code>{}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;xs: {\n              &nbsp;&nbsp;&nbsp;&nbsp;data1: 'x1',\n              &nbsp;&nbsp;&nbsp;&nbsp;data2: 'x2'\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/simple_xy_multiple.html\" ) Multiple XY Chart\n        %h5 Note:\n        %p <a href=\"#data-x\">data.x</a> should be used if the all of data have same x values.\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.xFormat' }\n        %p Set a format to parse string specified as x.\n        %h5 Default:\n        <code>%Y-%m-%d</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;xFormat: '%Y-%m-%d %H:%M:%S'\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/timeseries.html\" ) Timeseries Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.xLocaltime' }\n        %p not yet\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.xSort' }\n        %p not yet\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.names' }\n        %p Set custom data name.\n        %h5 Default:\n        <code>{}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;names: {\n              &nbsp;&nbsp;&nbsp;&nbsp;data1: 'Data Name 1',\n              &nbsp;&nbsp;&nbsp;&nbsp;data2: 'Data Name 2'\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/data_name.html\" ) Data Name\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.classes' }\n        %p Set custom data class.\n        %br\n        %p If this option is specified, the element <span class=\"code\">g</span> for the data has an additional class that has the prefix <span class=\"code\">c3-target-</span> (e.g. <span class=\"code\">c3-target-additional-data1-class</span>).\n        %h5 Default:\n        <code>{}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;classes: {\n              &nbsp;&nbsp;&nbsp;&nbsp;data1: 'additional-data1-class',\n              &nbsp;&nbsp;&nbsp;&nbsp;data2: 'additional-data2-class'\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.groups' }\n        %p Set groups for the data for stacking.\n        %h5 Default:\n        <code>[]</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;groups: [\n              &nbsp;&nbsp;&nbsp;&nbsp;['data1', 'data2'],\n              &nbsp;&nbsp;&nbsp;&nbsp;['data3']\n              &nbsp;&nbsp;]\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_bar_stacked.html\" ) Stacked Bar Chart\n          %li\n            %a( href=\"/samples/chart_area_stacked.html\" ) Stacked Area Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.axes' }\n        %p Set y axis the data related to. <span class=\"code\">y</span> and <span class=\"code\">y2</span> can be used.\n        %h5 Default:\n        <code>{}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;axes: {\n              &nbsp;&nbsp;&nbsp;&nbsp;data1: 'y',\n              &nbsp;&nbsp;&nbsp;&nbsp;data2: 'y2'\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_y2.html\" ) Additional Y Axis\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.type' }\n        %p Set chart type at once.\n        %br\n        %p If this option is specified, the type will be applied to every data. This setting can be overwritten by <a href=\"#data-types\">data.types</a>.\n        %h5 Available Values:\n        %ul\n          %li line\n          %li spline\n          %li step\n          %li area\n          %li area-spline\n          %li area-step\n          %li bar\n          %li scatter\n          %li stanford\n          %li pie\n          %li donut\n          %li gauge\n        %h5 Default:\n        <code>line</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;type: 'bar'\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_spline.html\" ) Spline Chart\n          %li\n            %a( href=\"/samples/chart_step.html\" ) Step Chart\n          %li\n            %a( href=\"/samples/chart_area.html\" ) Area Chart\n          %li\n            %a( href=\"/samples/chart_bar.html\" ) Bar Chart\n          %li\n            %a( href=\"/samples/chart_scatter.html\" ) Scatter Chart\n          %li\n            %a( href=\"/samples/chart_stanford.html\" ) Stanford Chart\n          %li\n            %a( href=\"/samples/chart_pie.html\" ) Pie Chart\n          %li\n            %a( href=\"/samples/chart_donut.html\" ) Donut Chart\n          %li\n            %a( href=\"/samples/chart_gauge.html\" ) Gauge Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.types' }\n        %p Set chart type for each data.\n        %br\n        %p This setting overwrites <a href=\"#data-type\">data.type</a> setting.\n        %h5 Default:\n        <code>{}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;types: {\n              &nbsp;&nbsp;&nbsp;&nbsp;data1: 'bar'\n              &nbsp;&nbsp;&nbsp;&nbsp;data2: 'spline'\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_combination.html\" ) Combination Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.labels' }\n        %p Show labels on each data points.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;labels: true\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/data_label.html\" ) Data Label\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.labels.format' }\n        %p Set formatter function for data labels.\n        %br\n        %p The formatter function receives 4 arguments such as <span class=\"code\">v</span>, <span class=\"code\">id</span>, <span class=\"code\">i</span>, <span class=\"code\">j</span> and it must return a string that will be shown as the label. The arguments are:\n        %br\n        %ul\n          %li <span class=\"code\">v</span> is the value of the data point where the label is shown.\n          %li <span class=\"code\">id</span> is the id of the data where the label is shown.\n          %li <span class=\"code\">i</span> is the index of the data point where the label is shown.\n          %li <span class=\"code\">j</span> is the sub index of the data point where the label is shown.\n        %p Formatter function can be defined for each data by specifying as an object and D3 formatter function can be set (e.g. <span class=\"code\">d3.format('$')</span>)\n        %h5 Default:\n        <code>{}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;labels: {\n              &nbsp;&nbsp;&nbsp;&nbsp;format: function (v, id, i, j) { ... }\n              &nbsp;&nbsp;&nbsp;&nbsp;// it's possible to set for each data\n              &nbsp;&nbsp;&nbsp;&nbsp;//format: {\n              &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;data1: function (v, id, i, j) { ... },\n              &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;...\n              &nbsp;&nbsp;&nbsp;&nbsp;//}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/data_label_format.html\" ) Data Label Format\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.order' }\n        %p Define the order of the data.\n        %br\n        %p This option changes the order of stacking the data and pieces of pie/donut. If <code>null</code> specified, it will be the order the data loaded. If function specified, it will be used to sort the data and it will receive the data as argument.\n        %h5 Available Values:\n        %ul\n          %li desc\n          %li asc\n          %li <span class=\"code\">function (data1, data2) { ... }</span>\n          %li <code>null</code>\n        %h5 Default:\n        <code>desc</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;order: 'asc'\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/data_order.html\" ) Data Order\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.regions' }\n        %p Define regions for each data.\n        %br\n        %p The values must be an array for each data and it should include an object that has <span class=\"code\">start</span>, <span class=\"code\">end</span>, <span class=\"code\">style</span>. If <span class=\"code\">start</span> is not set, the start will be the first data point. If <span class=\"code\">end</span> is not set, the end will be the last data point.\n        %br\n        %p Currently this option supports only line chart and dashed style. If this option specified, the line will be dashed only in the regions.\n        %br\n        %p An optional <span class=\"code\">label</span> property can be provided to display a label for the region. If a label option is not specified, no label will be displayed for the region. For each region, you may also specify the <span class=\"code\">paddingY</span> and <span class=\"code\">paddingX</span> options to control the position of label text. Finally, a <span class=\"code\">vertical</span> option can be used to identify whether or not the label text should be rotated 90 degrees.\n        %h5 Default:\n        <code>{}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;regions: {\n              &nbsp;&nbsp;&nbsp;&nbsp;data1: [\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{'start':1, 'end':2, 'style':'dashed'},\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{'start':3, label:\"Region 2\", paddingX:2, paddingY:2, vertical=true}\n              &nbsp;&nbsp;&nbsp;&nbsp;],\n              &nbsp;&nbsp;&nbsp;&nbsp;...\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/simple_regions.html\" ) Line Chart with Region\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.color' }\n        %p Set color converter function.\n        %br\n        %p This option should a function and the specified function receives <span class=\"code\">color</span> (e.g. '#ff0000') and <span class=\"code\">d</span> that has data parameters like id, value, index, etc. And it must return a string that represents color (e.g. '#00ff00').\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;color: function (color, d) { ... }\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/data_color.html\" ) Data Color\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.colors' }\n        %p Set color for each data.\n        %h5 Default:\n        <code>{}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;colors: {\n              &nbsp;&nbsp;&nbsp;&nbsp;data1: '#ff0000',\n              &nbsp;&nbsp;&nbsp;&nbsp;...\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/data_color.html\" ) Data Color\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.hide' }\n        %p Hide each data when the chart appears.\n        %br\n        %p If <code>true</code> specified, all of data will be hidden. If multiple ids specified as an array, those will be hidden.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;// all of data will be hidden\n              &nbsp;&nbsp;hide: true\n              &nbsp;&nbsp;// specified data will be hidden\n              &nbsp;&nbsp;hide: ['data1', ...]\n              }\n        %h5 Note:\n        %p This option does not hide legends, so we need to use <a href=\"#legend-hide\">legend.hide</a> option together if we want to hide legend too.\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.empty.label.text' }\n        %p Set text displayed when empty data.\n        %h5 Default:\n        <code>\"\"</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;empty: {\n              &nbsp;&nbsp;&nbsp;&nbsp;label: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text: \"No Data\"\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.selection.enabled' }\n        %p Set data selection enabled.\n        %br\n        %p If this option is set <code>true</code>, we can select the data points and get/set its state of selection by API (e.g. <a>select</a>, <a>unselect</a>, <a>selected</a>).\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;selection: {\n              &nbsp;&nbsp;&nbsp;&nbsp;enabled: true\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.selection.grouped' }\n        %p Set grouped selection enabled.\n        %br\n        %p If this option set <code>true</code>, multiple data points that have same x value will be selected by one selection.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;selection: {\n              &nbsp;&nbsp;&nbsp;&nbsp;grouped: true\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.selection.multiple' }\n        %p Set multiple data points selection enabled.\n        %br\n        %p If this option set <code>true</code>, multiple data points can have the selected state at the same time. If <code>false</code> set, only one data point can have the selected state and the others will be unselected when the new data point is selected.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;selection: {\n              &nbsp;&nbsp;&nbsp;&nbsp;multiple: true\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.selection.draggable' }\n        %p Enable to select data points by dragging.\n        %br\n        %p If this option set <code>true</code>, data points can be selected by dragging.\n        %h5 Note:\n        %p If this option set <code>true</code>, scrolling on the chart will be disabled because dragging event will handle the event.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;selection: {\n              &nbsp;&nbsp;&nbsp;&nbsp;draggable: true\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.selection.isselectable' }\n        %p Set a callback for each data point to determine if it's selectable or not.\n        %br\n        %p The callback will receive <span class=\"code\">d</span> as an argument and it has some parameters like <span class=\"code\">id</span>, <span class=\"code\">value</span>, <span class=\"code\">index</span>. This callback should return <span class=\"code\">boolean</span>.\n        %h5 Default:\n        <code>function () { return true; }</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;selection: {\n              &nbsp;&nbsp;&nbsp;&nbsp;isselectable: function (d) { ... }\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.stack.normalize' }\n        %p Set the stacking to be normalized\n        %br\n        %p For stacking, the `data.groups` option should be set and have positive values. The yAxis will be set in percentage value (0 ~ 100%).\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;stack: {\n              &nbsp;&nbsp;&nbsp;&nbsp;normalize: true\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.onclick' }\n        %p Set a callback for click event on each data point.\n        %br\n        %p This callback will be called when each data point clicked and will receive <span class=\"code\">d</span> and <span class=\"code\">element</span> as the arguments. <span class=\"code\">d</span> is the data clicked and <span class=\"code\">element</span> is the element clicked. In this callback, <span class=\"code\">this</span> will be the <span class=\"code\">Chart</span> object.\n        %h5 Default:\n        <code>function () {}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;onclick: function (d, element) { ... }\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.onmouseover' }\n        %p Set a callback for mouseover event on each data point.\n        %br\n        %p This callback will be called when mouse cursor moves onto each data point and will receive <span class=\"code\">d</span> as the argument. <span class=\"code\">d</span> is the data where mouse cursor moves onto. In this callback, <span class=\"code\">this</span> will be the <span class=\"code\">Chart</span> object.\n        %h5 Default:\n        <code>function () {}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;onmouseover: function (d) { ... }\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.onmouseout' }\n        %p Set a callback for mouseout event on each data point.\n        %br\n        %p This callback will be called when mouse cursor moves out each data point and will receive <span class=\"code\">d</span> as the argument. <span class=\"code\">d</span> is the data where mouse cursor moves out. In this callback, <span class=\"code\">this</span> will be the <span class=\"code\">Chart</span> object.\n        %h5 Default:\n        <code>function () {}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              data: {\n              &nbsp;&nbsp;onmouseout: function (d) { ... }\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.onselected' }\n        %p not yet\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.onunselected' }\n        %p not yet\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.ondragstart' }\n        %p not yet\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'data.ondragend' }\n        %p not yet\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.rotated' }\n        %p Switch x and y axis position.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;rotated: true\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_rotated.html\" ) Rotated Axis\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.show' }\n        %p Show or hide x axis.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;show: true\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.type' }\n        %p Set type of x axis.\n        %h5 Available Values\n        %ul\n          %li timeseries\n          %li category\n          %li indexed\n        %h5 Default:\n        <code>indexed</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;type: 'timeseries'\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/timeseries.html\" ) Timeseries Chart\n          %li\n            %a( href=\"/samples/categorized.html\" ) Category Axis\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.localtime' }\n        %p Set how to treat the timezone of x values.\n        %br\n        %p If true, treat x value as localtime. If false, convert to UTC internally.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;localtime: true\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_x_localtime.html\" ) X Axis Timezone\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.categories' }\n        %p Set category names on category axis.\n        %br\n        %p This must be an array that includes category names in string. If category names are included in the date by <span class=\"code\">data.x</span> option, this is not required.\n        %h5 Default:\n        <code>[]</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;categories: ['Category 1', 'Category 2', ...]\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/categorized.html\" ) Category Axis\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.tick.centered' }\n        %p Centerise ticks on category axis.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;centered: true\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.tick.format' }\n        %p A function to format tick value. Format string is also available for timeseries data.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format: function (x) { return x.getFullYear(); }\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.tick.culling' }\n        %p Setting for culling ticks.\n        %br\n        %p If <code>true</code> is set, the ticks will be culled, then only limitted tick text will be shown. This option does not hide the tick lines. If <code>false</code> is set, all of ticks will be shown.\n        %br\n        %p We can change the number of ticks to be shown by <a href=\"#axis-x-tick-culling-max\">axis.x.tick.culling.max</a>.\n        %h5 Default:\n        %ul\n          %li <code>true</code> for indexed axis and timeseries axis\n          %li <code>false</code> for category axis\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;culling: false\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_x_tick_culling.html\" ) X Axis Tick Culling\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.tick.culling.max' }\n        %p The number of tick texts will be adjusted to less than this value.\n        %h5 Default:\n        <code>10</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;culling: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max: 5\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_x_tick_culling.html\" ) X Axis Tick Culling\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.tick.count' }\n        %p The number of x axis ticks to show.\n        %br\n        %p This option hides tick lines together with tick text. If this option is used on timeseries axis, the ticks position will be determined precisely and not nicely positioned (e.g. it will have rough second value).\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count: 5\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_x_tick_count.html\" ) X Axis Tick Count\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.tick.fit' }\n        %p Fit x axis ticks.\n        %br\n        %p If <code>true</code> set, the ticks will be positioned nicely. If <code>false</code> set, the ticks will be positioned according to x value of the data points.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fit: true\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_x_tick_fit.html\" ) X Axis Tick Fit\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.tick.values' }\n        %p Set the x values of ticks manually.\n        %br\n        %p If this option is provided, the position of the ticks will be determined based on those values. This option works with timeseries data and the x values will be parsed accoding to the type of the value and <a href=\"#data-xFormat\">data.xFormat</a> option.\n        %h5 Default:\n        <code>null</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;values: [1, 2, 4, 8, 16, 32, ...]\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_x_tick_values.html\" ) X Axis Tick Values\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.tick.rotate' }\n        %p Rotate x axis tick text.\n        %br\n        %p If you set negative value, it will rotate to opposite direction.\n        %h5 Default:\n        <code>0</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rotate: 60\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_x_tick_rotate.html\" ) Rotate X Axis Tick Text\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.tick.outer' }\n        %p Show x axis outer tick.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outer: false\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.tick.multiline' }\n        %p Enable multiline.\n        %br\n        %p If this option is set <code>true</code>, when a tick's text on the x-axis is too long, it splits the text into multiple lines in order to avoid text overlapping.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;multiline: true\n              &nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.tick.multilineMax' }\n        %p If this option is set and is above <code>0</code>, the number of lines will be adjusted to less than this value and tick's text is ellipsified.\n        %br\n        %h5 Default:\n        <code>0</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;multiline: true,\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;multilineMax: 2,\n              &nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.tick.width' }\n        %p not yet\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.max' }\n        %p Set max value of x axis range.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;max: 100\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.min' }\n        %p Set min value of x axis range.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;min: -100\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.padding' }\n        %p Set padding for x axis.\n        %br\n        %p If this option is set, the range of the x axis will increase/decrease by the values. If no padding is needed for the x axis, set the values to <code>0</code>. This option is ignored when the axis type is <code>category</code>.\n        %h5 Default:\n        <code>{}</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;padding: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;left: 0,\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;right: 0\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.height' }\n        %p Set height of x axis.\n        %br\n        %p The height of x axis can be set manually by this option. If you need more space for x axis, please use this option for that. The unit is <code>pixel</code>.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;height: 20\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.extent' }\n        %p Set default extent for subchart and zoom. This can be an array or function that returns an array.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;extent: [5, 10]\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.x.label' }\n        %p Set label on x axis.\n        %br\n        %p You can set x axis label and change its position by this option. <code>string</code> and <code>object</code> can be passed and we can change the position by passing <code>object</code> that has <span class=\"code\">position</span> key. Available position differs according to the axis direction (vertical or horizontal). If <code>string</code> set, the position will be the default.\n        %br\n        %p If it's horizontal axis:\n        %ul\n          %li inner-right <code>[default]</code>\n          %li inner-center\n          %li inner-left\n          %li outer-right\n          %li outer-center\n          %li outer-left\n        %p If it's vertical axis:\n        %ul\n          %li inner-top <code>[default]</code>\n          %li inner-middle\n          %li inner-bottom\n          %li outer-top\n          %li outer-middle\n          %li outer-bottom\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;label: 'Your X Axis'\n              &nbsp;&nbsp;}\n              }\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;label: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text: 'Your X Axis',\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position: 'outer-center'\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_label.html\" ) Axis Label\n          %li\n            %a( href=\"/samples/axes_label_position.html\" ) Axis Label Position\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.show' }\n        %p Show or hide y axis.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;show: false\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.inner' }\n        %p Show y axis inside of the chart.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;inner: true\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.type' }\n        %p Scale type for Y axis.\n        %h5 Available Values:\n        %ul\n          %li linear\n          %li time¹\n          %li timeseries¹\n          %li log² <span class=\"secondary label\">Experimental</span>\n        %p ¹: The <code>timeseries</code> scale is an alias of <code>time</code>.\n        %p ²: The <code>log</code> scale is experimental and may not work in all cases (stacked, etc.)\n        %h5 Default:\n        <code>linear</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;type: 'linear'\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.max' }\n        %p Set max value of y axis.\n        %h5 Note:\n        %p Padding will be added based on this value, so if you don't need the padding, please set <span class=\"code\">axis.y.padding</span> to disable it (e.g. <span class=\"code\">axis.y.padding = 0</span>).\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;max: 1000\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_y_range.html\" ) Y Axis Range\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.min' }\n        %p Set min value of y axis.\n        %h5 Note:\n        %p Padding will be added based on this value, so if you don't need the padding, please set <span class=\"code\">axis.y.padding</span> to disable it (e.g. <span class=\"code\">axis.y.padding = 0</span>).\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;min: 1000\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_y_range.html\" ) Y Axis Range\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.inverted' }\n        %p Change the direction of y axis.\n        %br\n        %p If <code>true</code> set, the direction will be from the top to the bottom.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;inverted: true\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.center' }\n        %p Set center value of y axis.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;center: 0\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.label' }\n        %p Set label on y axis.\n        %br\n        %p You can set y axis label and change its position by this option. This option works in the same way as <a href=\"#axis-x-label\">axis.x.label</a>.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;label: 'Your Y Axis'\n              &nbsp;&nbsp;}\n              }\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;label: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text: 'Your Y Axis',\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position: 'outer-middle'\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_label.html\" ) Axis Label\n          %li\n            %a( href=\"/samples/axes_label_position.html\" ) Axis Label Position\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.tick.format' }\n        %p Set formatter for y axis tick text.\n        %br\n        %p This option accepts <span class=\"code\">d3.format</span> object as well as a function you define.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format: d3.format('$,')\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//or format: function (d) { return '$' + d; }\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_y_tick_format.html\" ) Y Axis Tick Format\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.tick.outer' }\n        %p Show or hide outer tick.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outer: false\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.tick.values' }\n        %p Set y axis tick values manually.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;values: [100, 1000, 10000]\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.tick.count' }\n        %p Set the number of y axis ticks.\n        %h5 Note:\n        %p The position of the ticks will be calculated precisely, so the values on the ticks will not be rounded nicely. In the case, <span class=\"code\">axis.y.tick.format</span> or <span class=\"code\">axis.y.tick.values</span> will be helpful.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count: 5\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.tick.time.value' }\n        %p not yet\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.tick.time.interval' }\n        %p not yet\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.padding' }\n        %p Set padding for y axis.\n        %br\n        %p You can set padding for y axis to create more space on the edge of the axis. This option accepts <code>object</code> and it can include <span class=\"code\">top</span> and <span class=\"code\">bottom</span>. <span class=\"code\">top</span>, <span class=\"code\">bottom</span> will be treated as pixels.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;padding: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;top: 100,\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bottom: 100\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_y_padding.html\" ) Y Axis Tick Padding\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y.default' }\n        %p Set default range of y axis.\n        %br\n        %p This option set the default value for y axis when there is no data on init.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;default: [0, 1000]\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.show' }\n        %p Show or hide y2 axis.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;show: true\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.inner' }\n        %p Show y2 axis inside of the chart.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;inner: true\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.type' }\n        %p Scale type for Y2 axis.\n        %h5 Available Values:\n        %ul\n          %li linear\n          %li time¹\n          %li timeseries¹\n          %li log² <span class=\"secondary label\">Experimental</span>\n        %p ¹: The <code>timeseries</code> scale is an alias of <code>time</code>.\n        %p ²: The <code>log</code> scale is experimental and may not work in all cases (stacked, etc.)\n        %h5 Default:\n        <code>linear</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;type: 'linear'\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.max' }\n        %p Set max value of y2 axis.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;max: 1000\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.min' }\n        %p Set min value of y2 axis.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;min: -1000\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.inverted' }\n        %p Change the direction of y2 axis.\n        %br\n        %p If <code>true</code> set, the direction will be from the top to the bottom.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;inverted: true\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.center' }\n        %p Set center value of y2 axis.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;center: 0\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.label' }\n        %p Set label on y2 axis.\n        %br\n        %p You can set y2 axis label and change its position by this option. This option works in the same way as <a href=\"#axis-x-label\">axis.x.label</a>.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;label: 'Your Y2 Axis'\n              &nbsp;&nbsp;}\n              }\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;label: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text: 'Your Y2 Axis',\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position: 'outer-middle'\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/axes_label.html\" ) Axis Label\n          %li\n            %a( href=\"/samples/axes_label_position.html\" ) Axis Label Position\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.tick.format' }\n        %p Set formatter for y axis tick text.\n        %br\n        %p This option works in the same way as <a href=\"#axis-y-format\">axis.y.format</a>.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format: d3.format('$,')\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//or format: function (d) { return '$' + d; }\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.tick.outer' }\n        %p Show or hide y2 axis outer tick.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outer: false\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.tick.values' }\n        %p Set y2 axis tick values manually.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;values: [100, 1000, 10000]\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.tick.count' }\n        %p Set the number of y2 axis ticks.\n        %h5 Note:\n        %p This works in the same way as <a href=\"#axis-y-tick-count\">axis.y.tick.count</a>.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;tick: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count: 5\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.padding' }\n        %p Set padding for y2 axis.\n        %br\n        %p This works in the same way as <a href=\"#axis-y-padding\">axis.y.padding</a>.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;padding: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;top: 100,\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bottom: 100\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'axis.y2.default' }\n        %p Set default range of y2 axis.\n        %br\n        %p This option set the default value for y2 axis when there is no data on init.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              axis: {\n              &nbsp;&nbsp;y2: {\n              &nbsp;&nbsp;&nbsp;&nbsp;default: [0, 1000]\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'grid.x.show' }\n        %p Show grids along x axis.\n        %br\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              grid: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;show: true\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/options_gridline.html\" ) Grid Lines\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'grid.x.lines' }\n        %p Show additional grid lines along x axis.\n        %br\n        %p This option accepts <code>array</code> including <code>object</code> that has <span class=\"code\">value</span>, <span class=\"code\">text</span>, <span class=\"code\">position</span> and <span class=\"code\">class</span>. <span class=\"code\">text</span>, <span class=\"code\">position</span> and <span class=\"code\">class</span> are optional. For <span class=\"code\">position</span>, <span class=\"code\">start</span>, <span class=\"code\">middle</span> and <span class=\"code\">end</span> (default) are available.\n        %p If x axis is category axis, <span class=\"code\">value</span> can be category name. If x axis is timeseries axis, <span class=\"code\">value</span> can be date string, Date object and unixtime integer.\n        %h5 Default:\n        <code>[]</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              grid: {\n              &nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;lines: [\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{value: 2, text: 'Label on 2'},\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{value: 5, text: 'Label on 5', class: 'label-5'},\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{value: 6, text: 'Label on 6', position: 'start'}\n              &nbsp;&nbsp;&nbsp;&nbsp;]\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/grid_x_lines.html\" ) Additional X Grid Lines\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'grid.y.show' }\n        %p Show grids along y axis.\n        %br\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              grid: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;show: true\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/options_gridline.html\" ) Grid Lines\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'grid.y.lines' }\n        %p Show additional grid lines along y axis.\n        %br\n        %p This option accepts <code>array</code> including <code>object</code> that has <span class=\"code\">value</span>, <span class=\"code\">text</span>, <span class=\"code\">position</span> and <span class=\"code\">class</span>.\n        %h5 Default:\n        <code>[]</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              grid: {\n              &nbsp;&nbsp;y: {\n              &nbsp;&nbsp;&nbsp;&nbsp;lines: [\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{value: 100, text: 'Label on 100'},\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{value: 200, text: 'Label on 200', class: 'label-200'},\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{value: 300, text: 'Label on 300', position: 'middle'}\n              &nbsp;&nbsp;&nbsp;&nbsp;]\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/grid_y_lines.html\" ) Additional Y Grid Lines\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'grid.y.ticks' }\n        %p not yet\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'regions' }\n        %p Show rectangles inside the chart.\n        %br\n        %p This option accepts <code>array</code> including <code>object</code> that has <span class=\"code\">axis</span>, <span class=\"code\">start</span>, <span class=\"code\">end</span> and <span class=\"code\">class</span>. The keys <span class=\"code\">start</span>, <span class=\"code\">end</span> and <span class=\"code\">class</span> are optional.\n        %p <span class=\"code\">axis</span> must be <span class=\"code\">x</span>, <span class=\"code\">y</span> or <span class=\"code\">y2</span>. <span class=\"code\">start</span> and <span class=\"code\">end</span> should be the value where regions start and end. If not specified, the edge values will be used. If timeseries x axis, date string, Date object and unixtime integer can be used. If <span class=\"code\">class</span> is set, the region element will have it as class.\n        %h5 Default:\n        <code>[]</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              regions: [\n              &nbsp;&nbsp;{axis: 'x', start: 1, end: 4, class: 'region-1-4'}\n              ]\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/region.html\" ) Regions\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'legend.show' }\n        %p Show or hide legend.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              legend: {\n              &nbsp;&nbsp;show: true\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/options_legend.html\" ) Hide Legend\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'legend.hide' }\n        %p Hide legend\n        %br\n        %p If <code>true</code> given, all legend will be hidden. If <code>string</code> or <code>array</code> given, only the legend that has the id will be hidden.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              legend: {\n              &nbsp;&nbsp;hide: true\n              &nbsp;&nbsp;//or hide: 'data1'\n              &nbsp;&nbsp;//or hide: ['data1', 'data2']\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'legend.position' }\n        %p Change the position of legend.\n        %br\n        %p Currently <span class=\"code\">bottom</span>, <span class=\"code\">right</span> and <span class=\"code\">inset</span> are supported.\n        %h5 Default:\n        <code>bottom</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              legend: {\n              &nbsp;&nbsp;position: 'bottom'\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/legend_position.html\" ) Legend Position\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'legend.inset' }\n        %p Change inset legend attributes.\n        %br\n        %p This option accepts <code>object</code> that has the keys <span class=\"code\">anchor</span>, <span class=\"code\">x</span>, <span class=\"code\">y</span> and <span class=\"code\">step</span>.\n        %p <span class=\"code\">anchor</span> decides the position of the legend. These anchors are available:\n        %ul\n          %li top-left\n          %li top-right\n          %li bottom-left\n          %li bottom-right\n        %p <span class=\"code\">x</span> and <span class=\"code\">y</span> set the position of the legend based on the anchor.\n        %p <span class=\"code\">step</span> defines the max step the legend has (e.g. If 2 set and legend has 3 legend item, the legend 2 columns).\n        %h5 Default:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              {\n              &nbsp;&nbsp;anchor: 'top-left',\n              &nbsp;&nbsp;x: 10,\n              &nbsp;&nbsp;y: 0,\n              &nbsp;&nbsp;step: undefined\n              }\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              legend: {\n              &nbsp;&nbsp;inset: {\n              &nbsp;&nbsp;&nbsp;&nbsp;anchor: 'top-right',\n              &nbsp;&nbsp;&nbsp;&nbsp;x: 20,\n              &nbsp;&nbsp;&nbsp;&nbsp;y: 10,\n              &nbsp;&nbsp;&nbsp;&nbsp;step: 2\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'legend.item.onclick' }\n        %p Set click event handler to the legend item.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              legend: {\n              &nbsp;&nbsp;item: {\n              &nbsp;&nbsp;&nbsp;&nbsp;onclick: function (id) { ... }\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/legend_custom.html\" ) Custom Legend\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'legend.item.onmouseover' }\n        %p Set mouseover event handler to the legend item.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              legend: {\n              &nbsp;&nbsp;item: {\n              &nbsp;&nbsp;&nbsp;&nbsp;onmouseover: function (id) { ... }\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/legend_custom.html\" ) Custom Legend\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'legend.item.onmouseout' }\n        %p Set mouseout event handler to the legend item.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              legend: {\n              &nbsp;&nbsp;item: {\n              &nbsp;&nbsp;&nbsp;&nbsp;onmouseout: function (id) { ... }\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/legend_custom.html\" ) Custom Legend\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'tooltip.show' }\n        %p Show or hide tooltip.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              tooltip: {\n              &nbsp;&nbsp;show: false\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/tooltip_show.html\" ) Hide Tooltip\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'tooltip.grouped' }\n        %p Set if tooltip is grouped or not for the data points.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              tooltip: {\n              &nbsp;&nbsp;grouped: false\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/tooltip_grouped.html\" ) Tooltip Grouping\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'tooltip.format.title' }\n        %p Set format for the title of tooltip.\n        %br\n        %p Specified function receives <span class=\"code\">x</span> and <span class=\"code\">index</span> of the data point to show.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              tooltip: {\n              &nbsp;&nbsp;format: {\n              &nbsp;&nbsp;&nbsp;&nbsp;title: function (x, index) { return 'Data ' + x; }\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/tooltip_format.html\" ) Tooltip Format\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'tooltip.format.name' }\n        %p Set format for the name of each data in tooltip.\n        %br\n        %p Specified function receives <span class=\"code\">name</span>, <span class=\"code\">ratio</span>, <span class=\"code\">id</span> and <span class=\"code\">index</span> of the data point to show. <span class=\"code\">ratio</span> will be <code>undefined</code> if the chart is not donut/pie/gauge.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              tooltip: {\n              &nbsp;&nbsp;format: {\n              &nbsp;&nbsp;&nbsp;&nbsp;name: function (name, ratio, id, index) { return name; }\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/tooltip_format.html\" ) Tooltip Format\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'tooltip.format.value' }\n        %p Set format for the value of each data in tooltip.\n        %br\n        %p Specified function receives <span class=\"code\">name</span>, <span class=\"code\">ratio</span>, <span class=\"code\">id</span> and <span class=\"code\">index</span> of the data point to show. <span class=\"code\">ratio</span> will be <code>undefined</code> if the chart is not donut/pie/gauge.\n        %p If <code>undefined</code> returned, the row of that value will be skipped.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              tooltip: {\n              &nbsp;&nbsp;format: {\n              &nbsp;&nbsp;&nbsp;&nbsp;value: function (value, ratio, id, index) { return ratio; }\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/tooltip_format.html\" ) Tooltip Format\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'tooltip.position' }\n        %p Set custom position for the tooltip.\n        %br\n        %p This option can be used to modify the tooltip position by returning <code>object</code> that has <span class=\"code\">top</span> and <span class=\"code\">left</span>.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              tooltip: {\n              &nbsp;&nbsp;position: function (data, width, height, element) {\n              &nbsp;&nbsp;&nbsp;&nbsp;return {top: 0, left: 0};\n              &nbsp;&nbsp;}\n              }\n        %h5 Reference:\n        %ul\n          %li\n            %a( href=\"https://github.com/c3js/c3/pull/833\" ) Introduce tooltip.position callback function #833\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'tooltip.contents' }\n        %p Set custom HTML for the tooltip.\n        %br\n        %p Specified function receives <span class=\"code\">data</span>, <span class=\"code\">defaultTitleFormat</span>, <span class=\"code\">defaultValueFormat</span> and <span class=\"code\">color</span> of the data point to show. If <span class=\"code\">tooltip.grouped</span> is <code>true</code>, <span class=\"code\">data</span> includes multiple data points.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              tooltip: {\n              &nbsp;&nbsp;contents: function (d, defaultTitleFormat, defaultValueFormat, color) {\n              &nbsp;&nbsp;&nbsp;&nbsp;return ... // formatted html as you want\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'tooltip.horizontal' }\n        %p Show the tooltips based on the horizontal position of the mouse.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              tooltip: {\n              &nbsp;&nbsp;horizontal: true\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/tooltip_horizontal.html\" ) Horizontal tooltip\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'subchart.show', experimental: true }\n        %p Show sub chart on the bottom of the chart.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              subchart: {\n              &nbsp;&nbsp;show: true\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/options_subchart.html\" ) Subchart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'subchart.size.height', experimental: true }\n        %p Change the height of the subchart.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              subchart: {\n              &nbsp;&nbsp;size: {\n              &nbsp;&nbsp;&nbsp;&nbsp;height: 20\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'subchart.onbrush', experimental: true }\n        %p Set callback for brush event.\n        %br\n        %p Specified function receives the current zoomed x domain.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              subchart: {\n              &nbsp;&nbsp;onbrush: function (domain) { ... }\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'subchart.axis.x.show', experimental: true }\n        %p Show or hide x axis of subchart.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              subchart: {\n              &nbsp;&nbsp;axis: {\n              &nbsp;&nbsp;&nbsp;&nbsp;x: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;show: true\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'zoom.enabled', experimental: true }\n        %p Enable zooming.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              zoom: {\n              &nbsp;&nbsp;enabled: false\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/interaction_zoom.html\" ) Zoom\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'zoom.type', experimental: true }\n        %p There are two types of zoom behavior: 'scroll' and 'drag'\n        %h5 Default:\n        <code>'scroll'</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              zoom: {\n              &nbsp;&nbsp;type: 'drag'\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/interaction_zoom_by_drag.html\" ) Zoom by Drag\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'zoom.rescale', experimental: true }\n        %p Enable to rescale after zooming.\n        %br\n        %p If <code>true</code> set, y domain will be updated according to the zoomed region.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              zoom: {\n              &nbsp;&nbsp;rescale: true\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'zoom.extent', experimental: true }\n        %p Change zoom extent.\n        %h5 Default:\n        <code>[1, 10]</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              zoom: {\n              &nbsp;&nbsp;extent: [1, 100] // enable more zooming\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'zoom.onzoom', experimental: true }\n        %p Set callback that is called when the chart is zooming.\n        %br\n        %p Specified function receives the zoomed domain.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              zoom: {\n              &nbsp;&nbsp;onzoom: function (domain) { ... }\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'zoom.onzoomstart', experimental: true }\n        %p Set callback that is called when zooming starts.\n        %br\n        %p Specified function receives the zoom event.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              zoom: {\n              &nbsp;&nbsp;onzoomstart: function (event) { ... }\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'zoom.onzoomend', experimental: true }\n        %p Set callback that is called when zooming ends.\n        %br\n        %p Specified function receives the zoomed domain.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              zoom: {\n              &nbsp;&nbsp;onzoomend: function (domain) { ... }\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'zoom.disableDefaultBehavior', experimental: true }\n        %p Disable the default animation of zoom. This option is useful when you want to get the zoomed domain by onzoom or onzoomend handlers and override the default animation behavior. See <a href=\"https://github.com/c3js/c3/pull/2439\">#2439</a> for details.\n\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              zoom: {\n              &nbsp;&nbsp;enabled: true,\n              &nbsp;&nbsp;disableDefaultBehavior: true,\n              &nbsp;&nbsp;onzoomend: d => console.log(d)\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'point.show' }\n        %p Whether to show each point in line.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              point: {\n              &nbsp;&nbsp;show: false\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'point.r' }\n        %p The radius size of each point.\n        %h5 Default:\n        <code>2.5</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              point: {\n              &nbsp;&nbsp;r: 5\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'point.focus.expand.enabled' }\n        %p Whether to expand each point on focus.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              point: {\n              &nbsp;&nbsp;focus: {\n              &nbsp;&nbsp;&nbsp;&nbsp;expand: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enabled: true\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'point.focus.expand.r' }\n        %p The radius size of each point on focus.\n        %h5 Default:\n        <code>point.r * 1.75</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              point: {\n              &nbsp;&nbsp;focus: {\n              &nbsp;&nbsp;&nbsp;&nbsp;expand: {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r: 1\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'point.select.r' }\n        %p The radius size of each point on selected.\n        %h5 Default:\n        <code>point.r * 4</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              point: {\n              &nbsp;&nbsp;select: {\n              &nbsp;&nbsp;&nbsp;&nbsp;r: 3\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'line.connectNull' }\n        %p Set if null data point will be connected or not.\n        %br\n        %p If <code>true</code> set, the region of null data will be connected without any data point. If <code>false</code> set, the region of null data will not be connected and get empty.\n        %h5 Default:\n        <code>false</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              line: {\n              &nbsp;&nbsp;connectNull: true\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'line.step.type' }\n        %p Change step type for step chart.\n        %br\n        %p <span class=\"code\">step</span>, <span class=\"code\">step-before</span> and <span class=\"code\">step-after</span> can be used.\n        %h5 Default:\n        <code>'step'</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              line: {\n              &nbsp;&nbsp;step: {\n              &nbsp;&nbsp;&nbsp;&nbsp;type: 'step-after'\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'area.zerobased' }\n        %p Set if min or max value will be 0 on area chart.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              area: {\n              &nbsp;&nbsp;zerobased: false\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'bar.width' }\n        %p Change the width of bar chart.\n        %h5 Default:\n        <code>auto</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              bar: {\n              &nbsp;&nbsp;width: 10\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_bar.html\" ) Bar Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'bar.width.ratio' }\n        %p Change the width of bar chart by ratio.\n        %h5 Default:\n        <code>0.6</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              bar: {\n              &nbsp;&nbsp;width: {\n              &nbsp;&nbsp;&nbsp;&nbsp;ratio: 0.2\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_bar.html\" ) Bar Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'bar.zerobased' }\n        %p Set if min or max value will be 0 on bar chart.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              bar: {\n              &nbsp;&nbsp;zerobased: false\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'pie.label.show' }\n        %p Show or hide label on each pie piece.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              pie: {\n              &nbsp;&nbsp;label: {\n              &nbsp;&nbsp;&nbsp;&nbsp;show: false\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'pie.label.format' }\n        %p Set formatter for the label on each pie piece.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              pie: {\n              &nbsp;&nbsp;label: {\n              &nbsp;&nbsp;&nbsp;&nbsp;format: function (value, ratio, id) {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return d3.format('$')(value);\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/pie_label_format.html\" ) Pie Label Format\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'pie.label.threshold' }\n        %p Set threshold to show/hide labels.\n        %h5 Default:\n        <code>0.05</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              pie: {\n              &nbsp;&nbsp;label: {\n              &nbsp;&nbsp;&nbsp;&nbsp;threshold: 0.1\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'pie.expand' }\n        %p Enable or disable expanding pie pieces.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              pie: {\n              &nbsp;&nbsp;expand: false\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'pie.padAngle' }\n        %p Sets the angular separation between each adjacent arc.\n        %h5 Default:\n        <code>0</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              pie: {\n              &nbsp;&nbsp;padAngle: .1\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'donut.label.show' }\n        %p Show or hide label on each donut piece.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              donut: {\n              &nbsp;&nbsp;label: {\n              &nbsp;&nbsp;&nbsp;&nbsp;show: false\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'donut.label.format' }\n        %p Set formatter for the label on each donut piece.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              donut: {\n              &nbsp;&nbsp;label: {\n              &nbsp;&nbsp;&nbsp;&nbsp;format: function (value, ratio, id) {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return d3.format('$')(value);\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'donut.label.threshold' }\n        %p Set threshold to show/hide labels.\n        %h5 Default:\n        <code>0.05</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              donut: {\n              &nbsp;&nbsp;label: {\n              &nbsp;&nbsp;&nbsp;&nbsp;threshold: 0.1\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'donut.expand' }\n        %p Enable or disable expanding donut pieces.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              donut: {\n              &nbsp;&nbsp;expand: false\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'donut.padAngle' }\n        %p Sets the angular separation between each adjacent arc.\n        %h5 Default:\n        <code>0</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              donut: {\n              &nbsp;&nbsp;padAngle: .1\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'donut.width' }\n        %p Set width of donut chart.\n        %h5 Default:\n        <code>auto</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              donut: {\n              &nbsp;&nbsp;width: 10\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'donut.title' }\n        %p Set title of donut chart.\n        %h5 Default:\n        <code>''</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              donut: {\n              &nbsp;&nbsp;title: 'Title'\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'gauge.label.show' }\n        %p Show or hide label on gauge.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              gauge: {\n              &nbsp;&nbsp;label: {\n              &nbsp;&nbsp;&nbsp;&nbsp;show: false\n              &nbsp;&nbsp;}\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'gauge.label.format' }\n        %p Set formatter for the label on gauge.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              gauge: {\n              &nbsp;&nbsp;label: {\n              &nbsp;&nbsp;&nbsp;&nbsp;format: function (value, ratio) {\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return value;\n              &nbsp;&nbsp;&nbsp;&nbsp;}\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_gauge.html\" ) Gauge Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'gauge.expand' }\n        %p Enable or disable expanding gauge.\n        %h5 Default:\n        <code>true</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              gauge: {\n              &nbsp;&nbsp;expand: false\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'gauge.min' }\n        %p Set min value of the gauge.\n        %h5 Default:\n        <code>0</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              gauge: {\n              &nbsp;&nbsp;min: -100\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'gauge.max' }\n        %p Set max value of the gauge.\n        %h5 Default:\n        <code>100</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              gauge: {\n              &nbsp;&nbsp;max: 200\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'gauge.units' }\n        %p Set units of the gauge.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              gauge: {\n              &nbsp;&nbsp;units: ' %'\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'gauge.width' }\n        %p Set width of gauge chart.\n        %h5 Default:\n        <code>auto</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              gauge: {\n              &nbsp;&nbsp;width: 10\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'spline.interpolation.type' }\n        %p Set type of curve interpolation.\n        %h5 Default:\n        <code>cardinal</code>\n        %p Available interpolation are:\n        %ul\n          %li linear\n          %li linear-closed\n          %li basis\n          %li basis-open\n          %li basis-closed\n          %li bundle\n          %li cardinal <code>[default]</code>\n          %li cardinal-open\n          %li cardinal-closed\n          %li monotone\n          %li step\n          %li step-before\n          %li step-after\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              interpolation: {\n              &nbsp;&nbsp;type: \"monotone\"\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'stanford.scaleMin' }\n        %p Change the minimum value of the stanford color scale.\n        %h5 Default:\n        <code>auto</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              stanford: {\n              &nbsp;&nbsp;scaleMin: 1\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_stanford.html\" ) Stanford Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'stanford.scaleMax' }\n        %p Change the maximum value of the stanford color scale.\n        %h5 Default:\n        <code>auto</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              stanford: {\n              &nbsp;&nbsp;scaleMax: 10000\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_stanford.html\" ) Stanford Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'stanford.scaleWidth' }\n        %p Change the width of the stanford color scale.\n        %h5 Default:\n        <code>20</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              stanford: {\n              &nbsp;&nbsp;scaleWidth: 20\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_stanford.html\" ) Stanford Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'stanford.scaleFormat' }\n        %p Set formatter for stanford color scale axis tick text.\n        %br\n        %p This option accepts the string <span class=\"code\">'pow10'</span>, a d3.format object and any function you define.\n        %h5 Default:\n        <code>d3.format(\"d\")</code> - decimal notation, rounded to integer\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              stanford: {\n              &nbsp;&nbsp;scaleFormat: 'pow10'\n              &nbsp;&nbsp;// or d3.format(\"d\")\n              &nbsp;&nbsp;// or a function\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_stanford.html\" ) Stanford Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'stanford.scaleValues' }\n        %p Set the values for stanford color scale axis tick text.\n        %br\n        %p This option accepts a function that returns an array of numbers.\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              stanford: {\n              &nbsp;&nbsp;scaleValues: (minValue, maxValue) => {\n              &nbsp;&nbsp;&nbsp;&nbsp;const step = (maxValue - minValue) / 10;\n              &nbsp;&nbsp;&nbsp;&nbsp;return d3.range(minValue, maxValue + step, step);\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_stanford.html\" ) Stanford Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'stanford.colors' }\n        %p Set the color interpolator for stanford color scale.\n        %br\n        %p This option is a d3.interpolate* object or any function you define that receives a value between 0 and 1, and returns a color as string.\n        %h5 Default:\n        <code>d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5))</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              stanford: {\n              &nbsp;&nbsp;colors: d3.interpolatePlasma\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_stanford.html\" ) Stanford Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'stanford.padding' }\n        %p Set the padding for the stanford color scale.\n\n        %p This option accepts <code>array</code> including <code>object</code> that has <span class=\"code\">top</span>, <span class=\"code\">right</span>, <span class=\"code\">bottom</span> and <span class=\"code\">left</span>.\n\n        %h5 Default:\n        <code>undefined</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              stanford: {\n              &nbsp;&nbsp;padding: {\n              &nbsp;&nbsp;&nbsp;&nbsp;top: 15,\n              &nbsp;&nbsp;&nbsp;&nbsp;right: 0,\n              &nbsp;&nbsp;&nbsp;&nbsp;bottom: 0,\n              &nbsp;&nbsp;&nbsp;&nbsp;left: 0\n              &nbsp;&nbsp;}\n              }\n        %h5 Example:\n        %ul\n          %li\n            %a( href=\"/samples/chart_stanford.html\" ) Stanford Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'stanford.texts' }\n        %p Show text anywhere inside the chart.\n        %br\n        %p This option accepts <code>array</code> including <code>object</code> that has <span class=\"code\">x</span>, <span class=\"code\">y</span>, <span class=\"code\">content</span> and <span class=\"code\">class</span>. The key <span class=\"code\">class</span> is optional.\n        %p <span class=\"code\">x</span> and <span class=\"code\">y</span> are the starting position of the text, <span class=\"code\">content</span> is the text content to show. If <span class=\"code\">class</span> is set, the text element will have it as class.\n        %h5 Default:\n        <code>[]</code>\n        %h5 Format:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              stanford: {\n              &nbsp;&nbsp;texts: [\n              &nbsp;&nbsp;&nbsp;&nbsp;{x: 1, y: 4, content: 'my custom text here', class: 'text-1-4'}\n              &nbsp;&nbsp;]\n              }\n        %hr\n\n        %section\n          %h3\n            = partial :reference_item_link, locals: { id: 'stanford.lines' }\n          %p Show lines anywhere inside the chart.\n          %br\n          %p This option accepts <code>array</code> including <code>object</code> that has <span class=\"code\">value_x1</span>, <span class=\"code\">value_y1</span>, <span class=\"code\">value_x2</span>, <span class=\"code\">value_y2</span> and <span class=\"code\">class</span>. The key <span class=\"code\">class</span> is optional.\n          %p <span class=\"code\">value_x1</span> and <span class=\"code\">value_y1</span> are the starting position of the line, <span class=\"code\">value_x2</span> and <span class=\"code\">value_y2</span> are the ending position of the line. If <span class=\"code\">class</span> is set, the line element will have it as class.\n          %h5 Default:\n          <code>[]</code>\n          %h5 Format:\n          %div.sourcecode\n            %pre\n              %code.html.javascript\n                stanford: {\n                &nbsp;&nbsp;lines: [\n                &nbsp;&nbsp;&nbsp;&nbsp;{value_x1: 0, value_y1: 0, value_x2: 65, value_y2: 65, class: \"line-0-65\"}\n                &nbsp;&nbsp;]\n                }\n        %hr\n\n        %section\n          %h3\n            = partial :reference_item_link, locals: { id: 'stanford.regions' }\n          %p Show regions anywhere inside the chart.\n          %br\n          %p This option accepts <code>array</code> including <code>object</code> that has <span class=\"code\">points</span>, <span class=\"code\">text</span>, <span class=\"code\">opacity</span> and <span class=\"code\">class</span>. The keys <span class=\"code\">text</span>, <span class=\"code\">opacity</span> and <span class=\"code\">class</span> are optional.\n          %p <span class=\"code\">points</span> accepts <code>array</code> including <code>object</code> that has <span class=\"code\">x</span> and <span class=\"code\">y</span> that represent the coordinates of each point.\n          %p <span class=\"code\">text</span> accepts <code>function</code> that returns a <code>string</code> with the text to show. If the current chart type is stanford the function receives <span class=\"code\">value</span> and <span class=\"code\">percentage</span> as parameters that represent the number of points in this region.\n          %p <span class=\"code\">opacity</span> accepts a number between 0 and 1, the default <span class=\"code\">opacity</span> is 0.2.\n          %p If <span class=\"code\">class</span> is set, the line element will have it as class.\n          %b\n          %h5 Note:\n          %p Points should be added in  a counter-clockwise direction to close the polygon.\n          %h5 Default:\n          <code>[]</code>\n          %h5 Format:\n          %div.sourcecode\n            %pre\n              %code.html.javascript\n                stanford: {\n                &nbsp;&nbsp;regions: [\n                &nbsp;&nbsp;&nbsp;&nbsp;{\n                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;points: [ // add points counter-clockwise\n                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{x: 0, y: 0},\n                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{x: 40, y: 40},\n                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{x: 0, y: 40}\n                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;],\n                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text: function (value, percentage) {\n                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return \"Normal Operations: \" + value + \" (\" + percentage + \"%)\";\n                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},\n                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;opacity: 0.2, // 0 to 1\n                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class: \"region-triangle-1\"\n                &nbsp;&nbsp;&nbsp;&nbsp;}\n                &nbsp;&nbsp;]\n                }\n      %hr\n\n      %br\n      %section\n        %h2 API\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.focus' }\n        %p This API highlights specified targets and fade out the others.\n        %br\n        %p You can specify multiple targets by giving an array that includes <span class=\"code\">id</span> as <code>String</code>. If no argument is given, all of targets will be highlighted.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.focus(targetIds)\n        %p <span class=\"code\">targetIds</span>&nbsp;&nbsp;<code>String</code> or <code>Array</code>\n        %p Target ids to be highlighted.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// data1 will be highlighted and the others will be faded out\n              chart.focus('data1');\n              \\\n              \\// data1 and data2 will be highlighted and the others will be faded out\n              chart.focus(['data1', 'data2']);\n              \\\n              \\// all targets will be highlighted\n              chart.focus();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.defocus' }\n        %p This API fades out specified targets and reverts the others.\n        %br\n        %p You can specify multiple targets by giving an array that includes <span class=\"code\">id</span> as <code>String</code>. If no argument is given, all of targets will be faded out.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.defocus(targetIds)\n        %p <span class=\"code\">targetIds</span>&nbsp;&nbsp;<code>String</code> or <code>Array</code>\n        %p Target ids to be faded out.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// data1 will be faded out and the others will be reverted.\n              chart.defocus('data1');\n              \\\n              \\// data1 and data2 will be faded out and the others will be reverted.\n              chart.defocus(['data1', 'data2']);\n              \\\n              \\// all targets will be faded out.\n              chart.defocus();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.revert' }\n        %p This API reverts specified targets.\n        %br\n        %p You can specify multiple targets by giving an array that includes <span class=\"code\">id</span> as <code>String</code>. If no argument is given, all of targets will be reverted.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.revert(targetIds)\n        %p <span class=\"code\">targetIds</span>&nbsp;&nbsp;<code>String</code> or <code>Array</code>\n        %p Target ids to be reverted.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// data1 will be reverted.\n              chart.revert('data1');\n              \\\n              \\// data1 and data2 will be reverted.\n              chart.revert(['data1', 'data2']);\n              \\\n              \\// all targets will be reverted.\n              chart.revert();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.show' }\n        %p This API shows specified targets.\n        %br\n        %p You can specify multiple targets by giving an array that includes <span class=\"code\">id</span> as <code>String</code>. If no argument is given, all of targets will be shown.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.show(targetIds, options)\n        %p <span class=\"code\">targetIds</span>&nbsp;&nbsp;<code>String</code> or <code>Array</code>\n        %p Target ids to be shown.\n        %br\n        %p <span class=\"code\">options</span>&nbsp;&nbsp;<code>Object</code>\n        %p If <span class=\"code\">withLegend</span> is set <code>true</code>, legend will be shown together with the specified data.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// data1 will be shown.\n              chart.show('data1');\n              \\\n              \\// data1 and data2 will be shown.\n              chart.show(['data1', 'data2']);\n              \\\n              \\// all targets will be shown.\n              chart.show();\n              \\\n              \\// data1 will be shown together with its legend.\n              chart.show('data1', {withLegend: true});\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.hide' }\n        %p This API hides specified targets.\n        %br\n        %p You can specify multiple targets by giving an array that includes <span class=\"code\">id</span> as <code>String</code>. If no argument is given, all of targets will be hidden.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.hide(targetIds, options)\n        %p <span class=\"code\">targetIds</span>&nbsp;&nbsp;<code>String</code> or <code>Array</code>\n        %p Target ids to be hidden.\n        %br\n        %p <span class=\"code\">options</span>&nbsp;&nbsp;<code>Object</code>\n        %p If <span class=\"code\">withLegend</span> is set <code>true</code>, legend will be hidden together with the specified data.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// data1 will be hidden.\n              chart.hide('data1');\n              \\\n              \\// data1 and data2 will be hidden.\n              chart.hide(['data1', 'data2']);\n              \\\n              \\// all targets will be hidden.\n              chart.hide();\n              \\\n              \\// data1 will be hidden together with its legend.\n              chart.hide('data1', {withLegend: true});\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.toggle' }\n        %p This API toggles (shows or hides) specified targets.\n        %br\n        %p You can specify multiple targets by giving an array that includes <span class=\"code\">id</span> as <code>String</code>. If no argument is given, all of targets will be toggles.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.toggle(targetIds, options)\n        %p <span class=\"code\">targetIds</span>&nbsp;&nbsp;<code>String</code> or <code>Array</code>\n        %p Target ids to be toggled.\n        %br\n        %p <span class=\"code\">options</span>&nbsp;&nbsp;<code>Object</code>\n        %p If <span class=\"code\">withLegend</span> is set <code>true</code>, legend will be toggled together with the specified data.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// data1 will be toggled.\n              chart.toggle('data1');\n              \\\n              \\// data1 and data2 will be toggled.\n              chart.toggle(['data1', 'data2']);\n              \\\n              \\// all targets will be toggled.\n              chart.toggle();\n              \\\n              \\// data1 will be toggled together with its legend.\n              chart.toggle('data1', {withLegend: true});\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.load' }\n        %p Load data to the chart.\n        %br\n        %p You can specify multiple targets by giving an array that includes <span class=\"code\">id</span> as <code>String</code>. If no argument is given, all of targets will be toggles.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.load(args)\n        %p <span class=\"code\">args</span>&nbsp;&nbsp;<code>Object</code>\n        %p If <span class=\"code\">url</span>, <span class=\"code\">json</span>, <span class=\"code\">rows</span> and <span class=\"code\">columns</span> given, the data will be loaded. If data that has the same target id is given, the chart will be updated. Otherwise, new target will be added.\n        %br\n        %p If <span class=\"code\">classes</span> given, the classes specified by <span class=\"code\">data.classes</span> will be updated. <span class=\"code\">classes</span> must be <code>Object</code> that has target id as keys.\n        %br\n        %p If <span class=\"code\">categories</span> given, the categories specified by <span class=\"code\">axis.x.categories</span> or <span class=\"code\">data.x</span> will be updated. <span class=\"code\">categories</span> must be <code>Array</code>.\n        %br\n        %p If <span class=\"code\">axes</span> given, the axes specified by <span class=\"code\">data.axes</span> will be updated. <span class=\"code\">axes</span> must be <code>Object</code> that has target id as keys.\n        %br\n        %p If <span class=\"code\">colors</span> given, the colors specified by <span class=\"code\">data.colors</span> will be updated. <span class=\"code\">colors</span> must be <code>Object</code> that has target id as keys.\n        %br\n        %p If <span class=\"code\">type</span> or <span class=\"code\">types</span> given, the type of targets will be updated. <span class=\"code\">type</span> must be <code>String</code> and <span class=\"code\">types</span> must be <code>Object</code>.\n        %br\n        %p If <span class=\"code\">unload</span> given, data will be unloaded before loading new data. If <code>true</code> given, all of data will be unloaded. If target ids given as <code>String</code> or <code>Array</code>, specified targets will be unloaded.\n        %br\n        %p If <span class=\"code\">done</span> given, the specified function will be called after data loded.\n\n        %h5 Note:\n        %p <span class=\"code\">unload</span> should be used if some data needs to be unloaded simultaneously. If you call <span class=\"code\">unload</span> API soon after/before <span class=\"code\">load</span> instead of <span class=\"code\">unload</span> param, chart will not be rendered properly because of cancel of animation.\n        %br\n        %p <span class=\"code\">done</span> will be called after data loaded, but it's not after rendering. It's because rendering will finish after some transition and there is some time lag between loading and rendering.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Load data1 and unload data2 and data3\n              chart.load({\n              &nbsp;&nbsp;columns: [\n              &nbsp;&nbsp;&nbsp;&nbsp;['data1', 100, 200, 150, ...],\n              &nbsp;&nbsp;&nbsp;&nbsp;...\n              &nbsp;&nbsp;],\n              &nbsp;&nbsp;unload: ['data2', 'data3']\n              });\n        %ul\n          %li\n            %a( href=\"/samples/data_load.html\" ) Load Data\n          %li\n            %a( href=\"/samples/data_stringx.html\" ) Load Category Data\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.unload' }\n        %p Unload data to the chart.\n        %br\n        %p You can specify multiple targets by giving an array that includes <span class=\"code\">id</span> as <code>String</code>. If no argument is given, all of targets will be toggles.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.unload(args)\n        %p <span class=\"code\">args</span>&nbsp;&nbsp;<code>Object</code>\n        %p If <span class=\"code\">ids</span> given, the data that has specified target id will be unloaded. <span class=\"code\">ids</span> should be <code>String</code> or <code>Array</code>. If <span class=\"code\">ids</span> is not specified, all data will be unloaded.\n        %br\n        %p If <span class=\"code\">done</span> given, the specified function will be called after data loded.\n\n        %h5 Note:\n        %p If you call <span class=\"code\">load</span> API soon after/before <span class=\"code\">unload</span>, <span class=\"code\">unload</span> param of <span class=\"code\">load</span> should be used. Otherwise chart will not be rendered properly because of cancel of animation.\n        %br\n        %p <span class=\"code\">done</span> will be called after data loaded, but it's not after rendering. It's because rendering will finish after some transition and there is some time lag between loading and rendering.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Unload data2 and data3\n              chart.unload({\n              &nbsp;&nbsp;ids: ['data2', 'data3']\n              });\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.flow' }\n        %p Flow data to the chart.\n        %br\n        %p By this API, you can append new data points to the chart.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.flow(args)\n        %p <span class=\"code\">args</span>&nbsp;&nbsp;<code>Object</code>\n        %p If <span class=\"code\">json</span>, <span class=\"code\">rows</span> and <span class=\"code\">columns</span> given, the data will be loaded. If data that has the same target id is given, the chart will be appended. Otherwise, new target will be added. One of these is required when calling. If <span class=\"code\">json</span> specified, <span class=\"code\">keys</span> is required as well as <a href=\"#data-json\">data.json</a>\n        %br\n        %p If <span class=\"code\">to</span> is given, the lower x edge will move to that point. If not given, the lower x edge will move by the number of given data points.\n        %br\n        %p If <span class=\"code\">length</span> is given, the lower x edge will move by the number of this argument.\n        %br\n        %p If <span class=\"code\">duration</span> is given, the duration of the transition will be specified value. If not given, <a href=\"#transition-duration\">transition.duration</a> will be used as default.\n        %br\n        %p If <span class=\"code\">done</span> is given, the specified function will be called when flow ends.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// 2 data points will be apprended to the tail and popped from the head.\n              \\// After that, 4 data points will be appended and no data points will be poppoed.\n              chart.flow({\n              &nbsp;&nbsp;columns: [\n              &nbsp;&nbsp;&nbsp;&nbsp;['x', '2013-01-11', '2013-01-21'],\n              &nbsp;&nbsp;&nbsp;&nbsp;['data1', 500, 200],\n              &nbsp;&nbsp;&nbsp;&nbsp;['data2', 100, 300],\n              &nbsp;&nbsp;&nbsp;&nbsp;['data3', 200, 120]\n              &nbsp;&nbsp;],\n              &nbsp;&nbsp;done: function () {\n              &nbsp;&nbsp;&nbsp;&nbsp;chart.flow({\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;columns: [\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['x', '2013-02-11', '2013-02-12', '2013-02-13', '2013-02-14'],\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['data1', 200, 300, 100, 250],\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['data2', 100, 90, 40, 120],\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;['data3', 100, 100, 300, 500]\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;],\n              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;length: 0\n              &nbsp;&nbsp;&nbsp;&nbsp;});\n              &nbsp;&nbsp;}\n              });\n        %ul\n          %li\n            %a( href=\"/samples/api_flow.html\" ) Flow\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.select' }\n        %p Change data point state to selected.\n        %br\n        %p By this API, you can select data points. To use this API, <a href=\"#data-selection-enabled\">data.selection.enabled</a> needs to be set <code>true</code>.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.select(ids, indices, resetOthers)\n        %p <span class=\"code\">ids</span>&nbsp;&nbsp;<code>Array</code>\n        %p Specify target ids to be selected. If this argument is not given, all targets will be the candidate.\n        %br\n        %p <span class=\"code\">indices</span>&nbsp;&nbsp;<code>Array</code>\n        %p Specify indices to be selected. If this argument is not given, all data points will be the candidate.\n        %br\n        %p <span class=\"code\">resetOthers</span>&nbsp;&nbsp;<code>boolean</code>\n        %p If this argument is set <code>true</code>, the data points that are not specified by <span class=\"code\">ids</span>, <span class=\"code\">indices</span> will be unselected.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// all data points of data1 will be selected.\n              chart.select(['data1']);\n              \\\n              \\// 3 data points on index 1, 3, 5 of data1 will be selected.\n              chart.select(['data1'], [1,3,5]);\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.unselect' }\n        %p Change data point state to unselected.\n        %br\n        %p By this API, you can unselect data points. To use this API, <a href=\"#data-selection-enabled\">data.selection.enabled</a> needs to be set <code>true</code>.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.unselect(ids, indices)\n        %p <span class=\"code\">ids</span>&nbsp;&nbsp;<code>Array</code>\n        %p Specify target ids to be unselected. If this argument is not given, all targets will be the candidate.\n        %br\n        %p <span class=\"code\">indices</span>&nbsp;&nbsp;<code>Array</code>\n        %p Specify indices to be unselected. If this argument is not given, all data points will be the candidate.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// all data points of data1 will be unselected.\n              chart.unselect(['data1']);\n              \\\n              \\// 3 data points on index 1, 3, 5 of data1 will be unselected.\n              chart.unselect(['data1'], [1,3,5]);\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.selected' }\n        %p Get selected data points.\n        %br\n        %p By this API, you can get selected data points information. To use this API, <a href=\"#data-selection-enabled\">data.selection.enabled</a> needs to be set <code>true</code>.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.selected(targetId)\n        %p <span class=\"code\">targetId</span>&nbsp;&nbsp;<code>String</code>\n        %p You can filter the result by giving target id that you want to get. If not given, all of data points will be returned.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// all selected data points will be returned.\n              chart.selected();\n              \\\n              \\// all selected data points of data1 will be returned.\n              chart.selected('data1');\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.transform' }\n        %p Change the type of the chart.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.transform(type, targetIds)\n        %p <span class=\"code\">type</span>&nbsp;&nbsp;<code>String</code>\n        %p Specify the type to be transformed. The types listed in <a href=\"#data-type\">data.type</a> can be used.\n        %br\n        %p <span class=\"code\">targetIds</span>&nbsp;&nbsp;<code>String</code> or <code>Array</code>\n        %p Specify targets to be transformed. If not given, all targets will be the candidate.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// all targets will be bar chart.\n              chart.transform('bar');\n              \\\n              \\// only data1 will be bar chart.\n              chart.transform('bar', 'data1');\n              \\\n              \\// only data1 and data2 will be bar chart.\n              chart.transform('bar', ['data1', 'data2']);\n        %ul\n          %li\n            %a( href=\"/samples/transform_line.html\" ) Transform to Line Chart\n            %a( href=\"/samples/transform_bar.html\" ) Transform to Bar Chart\n            %a( href=\"/samples/transform_pie.html\" ) Transform to Pie Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.groups' }\n        %p Update groups for the targets.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.groups(groups)\n        %p <span class=\"code\">groups</span>&nbsp;&nbsp;<code>Array</code>\n        %p This argument needs to be an <code>Array</code> that includes one or more <code>Array</code> that includes target ids to be grouped.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// data1 and data2 will be a new group.\n              chart.groups([['data1', 'data2']]);\n        %ul\n          %li\n            %a( href=\"/samples/chart_bar_stacked.html\" ) Stacked Bar Chart\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.xgrids' }\n        %p Update x grid lines.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.xgrids(grids)\n        %p <span class=\"code\">grids</span>&nbsp;&nbsp;<code>Array</code>\n        %p X grid lines will be replaced with this argument. The format of this argument is the same as <a href=\"#grid-x-lines\">grid.x.lines</a>.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Show 2 x grid lines\n              chart.xgrids([\n              &nbsp;&nbsp;{value: 1, text:'Label 1'},\n              &nbsp;&nbsp;{value: 4, text: 'Label 4'}\n              ]);\n        %ul\n          %li\n            %a( href=\"/samples/api_grid_x.html\" ) X Grids\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.xgrids.add' }\n        %p Add x grid lines.\n        %br\n        %p This API adds new x grid lines instead of replacing like <a href=\"#api-xgrids\">xgrids</a>.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.xgrids.add(grids)\n        %p <span class=\"code\">grids</span>&nbsp;&nbsp;<code>Array</code> or <code>Object</code>\n        %p New x grid lines will be added. The format of this argument is the same as <a href=\"#grid-x-lines\">grid.x.lines</a> and it's possible to give an <code>Object</code> if only one line will be added.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Add a new x grid line\n              chart.xgrids.add(\n              &nbsp;&nbsp;{value: 4, text: 'Label 4'}\n              );\n              \\\n              \\// Add new x grid lines\n              chart.xgrids.add([\n              &nbsp;&nbsp;{value: 2, text: 'Label 2'},\n              &nbsp;&nbsp;{value: 4, text: 'Label 4'}\n              ]);\n        %ul\n          %li\n            %a( href=\"/samples/api_grid_x.html\" ) X Grids\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.xgrids.remove' }\n        %p Remove x grid lines.\n        %br\n        %p This API removes x grid lines.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.xgrids.remove(args)\n        %p <span class=\"code\">args</span>&nbsp;&nbsp;<code>Object</code>\n        %p This argument should include <span class=\"code\">value</span> or <span class=\"code\">class</span>. If <span class=\"code\">value</span> is given, the x grid lines that have specified x value will be removed. If <span class=\"code\">class</span> is given, the x grid lines that have specified class will be removed. If <span class=\"code\">args</span> is not given, all of x grid lines will be removed.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// x grid line on x = 2 will be removed\n              chart.xgrids.remove({value: 2});\n              \\\n              \\// x grid lines that have 'grid-A' will be removed\n              chart.xgrids.remove({class: 'grid-A'});\n              \\\n              \\// all of x grid lines will be removed\n              chart.xgrids.remove();\n        %ul\n          %li\n            %a( href=\"/samples/api_grid_x.html\" ) X Grids\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.ygrids' }\n        %p Update y grid lines.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.ygrids(grids)\n        %p <span class=\"code\">grids</span>&nbsp;&nbsp;<code>Array</code>\n        %p X grid lines will be replaced with this argument. The format of this argument is the same as <a href=\"#grid-y-lines\">grid.y.lines</a>.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Show 2 y grid lines\n              chart.ygrids([\n              &nbsp;&nbsp;{value: 100, text:'Label 1'},\n              &nbsp;&nbsp;{value: 400, text: 'Label 4'}\n              ]);\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.ygrids.add' }\n        %p Add y grid lines.\n        %br\n        %p This API adds new y grid lines instead of replacing like <a href=\"#api-ygrids\">ygrids</a>.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.ygrids.add(grids)\n        %p <span class=\"code\">grids</span>&nbsp;&nbsp;<code>Array</code> or <code>Object</code>\n        %p New y grid lines will be added. The format of this argument is the same as <a href=\"#grid-y-lines\">grid.y.lines</a> and it's possible to give an <code>Object</code> if only one line will be added.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Add a new y grid line\n              chart.ygrids.add(\n              &nbsp;&nbsp;{value: 400, text: 'Label 4'}\n              );\n              \\\n              \\// Add new y grid lines\n              chart.ygrids.add([\n              &nbsp;&nbsp;{value: 200, text: 'Label 2'},\n              &nbsp;&nbsp;{value: 400, text: 'Label 4'}\n              ]);\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.ygrids.remove' }\n        %p Remove y grid lines.\n        %br\n        %p This API removes y grid lines.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.ygrids.remove(args)\n        %p <span class=\"code\">args</span>&nbsp;&nbsp;<code>Object</code>\n        %p This argument should include <span class=\"code\">value</span> or <span class=\"code\">class</span>. If <span class=\"code\">value</span> is given, the y grid lines that have specified y value will be removed. If <span class=\"code\">class</span> is given, the y grid lines that have specified class will be removed. If <span class=\"code\">args</span> is not given, all of y grid lines will be removed.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// y grid line on y = 200 will be removed\n              chart.ygrids.remove({value: 200});\n              \\\n              \\// y grid lines that have 'grid-A' will be removed\n              chart.ygrids.remove({class: 'grid-A'});\n              \\\n              \\// all of y grid lines will be removed\n              chart.ygrids.remove();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.regions' }\n        %p Update regions.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.regions(regions)\n        %p <span class=\"code\">regions</span>&nbsp;&nbsp;<code>Array</code>\n        %p Regions will be replaced with this argument. The format of this argument is the same as <a href=\"#regions\">regions</a>.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Show 2 regions\n              chart.regions([\n              &nbsp;&nbsp;{axis: 'x', start: 5, class: 'regionX'},\n              &nbsp;&nbsp;{axis: 'y', end: 50, class: 'regionY'}\n              ]);\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.regions.add' }\n        %p Add new region.\n        %br\n        %p This API adds new region instead of replacing like <a href=\"#api-regions\">regions</a>.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.regions.add(regions)\n        %p <span class=\"code\">regions</span>&nbsp;&nbsp;<code>Array</code> or <code>Object</code>\n        %p New region will be added. The format of this argument is the same as <a href=\"#regions\">regions</a> and it's possible to give an <code>Object</code> if only one region will be added.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Add a new region\n              chart.regions.add(\n              &nbsp;&nbsp;{axis: 'x', start: 5, class: 'regionX'}\n              );\n              \\\n              \\// Add new regions\n              chart.regions.add([\n              &nbsp;&nbsp;{axis: 'x', start: 5, class: 'regionX'},\n              &nbsp;&nbsp;{axis: 'y', end: 50, class: 'regionY'}\n              ]);\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.regions.remove' }\n        %p Remove regions.\n        %br\n        %p This API removes regions.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.regions.remove(args)\n        %p <span class=\"code\">args</span>&nbsp;&nbsp;<code>Object</code>\n        %p This argument should include <span class=\"code\">classes</span>. If <span class=\"code\">classes</span> is given, the regions that have one of the specified classes will be removed. If <span class=\"code\">args</span> is not given, all of regions will be removed.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// regions that have 'region-A' or 'region-B' will be removed.\n              chart.regions.remove({classes: ['region-A', 'region-B']});\n              \\\n              \\// all of regions will be removed.\n              chart.regions.remove();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.data' }\n        %p Get data loaded in the chart.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.data(targetIds)\n        %p <span class=\"code\">targetIds</span>&nbsp;&nbsp;<code>String</code> or <code>Array</code>\n        %p If this argument is given, this API returns the specified target data. If this argument is not given, all of data will be returned.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Get only data1 data\n              chart.data('data1');\n              \\\n              \\// Get data1 and data2 data\n              chart.data(['data1', 'data2']);\n              \\\n              \\// Get all data\n              chart.data();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.data.shown' }\n        %p Get data shown in the chart.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.data.shown(targetIds)\n        %p <span class=\"code\">targetIds</span>&nbsp;&nbsp;<code>String</code> or <code>Array</code>\n        %p If this argument is given, this API filters the data with specified target ids. If this argument is not given, all shown data will be returned.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Get shown data by filtering to include only data1 data\n              chart.data.shown('data1');\n              \\\n              \\// Get shown data by filtering to include data1 and data2 data\n              chart.data.shown(['data1', 'data2']);\n              \\\n              \\// Get all shown data\n              chart.data.shown();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.data.values' }\n        %p Get values of the data loaded in the chart.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.data.values(targetId)\n        %p <span class=\"code\">targetId</span>&nbsp;&nbsp;<code>String</code>\n        %p This API returns the values of specified target. If this argument is not given, <code>null</code> will be retruned.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Get data1 values\n              chart.data.values('data1');\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.data.names' }\n        %p Get and set names of the data loaded in the chart.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.data.names(names)\n        %p <span class=\"code\">names</span>&nbsp;&nbsp;<code>Object</code>\n        %p If this argument is given, the names of data will be updated. If not given, the current names will be returned. The format of this argument is the same as <a href=\"#data-names\">data.names</a>.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Get current names\n              chart.data.names();\n              \\\n              \\// Update names\n              chart.data.names({\n              &nbsp;&nbsp;data1: 'New Name 1',\n              &nbsp;&nbsp;data2: 'New Name 2'\n              });\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.data.colors' }\n        %p Get and set colors of the data loaded in the chart.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.data.colors(colors)\n        %p <span class=\"code\">colors</span>&nbsp;&nbsp;<code>Object</code>\n        %p If this argument is given, the colors of data will be updated. If not given, the current colors will be returned. The format of this argument is the same as <a href=\"#data-colors\">data.colors</a>.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Get current colors\n              chart.data.colors();\n              \\\n              \\// Update colors\n              chart.data.colors({\n              &nbsp;&nbsp;data1: '#FFFFFF',\n              &nbsp;&nbsp;data2: '#000000'\n              });\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.data.axes' }\n        %p Get and set axes of the data loaded in the chart.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.data.axes(axes)\n        %p <span class=\"code\">axes</span>&nbsp;&nbsp;<code>Object</code>\n        %p If this argument is given, the axes of data will be updated. If not given, the current axes will be returned. The format of this argument is the same as <a href=\"#data-axes\">data.axes</a>.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Get current axes\n              chart.data.axes();\n              \\\n              \\// Update axes\n              chart.data.axes({\n              &nbsp;&nbsp;data1: 'y',\n              &nbsp;&nbsp;data2: 'y2'\n              });\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.x' }\n        %p Get and set x values for the chart.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.x(x)\n        %p <span class=\"code\">x</span>&nbsp;&nbsp;<code>Array</code>\n        %p If <span class=\"code\">x</span> is given, x values of every target will be updated. If no argument is given, current x values will be returned as an <code>Object</code> whose keys are the target ids.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Get current x values\n              chart.x();\n              \\\n              \\// Update x values for all targets\n              chart.x([100, 200, 300, 400, ...]);\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.xs' }\n        %p Get and set x values for the chart.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.xs(xs)\n        %p <span class=\"code\">xs</span>&nbsp;&nbsp;<code>Object</code>\n        %p If <span class=\"code\">xs</span> is given, specified target's x values will be updated. If no argument is given, current x values will be returned as an <code>Object</code> whose keys are the target ids.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Get current x values\n              chart.xs();\n              \\\n              \\// Update x values for all targets\n              chart.xs({\n              &nbsp;&nbsp;data1: [10, 20, 30, 40, ...],\n              &nbsp;&nbsp;data2: [100, 200, 300, 400, ...]\n              });\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.axis.labels' }\n        %p Get and set axis labels.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.axis.labels(labels)\n        %p <span class=\"code\">labels</span>&nbsp;&nbsp;<code>Object</code>\n        %p If <span class=\"code\">labels</span> is given, specified axis' label will be updated.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Update axis' label\n              chart.axis.labels({\n              &nbsp;&nbsp;x: 'New X Axis Label',\n              &nbsp;&nbsp;y: 'New Y Axis Label'\n              });\n        %ul\n          %li\n            %a( href=\"/samples/api_axis_label.html\" ) Update Axis Label\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.axis.min' }\n        %p Get and set axis min value.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.axis.min(min)\n        %p <span class=\"code\">min</span>&nbsp;&nbsp;<code>Object</code>\n        %p If <span class=\"code\">min</span> is given, specified axis' min value will be updated. If no argument is given, the current min values for each axis will be returned.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Update axis' min\n              chart.axis.min({\n              &nbsp;&nbsp;x: -10,\n              &nbsp;&nbsp;y: 1000,\n              &nbsp;&nbsp;y2: 100\n              });\n        %ul\n          %li\n            %a( href=\"/samples/api_axis_range.html\" ) Update Axis Range\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.axis.max' }\n        %p Get and set axis max value.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.axis.max(max)\n        %p <span class=\"code\">max</span>&nbsp;&nbsp;<code>Object</code>\n        %p If <span class=\"code\">max</span> is given, specified axis' max value will be updated. If no argument is given, the current max values for each axis will be returned.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Update axis' max\n              chart.axis.max({\n              &nbsp;&nbsp;x: 100,\n              &nbsp;&nbsp;y: 1000,\n              &nbsp;&nbsp;y2: 10000\n              });\n        %ul\n          %li\n            %a( href=\"/samples/api_axis_range.html\" ) Update Axis Range\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.axis.range' }\n        %p Get and set axis min and max value.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.axis.range(range)\n        %p <span class=\"code\">range</span>&nbsp;&nbsp;<code>Object</code>\n        %p If <span class=\"code\">range</span> is given, specified axis' min and max value will be updated. If no argument is given, the current min and max values for each axis will be returned.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Update axis' min and max values\n              chart.axis.range({\n              &nbsp;&nbsp;min: {\n              &nbsp;&nbsp;&nbsp;&nbsp;x: -10,\n              &nbsp;&nbsp;&nbsp;&nbsp;y: -1000,\n              &nbsp;&nbsp;&nbsp;&nbsp;y2: -10000\n              &nbsp;&nbsp;},\n              &nbsp;&nbsp;max: {\n              &nbsp;&nbsp;&nbsp;&nbsp;x: 100,\n              &nbsp;&nbsp;&nbsp;&nbsp;y: 1000,\n              &nbsp;&nbsp;&nbsp;&nbsp;y2: 10000\n              &nbsp;&nbsp;}\n              });\n        %ul\n          %li\n            %a( href=\"/samples/api_axis_range.html\" ) Update Axis Range\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.axis.types' }\n        %p Get and set axis y/y2 types.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.axis.types(types)\n        %p <span class=\"code\">types</span>&nbsp;&nbsp;<code>Object</code>\n        %p If <span class=\"code\">types</span> is given, specified axis' type value will be updated. If no argument is given, the current types for y/y2 axis will be returned.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Update axis' types\n              chart.axis.types({\n              &nbsp;&nbsp;y: 'linear',\n              &nbsp;&nbsp;y2: 'log'\n              });\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.legend.show' }\n        %p Show legend for each target.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.legend.show(targetIds)\n        %p <span class=\"code\">targetIds</span>&nbsp;&nbsp;<code>Array</code> or <code>String</code>\n        %p If <span class=\"code\">targetIds</span> is given, specified target's legend will be shown. If only one target is the candidate, <code>String</code> can be passed. If no argument is given, all of target's legend will be shown.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Show legend for data1.\n              chart.legend.show('data1');\n              \\\n              \\// Show legend for data1 and data2.\n              chart.legend.show(['data1', 'data2']);\n              \\\n              \\// Show all legend.\n              chart.legend.show();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.legend.hide' }\n        %p Hide legend for each target.\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.legend.hide(targetIds)\n        %p <span class=\"code\">targetIds</span>&nbsp;&nbsp;<code>Array</code> or <code>String</code>\n        %p If <span class=\"code\">targetIds</span> is given, specified target's legend will be hidden. If only one target is the candidate, <code>String</code> can be passed. If no argument is given, all of target's legend will be hidden.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Hide legend for data1.\n              chart.legend.hide('data1');\n              \\\n              \\// Hide legend for data1 and data2.\n              chart.legend.hide(['data1', 'data2']);\n              \\\n              \\// Hide all legend.\n              chart.legend.hide();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.subchart.isShown' }\n        %p Returns <code>true</code> if the sub chart is shown.\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              if (chart.subchart.isShown()) {\n              &nbsp;&nbsp;// Sub chart is shown\n              }\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.subchart.show' }\n        %p Shows sub chart at the bottom of the chart.\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Show sub chart\n              chart.subchart.show();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.subchart.hide' }\n        %p Hides sub chart.\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Hide sub chart\n              chart.subchart.hide();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.zoom' }\n        %p Zoom by giving x domain.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.zoom(domain)\n        %p <span class=\"code\">domain</span>&nbsp;&nbsp;<code>Array</code>\n        %p If <span class=\"code\">domain</span> is given, the chart will be zoomed to the given domain. If no argument is given, the current zoomed domain will be returned.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Zoom to specified domain\n              chart.zoom([10, 20]);\n              \\\n              \\// Get the current zoomed domain\n              chart.zoom();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.unzoom' }\n        %p Unzoom to the original domain.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.unzoom()\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Unzoom to the original domain\n              chart.unzoom();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.zoom.enable' }\n        %p Enable and disable zooming.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.zoom.enable(enabled)\n        %p <span class=\"code\">enabled</span>&nbsp;&nbsp;<code>Boolean</code>\n        %p If <span class=\"code\">enabled</span> is <code>true</code>, the feature of zooming will be enabled. If <code>false</code> is given, it will be disabled.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Enable zooming\n              chart.zoom.enable(true);\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.resize' }\n        %p Resize the chart.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.resize(size)\n        %p <span class=\"code\">size</span>&nbsp;&nbsp;<code>Object</code>\n        %p This argument should include <span class=\"code\">width</span> and <span class=\"code\">height</span> in pixels.\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Resize to 640x480\n              chart.resize({\n              &nbsp;&nbsp;height: 640,\n              &nbsp;&nbsp;width: 480\n              });\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.flush' }\n        %p Force to redraw.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.flush()\n\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Force to redraw\n              chart.flush();\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'api.destroy' }\n        %p Reset the chart object and remove element and events completely.\n        %h5 Arguments:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\.destroy()\n        %h5 Example:\n        %div.sourcecode\n          %pre\n            %code.html.javascript\n              \\// Destroy the chart\n              chart.destroy();\n              \\\n              \\// If you have a reference to the chart make sure to call destroy in the following manner\n              chart = chart.destroy();\n      %hr\n\n      %br\n      %section\n        %h2 CLASS\n      %hr\n\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-line' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-lines' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-bar' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-bars' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-text' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-texts' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-arc' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-arcs' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-arcs-title' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-arcs-background' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-arcs-gauge-unit' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-arcs-gauge-max' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-chart-arcs-gauge-min' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-selected-circle' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-selected-circles' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-event-rect' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-event-rects' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-event-rects-single' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-event-rects-multiple' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-zoom-rect' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-brush' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-focused' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-region' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-regions' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-tooltip' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-tooltip-name' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-shape' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-shapes' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-line' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-lines' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-bar' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-bars' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-circle' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-circles' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-arc' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-arcs' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-area' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-areas' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-empty' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-text' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-texts' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-gauge-value' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-grid' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-xgrid' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-xgrids' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-xgrid-line' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-xgrid-lines' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-xgrid-focus' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-ygrid' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-ygrids' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-ygrid-line' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-ygrid-lines' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-stanford-elements' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-stanford-line' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-stanford-lines' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-stanford-region' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-stanford-regions' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-stanford-text' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-stanford-texts' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-axis' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-axis-x' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-axis-x-label' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-axis-y' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-axis-y-label' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-axis-y2' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-axis-y2-label' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-legend-item' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-legend-item-event' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-legend-item-tile' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-legend-item-hidden' }\n        %p ...\n      %hr\n      %section\n        %h3\n          = partial :reference_item_link, locals: { id: 'class.c3-legend-item-focused' }\n        %p ...\n      %hr\n\n  = partial :footer\n\n= partial :script\n= partial :script_scroll\n"
  },
  {
    "path": "docs/robots.txt",
    "content": ""
  },
  {
    "path": "docs/samples/api_axis_label.html.haml",
    "content": "= partial :sample, locals: { id: 'api_axis_label' }\n"
  },
  {
    "path": "docs/samples/api_axis_range.html.haml",
    "content": "= partial :sample, locals: { id: 'api_axis_range' }\n"
  },
  {
    "path": "docs/samples/api_data_color.html.haml",
    "content": "= partial :sample, locals: { id: 'api_data_color' }\n"
  },
  {
    "path": "docs/samples/api_data_name.html.haml",
    "content": "= partial :sample, locals: { id: 'api_data_name' }\n"
  },
  {
    "path": "docs/samples/api_flow.html.haml",
    "content": "= partial :sample, locals: { id: 'api_flow' }\n"
  },
  {
    "path": "docs/samples/api_grid_x.html.haml",
    "content": "= partial :sample, locals: { id: 'api_grid_x' }\n"
  },
  {
    "path": "docs/samples/api_resize.html.haml",
    "content": "= partial :sample, locals: { id: 'api_resize' }\n"
  },
  {
    "path": "docs/samples/axes_label.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_label' }\n"
  },
  {
    "path": "docs/samples/axes_label_position.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_label_position' }\n"
  },
  {
    "path": "docs/samples/axes_rotated.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_rotated' }\n"
  },
  {
    "path": "docs/samples/axes_x_localtime.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_x_localtime' }\n"
  },
  {
    "path": "docs/samples/axes_x_tick_count.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_x_tick_count' }\n"
  },
  {
    "path": "docs/samples/axes_x_tick_culling.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_x_tick_culling' }\n"
  },
  {
    "path": "docs/samples/axes_x_tick_fit.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_x_tick_fit' }\n"
  },
  {
    "path": "docs/samples/axes_x_tick_format.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_x_tick_format' }\n"
  },
  {
    "path": "docs/samples/axes_x_tick_rotate.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_x_tick_rotate' }\n"
  },
  {
    "path": "docs/samples/axes_x_tick_values.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_x_tick_values' }\n"
  },
  {
    "path": "docs/samples/axes_y2.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_y2' }\n"
  },
  {
    "path": "docs/samples/axes_y_padding.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_y_padding' }\n"
  },
  {
    "path": "docs/samples/axes_y_range.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_y_range' }\n"
  },
  {
    "path": "docs/samples/axes_y_tick_format.html.haml",
    "content": "= partial :sample, locals: { id: 'axes_y_tick_format' }\n"
  },
  {
    "path": "docs/samples/categorized.html.haml",
    "content": "= partial :sample, locals: { id: 'categorized' }\n"
  },
  {
    "path": "docs/samples/chart_area.html.haml",
    "content": "= partial :sample, locals: { id: 'chart_area' }\n"
  },
  {
    "path": "docs/samples/chart_area_stacked.html.haml",
    "content": "= partial :sample, locals: { id: 'chart_area_stacked' }\n"
  },
  {
    "path": "docs/samples/chart_bar.html.haml",
    "content": "= partial :sample, locals: { id: 'chart_bar' }\n"
  },
  {
    "path": "docs/samples/chart_bar_stacked.html.haml",
    "content": "= partial :sample, locals: { id: 'chart_bar_stacked' }\n"
  },
  {
    "path": "docs/samples/chart_combination.html.haml",
    "content": "= partial :sample, locals: { id: 'chart_combination' }\n"
  },
  {
    "path": "docs/samples/chart_donut.html.haml",
    "content": "= partial :sample, locals: { id: 'chart_donut' }\n"
  },
  {
    "path": "docs/samples/chart_gauge.html.haml",
    "content": "= partial :sample, locals: { id: 'chart_gauge' }\n"
  },
  {
    "path": "docs/samples/chart_pie.html.haml",
    "content": "= partial :sample, locals: { id: 'chart_pie' }\n"
  },
  {
    "path": "docs/samples/chart_scatter.html.haml",
    "content": "= partial :sample, locals: { id: 'chart_scatter' }\n"
  },
  {
    "path": "docs/samples/chart_spline.html.haml",
    "content": "= partial :sample, locals: { id: 'chart_spline' }\n"
  },
  {
    "path": "docs/samples/chart_stanford.html.haml",
    "content": "= partial :sample, locals: { id: 'chart_stanford' }\n"
  },
  {
    "path": "docs/samples/chart_step.html.haml",
    "content": "= partial :sample, locals: { id: 'chart_step' }\n"
  },
  {
    "path": "docs/samples/data_color.html.haml",
    "content": "= partial :sample, locals: { id: 'data_color' }\n"
  },
  {
    "path": "docs/samples/data_columned.html.haml",
    "content": "= partial :sample, locals: { id: 'data_columned' }\n"
  },
  {
    "path": "docs/samples/data_json.html.haml",
    "content": "= partial :sample, locals: { id: 'data_json' }\n"
  },
  {
    "path": "docs/samples/data_label.html.haml",
    "content": "= partial :sample, locals: { id: 'data_label' }\n"
  },
  {
    "path": "docs/samples/data_label_format.html.haml",
    "content": "= partial :sample, locals: { id: 'data_label_format' }\n"
  },
  {
    "path": "docs/samples/data_load.html.haml",
    "content": "= partial :sample, locals: { id: 'data_load', other_files: ['c3_test.csv', 'c3_test2.csv'] }\n"
  },
  {
    "path": "docs/samples/data_name.html.haml",
    "content": "= partial :sample, locals: { id: 'data_name' }\n"
  },
  {
    "path": "docs/samples/data_number_format_l10n.html.haml",
    "content": "= partial :sample, locals: { id: 'data_number_format_l10n' }\n"
  },
  {
    "path": "docs/samples/data_order.html.haml",
    "content": "= partial :sample, locals: { id: 'data_order' }\n"
  },
  {
    "path": "docs/samples/data_rowed.html.haml",
    "content": "= partial :sample, locals: { id: 'data_rowed' }\n"
  },
  {
    "path": "docs/samples/data_stringx.html.haml",
    "content": "= partial :sample, locals: { id: 'data_stringx', other_files: ['c3_string_x.csv'] }\n"
  },
  {
    "path": "docs/samples/data_url.html.haml",
    "content": "= partial :sample, locals: { id: 'data_url', other_files: ['c3_test.csv', 'c3_test.json'] }\n"
  },
  {
    "path": "docs/samples/grid_x_lines.html.haml",
    "content": "= partial :sample, locals: { id: 'grid_x_lines' }\n"
  },
  {
    "path": "docs/samples/grid_y_lines.html.haml",
    "content": "= partial :sample, locals: { id: 'grid_y_lines' }\n"
  },
  {
    "path": "docs/samples/interaction_zoom.html.haml",
    "content": "= partial :sample, locals: { id: 'interaction_zoom' }\n"
  },
  {
    "path": "docs/samples/interaction_zoom_by_drag.html.haml",
    "content": "= partial :sample, locals: { id: 'interaction_zoom_by_drag' }\n"
  },
  {
    "path": "docs/samples/legend_custom.html.haml",
    "content": "= partial :sample, locals: { id: 'legend_custom', other_css: 'legend_custom.css' }\n"
  },
  {
    "path": "docs/samples/legend_position.html.haml",
    "content": "= partial :sample, locals: { id: 'legend_position' }\n"
  },
  {
    "path": "docs/samples/options_color.html.haml",
    "content": "= partial :sample, locals: { id: 'options_color' }\n"
  },
  {
    "path": "docs/samples/options_gridline.html.haml",
    "content": "= partial :sample, locals: { id: 'options_gridline' }\n"
  },
  {
    "path": "docs/samples/options_legend.html.haml",
    "content": "= partial :sample, locals: { id: 'options_legend' }\n"
  },
  {
    "path": "docs/samples/options_padding.html.haml",
    "content": "= partial :sample, locals: { id: 'options_padding' }\n"
  },
  {
    "path": "docs/samples/options_size.html.haml",
    "content": "= partial :sample, locals: { id: 'options_size' }\n"
  },
  {
    "path": "docs/samples/options_subchart.html.haml",
    "content": "= partial :sample, locals: { id: 'options_subchart' }\n"
  },
  {
    "path": "docs/samples/pie_label_format.html.haml",
    "content": "= partial :sample, locals: { id: 'pie_label_format' }\n"
  },
  {
    "path": "docs/samples/point_show.html.haml",
    "content": "= partial :sample, locals: { id: 'point_show' }\n"
  },
  {
    "path": "docs/samples/region.html.haml",
    "content": "= partial :sample, locals: { id: 'region', other_css: 'region.css'  }\n"
  },
  {
    "path": "docs/samples/region_timeseries.html.haml",
    "content": "= partial :sample, locals: { id: 'region_timeseries' }\n"
  },
  {
    "path": "docs/samples/simple_multiple.html.haml",
    "content": "= partial :sample, locals: { id: 'simple_multiple' }\n"
  },
  {
    "path": "docs/samples/simple_regions.html.haml",
    "content": "= partial :sample, locals: { id: 'simple_regions' }\n"
  },
  {
    "path": "docs/samples/simple_xy.html.haml",
    "content": "= partial :sample, locals: { id: 'simple_xy' }\n"
  },
  {
    "path": "docs/samples/simple_xy_multiple.html.haml",
    "content": "= partial :sample, locals: { id: 'simple_xy_multiple' }\n"
  },
  {
    "path": "docs/samples/style_grid.html.haml",
    "content": "= partial :sample, locals: { id: 'style_grid', other_css: 'style_grid.css' }\n"
  },
  {
    "path": "docs/samples/style_region.html.haml",
    "content": "= partial :sample, locals: { id: 'style_region', other_css: 'style_region.css' }\n"
  },
  {
    "path": "docs/samples/timeseries.html.haml",
    "content": "= partial :sample, locals: { id: 'timeseries' }\n"
  },
  {
    "path": "docs/samples/tooltip_format.html.haml",
    "content": "= partial :sample, locals: { id: 'tooltip_format' }\n"
  },
  {
    "path": "docs/samples/tooltip_grouped.html.haml",
    "content": "= partial :sample, locals: { id: 'tooltip_grouped' }\n"
  },
  {
    "path": "docs/samples/tooltip_horizontal.html.haml",
    "content": "= partial :sample, locals: { id: 'tooltip_horizontal' }\n"
  },
  {
    "path": "docs/samples/tooltip_show.html.haml",
    "content": "= partial :sample, locals: { id: 'tooltip_show' }\n"
  },
  {
    "path": "docs/samples/transform_area.html.haml",
    "content": "= partial :sample, locals: { id: 'transform_area' }\n"
  },
  {
    "path": "docs/samples/transform_areaspline.html.haml",
    "content": "= partial :sample, locals: { id: 'transform_areaspline' }\n"
  },
  {
    "path": "docs/samples/transform_bar.html.haml",
    "content": "= partial :sample, locals: { id: 'transform_bar' }\n"
  },
  {
    "path": "docs/samples/transform_donut.html.haml",
    "content": "= partial :sample, locals: { id: 'transform_donut' }\n"
  },
  {
    "path": "docs/samples/transform_line.html.haml",
    "content": "= partial :sample, locals: { id: 'transform_line' }\n"
  },
  {
    "path": "docs/samples/transform_pie.html.haml",
    "content": "= partial :sample, locals: { id: 'transform_pie' }\n"
  },
  {
    "path": "docs/samples/transform_scatter.html.haml",
    "content": "= partial :sample, locals: { id: 'transform_scatter' }\n"
  },
  {
    "path": "docs/samples/transform_spline.html.haml",
    "content": "= partial :sample, locals: { id: 'transform_spline' }\n"
  },
  {
    "path": "docs/samples/transition_duration.html.haml",
    "content": "= partial :sample, locals: { id: 'transition_duration' }\n"
  },
  {
    "path": "extensions/chart-bubble/bubble.js",
    "content": ";(function() {\n  var extra = {}\n\n  c3.chart.internal.fn.additionalConfig = {\n    data_pairs: []\n  }\n\n  c3.chart.internal.fn.beforeInit = function(config) {\n    var that = this\n\n    // update internals only when chart type is \"bubble\"\n    if (config.data.type !== 'bubble') {\n      return\n    }\n\n    // Set extra to ba able to be used in other part\n    this.extra = extra\n\n    extra.getKey = function(x, y) {\n      return x + '::' + y\n    }\n\n    this.config.data_type = 'scatter'\n\n    this.config.axis_x_padding = 0\n    this.config.axis_y_padding = 0\n    this.config.axis_x_tick_centered = true\n    this.config.axis_x_tick_format = function(d) {\n      return extra.names[d]\n    }\n    this.config.axis_y_tick_format = function(d) {\n      return extra.names[d]\n    }\n\n    if (!config.color || !config.color.pattern) {\n      this.config.color_pattern = ['#1f77b4']\n    }\n\n    this.config.point_r = function(d) {\n      var names = extra.names,\n        values = extra.values,\n        base_length = extra.base_length,\n        x = names[d.x],\n        y = d.id,\n        key = extra.getKey(x, y),\n        value = !values[key] ? 0 : values[key],\n        max,\n        max_r,\n        max_area,\n        a,\n        area,\n        r\n\n      if (!base_length) {\n        base_length = extra.base_length = d3.min([\n          that.svg\n            .select('.c3-axis.c3-axis-y path')\n            .node()\n            .getTotalLength(),\n          that.svg\n            .select('.c3-axis.c3-axis-x path')\n            .node()\n            .getTotalLength()\n        ])\n      }\n\n      max = d3.max(\n        Object.keys(values).map(function(key) {\n          return values[key]\n        })\n      )\n      max_r = base_length / (names.length * 2)\n      max_area = max_r * max_r * Math.PI\n\n      a = max_area / max\n\n      area = value * a\n      r = Math.sqrt(area / Math.PI)\n\n      return r\n    }\n    this.config.point_sensitivity = 25\n    this.config.point_focus_expand_enabled = false\n\n    this.config.legend_show = false\n\n    if (!config.tooltip || !config.tooltip.contents) {\n      this.config.tooltip_contents = function(\n        d,\n        defaultTitleFormat,\n        defaultValueFormat,\n        color\n      ) {\n        var x = extra.names[d[0].x],\n          y = d[0].name,\n          v = extra.values[extra.getKey(x, y)],\n          text\n\n        text = \"<table class='\" + this.CLASS.tooltip + \"'>\"\n        text += \"<tr><th colspan='2'>\" + x + '&nbsp;/&nbsp;' + y + '</th></tr>'\n        text += \"<tr><td class='value'>\" + (!v ? 0 : v) + '</td></tr>'\n        text += '</table>'\n\n        return text\n      }\n    }\n\n    // construct bubble chart data and setup config based on the values\n\n    var xs = this.config.data_pairs.map(function(pair) {\n        return pair.x\n      }),\n      ys = this.config.data_pairs.map(function(pair) {\n        return pair.y\n      })\n\n    extra.names = d3\n      .set(xs.concat(ys))\n      .values()\n      .sort()\n\n    this.config.axis_y_tick_values = extra.names.map(function(name, i) {\n      return i\n    })\n\n    var data_xs = {}\n    extra.names.forEach(function(name) {\n      data_xs[name] = name + '_x'\n    })\n    var data_columns_xs = Object.keys(data_xs).map(function(key) {\n      return [data_xs[key]].concat(\n        extra.names.map(function(name, i) {\n          return i\n        })\n      )\n    })\n    var data_columns_values = extra.names.map(function(name, i) {\n      return [name].concat(\n        extra.names.map(function(name) {\n          return i\n        })\n      )\n    })\n    this.config.data_xs = data_xs\n    this.config.data_columns = data_columns_xs.concat(data_columns_values)\n\n    var values = {}\n    this.config.data_pairs.forEach(function(pair) {\n      if (!pair.x || !pair.y) {\n        throw 'x and y are required in data.'\n      }\n      values[extra.getKey(pair.x, pair.y)] = pair.value\n    })\n    extra.values = values\n\n    this.config.axis_x_min = this.config.axis_y_min = -0.5\n    this.config.axis_x_max = this.config.axis_y_max = extra.names.length - 0.5\n  }\n})(window)\n"
  },
  {
    "path": "extensions/chart-bubble/index.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"http://d3js.org/d3.v4.min.js\" charset=\"utf-8\"></script>\n    <script src=\"c3.min.js\"></script>\n    <script src=\"bubble.js\"></script>\n    <script>\n     var chart = c3.generate({\n         data: {\n             type: 'bubble',\n             pairs: [\n                 { x: 'Name_0', y: 'Name_0', value: 10000 },\n                 { x: 'Name_0', y: 'Name_1', value: 20000 },\n                 { x: 'Name_0', y: 'Name_2', value: 39990 },\n//                 { x: 'Name_1', y: 'Name_0', value: 5000 },\n                 { x: 'Name_1', y: 'Name_1', value: 6000 },\n                 { x: 'Name_1', y: 'Name_2', value: 50000 },\n                 { x: 'Name_2', y: 'Name_0', value: 1000 },\n                 { x: 'Name_2', y: 'Name_1', value: 2000 },\n                 { x: 'Name_2', y: 'Name_2', value: 3000 },\n             ]\n         },\n         grid: {\n             x: {\n                 show: true\n             },\n             y: {\n                 show: true\n             }\n         },\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "extensions/exporter/config.json",
    "content": "{\n\t\"js\": [\n\t\t\"../../bower_components/d3/d3.min.js\",\n\t\t\"../../c3.min.js\"\n\t],\n\t\"css\": [\n\t\t\"../../c3.css\"\n\t],\n\n\t\"template\": \"<html><head><meta charset=\\\"utf-8\\\"><style>{0}</style></head><body><div id=\\\"chart\\\"></div></body></html>\"\n}"
  },
  {
    "path": "extensions/exporter/phantom-exporter.js",
    "content": "/**\n *  PNG\\JPEG exporter for C3.js, version 0.2\n *  (c) 2014 Yuval Bar-On\n *\n * usage: path/to/phantomjs output options [WxH]\n *\n */\n\n// useful python-styled string formatting, \"hello {0}! Javascript is {1}\".format(\"world\", \"awesome\");\nif (!String.prototype.format) {\n  String.prototype.format = function() {\n    var args = arguments\n    return this.replace(/{(\\d+)}/g, function(match, number) {\n      return typeof args[number] != 'undefined' ? args[number] : match\n    })\n  }\n}\n\n// defaults\nvar page = require('webpage').create(),\n  fs = require('fs'),\n  system = require('system'),\n  config = JSON.parse(fs.read('config.json')),\n  output,\n  size\n\nif (system.args.length < 3) {\n  console.log('Usage: phantasm.js filename html [WxH]')\n  phantom.exit(1)\n} else {\n  out = system.args[1]\n  opts = JSON.parse(system.args[2])\n\n  if (system.args[3]) {\n    var dimensions = system.args[3].split('x'),\n      width = dimensions[0],\n      height = dimensions[1]\n\n    function checkNum(check) {\n      check = parseInt(check)\n      if (!isNaN(check)) return check\n      return false\n    }\n\n    width = checkNum(width)\n    height = checkNum(height)\n\n    if (width && height) {\n      page.viewportSize = {\n        height: height,\n        width: width\n      }\n    }\n\n    // fit chart size to img size, if undefined\n    if (!opts.size) {\n      opts.size = {\n        height: height,\n        width: width\n      }\n    }\n  } else {\n    // check if size is defined in chart,\n    // else apply defaults\n    page.viewportSize = {\n      height: opts.size && opts.size.height ? opts.size.height : 320,\n      width: opts.size && opts.size.width ? opts.size.width : 710\n    }\n  }\n}\n\npage.onResourceRequested = function(requestData, request) {\n  console.log('::loading resource ', requestData['url'])\n}\n\n// helpful debug functions\npage.onConsoleMessage = function(msg) {\n  console.log(msg)\n}\n\npage.onError = function(msg, trace) {\n  var msgStack = ['ERROR: ' + msg]\n\n  if (trace && trace.length) {\n    msgStack.push('TRACE:')\n    trace.forEach(function(t) {\n      msgStack.push(\n        ' -> ' +\n          t.file +\n          ': ' +\n          t.line +\n          (t.function ? ' (in function \"' + t.function + '\")' : '')\n      )\n    })\n  }\n\n  console.error(msgStack.join('\\n'))\n}\n\n// render page\nfunction injectVerify(script) {\n  var req = page.injectJs(script)\n  if (!req) {\n    console.log('\\nError!\\n' + script + ' not found!\\n')\n    phantom.exit(1)\n  }\n}\n\npage.onLoadFinished = function() {\n  console.log('::rendering')\n\n  for (var j in config.js) {\n    injectVerify(config.js[j])\n  }\n\n  page.evaluate(function(chartoptions) {\n    // phantomjs doesn't know how to handle .bind, so we override\n    Function.prototype.bind =\n      Function.prototype.bind ||\n      function(thisp) {\n        var fn = this\n        return function() {\n          return fn.apply(thisp, arguments)\n        }\n      }\n\n    // generate chart\n    c3.generate(chartoptions)\n  }, opts)\n\n  // setting transition to 0 has proven not to work thus far, but 300ms isn't much\n  // so this is acceptable for now\n  setTimeout(function() {\n    page.render(out)\n    phantom.exit()\n  }, 300)\n}\n\n//  apply css inline because that usually renders better\nvar css = ''\nfor (var i in config.css) {\n  css += fs.read(config.css[i])\n}\npage.content = config.template.format(css)\n"
  },
  {
    "path": "extensions/js/c3ext.js",
    "content": "var c3ext = {}\nc3ext.generate = function(options) {\n  if (options.zoom2 != null) {\n    zoom2_reducers = options.zoom2.reducers || {}\n    zoom2_enabled = options.zoom2.enabled\n    _zoom2_factor = options.zoom2.factor || 1\n    _zoom2_maxItems = options.zoom2.maxItems\n  }\n\n  if (!zoom2_enabled) {\n    return c3.generate(options)\n  }\n\n  var originalData = Q.copy(options.data)\n  var zoom2_reducers\n  var zoom2_enabled\n  var _zoom2_maxItems\n\n  if (_zoom2_maxItems == null) {\n    var el = d3.select(options.bindto).node()\n    if (el != null) {\n      var availWidth = el.clientWidth\n\n      var pointSize = 20\n      _zoom2_maxItems = Math.ceil(availWidth / pointSize)\n    }\n    if (_zoom2_maxItems == null || _zoom2_maxItems < 10) {\n      _zoom2_maxItems = 10\n    }\n  }\n\n  function onZoomChanged(e) {\n    refresh()\n  }\n\n  var zoom2 = c3ext.ZoomBehavior({\n    changed: onZoomChanged,\n    bindto: options.bindto\n  })\n\n  zoom2.enhance = function() {\n    _zoom2_maxItems *= 2\n    var totalItems = zoom2.getZoom().totalItems\n    if (_zoom2_maxItems > totalItems) _zoom2_maxItems = totalItems\n    refresh()\n  }\n  zoom2.dehance = function() {\n    _zoom2_maxItems = Math.ceil(_zoom2_maxItems / 2) + 1\n    refresh()\n  }\n\n  zoom2.maxItems = function() {\n    return _zoom2_maxItems\n  }\n  function zoomAndReduceData(list, zoomRange, func, maxItems) {\n    //var maxItems = 10;//Math.ceil(10 * zoomFactor);\n    var list2 = list.slice(zoomRange[0], zoomRange[1])\n    var chunkSize = 1\n    var list3 = list2\n    if (list3.length > maxItems) {\n      var chunkSize = Math.ceil(list2.length / maxItems)\n      list3 = list3.splitIntoChunksOf(chunkSize).map(func)\n    }\n    //console.log(\"x\" + getCurrentZoomLevel() + \", maxItems=\" + maxItems + \" chunkSize=\" + chunkSize + \" totalBefore=\" + list2.length + \", totalAfter=\" + list3.length);\n    return list3\n  }\n\n  function first(t) {\n    return t[0]\n  }\n\n  var getDataForZoom = function(data) {\n    if (data.columns == null || data.columns.length == 0) return\n\n    var zoomInfo = zoom2.getZoom()\n    if (zoomInfo.totalItems != data.columns[0].length - 1) {\n      zoom2.setOptions({ totalItems: data.columns[0].length - 1 })\n      zoomInfo = zoom2.getZoom()\n    }\n    data.columns = originalData.columns.map(function(column) {\n      var name = column[0]\n      var reducer = zoom2_reducers[name] || first //by default take the first\n\n      var values = column.slice(1)\n      var newValues = zoomAndReduceData(\n        values,\n        zoomInfo.currentZoom,\n        reducer,\n        _zoom2_maxItems\n      )\n      return [name].concat(newValues)\n    })\n    return data\n  }\n\n  getDataForZoom(options.data)\n  var chart = c3.generate(options)\n  var _chart_load_org = chart.load.bind(chart)\n  chart.zoom2 = zoom2\n  chart.load = function(data) {\n    if (data.unload) {\n      unload(data.unload)\n      delete data.unload\n    }\n    Q.copy(data, originalData)\n    refresh()\n  }\n  chart.unload = function(names) {\n    unload(names)\n    refresh()\n  }\n\n  function unload(names) {\n    originalData.columns.removeAll(function(t) {\n      names.contains(t)\n    })\n  }\n\n  function refresh() {\n    var data = Q.copy(originalData)\n    getDataForZoom(data)\n    _chart_load_org(data)\n  }\n\n  return chart\n}\n\nc3ext.ZoomBehavior = function(options) {\n  var zoom = { __type: 'ZoomBehavior' }\n\n  var _zoom2_factor\n  var _left\n  var totalItems\n  var currentZoom\n  var bindto = options.bindto\n  var _zoomChanged = options.changed || function() {}\n  var element\n  var mousewheelTimer\n  var deltaY = 0\n  var leftRatio = 0\n\n  zoom.setOptions = function(options) {\n    if (options == null) options = {}\n    _zoom2_factor = options.factor || 1\n    _left = 0\n    totalItems = options.totalItems || 0\n    currentZoom = [0, totalItems]\n    _zoomChanged = options.changed || _zoomChanged\n  }\n\n  zoom.setOptions(options)\n\n  function verifyZoom(newZoom) {\n    //newZoom.sort();\n    if (newZoom[1] > totalItems) {\n      var diff = newZoom[1] - totalItems\n      newZoom[0] -= diff\n      newZoom[1] -= diff\n    }\n    if (newZoom[0] < 0) {\n      var diff = newZoom[0] * -1\n      newZoom[0] += diff\n      newZoom[1] += diff\n    }\n    if (newZoom[1] > totalItems) newZoom[1] = totalItems\n    if (newZoom[0] < 0) newZoom[0] = 0\n  }\n\n  function zoomAndPan(zoomFactor, left) {\n    var itemsToShow = Math.ceil(totalItems / zoomFactor)\n    var newZoom = [left, left + itemsToShow]\n    verifyZoom(newZoom)\n    currentZoom = newZoom\n    onZoomChanged()\n  }\n\n  function onZoomChanged() {\n    if (_zoomChanged != null) _zoomChanged(zoom.getZoom())\n  }\n  function applyZoomAndPan() {\n    zoomAndPan(_zoom2_factor, _left)\n  }\n  function getItemsToShow() {\n    var itemsToShow = Math.ceil(totalItems / _zoom2_factor)\n    return itemsToShow\n  }\n\n  zoom.getZoom = function() {\n    return { totalItems: totalItems, currentZoom: currentZoom.slice() }\n  }\n\n  zoom.factor = function(factor, skipDraw) {\n    if (arguments.length == 0) return _zoom2_factor\n    _zoom2_factor = factor\n    if (_zoom2_factor < 1) _zoom2_factor = 1\n    if (skipDraw) return\n    applyZoomAndPan()\n  }\n  zoom.left = function(left, skipDraw) {\n    if (arguments.length == 0) return _left\n    _left = left\n    if (_left < 0) _left = 0\n    var pageSize = getItemsToShow()\n    //_left += pageSize;\n    if (_left + pageSize > totalItems) _left = totalItems - pageSize\n    console.log({ left: _left, pageSize: pageSize })\n    if (skipDraw) return\n    applyZoomAndPan()\n  }\n\n  zoom.zoomAndPanByRatio = function(zoomRatio, panRatio) {\n    var pageSize = getItemsToShow()\n    var leftOffset = Math.round(pageSize * panRatio)\n    var mouseLeft = _left + leftOffset\n    zoom.factor(zoom.factor() * zoomRatio, true)\n\n    var finalLeft = mouseLeft\n    if (zoomRatio != 1) {\n      var pageSize2 = getItemsToShow()\n      var leftOffset2 = Math.round(pageSize2 * panRatio)\n      finalLeft = mouseLeft - leftOffset2\n    }\n    zoom.left(finalLeft, true)\n    applyZoomAndPan()\n  }\n\n  zoom.zoomIn = function() {\n    zoom.zoomAndPanByRatio(2, 0)\n  }\n\n  zoom.zoomOut = function() {\n    zoom.zoomAndPanByRatio(0.5, 0)\n  }\n\n  zoom.panLeft = function() {\n    zoom.zoomAndPanByRatio(1, -1)\n  }\n  zoom.panRight = function() {\n    zoom.zoomAndPanByRatio(1, 1)\n  }\n\n  zoom.reset = function() {\n    _left = 0\n    _zoom2_factor = 1\n    applyZoomAndPan()\n  }\n\n  function doZoom() {\n    if (deltaY != 0) {\n      var maxDelta = 10\n      var multiply = (maxDelta + deltaY) / maxDelta\n      //var factor = chart.zoom2.factor()*multiply;\n      //factor= Math.ceil(factor*100) / 100;\n      console.log({ deltaY: deltaY, multiply: multiply })\n      zoom.zoomAndPanByRatio(multiply, leftRatio) //0.5);//leftRatio);\n      deltaY = 0\n    }\n  }\n\n  function element_mousewheel(e) {\n    deltaY += e.deltaY\n    leftRatio = (e.offsetX - 70) / (e.currentTarget.offsetWidth - 70)\n    //console.log({ \"e.offsetX\": e.offsetX, \"e.currentTarget.offsetWidth\": e.currentTarget.offsetWidth, leftRatio: leftRatio });\n    mousewheelTimer.set(150)\n    e.preventDefault()\n  }\n\n  if (bindto != null) {\n    element = $(options.bindto)\n    if (element.mousewheel) {\n      mousewheelTimer = new Timer(doZoom)\n      element.mousewheel(element_mousewheel)\n    }\n  }\n\n  return zoom\n}\n\nif (typeof Q == 'undefined') {\n  var Q = function() {}\n\n  Q.copy = function(src, target, options, depth) {\n    ///<summary>Copies an object into a target object, recursively cloning any object or array in the way, overwrite=true will overwrite a primitive field value even if exists</summary>\n    ///<param name=\"src\" />\n    ///<param name=\"target\" />\n    ///<param name=\"options\" type=\"Object\">{ overwrite:false }</param>\n    ///<returns type=\"Object\">The copied object</returns>\n    if (depth == null) depth = 0\n    if (depth == 100) {\n      console.warn('Q.copy is in depth of 100 - possible circular reference')\n    }\n    options = options || { overwrite: false }\n    if (src == target || src == null) return target\n    if (typeof src != 'object') {\n      if (options.overwrite || target == null) return src\n      return target\n    }\n    if (typeof src.clone == 'function') {\n      if (options.overwrite || target == null) return src.clone()\n      return target\n    }\n    if (target == null) {\n      if (src instanceof Array) target = []\n      else target = {}\n    }\n\n    if (src instanceof Array) {\n      for (var i = 0; i < src.length; i++) {\n        var item = src[i]\n        var item2 = target[i]\n        item2 = Q.copy(item, item2, options, depth + 1)\n        target[i] = item2\n      }\n      target.splice(src.length, target.length - src.length)\n      return target\n    }\n    for (var p in src) {\n      var value = src[p]\n      var value2 = target[p]\n      value2 = Q.copy(value, value2, options, depth + 1)\n      target[p] = value2\n    }\n    return target\n  }\n}\nif (typeof Timer == 'undefined') {\n  var Timer = function(action, ms) {\n    this.action = action\n    if (ms != null) this.set(ms)\n  }\n\n  Timer.prototype.set = function(ms) {\n    if (ms == null) ms = this._ms\n    else this._ms = ms\n    this.clear()\n    if (ms == null) return\n    this.timeout = window.setTimeout(this.onTick.bind(this), ms)\n  }\n\n  Timer.prototype.onTick = function() {\n    this.clear()\n    this.action()\n  }\n\n  Timer.prototype.clear = function(ms) {\n    if (this.timeout == null) return\n    window.clearTimeout(this.timeout)\n    this.timeout = null\n  }\n}\nif (typeof Array.prototype.splitIntoChunksOf == 'undefined') {\n  Array.prototype.splitIntoChunksOf = function(countInEachChunk) {\n    var chunks = Math.ceil(this.length / countInEachChunk)\n    var list = []\n    for (var i = 0; i < this.length; i += countInEachChunk) {\n      list.push(this.slice(i, i + countInEachChunk))\n    }\n    return list\n  }\n}\n"
  },
  {
    "path": "htdocs/css/index.css",
    "content": ".row {\n  margin-left: 8px;\n}\n.row a {\n  display: block;\n  text-align: left;\n  font-size: 1.2em;\n  line-height: 1.8;\n}\n.row h3 {\n  color: #777;\n}"
  },
  {
    "path": "htdocs/css/style.css",
    "content": "\nbody {\n  text-align: center;\n}\n\n#chart {\n  width: 720px;\n  margin: 24px auto;\n}\n"
  },
  {
    "path": "htdocs/data/c3_stanford_data.json",
    "content": "[\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 24.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 24,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 27.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 26,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 39,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 39.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 41,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 40,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 42.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 40.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 41.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 30,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 56,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 47,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 54,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 48.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 54.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 53,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 51.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 50,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 52,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 55,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 56.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 54,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 55.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 56,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 48.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 56,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 56.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 53.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 51.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 52,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 31.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5.5,\n    \"HPL\": 37,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5.5,\n    \"HPL\": 38,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5.5,\n    \"HPL\": 38.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 36.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 38.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 22,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 21,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 22.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 19,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 13.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 16.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 15.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 14.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 11.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 11,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 12,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 14.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 19,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 19.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 56.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 26.5,\n    \"epochs\": 1\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 22,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 12.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 2,\n    \"HPL\": 11,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 13.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 11,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 43,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 55.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 53.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 48,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 49.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 54.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 51.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 52.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 49.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 47,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 45.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 46,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 5.5,\n    \"HPL\": 34.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 5.5,\n    \"HPL\": 37.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 20,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 19.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 24,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 12.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 14,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 10.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 17,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 56,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 55,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 14.5,\n    \"epochs\": 2\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 22.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 29,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 27.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 28,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 10,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 26.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 29,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 39.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 48.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 50.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 52.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 50.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 53,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 37,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 5.5,\n    \"HPL\": 31.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 5.5,\n    \"HPL\": 33,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 5.5,\n    \"HPL\": 32,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 5.5,\n    \"HPL\": 36,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 36,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 34.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 20.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 19.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 13,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 18.5,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 20,\n    \"epochs\": 3\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 28,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 24.5,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 29,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 28.5,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 29,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 30,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 11.5,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 49.5,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 49,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 52.5,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 53,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 50,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 47.5,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 38,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 5.5,\n    \"HPL\": 34,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 35,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 23.5,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 20.5,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 31.5,\n    \"epochs\": 4\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 21,\n    \"epochs\": 5\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 28.5,\n    \"epochs\": 5\n  },\n  {\n    \"HPE\": 2,\n    \"HPL\": 12,\n    \"epochs\": 5\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 36.5,\n    \"epochs\": 5\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 36.5,\n    \"epochs\": 5\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 51,\n    \"epochs\": 5\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 51,\n    \"epochs\": 5\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 50.5,\n    \"epochs\": 5\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 50,\n    \"epochs\": 5\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 20,\n    \"epochs\": 5\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 12,\n    \"epochs\": 5\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 58.5,\n    \"epochs\": 5\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 23,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 29.5,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 29.5,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 28.5,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 17.5,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 38.5,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 38.5,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 49,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 52.5,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 34,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 57.5,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 2,\n    \"HPL\": 56,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 2,\n    \"HPL\": 55,\n    \"epochs\": 6\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 20.5,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 27,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 2,\n    \"HPL\": 11.5,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 30,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 10,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 51.5,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 50.5,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 49,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 51,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 48,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 5.5,\n    \"HPL\": 33.5,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 5.5,\n    \"HPL\": 32.5,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 23,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 18,\n    \"epochs\": 7\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 28,\n    \"epochs\": 8\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 27,\n    \"epochs\": 8\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 25.5,\n    \"epochs\": 8\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 10.5,\n    \"epochs\": 8\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 52,\n    \"epochs\": 8\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 57.5,\n    \"epochs\": 8\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 28.5,\n    \"epochs\": 9\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 27.5,\n    \"epochs\": 9\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 29.5,\n    \"epochs\": 9\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 50,\n    \"epochs\": 9\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 51.5,\n    \"epochs\": 9\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 35.5,\n    \"epochs\": 9\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 21.5,\n    \"epochs\": 9\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 37.5,\n    \"epochs\": 10\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 39,\n    \"epochs\": 10\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 49.5,\n    \"epochs\": 10\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 50,\n    \"epochs\": 10\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 51,\n    \"epochs\": 10\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 22.5,\n    \"epochs\": 10\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 20,\n    \"epochs\": 11\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 25.5,\n    \"epochs\": 11\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 58,\n    \"epochs\": 11\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 48.5,\n    \"epochs\": 12\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 32,\n    \"epochs\": 12\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 23.5,\n    \"epochs\": 13\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 23,\n    \"epochs\": 13\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 25,\n    \"epochs\": 13\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 30,\n    \"epochs\": 13\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 24.5,\n    \"epochs\": 13\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 29.5,\n    \"epochs\": 13\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 21,\n    \"epochs\": 13\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 38,\n    \"epochs\": 14\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 32.5,\n    \"epochs\": 14\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 22,\n    \"epochs\": 15\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 12,\n    \"epochs\": 15\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 37,\n    \"epochs\": 15\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 22,\n    \"epochs\": 16\n  },\n  {\n    \"HPE\": 2,\n    \"HPL\": 55.5,\n    \"epochs\": 16\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 38,\n    \"epochs\": 17\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 23.5,\n    \"epochs\": 18\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 21,\n    \"epochs\": 18\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 29,\n    \"epochs\": 18\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 55.5,\n    \"epochs\": 18\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 11.5,\n    \"epochs\": 19\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 12.5,\n    \"epochs\": 19\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 21.5,\n    \"epochs\": 19\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 56.5,\n    \"epochs\": 19\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 14,\n    \"epochs\": 19\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 33,\n    \"epochs\": 20\n  },\n  {\n    \"HPE\": 5,\n    \"HPL\": 33.5,\n    \"epochs\": 20\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 20.5,\n    \"epochs\": 20\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 27,\n    \"epochs\": 22\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 22.5,\n    \"epochs\": 23\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 10.5,\n    \"epochs\": 23\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 13,\n    \"epochs\": 23\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 24,\n    \"epochs\": 24\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 28,\n    \"epochs\": 24\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 28.5,\n    \"epochs\": 24\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 57,\n    \"epochs\": 24\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 10,\n    \"epochs\": 25\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 37,\n    \"epochs\": 28\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 37.5,\n    \"epochs\": 29\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 56,\n    \"epochs\": 29\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 11,\n    \"epochs\": 36\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 10.5,\n    \"epochs\": 38\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 28,\n    \"epochs\": 39\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 13.5,\n    \"epochs\": 43\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 26,\n    \"epochs\": 44\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 11,\n    \"epochs\": 47\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 27.5,\n    \"epochs\": 50\n  },\n  {\n    \"HPE\": 4.5,\n    \"HPL\": 26.5,\n    \"epochs\": 54\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 12,\n    \"epochs\": 54\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 26,\n    \"epochs\": 59\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 24.5,\n    \"epochs\": 62\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 24,\n    \"epochs\": 62\n  },\n  {\n    \"HPE\": 3,\n    \"HPL\": 25,\n    \"epochs\": 70\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 25,\n    \"epochs\": 70\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 25,\n    \"epochs\": 81\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 11.5,\n    \"epochs\": 84\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 25.5,\n    \"epochs\": 85\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 26.5,\n    \"epochs\": 86\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 26,\n    \"epochs\": 88\n  },\n  {\n    \"HPE\": 2.5,\n    \"HPL\": 25.5,\n    \"epochs\": 89\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 27.5,\n    \"epochs\": 93\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 27,\n    \"epochs\": 94\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 25,\n    \"epochs\": 95\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 27,\n    \"epochs\": 106\n  },\n  {\n    \"HPE\": 3.5,\n    \"HPL\": 24.5,\n    \"epochs\": 110\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 26,\n    \"epochs\": 111\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 26.5,\n    \"epochs\": 115\n  },\n  {\n    \"HPE\": 4,\n    \"HPL\": 25.5,\n    \"epochs\": 170\n  }\n]\n"
  },
  {
    "path": "htdocs/data/c3_test.csv",
    "content": "data1,data2,data3\n120,80,200\n140,50,210\n170,100,250\n150,70,300\n180,120,280"
  },
  {
    "path": "htdocs/data/c3_test.json",
    "content": "{\n  \"data1\": [120, 140, 170, 150, 180],\n  \"data2\": [80, 50, 100, 70, 120],\n  \"data3\": [200, 210, 250, 300, 280]\n}\n"
  },
  {
    "path": "htdocs/data/c3_test.tsv",
    "content": "data1\tdata2\tdata3\n520\t380\t100\n540\t350\t110\n570\t400\t150\n550\t370\t200\n580\t420\t180"
  },
  {
    "path": "htdocs/data/c3_test2.csv",
    "content": "data1,data2,data3\n20,180,400\n40,150,310\n70,120,470\n50,170,400\n80,200,380"
  },
  {
    "path": "htdocs/data/c3_test2_ts.csv",
    "content": "x,data1,data2,data3\n2013-04-01,20,180,400\n2013-04-02,40,150,310\n2013-04-03,70,120,470\n2013-04-04,50,170,400\n2013-04-05,80,200,380"
  },
  {
    "path": "htdocs/data/c3_test3.csv",
    "content": "x,download,loading\nwww.hogehoge.com,30,19\nwww.aaaa.com,30,13\nwww.bb.com,20,24\n"
  },
  {
    "path": "htdocs/data/c3_test_2.json",
    "content": "{\n  \"data1\": [20, 40, 70, 50, 80, 30],\n  \"data2\": [180, 150, 200, 170, 220, 400],\n  \"data3\": [1200, 1210, 1250, 1300, 1280, 1000]\n}\n"
  },
  {
    "path": "htdocs/data/c3_test_3.json",
    "content": "[\n  { \"id\": 1, \"name\": \"abc\", \"data1\": 1200, \"data2\": 500 },\n  { \"id\": 2, \"name\": \"efg\", \"data1\": 900,  \"data2\": 600 },\n  { \"id\": 3, \"name\": \"pqr\", \"data1\": 1150, \"data2\": 300 },\n  { \"id\": 4, \"name\": \"xyz\", \"data1\": 1020, \"data2\": 900 }\n]\n"
  },
  {
    "path": "htdocs/data/c3_test_ts.csv",
    "content": "x,data1,data2,data3\n2012-12-31,120,80,200\n2013-01-01,140,50,210\n2013-01-02,170,100,250\n2013-01-03,150,70,300\n2013-01-04,180,120,280"
  },
  {
    "path": "htdocs/index.html",
    "content": "<html>\n  <head>\n    <link rel=\"icon\" href=\"favicon.png\">\n    <link href=\"./css/bootstrap.min.css\" rel=\"stylesheet\">\n    <link href=\"./css/index.css\" rel=\"stylesheet\">\n  </head>\n  <body>\n    <div class=\"container\">\n      <div class=\"section\">\n        <h2># <span>Chart Type</span></h2>\n        <div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Line Chart</h3>\n              <a href=\"./samples/simple.html\">\n                Line chart with ordinary data\n              </a>\n              <a href=\"./samples/chart_spline.html\">\n                Spline chart with ordinary data\n              </a>\n              <a href=\"./samples/chart_step.html\">\n                Step chart with ordinary data\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Area Chart</h3>\n              <a href=\"./samples/chart_area.html\">\n                Area chart with ordinary data\n              </a>\n              <a href=\"./samples/chart_area_spline.html\">\n                Area-spline chart with ordinary data\n              </a>\n              <a href=\"./samples/chart_area_step.html\">\n                Area-step chart with ordinary data\n              </a>\n              <a href=\"./samples/chart_area_stacked.html\">\n                Stacked Area chart with ordinary data\n              </a>\n              <a href=\"./samples/chart_area_spline_stacked.html\">\n                Stacked Area-spline chart with ordinary data\n              </a>\n              <a href=\"./samples/chart_area_step_stacked.html\">\n                Stacked Area-step chart with ordinary data\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Bar Chart</h3>\n              <a href=\"./samples/chart_bar_space.html\">\n                  Bar chart with spaces\n              </a>\n              <a href=\"./samples/chart_bar.html\">\n                Bar chart with ordinary data\n              </a>\n              <a href=\"./samples/chart_bar_stacked.html\">\n                Stacked Bar chart with ordinary data\n              </a>\n              <a href=\"./samples/chart_bar_stacked_normalized.html\">\n                Stacked Bar chart with normalized data\n              </a>\n              <a href=\"./samples/chart_bar_max_width.html\">\n                Bar chart with max width\n              </a>\n            </div>\n          </div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Pie Chart</h3>\n              <a href=\"./samples/chart_pie.html\">\n                Pie chart with ordinary data\n              </a>\n              <a href=\"./samples/chart_pie_sort.html\">\n                Pie chart with/without sort\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Donut Chart</h3>\n              <a href=\"./samples/chart_donut.html\">\n                Donut chart with ordinary data\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Gauge Chart</h3>\n              <a href=\"./samples/chart_gauge.html\">\n                Gauge chart with ordinary data\n              </a>\n              <a href=\"./samples/chart_multi_arc_gauge.html\">\n                Gauge chart with multiple arcs\n              </a>\n              <a href=\"./samples/chart_arc.html\">\n                Arc chart with full circle\n              </a>\n            </div>\n          </div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Scatter Chart</h3>\n              <a href=\"./samples/chart_scatter.html\">\n                Scatter chart with ordinary data\n              </a>\n            </div>\n              <div class=\"col-md-4\">\n                  <h3>Stanford Chart</h3>\n                  <a href=\"./samples/chart_stanford.html\">\n                      Stanford chart with ordinary data\n                  </a>\n                  <a href=\"./samples/chart_stanford_custom_elements.html\">\n                      Stanford chart with custom elements\n                  </a>\n              </div>\n            <div class=\"col-md-4\">\n              <h3>Combination Chart</h3>\n              <a href=\"./samples/chart_combination.html\">\n                Combination chart with ordinary data\n              </a>\n              <a href=\"./samples/chart_combination_normalized.html\">\n                Combination chart with normalized data\n              </a>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"section\">\n        <h2># <span>Axes</span></h2>\n        <div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Timeseries Axis</h3>\n              <a href=\"./samples/timeseries.html\">\n                Line chart with timeseries data\n              </a>\n              <a href=\"./samples/timeseries_descendent.html\">\n                Line chart with descendent timeseries data\n              </a>\n              <a href=\"./samples/timeseries_raw.html\">\n                Line chart with timeseries data as Number\n              </a>\n              <a href=\"./samples/timeseries_date.html\">\n                Line chart with timeseries data as Date object\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Category Axis</h3>\n              <a href=\"./samples/categorized.html\">\n                Chart with category axis\n              </a>\n              <a href=\"./samples/custom_x_categorized.html\">\n                Chart with category data on category axis\n              </a>\n              <a href=\"./samples/different_category_datasets.html\">\n                Chart with different category datasets\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Additional Axis</h3>\n              <a href=\"./samples/axes_y2.html\">\n                Add y2 axis\n              </a>\n            </div>\n          </div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Axis Range</h3>\n              <a href=\"./samples/axes_range.html\">\n                Set range of axis\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Axis Padding</h3>\n              <a href=\"./samples/axes_padding.html\">\n                Set padding of axis\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>X Axis Tick</h3>\n              <a href=\"./samples/axes_x_tick_values.html\">\n                Set values for x axis\n              </a>\n              <a href=\"./samples/axes_x_tick_culling.html\">\n                Set culling for x axis\n              </a>\n              <a href=\"./samples/axes_x_tick_fit.html\">\n                Set fitting for x axis\n              </a>\n              <a href=\"./samples/axes_x_tick_rotate.html\">\n                Set rotation for x axis\n              </a>\n              <a href=\"./samples/axes_x_range_timeseries.html\">\n                Set range in timeseries for x axis\n              </a>\n            </div>\n          </div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Default Y Domain</h3>\n              <a href=\"./samples/axes_y_default.html\">\n                Set default y domain\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Y Domain</h3>\n              <a href=\"./samples/domain_y.html\">\n                Update y domain automatically\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Default X Selection</h3>\n              <a href=\"./samples/axes_x_selection.html\">\n                Set default x selection\n              </a>\n            </div>\n          </div>\n            <div class=\"row\">\n                <div class=\"col-md-4\">\n                    <h3>Axis scales</h3>\n                    <a href=\"./samples/axes_log_scales.html\">\n                        Log scale\n                    </a>\n                </div>\n            </div>\n        </div>\n      </div>\n\n      <div class=\"section\">\n        <h2># <span>Data</span></h2>\n        <div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Input Data</h3>\n              <a href=\"./samples/data_columned.html\">\n                Columned data\n              </a>\n              <a href=\"./samples/data_rowed.html\">\n                Rowed data\n              </a>\n              <a href=\"./samples/data_json.html\">\n                JSON data\n              </a>\n              <a href=\"./samples/data_url.html\">\n                Data from URL\n              </a>\n              <a href=\"./samples/data_hide.html\">\n                Hide data when init\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Load Data</h3>\n              <a href=\"./samples/data_load.html\">\n                Load ordinary data\n              </a>\n              <a href=\"./samples/data_load_timeseries.html\">\n                Load timeseries data\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Custom X</h3>\n              <a href=\"./samples/custom_x_scale.html\">\n                Custom x for all data\n              </a>\n              <a href=\"./samples/custom_xs_scale.html\">\n                Custom x for each data\n              </a>\n            </div>\n          </div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Data Label</h3>\n              <a href=\"./samples/data_label.html\">\n                Show label on data\n              </a>\n              <a href=\"./samples/data_label_format.html\">\n                Show label on data with format\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Data Region</h3>\n              <a href=\"./samples/data_region.html\">\n                Set region of data\n              </a>\n              <a href=\"./samples/data_region_timeseries.html\">\n                Set region of timeseries data\n              </a>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"section\">\n        <h2># <span>Components</span></h2>\n        <div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Grid</h3>\n              <a href=\"./samples/grids.html\">\n                 Show x/y grids\n              </a>\n              <a href=\"./samples/grids_timeseries.html\">\n                 Show x/y grids with timeseries\n              </a>\n              <a href=\"./samples/grid_x_lines.html\">\n                 Show optional x grids\n              </a>\n              <a href=\"./samples/grid_x_lines_timeseries.html\">\n                 Show optional x grids with timeseries\n              </a>\n              <a href=\"./samples/grid_focus.html\">\n                 Hide focus grid\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Region</h3>\n              <a href=\"./samples/regions.html\">\n                 Show regions\n              </a>\n              <a href=\"./samples/regions_timeseries.html\">\n                 Show regions with timeseries\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Legend</h3>\n              <a href=\"./samples/legend.html\">\n                 Show legend\n              </a>\n            </div>\n          </div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Tooltip</h3>\n              <a href=\"./samples/tooltip_show.html\">\n                Show tooltip\n              </a>\n              <a href=\"./samples/tooltip_grouped.html\">\n                Show tooltip as each data\n              </a>\n              <a href=\"./samples/tooltip_horizontal.html\">\n                Show tooltip based on horizontal mouse position\n              </a>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"section\">\n        <h2># <span>Chart Option</span></h2>\n        <div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Bind</h3>\n              <a href=\"./samples/bindto.html\">\n                Specify the element binded\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Padding</h3>\n              <a href=\"./samples/padding.html\">\n                Change padding of chart\n              </a>\n              <a href=\"./samples/padding_update.html\">\n                Auto padding when chart updated\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Empty Data</h3>\n              <a href=\"./samples/emptydata.html\">\n                Show text when empty data\n              </a>\n            </div>\n          </div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Point</h3>\n              <a href=\"./samples/point_r.html\">\n                Change radius of data point\n              </a>\n              <a href=\"./samples/point_show.html\">\n                Show points based on condition\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Bar</h3>\n              <a href=\"./samples/bar_zerobased.html\">\n                Disable zero-based y domain\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Area</h3>\n              <a href=\"./samples/area_zerobased.html\">\n                Disable zero-based y domain\n              </a>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"section\">\n        <h2># <span>Interaction</span></h2>\n        <div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Zoom</h3>\n              <a href=\"./samples/zoom.html\">\n                Enable zoom\n              </a>\n              <a href=\"./samples/zoom_type.html\">\n                Change Zoom Type\n              </a>\n              <a href=\"./samples/zoom_type_disable_default_behavior.html\">\n                Zoom Types with disableDefaultBehavior: true\n              </a>\n              <a href=\"./samples/zoom_category.html\">\n                Zoom on category axis\n              </a>\n              <a href=\"./samples/zoom_reduction.html\">\n                Zoom with reduction\n              </a>\n              <a href=\"./samples/zoom_onzoom.html\">\n                Callback on zoom\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Subchart</h3>\n              <a href=\"./samples/subchart.html\">\n                Show subchart\n              </a>\n              <a href=\"./samples/subchart_onbrush.html\">\n                Callback on brush\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Selection</h3>\n              <a href=\"./samples/selection.html\">\n                Select data\n              </a>\n            </div>\n          </div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Disable Interaction</h3>\n              <a href=\"./samples/interaction_enabled.html\">\n                Disable interaction\n              </a>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"section\">\n        <h2># <span>API</span></h2>\n        <div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Flow</h3>\n              <a href=\"./samples/api_flow.html\">\n                Flow ordinary data\n              </a>\n              <a href=\"./samples/api_flow_timeseries.html\">\n                Flow timeseries data\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Axis</h3>\n              <a href=\"./samples/api_axis_range.html\">\n                Update axis range\n              </a>\n              <a href=\"./samples/api_axis_label.html\">\n                Update axis label\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Grid</h3>\n              <a href=\"./samples/api_xgrid_lines.html\">\n                Update x grid lines\n              </a>\n              <a href=\"./samples/api_ygrid_lines.html\">\n                Update y grid lines\n              </a>\n            </div>\n          </div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Legend</h3>\n              <a href=\"./samples/api_legend.html\">\n                Update legend\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Transform</h3>\n              <a href=\"./samples/api_transform.html\">\n                Transform chart\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Element</h3>\n              <a href=\"./samples/element.html\">\n                Access svg element of chart\n              </a>\n            </div>\n          </div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Data</h3>\n              <a href=\"./samples/api_data_colors.html\">\n                Update data color\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Tooltip</h3>\n              <a href=\"./samples/api_tooltip_show.html\">\n                Show tooltip programmatically\n              </a>\n            </div>\n            <div class=\"col-md-4\">\n              <h3>Zoom</h3>\n              <a href=\"./samples/api_zoom.html\">\n                Zoom programmatically\n              </a>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"section\">\n        <h2># <span>Other Library</span></h2>\n        <div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>RequireJS</h3>\n              <a href=\"./samples/requirejs.html\">\n                Load by RequireJS\n              </a>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"section\">\n        <h2># <span>Misc</span></h2>\n        <div>\n          <div class=\"row\">\n            <div class=\"col-md-4\">\n              <h3>Issues</h3>\n              <p>\n              <a href=\"./samples/resize.html\">\n                Demo for resizing (Issue #2467)\n              </a>\n              </p>\n            </div>\n          </div>\n        </div>\n      </div>\n\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/js/require.js",
    "content": "/*\n RequireJS 2.1.11 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.\n Available via the MIT or new BSD license.\n see: http://github.com/jrburke/requirejs for details\n*/\nvar requirejs,require,define;\n(function(ca){function G(b){return\"[object Function]\"===M.call(b)}function H(b){return\"[object Array]\"===M.call(b)}function v(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function U(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function s(b,c){return ga.call(b,c)}function j(b,c){return s(b,c)&&b[c]}function B(b,c){for(var d in b)if(s(b,d)&&c(b[d],d))break}function V(b,c,d,g){c&&B(c,function(c,h){if(d||!s(b,h))g&&\"object\"===typeof c&&c&&!H(c)&&!G(c)&&!(c instanceof\nRegExp)?(b[h]||(b[h]={}),V(b[h],c,d,g)):b[h]=c});return b}function t(b,c){return function(){return c.apply(b,arguments)}}function da(b){throw b;}function ea(b){if(!b)return b;var c=ca;v(b.split(\".\"),function(b){c=c[b]});return c}function C(b,c,d,g){c=Error(c+\"\\nhttp://requirejs.org/docs/errors.html#\"+b);c.requireType=b;c.requireModules=g;d&&(c.originalError=d);return c}function ha(b){function c(a,e,b){var f,n,c,d,g,h,i,I=e&&e.split(\"/\");n=I;var m=l.map,k=m&&m[\"*\"];if(a&&\".\"===a.charAt(0))if(e){n=\nI.slice(0,I.length-1);a=a.split(\"/\");e=a.length-1;l.nodeIdCompat&&R.test(a[e])&&(a[e]=a[e].replace(R,\"\"));n=a=n.concat(a);d=n.length;for(e=0;e<d;e++)if(c=n[e],\".\"===c)n.splice(e,1),e-=1;else if(\"..\"===c)if(1===e&&(\"..\"===n[2]||\"..\"===n[0]))break;else 0<e&&(n.splice(e-1,2),e-=2);a=a.join(\"/\")}else 0===a.indexOf(\"./\")&&(a=a.substring(2));if(b&&m&&(I||k)){n=a.split(\"/\");e=n.length;a:for(;0<e;e-=1){d=n.slice(0,e).join(\"/\");if(I)for(c=I.length;0<c;c-=1)if(b=j(m,I.slice(0,c).join(\"/\")))if(b=j(b,d)){f=b;\ng=e;break a}!h&&(k&&j(k,d))&&(h=j(k,d),i=e)}!f&&h&&(f=h,g=i);f&&(n.splice(0,g,f),a=n.join(\"/\"))}return(f=j(l.pkgs,a))?f:a}function d(a){z&&v(document.getElementsByTagName(\"script\"),function(e){if(e.getAttribute(\"data-requiremodule\")===a&&e.getAttribute(\"data-requirecontext\")===i.contextName)return e.parentNode.removeChild(e),!0})}function g(a){var e=j(l.paths,a);if(e&&H(e)&&1<e.length)return e.shift(),i.require.undef(a),i.require([a]),!0}function u(a){var e,b=a?a.indexOf(\"!\"):-1;-1<b&&(e=a.substring(0,\nb),a=a.substring(b+1,a.length));return[e,a]}function m(a,e,b,f){var n,d,g=null,h=e?e.name:null,l=a,m=!0,k=\"\";a||(m=!1,a=\"_@r\"+(M+=1));a=u(a);g=a[0];a=a[1];g&&(g=c(g,h,f),d=j(p,g));a&&(g?k=d&&d.normalize?d.normalize(a,function(a){return c(a,h,f)}):c(a,h,f):(k=c(a,h,f),a=u(k),g=a[0],k=a[1],b=!0,n=i.nameToUrl(k)));b=g&&!d&&!b?\"_unnormalized\"+(Q+=1):\"\";return{prefix:g,name:k,parentMap:e,unnormalized:!!b,url:n,originalName:l,isDefine:m,id:(g?g+\"!\"+k:k)+b}}function q(a){var e=a.id,b=j(k,e);b||(b=k[e]=new i.Module(a));\nreturn b}function r(a,e,b){var f=a.id,n=j(k,f);if(s(p,f)&&(!n||n.defineEmitComplete))\"defined\"===e&&b(p[f]);else if(n=q(a),n.error&&\"error\"===e)b(n.error);else n.on(e,b)}function w(a,e){var b=a.requireModules,f=!1;if(e)e(a);else if(v(b,function(e){if(e=j(k,e))e.error=a,e.events.error&&(f=!0,e.emit(\"error\",a))}),!f)h.onError(a)}function x(){S.length&&(ia.apply(A,[A.length,0].concat(S)),S=[])}function y(a){delete k[a];delete W[a]}function F(a,e,b){var f=a.map.id;a.error?a.emit(\"error\",a.error):(e[f]=\n!0,v(a.depMaps,function(f,c){var d=f.id,g=j(k,d);g&&(!a.depMatched[c]&&!b[d])&&(j(e,d)?(a.defineDep(c,p[d]),a.check()):F(g,e,b))}),b[f]=!0)}function D(){var a,e,b=(a=1E3*l.waitSeconds)&&i.startTime+a<(new Date).getTime(),f=[],c=[],h=!1,k=!0;if(!X){X=!0;B(W,function(a){var i=a.map,m=i.id;if(a.enabled&&(i.isDefine||c.push(a),!a.error))if(!a.inited&&b)g(m)?h=e=!0:(f.push(m),d(m));else if(!a.inited&&(a.fetched&&i.isDefine)&&(h=!0,!i.prefix))return k=!1});if(b&&f.length)return a=C(\"timeout\",\"Load timeout for modules: \"+\nf,null,f),a.contextName=i.contextName,w(a);k&&v(c,function(a){F(a,{},{})});if((!b||e)&&h)if((z||fa)&&!Y)Y=setTimeout(function(){Y=0;D()},50);X=!1}}function E(a){s(p,a[0])||q(m(a[0],null,!0)).init(a[1],a[2])}function K(a){var a=a.currentTarget||a.srcElement,e=i.onScriptLoad;a.detachEvent&&!Z?a.detachEvent(\"onreadystatechange\",e):a.removeEventListener(\"load\",e,!1);e=i.onScriptError;(!a.detachEvent||Z)&&a.removeEventListener(\"error\",e,!1);return{node:a,id:a&&a.getAttribute(\"data-requiremodule\")}}function L(){var a;\nfor(x();A.length;){a=A.shift();if(null===a[0])return w(C(\"mismatch\",\"Mismatched anonymous define() module: \"+a[a.length-1]));E(a)}}var X,$,i,N,Y,l={waitSeconds:7,baseUrl:\"./\",paths:{},bundles:{},pkgs:{},shim:{},config:{}},k={},W={},aa={},A=[],p={},T={},ba={},M=1,Q=1;N={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?p[a.map.id]=a.exports:a.exports=p[a.map.id]={}},module:function(a){return a.module?\na.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return j(l.config,a.map.id)||{}},exports:a.exports||(a.exports={})}}};$=function(a){this.events=j(aa,a.id)||{};this.map=a;this.shim=j(l.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};$.prototype={init:function(a,e,b,f){f=f||{};if(!this.inited){this.factory=e;if(b)this.on(\"error\",b);else this.events.error&&(b=t(this,function(a){this.emit(\"error\",a)}));this.depMaps=a&&a.slice(0);this.errback=\nb;this.inited=!0;this.ignore=f.ignore;f.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,e){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=e)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],t(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=\nthis.map.url;T[a]||(T[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,e,b=this.map.id;e=this.depExports;var f=this.exports,c=this.factory;if(this.inited)if(this.error)this.emit(\"error\",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(G(c)){if(this.events.error&&this.map.isDefine||h.onError!==da)try{f=i.execCb(b,c,e,f)}catch(d){a=d}else f=i.execCb(b,c,e,f);this.map.isDefine&&void 0===f&&((e=this.module)?f=e.exports:this.usingExports&&\n(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?\"define\":\"require\",w(this.error=a)}else f=c;this.exports=f;if(this.map.isDefine&&!this.ignore&&(p[b]=f,h.onResourceLoad))h.onResourceLoad(i,this.map,this.depMaps);y(b);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit(\"defined\",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=\nthis.map,b=a.id,d=m(a.prefix);this.depMaps.push(d);r(d,\"defined\",t(this,function(f){var d,g;g=j(ba,this.map.id);var J=this.map.name,u=this.map.parentMap?this.map.parentMap.name:null,p=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(J=f.normalize(J,function(a){return c(a,u,!0)})||\"\"),f=m(a.prefix+\"!\"+J,this.map.parentMap),r(f,\"defined\",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),g=j(k,f.id)){this.depMaps.push(f);\nif(this.events.error)g.on(\"error\",t(this,function(a){this.emit(\"error\",a)}));g.enable()}}else g?(this.map.url=i.nameToUrl(g),this.load()):(d=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),d.error=t(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(k,function(a){0===a.map.id.indexOf(b+\"_unnormalized\")&&y(a.map.id)});w(a)}),d.fromText=t(this,function(f,c){var g=a.name,J=m(g),k=O;c&&(f=c);k&&(O=!1);q(J);s(l.config,b)&&(l.config[g]=l.config[b]);try{h.exec(f)}catch(j){return w(C(\"fromtexteval\",\n\"fromText eval for \"+b+\" failed: \"+j,j,[b]))}k&&(O=!0);this.depMaps.push(J);i.completeLoad(g);p([g],d)}),f.load(a.name,p,d,l))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){W[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,t(this,function(a,b){var c,f;if(\"string\"===typeof a){a=m(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=j(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;r(a,\"defined\",t(this,function(a){this.defineDep(b,\na);this.check()}));this.errback&&r(a,\"error\",t(this,this.errback))}c=a.id;f=k[c];!s(N,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,t(this,function(a){var b=j(k,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});\"error\"===a&&delete this.events[a]}};i={config:l,contextName:b,registry:k,defined:p,urlFetched:T,defQueue:A,Module:$,makeModuleMap:m,\nnextTick:h.nextTick,onError:w,configure:function(a){a.baseUrl&&\"/\"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+=\"/\");var b=l.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(l[b]||(l[b]={}),V(l[b],a,!0,!0)):l[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(ba[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),l.shim=b);a.packages&&v(a.packages,function(a){var b,\na=\"string\"===typeof a?{name:a}:a;b=a.name;a.location&&(l.paths[b]=a.location);l.pkgs[b]=a.name+\"/\"+(a.main||\"main\").replace(ja,\"\").replace(R,\"\")});B(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=m(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ca,arguments));return b||a.exports&&ea(a.exports)}},makeRequire:function(a,e){function g(f,c,d){var j,l;e.enableBuildCallback&&(c&&G(c))&&(c.__requireJsBuild=\n!0);if(\"string\"===typeof f){if(G(c))return w(C(\"requireargs\",\"Invalid require call\"),d);if(a&&s(N,f))return N[f](k[a.id]);if(h.get)return h.get(i,f,a,g);j=m(f,a,!1,!0);j=j.id;return!s(p,j)?w(C(\"notloaded\",'Module name \"'+j+'\" has not been loaded yet for context: '+b+(a?\"\":\". Use require([])\"))):p[j]}L();i.nextTick(function(){L();l=q(m(null,a));l.skipMap=e.skipMap;l.init(f,c,d,{enabled:!0});D()});return g}e=e||{};V(g,{isBrowser:z,toUrl:function(b){var e,d=b.lastIndexOf(\".\"),g=b.split(\"/\")[0];if(-1!==\nd&&(!(\".\"===g||\"..\"===g)||1<d))e=b.substring(d,b.length),b=b.substring(0,d);return i.nameToUrl(c(b,a&&a.id,!0),e,!0)},defined:function(b){return s(p,m(b,a,!1,!0).id)},specified:function(b){b=m(b,a,!1,!0).id;return s(p,b)||s(k,b)}});a||(g.undef=function(b){x();var c=m(b,a,!0),e=j(k,b);d(b);delete p[b];delete T[c.url];delete aa[b];U(A,function(a,c){a[0]===b&&A.splice(c,1)});e&&(e.events.defined&&(aa[b]=e.events),y(b))});return g},enable:function(a){j(k,a.id)&&q(a).enable()},completeLoad:function(a){var b,\nc,f=j(l.shim,a)||{},d=f.exports;for(x();A.length;){c=A.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=j(k,a);if(!b&&!s(p,a)&&c&&!c.inited){if(l.enforceDefine&&(!d||!ea(d)))return g(a)?void 0:w(C(\"nodefine\",\"No define call for \"+a,null,[a]));E([a,f.deps||[],f.exportsFn])}D()},nameToUrl:function(a,b,c){var f,d,g;(f=j(l.pkgs,a))&&(a=f);if(f=j(ba,a))return i.nameToUrl(f,b,c);if(h.jsExtRegExp.test(a))f=a+(b||\"\");else{f=l.paths;a=a.split(\"/\");for(d=a.length;0<d;d-=1)if(g=a.slice(0,\nd).join(\"/\"),g=j(f,g)){H(g)&&(g=g[0]);a.splice(0,d,g);break}f=a.join(\"/\");f+=b||(/^data\\:|\\?/.test(f)||c?\"\":\".js\");f=(\"/\"===f.charAt(0)||f.match(/^[\\w\\+\\.\\-]+:/)?\"\":l.baseUrl)+f}return l.urlArgs?f+((-1===f.indexOf(\"?\")?\"?\":\"&\")+l.urlArgs):f},load:function(a,b){h.load(i,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if(\"load\"===a.type||ka.test((a.currentTarget||a.srcElement).readyState))P=null,a=K(a),i.completeLoad(a.id)},onScriptError:function(a){var b=K(a);if(!g(b.id))return w(C(\"scripterror\",\n\"Script error for: \"+b.id,a,[b.id]))}};i.require=i.makeRequire();return i}var h,x,y,D,K,E,P,L,q,Q,la=/(\\/\\*([\\s\\S]*?)\\*\\/|([^:]|^)\\/\\/(.*)$)/mg,ma=/[^.]\\s*require\\s*\\(\\s*[\"']([^'\"\\s]+)[\"']\\s*\\)/g,R=/\\.js$/,ja=/^\\.\\//;x=Object.prototype;var M=x.toString,ga=x.hasOwnProperty,ia=Array.prototype.splice,z=!!(\"undefined\"!==typeof window&&\"undefined\"!==typeof navigator&&window.document),fa=!z&&\"undefined\"!==typeof importScripts,ka=z&&\"PLAYSTATION 3\"===navigator.platform?/^complete$/:/^(complete|loaded)$/,\nZ=\"undefined\"!==typeof opera&&\"[object Opera]\"===opera.toString(),F={},r={},S=[],O=!1;if(\"undefined\"===typeof define){if(\"undefined\"!==typeof requirejs){if(G(requirejs))return;r=requirejs;requirejs=void 0}\"undefined\"!==typeof require&&!G(require)&&(r=require,require=void 0);h=requirejs=function(b,c,d,g){var u,m=\"_\";!H(b)&&\"string\"!==typeof b&&(u=b,H(c)?(b=c,c=d,d=g):b=[]);u&&u.context&&(m=u.context);(g=j(F,m))||(g=F[m]=h.s.newContext(m));u&&g.configure(u);return g.require(b,c,d)};h.config=function(b){return h(b)};\nh.nextTick=\"undefined\"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=h);h.version=\"2.1.11\";h.jsExtRegExp=/^\\/|:|\\?|\\.js$/;h.isBrowser=z;x=h.s={contexts:F,newContext:ha};h({});v([\"toUrl\",\"undef\",\"defined\",\"specified\"],function(b){h[b]=function(){var c=F._;return c.require[b].apply(c,arguments)}});if(z&&(y=x.head=document.getElementsByTagName(\"head\")[0],D=document.getElementsByTagName(\"base\")[0]))y=x.head=D.parentNode;h.onError=da;h.createNode=function(b){var c=\nb.xhtml?document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"html:script\"):document.createElement(\"script\");c.type=b.scriptType||\"text/javascript\";c.charset=\"utf-8\";c.async=!0;return c};h.load=function(b,c,d){var g=b&&b.config||{};if(z)return g=h.createNode(g,c,d),g.setAttribute(\"data-requirecontext\",b.contextName),g.setAttribute(\"data-requiremodule\",c),g.attachEvent&&!(g.attachEvent.toString&&0>g.attachEvent.toString().indexOf(\"[native code\"))&&!Z?(O=!0,g.attachEvent(\"onreadystatechange\",b.onScriptLoad)):\n(g.addEventListener(\"load\",b.onScriptLoad,!1),g.addEventListener(\"error\",b.onScriptError,!1)),g.src=d,L=g,D?y.insertBefore(g,D):y.appendChild(g),L=null,g;if(fa)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(C(\"importscripts\",\"importScripts failed for \"+c+\" at \"+d,j,[c]))}};z&&!r.skipDataMain&&U(document.getElementsByTagName(\"script\"),function(b){y||(y=b.parentNode);if(K=b.getAttribute(\"data-main\"))return q=K,r.baseUrl||(E=q.split(\"/\"),q=E.pop(),Q=E.length?E.join(\"/\")+\"/\":\"./\",r.baseUrl=\nQ),q=q.replace(R,\"\"),h.jsExtRegExp.test(q)&&(q=K),r.deps=r.deps?r.deps.concat(q):[q],!0});define=function(b,c,d){var g,h;\"string\"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(la,\"\").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?[\"require\"]:[\"require\",\"exports\",\"module\"]).concat(c)));if(O){if(!(g=L))P&&\"interactive\"===P.readyState||U(document.getElementsByTagName(\"script\"),function(b){if(\"interactive\"===b.readyState)return P=b}),g=P;g&&(b||\n(b=g.getAttribute(\"data-requiremodule\")),h=F[g.getAttribute(\"data-requirecontext\")])}(h?h.defQueue:S).push([b,c,d])};define.amd={jQuery:!0};h.exec=function(b){return eval(b)};h(r)}})(this);\n"
  },
  {
    "path": "htdocs/js/samples/plugin.js",
    "content": "c3.chart.internal.fn.isTimeSeries = function () {\n    console.log('custom isTimeSeries');\n    return false;\n};\nc3.chart.internal.fn.additionalConfig.test1 = undefined;\nc3.chart.internal.fn.additionalConfig.test2 = undefined;\n\nc3.chart.fn.hoge = function () {\n    console.log(\"hoge()\", this.internal.isTimeSeries());\n};\nc3.chart.fn.test = function () {\n    console.log('test()', this.internal.config.test1);\n};\n"
  },
  {
    "path": "htdocs/js/samples/requirejs.js",
    "content": "require.config({\n    baseUrl: '/js',\n    paths: {\n        d3: \"http://d3js.org/d3.v4.min\"\n    }\n});\n\nrequire([\"d3\", \"c3\"], function(d3, c3) {\n\n    window.chart = c3.generate({\n        data: {\n            columns: [\n                ['sample', 30, 200, 100, 400, 150, 250]\n            ]\n        }\n    });\n\n});\n"
  },
  {
    "path": "htdocs/js/samples/zoom_reduction.js",
    "content": "﻿var chart;\nfunction refresh() {\n    if (suspendRefresh)\n        return;\n    chart.load({\n        columns: [\n            [\"Value\"].concat(zoom(column, currentZoom, \"t=>Math.round(t.avg())\".toLambda())),\n            [\"xColumn\"].concat(zoom(xColumn, currentZoom, \"t=>t[0]\".toLambda())),\n        ]\n    });\n}\n\nfunction getChart() {\n    return chart;\n}\nfunction main() {\n    var last = 0;\n    var max = 10000;\n    var column = Array.generate(max, function (i) {\n        return last += Math.randomInt(-10, 10);\n    });\n    var xColumn = Array.generateNumbers(0, max);\n    var options = {\n        bindto: \"#divChart\",\n        data: {\n            columns: [\n                [\"Value\"].concat(column),\n                [\"x\"].concat(xColumn),\n            ],\n            type: \"line\",\n            x: \"x\"\n        },\n        zoom2: {\n            enabled: true,\n        }\n    };\n    chart = c3ext.generate(options);\n\n    window.setInterval(refreshStatus, 1000);\n\n    function refreshStatus() {\n        var zoomInfo = chart.zoom2.getZoom();\n        var info = {\n            reduced: chart.zoom2.maxItems(),\n            actual: (zoomInfo.currentZoom[1] - zoomInfo.currentZoom[0]),\n            range: zoomInfo.currentZoom[0] + \"-\" + zoomInfo.currentZoom[1],\n            total: zoomInfo.totalItems\n        };\n        $(\"#status\").text(JSON.stringify(info, null, \" \"));\n    }\n\n};\n\nif (typeof (Array.generate) == \"undefined\") {\n    Array.generate = function (length, generator) {\n        var list = new Array(length);\n        for (var i = 0; i < length; i++) {\n            list[i] = generator(i);\n        }\n        return list;\n    }\n}\nif (typeof (Math.randomInt) == \"undefined\") {\n    Math.randomInt = function (min, max) {\n        return Math.floor(Math.random() * (max - min + 1)) + min;\n    }\n}\nif (typeof (Array.generateNumbers) == \"undefined\") {\n    Array.generateNumbers = function (from, until) {\n        if (arguments.length == 1) {\n            until = from;\n            from = 0;\n        }\n        var length = until - from;\n        var list = new Array(length);\n        for (var i = 0; i < length; i++) {\n            list[i] = i + from;\n        }\n        return list;\n    }\n}"
  },
  {
    "path": "htdocs/samples/api_axis_label.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          axes: {\n            data1: 'y',\n            data2: 'y2',\n          }\n        },\n        axis: {\n          x: {\n            label: 'X Label'\n          },\n          y: {\n            label: {\n              text: 'Y Axis Label',\n              position: 'outer-middle'\n            }\n          },\n          y2: {\n            show: true,\n            label: {\n              text: 'Y2 Axis Label',\n              position: 'outer-middle'\n            }\n          }\n        },\n        tooltip: {\n//          enabled: false\n        },\n        zoom: {\n//          enabled: true\n        },\n        subchart: {\n//          show: true\n        }\n      });\n\n      setTimeout(function () {\n        chart.axis.labels({\n          x: 'New X Axis Label',\n          y: 'New Y Axis Label',\n          y2: 'New Y2 Axis Label',\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['data1', 100, 300, 600, 200, 400, 500]\n          ]\n        });\n        chart.axis.labels({y: 'New Y Axis Label Again'});\n      }, 2000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/api_axis_range.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          axes: {\n            data1: 'y',\n            data2: 'y2',\n          }\n        },\n        axis: {\n          x: {\n            label: 'X Label'\n          },\n          y: {\n            label: {\n              text: 'Y Axis Label',\n              position: 'outer-middle'\n            }\n          },\n          y2: {\n            show: true,\n            label: {\n              text: 'Y2 Axis Label',\n              position: 'outer-middle'\n            }\n          }\n        },\n        tooltip: {\n//          enabled: false\n        },\n        zoom: {\n//          enabled: true\n        },\n        subchart: {\n//          show: true\n        }\n      });\n\n      setTimeout(function () {\n        chart.axis.max(500);\n      }, 1000);\n\n      setTimeout(function () {\n        chart.axis.min(-500);\n      }, 2000);\n\n      setTimeout(function () {\n        chart.axis.max({y: 600, y2: 100});\n      }, 3000);\n\n      setTimeout(function () {\n        chart.axis.min({y: -600, y2: -100});\n      }, 4000);\n\n      setTimeout(function () {\n        chart.axis.range({max: 1000, min: -1000});\n      }, 5000);\n\n      setTimeout(function () {\n        chart.axis.range({min: {y: 1000}, max: {y: 2000}});\n      }, 6000);\n\n      setTimeout(function () {\n        chart.axis.range({max: {y: 600, y2: 100}, min: {y: -100, y2: 0}});\n      }, 7000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/api_category.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n    <div id=\"message\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart = c3.generate({\n        data: {\n          x: 'x',\n          columns: [\n            ['x', '1e-3', '1e-2', '1'],\n            ['data1', 30, 200, 100, 400, 150, 250, 50, 100, 250]\n          ]\n        },\n        axis: {\n          x: {\n            type: 'categorized'\n          }\n        }\n      });\n\n      setTimeout(function () {\n        d3.select('#message').node().innerHTML = \"chart.categories() =>\" + chart.categories();\n      }, 1000);\n\n      setTimeout(function () {\n        chart.categories(['updated 1', 'updated 2', 'updated 3', 'updated 4']);\n        d3.select('#message').node().innerHTML = \"\";\n      }, 2000);\n\n      setTimeout(function () {\n        d3.select('#message').node().innerHTML = \"chart.category(1) =>\" + chart.category(1);\n      }, 3000);\n\n      setTimeout(function () {\n        chart.category(1, 'UPDATED 1');\n        d3.select('#message').node().innerHTML = \"\";\n      }, 4000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/api_data_colors.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n        },\n        axis: {\n          x: {\n            type: 'category'\n          }\n        }\n      });\n\n      setTimeout(function () {\n        chart.data.colors({data1: '#000'});\n      }, 1000);\n\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/api_flow.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n    <style>\n      .c3-region-1 {\n        fill: #dd3333;\n        fill-opacity: 0.8\n      }\n    </style>\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var padding = {}, types = {}, chart, generate = function () { return c3.generate({\n        data: {\n          columns: [\n            ['data1'],\n            ['data2'],\n          ],\n          types: types,\n          labels: true\n        },\n        bar: {\n          width: 10\n        },\n        axis: {\n          x: {\n            padding: padding\n          },\n          y: {\n/*\n            min: -100,\n            max: 1000\n*/\n          }\n        },\n        grid: {\n          x: {\n            show: true,\n            lines: [{value: 3, text:'Label 3'}, {value: 4.5, text: 'Label 4.5'}]\n          },\n          y: {\n            show: true\n          }\n        },\n        regions: [\n          {start:2, end:4, class:'region1'},\n          {start:100, end:200, axis:'y'},\n        ],\n      });\n      };\n\n    function run() {\n\n      chart = generate();\n\n      setTimeout(function () {\n        // Load only one data\n        chart.flow({\n          rows: [\n            ['data1', 'data2', 'data3'],\n            [500, 100, 200],\n            [200, null, null],\n            [100, 50, null]\n          ],\n          duration: 1500,\n\n          done: function () {\n            // Load 2 data without data2 and remove 1 data\n            chart.flow({\n              columns: [\n                ['data1', 200, 300],\n                ['data3', 100, 100]\n              ],\n              length: 0,\n              duration: 1500,\n\n              done: function () {\n                chart.flow({\n                  columns: [\n                    ['data1', 200, 300],\n                    ['data2', 200, 300],\n                    ['data3', 100, 100]\n                  ],\n                  length: 2,\n                  duration: 1500,\n                  done: function () {\n\n                    chart.flow({\n                      columns: [\n                        ['data1', 500],\n                        ['data2', 100],\n                        ['data3', 200]\n                      ],\n                      length: 1,\n                      duration: 1500,\n                    });\n                  }\n\n                });\n              }// done\n\n            });\n          },\n\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['data1', 250],\n            ['data2', 350],\n            ['data3', 150]\n          ],\n          length: 0\n        });\n      }, 9000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['data1', 100],\n            ['data2', 50],\n            ['data3', 300]\n          ],\n          length: 2\n        });\n      }, 10000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['data1', 600],\n            ['data2', 400],\n            ['data3', 500]\n          ],\n          to: 2,\n        });\n      }, 11000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['data1', 100],\n            ['data2', 200],\n            ['data3', 300]\n          ]\n        });\n      }, 12000);\n\n      setTimeout(function () {\n        chart = generate();\n      }, 13000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['data1', 500, 100],\n            ['data2', 100, 200],\n            ['data3', 200, 300],\n          ],\n          duration: 1500,\n          done: function () {\n            chart.flow({\n              columns: [\n                ['data1', 200],\n                ['data3', 100]\n              ],\n//              duration: 1000,\n              length: 1\n            });\n          },\n        });\n      }, 14000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['data1', 200],\n            ['data2', 300],\n            ['data3', 100]\n          ],\n          to: 1,\n        });\n      }, 18000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['data1', 200],\n            ['data2', 300],\n            ['data3', 400]\n          ]\n        });\n      }, 19000);\n\n    }\n\n    run();\n\n    // Test for no padding\n    setTimeout(function () {\n      padding = {left: 0, right: 0};\n      run();\n    }, 22000);\n\n    // Test for other chart types\n    setTimeout(function () {\n      types = {\n        data2: 'area',\n        data3: 'bar',\n      };\n      run();\n    }, 45000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/api_flow_timeseries.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var padding = {}, types = {};\n\n      var generate = function () { return c3.generate({\n        data: {\n          x: 'x',\n          columns: [\n            ['x', ],\n            ['data1', ],\n            ['data2', ],\n//            ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-10', '2013-01-11', '2013-01-12'],\n//            ['data1', 30, 200, 100, 400, 150, 250],\n//            ['data2', 310, 400, 200, 100, 450, 150],\n//            ['data3', 310, 400, 200, 100, null, 150],\n          ],\n          types: types,\n//          labels: true\n        },\n        bar: {\n          width: 10\n        },\n        axis: {\n          x: {\n            type: 'timeseries',\n            tick: {\n              format: '%m/%d',\n            },\n            padding: padding\n          },\n          y: {\n/*\n            min: -100,\n            max: 1000\n*/\n          }\n        },\n/* not supported yet\n        grid: {\n          x: {\n            show: true\n          },\n          y: {\n            show: true\n          }\n        }\n*/\n      }); }, chart;\n\n    function run() {\n\n      chart = generate();\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['x', '2013-01-21'],\n            ['data1', 500],\n            ['data3', 200],\n          ],\n          duration: 1500\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['x', '2013-02-01', '2013-02-08', '2013-02-15'],\n            ['data1', 200, 400, 300],\n            ['data2', 100, 300, 200],\n            ['data3', 100, 200, 50]\n          ],\n          length: 1,\n          duration: 1500\n        });\n      }, 4000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['x', '2013-03-01', '2013-03-08'],\n            ['data1', 200, 500],\n            ['data2', 300, 400],\n            ['data3', 400, 200]\n          ],\n          to: '2013-02-08',\n          duration: 1500\n        });\n      }, 7000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['x', '2013-03-15', '2013-05-01'],\n            ['data1', 200, 500],\n            ['data2', 300, 400],\n            ['data3', 400, 200]\n          ],\n          length: 0,\n          duration: 1500\n        });\n      }, 10000);\n\n      setTimeout(function () {\n        chart = generate();\n      }, 14000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['x', '2013-01-21', '2013-01-25', '2013-01-26'],\n            ['data1', 500, 300, 100],\n            ['data3', 200, 150, null],\n          ],\n          duration: 1500\n        });\n      }, 15000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['x', '2013-02-01'],\n            ['data1', 200],\n            ['data2', 100],\n            ['data3', 100]\n          ],\n          length: 0,\n          duration: 1500\n        });\n      }, 18000);\n\n      setTimeout(function () {\n        chart.flow({\n          columns: [\n            ['x', '2013-03-01'],\n            ['data1', 200],\n            ['data2', 300],\n            ['data3', 400]\n          ],\n          to: '2013-02-01',\n          duration: 1500\n        });\n      }, 21000);\n    };\n\n    run();\n\n    setTimeout(function () {\n      padding = {left: 0, right: 0};\n      run();\n    }, 25000);\n\n    setTimeout(function () {\n      types = {\n        data2: 'area',\n        data3: 'bar',\n      }\n      run();\n    }, 50000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/api_legend.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var columns = [];\n      for (var i = 0; i < 5; i++ ) {\n        columns[i] = ['datahogehogeohgeohoge' + i, 10 * i, 20 * i, 30 * i];\n      }\n\n      var chart = c3.generate({\n        data: {\n          columns: columns,\n        },\n        axis: {\n          x: {\n            type: 'category'\n          }\n        }\n      });\n\n      setTimeout(function () {\n        chart.legend.hide();\n      }, 1000);\n\n      setTimeout(function () {\n        chart = c3.generate({\n          data: {\n            columns: columns,\n          },\n          axis: {\n            x: {\n              type: 'category'\n            }\n          },\n          legend: {\n            position: 'right'\n          }\n        });\n      }, 2000);\n\n      setTimeout(function () {\n        chart.legend.hide();\n      }, 3000);\n\n      setTimeout(function () {\n        chart = c3.generate({\n          data: {\n            columns: columns,\n          },\n          axis: {\n            rotated: true\n          }\n        });\n      }, 4000);\n\n      setTimeout(function () {\n        chart.legend.hide();\n      }, 5000);\n\n      setTimeout(function () {\n        chart = c3.generate({\n          data: {\n            columns: columns,\n          },\n          legend: {\n            position: 'right'\n          },\n          axis: {\n            rotated: true\n          }\n        });\n      }, 6000);\n\n      setTimeout(function () {\n        chart.legend.hide();\n      }, 7000);\n\n      setTimeout(function () {\n        chart = c3.generate({\n          data: {\n            columns: columns,\n          },\n          legend: {\n            show: false\n          }\n        });\n      }, 8000);\n\n      setTimeout(function () {\n        chart.legend.show();\n      }, 9000);\n\n      setTimeout(function () {\n        chart = c3.generate({\n          data: {\n            columns: columns,\n          },\n          legend: {\n            show: false\n          },\n          axis: {\n            rotated: true\n          }\n        });\n      }, 10000);\n\n      setTimeout(function () {\n        chart.legend.show();\n      }, 11000);\n\n      setTimeout(function () {\n        chart = c3.generate({\n          data: {\n            columns: columns,\n          },\n          legend: {\n            position: 'right',\n            show: false\n          }\n        });\n      }, 12000);\n\n      setTimeout(function () {\n        chart.legend.show();\n      }, 13000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/api_tooltip_show.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n        },\n        zoom: {\n            enabled: true,\n            initialRange: [0.8,3.2],\n        }\n      });\n\n      setTimeout(function () {\n        chart.tooltip.show({ x: 2 });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.tooltip.show({ x: 1 });\n      }, 2000);\n\n      setTimeout(function () {\n        chart.tooltip.show({ data: {x: 3, id: 'data1', value: 400} });\n      }, 3000);\n\n      setTimeout(function () {\n        chart.tooltip.hide();\n      }, 4000);\n\n      setTimeout(function () {\n        chart.internal.config.tooltip_grouped = false;\n        chart.tooltip.show({ x: 2 });\n      }, 5000);\n\n      setTimeout(function () {\n//        chart.internal.config.tooltip_grouped = false;\n        chart.tooltip.show({ x: 1, id: 'data2' });\n      }, 6000);\n\n      setTimeout(function () {\n//        chart.internal.config.tooltip_grouped = false;\n        chart.tooltip.show({ data: {x: 3, id: 'data1', value: 400} });\n      }, 7000);\n\n      setTimeout(function () {\n        chart.tooltip.hide();\n      }, 8000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/api_transform.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n        },\n      });\n\n      setTimeout(function () {\n        chart.transform('bar');\n      }, 1000);\n\n      setTimeout(function () {\n        chart.transform('pie');\n      }, 2000);\n\n      setTimeout(function () {\n        chart.transform('donut');\n      }, 3000);\n\n      setTimeout(function () {\n        chart.transform('area');\n      }, 4000);\n\n      setTimeout(function () {\n        chart.transform('spline');\n      }, 5000);\n\n      setTimeout(function () {\n        chart = c3.generate({\n          data: {\n            columns: [\n              ['data1', 30, 200, 100, 400, 150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25],\n              ['data1_x', 50, 20, 10, 40, 15, 25],\n              ['data2_x', 30, 200, 100, 400, 150, 250],\n            ],\n            xs: {\n              data1: 'data1_x',\n              data2: 'data2_x',\n            },\n            type: 'scatter'\n          },\n        });\n      }, 7000);\n\n      setTimeout(function () {\n        chart.transform('pie');\n      }, 8000);\n\n      setTimeout(function () {\n        chart.transform('scatter');\n      }, 9000);\n\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/api_xgrid_lines.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var axis_rotated = false, axis_x_type = \"\";\n\n      var generate = function () { return c3.generate({\n        bindto: '#chart',\n        data: {\n          columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n          ]\n        },\n        axis: {\n          rotated: axis_rotated,\n          x: {\n            type: axis_x_type\n          }\n        },\n        grid: {\n          x: {\n//            lines: [{value: 3, text:'Label 3'}, {value: 4.5, text: 'Label 4.5'}]\n          }\n        }\n      }); }, chart = generate();\n\n      var queue = [\n      function () {\n        chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);\n      },\n      function () {\n        chart.xgrids([{value: 2, text:'Label 2'}]);\n      },\n      function () {\n        chart.xgrids.add([{value: 3, text:'Label 3', class:'hoge'}]);\n      },\n      function () {\n        chart.xgrids.remove({value:2});\n      },\n      function () {\n        chart.xgrids.remove({class:'hoge'});\n      },\n      function () {\n        chart.xgrids.remove([{value: 1}, {value: 4}]);\n      },\n      function () {\n        chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);\n      },\n      function () {\n        chart.xgrids.remove();\n      },\n      function () {\n        axis_rotated = true;\n        chart = generate();\n      },\n      function () {\n        chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);\n      },\n      function () {\n        chart.xgrids([{value: 2, text:'Label 2'}]);\n      },\n      function () {\n        chart.xgrids.add([{value: 3, text:'Label 3', class:'hoge'}]);\n      },\n      function () {\n        chart.xgrids.remove({value:2});\n      },\n      function () {\n        chart.xgrids.remove({class:'hoge'});\n      },\n      function () {\n        chart.xgrids.remove([{value: 1}, {value: 4}]);\n      },\n      function () {\n        chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);\n      },\n      function () {\n        chart.xgrids.remove();\n      },\n      function () {\n        axis_rotated = false;\n        axis_x_type = 'category';\n        chart = generate();\n      },\n      function () {\n        chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);\n      },\n      function () {\n        chart.xgrids([{value: 2, text:'Label 2'}]);\n      },\n      function () {\n        chart.xgrids.add([{value: 3, text:'Label 3', class:'hoge'}]);\n      },\n      function () {\n        chart.xgrids.remove({value:2});\n      },\n      function () {\n        chart.xgrids.remove({class:'hoge'});\n      },\n      function () {\n        chart.xgrids.remove([{value: 1}, {value: 4}]);\n      },\n      function () {\n        chart.xgrids([{value: 1, text:'Label 1'}, {value: 4, text: 'Label 4'}]);\n      },\n      function () {\n        chart.xgrids.remove();\n      },\n      ];\n\n      var i = 0;\n      queue.forEach(function (f) {\n        setTimeout(f, 1000 * i++);\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/api_ygrid_lines.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n          ]\n        },\n        axis: {\n//          rotated: true,\n        },\n        grid: {\n          y: {\n            lines: [{value: 30, text:'Label 30'}, {value: 250, text: 'Label 250'}]\n          }\n        }\n      });\n\n      setTimeout(function () {\n        chart.ygrids([{value: 130, text:'Label 130'}, {value: 50, text: 'Label 50'}]);\n      }, 1000);\n\n      setTimeout(function () {\n        chart.ygrids([{value: 130, text:'Label 130', class: 'hoge'}]);\n      }, 2000);\n\n      setTimeout(function () {\n        chart.ygrids.add([{value: 230, text:'Label 230', class: 'hoge'}]);\n      }, 3000);\n\n      setTimeout(function () {\n        chart.ygrids.remove({value: 230});\n      }, 4000);\n\n      setTimeout(function () {\n        chart.ygrids.remove({class: 'hoge'});\n      }, 5000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/api_zoom.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          columns: [\n            generateData(100)\n          ],\n        },\n        zoom: {\n          enabled: true,\n          initialRange: [30, 60],\n          onzoomstart: function (event) {\n            console.log(\"onzoomstart\", event);\n          },\n          onzoom: function (domain) {\n            console.log(\"onzoom\", domain);\n          },\n          onzoomend: function (domain) {\n            console.log(\"onzoomend\", domain);\n          },\n        },\n        subchart: { show: true }\n      });\n\n      function generateData(n) {\n        var column = ['sample'];\n        for (var i = 0; i < n; i++) {\n          column.push(Math.random() * 500);\n        }\n        return column;\n      }\n\n     // with subchart\n     setTimeout(function () {\n         chart.zoom([45,75]);\n     }, 1000);\n\n     setTimeout(function () {\n         chart.zoom([25,90]);\n     }, 2000);\n\n     setTimeout(function () {\n         chart.unzoom();\n     }, 3000);\n\n     // without subchart\n     setTimeout(function () {\n         chart.internal.config.subchart_show = false;\n         chart.flush();\n     }, 4000);\n\n     setTimeout(function () {\n         chart.zoom([45,75]);\n     }, 5000);\n\n     setTimeout(function () {\n         chart.zoom([25,90]);\n     }, 6000);\n\n     setTimeout(function () {\n         chart.unzoom();\n     }, 7000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/area_zerobased.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 1030, 1200, 1100, 1400, 1150, 1250],\n            ['data2', 2130, 2100, 2140, 2200, 2150, 1850]\n          ],\n          type: 'area',\n        },\n        area: {\n          zerobased: false\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/axes_log_scales.html",
    "content": "<html>\n<head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n</head>\n<body>\n\n<div id=\"chart1\"></div>\n\n<script src=\"http://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n<script src=\"../js/c3.js\"></script>\n<script>\n    var chart = c3.generate({\n        bindto: '#chart1',\n        data: {\n            type: 'bar',\n            columns: [\n                ['linear', 318, 37, 0, 4, 0, 1],\n                ['log', 318, 37, 0, 4, 0, 1]\n            ],\n            axes: {\n                log: 'y2'\n            },\n            labels: true\n        },\n        axis: {\n            y2: {\n                show: true,\n                tick: {\n                  format: function(v) {\n                      return Math.ceil(v);\n                  }\n                },\n                type: 'log'\n            }\n        },\n    });\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/axes_padding.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 300, 2000, 1000, 4000, 1500, 2500],\n          ],\n          axes: {\n            data2: 'y2'\n          }\n        },\n        axis: {\n          y: {\n            padding: {\n              top: 0.1,\n              bottom: 0.1,\n              unit: 'ratio'\n            }\n          },\n          y2: {\n            show: true,\n            padding: {\n              top: 200,\n              bottom: 200,\n            }\n          }\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['data1', 3000, 20000, 10000, 40000, 15000, 25000],\n          ],\n        },\n        axis: {\n          y: {\n            padding: {\n              top: 0.1,\n              bottom: 0.1,\n              unit: 'ratio'\n            }\n          }\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/axes_range.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['sample', 100, 200, 100, 400, 150, 250]\n          ],\n        },\n        axis: {\n          x: {\n              min: -10,\n              max: 10,\n            }\n          },\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          x: 'x',\n          columns: [\n            ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],\n            ['sample', 100, 200, 100, 400, 150, 250]\n          ],\n        },\n        axis: {\n          x: {\n              type: 'timeseries',\n              min: new Date('2012-12-20'),\n              max: '2013-03-01',\n              tick : {\n                format : \"%Y-%m-%d %H:%M:%S\" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format\n              }\n            }\n          }\n      });\n\n      setTimeout(function () {\n        chart1.axis.max({x: 20});\n      }, 1000);\n\n      setTimeout(function () {\n        chart1.axis.min({x: -5});\n      }, 2000);\n\n      setTimeout(function () {\n        chart1.axis.range({max: {x: 5}, min: {x: 0}});\n      }, 3000);\n\n      setTimeout(function () {\n        chart2.axis.max({x: new Date('2013-02-01')});\n      }, 1000);\n\n      setTimeout(function () {\n        chart2.axis.min({x: new Date('2012-12-01')});\n      }, 2000);\n\n      setTimeout(function () {\n      chart2.axis.range({max: {x: '2013-01-06'}, min: {x: '2013-01-01'}});\n      }, 3000);\n\n      setTimeout(function () {\n        chart2.axis.max({y: 1000});\n      }, 4000);\n\n      setTimeout(function () {\n        chart2.axis.min({y: -1000});\n      }, 5000);\n\n      setTimeout(function () {\n        chart2.axis.range({max: {y: 400}, min: {y: 0}});\n      }, 6000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/axes_x_localtime.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var data, axis_x_localtime;\n\n      var data1 = {\n          x : 'date',\n          columns: [\n            ['date', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05'],\n            ['sample', 30, 200, 100, 400, 150],\n            ['sample2', 130, 300, 200, 450, 250]\n          ]\n      };\n\n      var data2 = {\n          x : 'date',\n          columns: [\n            ['date', 1356966000000, 1357052400000, 1357138800000, 1357225200000, 1357311600000],\n            ['sample', 30, 200, 100, 400, 150],\n            ['sample2', 130, 300, 200, 450, 250]\n          ]\n      };\n\n      var data3 = {\n          x : 'date',\n          columns: [\n            ['date', new Date(1356966000000), new Date(1357052400000), new Date(1357138800000), new Date(1357225200000), new Date(1357311600000)],\n            ['sample', 30, 200, 100, 400, 150],\n            ['sample2', 130, 300, 200, 450, 250]\n          ]\n      };\n\n      var data4 = {\n          x : 'date',\n          xFormat : '%Y%m%d',\n          columns: [\n            ['date', '20130101', '20130102', '20130103', '20130104', '20130105'],\n            ['sample', 1030, 1200, 1100, 1400, 1150],\n            ['sample2', 130, 300, 200, 450, 250]\n          ]\n      };\n\n      var data5 = {\n          x : 'date',\n          xFormat : '%Y%m%d %H:%M:%S',\n          columns: [\n            ['date', '20130101 00:00:00', '20130102 00:00:00', '20130103 00:00:00', '20130104 00:00:00', '20130105 00:00:00'],\n            ['sample', 30, 200, 100, 400, 150],\n            ['sample2', 1130, 1300, 1200, 1450, 1250]\n          ]\n      };\n\n      var generate = function () { return c3.generate({\n        bindto: '#chart',\n        data: data,\n        axis : {\n          x : {\n            type : 'timeseries',\n            tick : {\n              format : \"%Y-%m-%d %H:%M:%S\" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format\n            },\n            localtime: axis_x_localtime\n          }\n        }\n      }); };\n\n      setTimeout(function () {\n        data = data1;\n        axis_x_localtime = true;\n        chart = generate();\n      }, 1000);\n\n      setTimeout(function () {\n        data = data1;\n        axis_x_localtime = false;\n        chart = generate();\n      }, 2000);\n\n      setTimeout(function () {\n        data = data2;\n        axis_x_localtime = true;\n        chart = generate();\n      }, 3000);\n\n      setTimeout(function () {\n        data = data2;\n        axis_x_localtime = false;\n        chart = generate();\n      }, 4000);\n\n      setTimeout(function () {\n        data = data3;\n        axis_x_localtime = true;\n        chart = generate();\n      }, 5000);\n\n      setTimeout(function () {\n        data = data3;\n        axis_x_localtime = false;\n        chart = generate();\n      }, 6000);\n\n      setTimeout(function () {\n        data = data4;\n        axis_x_localtime = true;\n        chart = generate();\n      }, 7000);\n\n      setTimeout(function () {\n        data = data4;\n        axis_x_localtime = false;\n        chart = generate();\n      }, 8000);\n\n      setTimeout(function () {\n        data = data5;\n        axis_x_localtime = true;\n        chart = generate();\n      }, 9000);\n\n      setTimeout(function () {\n        data = data5;\n        axis_x_localtime = false;\n        chart = generate();\n      }, 10000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/axes_x_range_timeseries.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n    var chart1 = c3.generate({\n      \"bindto\": \"#chart1\",\n      \"axis\": {\n          \"x\": {\n            \"type\": \"timeseries\",\n            \"min\": 1401879600000,\n            \"max\": 1401969600000,\n          }\n      },\n      \"data\": {\n        \"type\": \"line\",\n        \"columns\": [\n            [\"epoch\", 1401879600000, 1401883200000, 1401886800000],\n            [\"y\", 1955, 2419, 2262]\n        ],\n        \"xs\": {\n            \"y\": \"epoch\"\n        }\n      }\n    });\n\n    var chart2 = c3.generate({\n      \"bindto\": \"#chart2\",\n      \"axis\": {\n          \"x\": {\n            \"type\": \"timeseries\",\n            \"min\": new Date(1401879600000),\n            \"max\": new Date(1401969600000),\n          }\n      },\n      \"data\": {\n        \"type\": \"line\",\n        \"columns\": [\n            [\"epoch\", 1401879600000, 1401883200000, 1401886800000],\n            [\"y\", 1955, 2419, 2262]\n        ],\n        \"xs\": {\n            \"y\": \"epoch\"\n        }\n      }\n    });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/axes_x_selection.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 100, 200, 50, 300, 400, 290],\n            ['data2', 10, 20, 50, 30, 10, 100],\n          ],\n        },\n        axis: {\n          x: {\n            selection: [2, 4.5]\n          }\n        },\n        subchart: {\n          show: true\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          x: 'x',\n          columns: [\n            ['x', '2014-01-01', '2014-02-01', '2014-03-01', '2014-04-01', '2014-05-01', '2014-06-01'],\n            ['data1', 100, 200, 50, 300, 400, 290],\n            ['data2', 10, 20, 50, 30, 10, 100],\n          ],\n        },\n        axis: {\n          x: {\n            type: 'timeseries',\n            selection: ['2014-03-01', '2014-04-20']\n          }\n        },\n        subchart: {\n          show: true\n        }\n      });\n\n      var chart3 = c3.generate({\n        bindto: '#chart3',\n        data: {\n          columns: [\n            ['data1', 100, 200, 50, 300, 400, 290],\n            ['data2', 10, 20, 50, 30, 10, 100],\n          ],\n        },\n        axis: {\n          x: {\n            selection: [1, 4.2]\n          }\n        },\n        zoom: {\n          enabled: true\n        },\n        subchart: {\n          show: true\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/axes_x_tick_culling.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ]\n        },\n        axis: {\n          x: {\n            tick: {\n              culling: {\n                max: 2\n              }\n            }\n          }\n        },\n        tooltip: {\n//          enabled: false\n        },\n        zoom: {\n//          enabled: true\n        },\n        subchart: {\n//          show: true\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/axes_x_tick_fit.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          x: 'x',\n          columns: [\n            ['x', '2013-10-31', '2013-11-30', '2013-12-31', '2014-01-31', '2014-02-28'],\n//            ['x', 30, 70, 150, 200, 350],\n            ['sample', 30, 200, 100, 400, 150],\n            ['sample2', 130, 300, 200, 500, 250]\n          ]\n        },\n        axis : {\n          x : {\n            type : 'timeseries',\n            tick: {\n              fit: true\n            }\n          }\n        },\n        subchart: {\n//          show: true\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/axes_x_tick_rotate.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250, 100, 600],\n            ['data2', 50, 20, 10, 40, 15, 25],\n          ]\n        },\n        axis: {\n//          rotated: true,\n          x: {\n            tick: {\n              format: function () { return \"hogehogehogehogehoge\"; },\n              rotate: -30,\n            },\n            label: {\n              text: 'Hogehoge',\n              position: 'outer-center'\n            },\n          },\n          y: {\n            label: {\n              text: 'Y Label',\n              position: 'outer-middle'\n            }\n          }\n        },\n        subchart: {\n          show: true\n        }\n      });\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n//            ['data1', 30, 200, 100, 400, 150, 250, 100, 400],\n            ['data1', 1030, 2000, 1000, 1400, 1500, 1250, 1100, 140000],\n          ]\n        })\n      }, 1000);\n\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/axes_x_tick_values.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n        },\n        axis: {\n          x : {\n            tick: {\n              values: [2, 4]\n            }\n          }\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          x : 'date',\n          xFormat : '%Y%m%d',\n          columns: [\n            ['date', '20130101', '20130102', '20130103', '20130104', '20130105', '20130106'],\n            ['sample', 30, 200, 100, 400, 150, 250],\n            ['sample2', 130, 300, 200, 450, 250, 350]\n          ]\n        },\n        axis : {\n          x : {\n            type : 'timeseries',\n            tick : {\n              format : \"%e %b %y\", // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format\n              values: ['20130103', '20130104']\n            }\n          }\n        }\n      });\n\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/axes_y2.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          axes: {\n            data1: 'y',\n            data2: 'y2'\n          }\n        },\n        axis: {\n          y2: {\n            show: true\n          }\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/axes_y_default.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1'],\n            ['data2'],\n          ],\n        },\n        axis: {\n          y: {\n            default: [-100, 100]\n          }\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/bar_zerobased.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 1030, 1200, 1100, 1400, 1150, 1250],\n            ['data2', 2130, 2100, 2140, 2200, 2150, 1850]\n          ],\n          type: 'bar',\n        },\n        bar: {\n          zerobased: false\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/bindto.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart1\" style=\"height:300px;\"></div>\n    <div class=\"chart2\" style=\"height:150px;\"></div>\n    <div class=\"chart3\" style=\"height:150px;\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 130, 210, 120, 440, 250, 350]\n          ]\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '.chart2',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250]\n          ]\n        }\n      });\n\n      var chart3 = c3.generate({\n        bindto: document.getElementsByClassName('chart3')[0],\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250]\n          ]\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/categorized.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          x: 'x',\n          columns: [\n            ['x', '1e-3', '1e-2', '1', 'kjlsdjfl lksl lk jlsjflk lskj lskdfjlk lksdfjlskdj lks'],\n            ['data1', 30, 200, 100, 400, 150, 250, 50, 100, 250]\n          ]\n        },\n        axis: {\n          x: {\n            type: 'categorized'\n          }\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250, 50, 100, 250]\n          ]\n        },\n        axis: {\n          x: {\n            categories: ['1e-3', '1e-2', '1e-1', '0', 'hoge'],\n            type: 'categorized'\n          }\n        }\n      });\n\n      setTimeout(function () {\n        chart1.load({columns:[['data2', 30, 20, 50, 40, 60, 50, 100, 200, 300,100]]});\n      }, 1000);\n\n      setTimeout(function () {\n        chart2.load({columns:[['data2', 30, 20, 50, 40, 60, 50, 100, 200, 300,100]]});\n      }, 2000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_arc.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart1 = c3.generate({\n          bindto: '#chart1',\n          data: {\n              columns: [\n                  ['data', 80.0]\n              ],\n              type: 'gauge',\n          },\n          gauge: {\n              label: {\n                  show: false\n              },\n              fullCircle: true,\n              min: 0,\n              max: 100\n          }\n      });\n      var chart2 = c3.generate({\n          bindto: '#chart2',\n          data: {\n              columns: [\n                  ['data', 50.0],\n              ],\n              type: 'gauge',\n          },\n          gauge: {\n              label: {\n                  show: false\n              },\n              fullCircle: true,\n              min: -100,\n              max: 100\n          }\n      });\n      var chart3 = c3.generate({\n          bindto: '#chart3',\n          data: {\n              columns: [\n                  ['data', -50.0],\n                  ['data2', 0.0],\n                  ['data3', 50.0],\n              ],\n              type: 'gauge',\n          },\n          gauge: {\n              label: {\n                  show: false\n              },\n              fullCircle: true,\n              min: -100,\n              max: 100\n          }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_area.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <h3>Zerobased</h3>\n    <div id=\"chart1\"></div>\n    <h3>Not zerobased because of axis.y.min</h3>\n    <div id=\"chart2\"></div>\n    <h3>Zerobased</h3>\n    <div id=\"chart3\"></div>\n    <h3>Not zerobased because of axis.y.min</h3>\n    <div id=\"chart4\"></div>\n    <h3>+/- vaulues</h3>\n    <div id=\"chart5\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 300, 350, 300, 0, 0, 0],\n            ['data2', 130, 100, 140, 200, 150, 50]\n          ],\n          type: 'area'\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['data1', 300, 350, 300, 0, 0, 0],\n            ['data2', 130, 100, 140, 200, 150, 50]\n          ],\n          type: 'area'\n        },\n        axis: {\n          y: {\n            min: 100,\n          }\n        },\n      });\n\n      var chart3 = c3.generate({\n        bindto: '#chart3',\n        data: {\n          columns: [\n            ['data1', -300, -350, -300, 0, 0, 0],\n            ['data2', -130, -100, -140, -200, -150, -50]\n          ],\n          type: 'area'\n        }\n      });\n\n      var chart4 = c3.generate({\n        bindto: '#chart4',\n        data: {\n          columns: [\n            ['data1', -300, -350, -300, 0, 0, 0],\n            ['data2', -130, -100, -140, -200, -150, -50]\n          ],\n          type: 'area'\n        },\n        axis: {\n          y: {\n            max: -100,\n          }\n        }\n      });\n\n      var chart5 = c3.generate({\n        bindto: '#chart5',\n        data: {\n          columns: [\n            ['data1', -300, 350, -300, 0, 0, 0],\n            ['data2', -130, -100, 140, -200, 150, -50]\n          ],\n          type: 'area'\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_area_spline.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 300, 350, 300, 0, 0, 0],\n            ['data2', 130, 100, 140, 200, 150, 50]\n          ],\n          type: 'area-spline'\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['data1', -300, -350, -300, 0, 0, 0],\n            ['data2', -130, -100, -140, -200, -150, -50]\n          ],\n          type: 'area-spline'\n        }\n      });\n\n      var chart3 = c3.generate({\n        bindto: '#chart3',\n        data: {\n          columns: [\n            ['data1', -300, 350, -300, 0, 0, 0],\n            ['data2', -130, -100, 140, -200, 150, -50]\n          ],\n          type: 'area-spline'\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_area_spline_stacked.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 300, 350, 300, 0, 0, 100],\n            ['data2', 130, 0, 140, 200, 0, 50],\n          ],\n          type: 'area-spline',\n          groups: [['data1', 'data2']],\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['data1', -300, -350, -300, 0, 0, -100],\n            ['data2', -130, 0, -140, -200, 0, -50]\n          ],\n          type: 'area-spline',\n          groups: [['data1', 'data2']],\n        }\n      });\n\n      var chart3 = c3.generate({\n        bindto: '#chart3',\n        data: {\n          columns: [\n            ['data1', -300, 350, -300, 0, 0, 100],\n            ['data2', -130, 0, 140, -200, 150, -50]\n          ],\n          type: 'area-spline',\n          groups: [['data1', 'data2']],\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_area_stacked.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 300, 350, 300, 0, 0, 100],\n            ['data2', 130, 0, 140, 200, 0, 50],\n          ],\n          type: 'area',\n          groups: [['data1', 'data2']],\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['data1', -300, -350, -300, 0, 0, -100],\n            ['data2', -130, 0, -140, -200, 0, -50]\n          ],\n          type: 'area',\n          groups: [['data1', 'data2']],\n        }\n      });\n\n      var chart3 = c3.generate({\n        bindto: '#chart3',\n        data: {\n          columns: [\n            ['data1', -300, 350, -300, 0, 0, 100],\n            ['data2', -130, 0, 140, -200, 150, -50]\n          ],\n          type: 'area',\n          groups: [['data1', 'data2']],\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_area_step.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 300, 350, 300, 0, 0, 0],\n            ['data2', 130, 100, 140, 200, 150, 50]\n          ],\n          type: 'area-step'\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['data1', -300, -350, -300, 0, 0, 0],\n            ['data2', -130, -100, -140, -200, -150, -50]\n          ],\n          type: 'area-step'\n        }\n      });\n\n      var chart3 = c3.generate({\n        bindto: '#chart3',\n        data: {\n          columns: [\n            ['data1', -300, 350, -300, 0, 0, 0],\n            ['data2', -130, -100, 140, -200, 150, -50]\n          ],\n          type: 'area-step'\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_area_step_stacked.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 300, 350, 300, 0, 0, 0],\n            ['data2', 130, 100, 140, 200, 150, 50]\n          ],\n          type: 'area-step',\n          groups: [['data1', 'data2']],\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['data1', -300, -350, -300, 0, 0, 0],\n            ['data2', -130, -100, -140, -200, -150, -50]\n          ],\n          type: 'area-step',\n          groups: [['data1', 'data2']],\n        }\n      });\n\n      var chart3 = c3.generate({\n        bindto: '#chart3',\n        data: {\n          columns: [\n            ['data1', -300, 350, -300, 0, 0, 0],\n            ['data2', -130, -100, 140, -200, 150, -50]\n          ],\n          type: 'area-step',\n          groups: [['data1', 'data2']],\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_bar.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 1030, 1200, 1100, 1400, 1150, 1250],\n            ['data2', 2130, 2100, 2140, 2200, 2150, 1850]\n//           ['data1', 30, 200, 100, 400, 150, 250],\n//           ['data2', 130, 100, 140, 200, 150, 50]\n          ],\n          type: 'bar',\n          onclick: function (d, element) { console.log(\"onclick\", d, element); },\n          onmouseover: function (d) { console.log(\"onmouseover\", d); },\n          onmouseout: function (d) { console.log(\"onmouseout\", d); }\n        },\n        axis: {\n          x: {\n            type: 'categorized'\n          }\n        },\n        bar: {\n          width: {\n            ratio: 0.3,\n//            max: 30\n          },\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_bar_max_width.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 1030, 1200, 1100, 1400, 1150, 1250],\n            ['data2', 2130, 2100, 2140, 2200, 2150, 1850]\n          ],\n          type: 'bar',\n          onclick: function (d, element) { console.log(\"onclick\", d, element); },\n          onmouseover: function (d) { console.log(\"onmouseover\", d); },\n          onmouseout: function (d) { console.log(\"onmouseout\", d); }\n        },\n        axis: {\n          x: {\n            type: 'categorized'\n          }\n        },\n        bar: {\n          width: {\n            max: 40\n          }\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_bar_space.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var generate = function () { return c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100],\n            ['data2', 50, 20, 10],\n            ['data3', 150, 120, 110]\n          ],\n          type: 'bar'\n        },\n        bar: {\n          space: 0.25\n        }\n      }); }, chart = generate();\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_bar_stacked.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var axis_x_type = 'category',\n          axis_rotated = false;\n\n      var generate = function () { return c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 200, 400, 150, -250],\n            ['data2', 130, -100, 100, 200, 150, 50],\n            ['data3', 230, -200, 200, 0, 250, 250]\n          ],\n          type: 'bar',\n          groups: [\n            ['data1', 'data2']\n          ]\n        },\n        axis: {\n          x: {\n            type: axis_x_type\n          },\n          rotated: axis_rotated\n        },\n        grid: {\n          y: {\n            lines: [{value:0}]\n          }\n        },\n      }); }, chart = generate();\n\n      function update1() {\n        chart.groups([['data1', 'data2', 'data3']])\n      }\n\n      function update2() {\n        chart.load({\n          columns: [['data4', 100, 50, 150, -200, 300, -100]]\n        });\n      }\n\n      function update3() {\n        chart.groups([['data1', 'data2', 'data3', 'data4']])\n      }\n\n\n      setTimeout(update1, 1000);\n      setTimeout(update2, 2000);\n      setTimeout(update3, 3000);\n\n\n      setTimeout(function () {\n        axis_rotated = true;\n        chart = generate();\n      }, 4000);\n      setTimeout(update1, 5000);\n      setTimeout(update2, 6000);\n      setTimeout(update3, 7000);\n\n\n      setTimeout(function () {\n        axis_x_type = '';\n        axis_rotated = false;\n        chart = generate();\n      }, 8000);\n      setTimeout(update1, 9000);\n      setTimeout(update2, 10000);\n      setTimeout(update3, 11000);\n\n\n      setTimeout(function () {\n        axis_x_type = '';\n        axis_rotated = true;\n        chart = generate();\n      }, 12000);\n      setTimeout(update1, 13000);\n      setTimeout(update2, 14000);\n      setTimeout(update3, 15000);\n\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_bar_stacked_normalized.html",
    "content": "<html>\n<head>\n  <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n</head>\n<body>\n<div id=\"chart\"></div>\n\n<script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n<script src=\"../js/c3.js\"></script>\n<script>\n\n  var axis_x_type = 'category',\n    axis_rotated = false;\n\n  var generate = function () { return c3.generate({\n    data: {\n      columns: [\n        ['data1', 30, 200, 200, 400, 150, 250],\n        ['data2', 130, 100, 100, 200, 150, 50],\n        ['data3', 230, 200, 200, 0, 250, 250]\n      ],\n      type: 'bar',\n      groups: [\n        ['data1', 'data2', 'data3']\n      ],\n      stack: {\n        normalize: false\n      }\n    },\n    axis: {\n      x: {\n        type: axis_x_type\n      },\n      rotated: axis_rotated\n    },\n    grid: {\n      y: {\n        lines: [{value:0}]\n      }\n    },\n  }); }, chart = generate();\n\n  function update1() {\n    chart.data.stackNormalized(true);\n  }\n\n  function update2() {\n    chart.load({\n      columns: [['data4', 100, 50, 150, 200, 300, 100]]\n    });\n  }\n\n  function update3() {\n    chart.groups([['data1', 'data2', 'data3', 'data4']])\n  }\n\n  function update4() {\n    chart.hide(['data2', 'data3'])\n  }\n\n  let delay = 1000;\n\n  function enqueue(fct) {\n    setTimeout(fct, delay);\n    delay += 1000;\n  }\n\n  enqueue(update1);\n  enqueue(update2);\n  enqueue(update3);\n  enqueue(update4);\n\n  enqueue(function () {\n    axis_rotated = true;\n    chart = generate();\n  });\n  enqueue(update1);\n  enqueue(update2);\n  enqueue(update3);\n  enqueue(update4);\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_combination.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n            ['data2', 200, 130, 90, 240, 130, 220],\n            ['data3', 300, 200, 160, 400, 250, 250],\n            ['data4', 200, 130, 90, 240, 130, 220],\n            ['data5', 130, 120, 150, 140, 160, 150],\n            ['data6', 90, 70, 20, 50, 60, 120],\n          ],\n          types: {\n            data1: 'bar',\n            data2: 'bar',\n            data3: 'spline',\n            data4: 'line',\n            data5: 'bar',\n            data6: 'area'\n          },\n          groups: [\n            ['data1','data2']\n          ]\n        },\n        axis: {\n          x: {\n            type: 'categorized'\n          }\n        }\n    });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_combination_normalized.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      const colorScale = d3.scaleLinear()\n        .domain([1, 5])\n        .range(['#a6d96a', '#1a9850'])\n        .interpolate(d3.interpolateHcl);\n\n      const columns = [\n        ['data1', 300, 200, 500, 400, 600, 500],\n        ['data2', 200, 130, 90, 240, 130, 220],\n        ['data3', 300, 200, 160, 400, 250, 250],\n        ['data4', 200, 130, 90, 240, 130, 220],\n        ['data5', 130, 120, 150, 140, 160, 150],\n        ['data6', 2500, 7500, 2450, 5670, 4580, 6500],\n      ];\n\n      var chart = c3.generate({\n        data: {\n          columns: columns,\n          type: 'bar',\n          types: {\n            data6: 'line'\n          },\n          axes: {\n            data6: 'y2'\n          },\n          stack: {\n            normalize: true\n          },\n          groups: [\n            ['data1','data2','data3','data4', 'data5']\n          ],\n          colors: {\n            data1: colorScale(0),\n            data2: colorScale(1),\n            data3: colorScale(2),\n            data4: colorScale(3),\n            data5: colorScale(4),\n            data6: '#FF0000'\n          }\n        },\n        bar: {\n          space: 0,\n          width: {\n            ratio: 1\n          }\n        },\n        axis: {\n          x: {\n            type: 'categorized'\n          },\n          y2: {\n            show: true\n          }\n        }\n    });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_donut.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n//            [\"setosa\", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],\n            [\"versicolor\", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],\n            [\"virginica\", 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8],\n            [\"setosa\", 30],\n//            [\"versicolor\", 40],\n//            [\"virginica\", 50],\n          ],\n          type : 'donut',\n          onmouseover: function (d, i) { console.log(\"onmouseover\", d, i, this); },\n          onmouseout: function (d, i) { console.log(\"onmouseout\", d, i, this); },\n          onclick: function (d, i) { console.log(\"onclick\", d, i, this); },\n          order: null // set null to disable sort of data. desc is the default.\n        },\n        axis: {\n          x: {\n            label: 'Sepal.Width'\n          },\n          y: {\n            label: 'Petal.Width'\n          }\n        },\n        donut: {\n          label: {\n//            format: function (d, ratio) { return \"\"; }\n          },\n          title: \"Iris Petal Width\",\n          width: 70,\n          padAngle: .1\n        }\n      });\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n          ]\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.unload({\n          ids: 'virginica'\n        });\n      }, 2000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_gauge.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            [ 'data', 91.4 ]\n          ],\n          type: 'gauge',\n          onmouseover: function (d, i) { console.log(\"onmouseover\", d, i, this); },\n          onmouseout: function (d, i) { console.log(\"onmouseout\", d, i, this); },\n          onclick: function (d, i) { console.log(\"onclick\", d, i, this); },\n        },\n        gauge: {\n          label: {\n//            format: function(value, ratio) {\n//              return value;\n//            },\n//            extents: function (value, isMax) {\n//                return value + '%';\n//            },\n//          show: false // to turn off the min/max labels.\n          },\n//          min: 0, // 0 is default, //can handle negative min e.g. vacuum / voltage / current flow / rate of change\n//          max: 100, // 100 is default\n//          units: ' %',\n//          width: 39 // for adjusting arc thickness\n        },\n        color: {\n          pattern: ['#FF0000', '#F6C600', '#60B044'], // the three color levels for the percentage values.\n          threshold: {\n//            unit: 'value', // percentage is default\n//            max: 200, // 100 is default\n            values: [30, 60, 90] // alternate first value is 'value'\n          }\n        }\n      });\n\n      var chart1 = c3.generate({\n          bindto: '#chart1',\n          data: {\n              columns: [\n                  ['data', 75.0]\n              ],\n              type: 'gauge',\n          },\n          gauge: {\n              min: 50,\n              max: 100\n          }\n      });\n\n      var chart2 = c3.generate({\n          bindto: '#chart2',\n          data: {\n              columns: [\n                  ['data', 0.0]\n              ],\n              type: 'gauge',\n          },\n          gauge: {\n              min: -100,\n              max: 100\n          }\n      });\n\n      var chart3 = c3.generate({\n          bindto: '#chart3',\n          data: {\n              columns: [\n                  ['data', -75.0]\n              ],\n              type: 'gauge',\n          },\n          gauge: {\n              min: -100,\n              max: -50\n          }\n      });\n\n      var cycleDemo = function () {\n\n        setTimeout(function () {\n          d3.select('#chart .c3-chart-arcs-background')\n            .transition()\n            .style('fill', '#333');\n        }, 1000);\n\n        setTimeout(function () {\n            chart.load({\n              columns: [[ 'data', 10 ]]\n            });\n        }, 2000);\n\n        setTimeout(function () {\n            chart.load({\n              columns: [[ 'data', 50 ]]\n            });\n        }, 3000);\n\n        setTimeout(function () {\n            chart.load({\n              columns: [[ 'data', 91.4 ]]\n            });\n        }, 4000);\n\n        setTimeout(function () {\n          d3.select('#chart .c3-chart-arcs-background')\n            .transition()\n            .style('fill', '#e0e0e0');\n        }, 5000);\n\n        setTimeout(function () {\n            chart.load({\n              columns: [[ 'data', 0 ]]\n            });\n        }, 6000);\n\n        setTimeout(function () {\n            chart.load({\n              columns: [[ 'data', 50 ]]\n            });\n        }, 7000);\n\n        setTimeout(function () {\n            chart.load({\n              columns: [[ 'data', 91.4 ]]\n            });\n        }, 8000);\n\n        setTimeout(function () {\n            chart.load({\n              columns: [[ 'data', 0 ]]\n            });\n        }, 9000);\n\n        setTimeout(function () {\n            chart.load({\n              columns: [[ 'data', 50 ]]\n            });\n        }, 10000);\n\n        setTimeout(function () {\n            chart.load({\n              columns: [[ 'data', 91.4 ]]\n            });\n        }, 11000);\n\n        setTimeout(function () {\n            chart.load({\n              columns: [[ 'data', 0 ]]\n            });\n        }, 12000);\n\n        setTimeout(function () {\n            chart.load({\n              columns: [[ 'data', 50 ]]\n            });\n        }, 13000);\n\n        setTimeout(function () {\n            chart.load({\n              columns: [[ 'data', 91.4 ]]\n            });\n        }, 14000);\n\n      }\n\n      cycleDemo();\n\n//      setInterval(cycleDemo, 30000);\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_multi_arc_gauge.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['padded1', 100],\n            ['padded2', 90],\n            ['padded3', 50],\n            ['padded4', 20]\n          ],\n          type: 'gauge',\n        },\n        color: {\n          pattern: ['#FF0000', '#F97600', '#F6C600', '#60B044'],\n          threshold: {\n            values: [30, 80, 95]\n          }\n        },\n        size: {\n          height: 320,\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_pie.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n//            [\"setosa\", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],\n            [\"versicolor\", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],\n            [\"virginica\", 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8],\n            [\"setosa\", 30],\n//            [\"versicolor\", 40],\n//            [\"virginica\", 50],\n          ],\n          type : 'pie',\n          onmouseover: function (d, i) { console.log(\"onmouseover\", d, i, this); },\n          onmouseout: function (d, i) { console.log(\"onmouseout\", d, i, this); },\n          onclick: function (d, i) { console.log(\"onclick\", d, i, this); },\n        },\n        axis: {\n          x: {\n            label: 'Sepal.Width'\n          },\n          y: {\n            label: 'Petal.Width'\n          }\n        }\n      });\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            [\"setosa\", 130],\n          ]\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.unload({\n          ids: 'virginica'\n        });\n      }, 2000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_pie_sort.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var sort = true;\n\n      var generate = function () { return c3.generate({\n        data: {\n          columns: [\n//            [\"setosa\", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],\n            [\"versicolor\", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],\n            [\"virginica\", 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8],\n            [\"setosa\", 30],\n//            [\"versicolor\", 40],\n//            [\"virginica\", 50],\n          ],\n          type : 'pie',\n        },\n        axis: {\n          x: {\n            label: 'Sepal.Width'\n          },\n          y: {\n            label: 'Petal.Width'\n          }\n        },\n        pie: {\n          sort: sort,\n          onmouseover: function (d, i) { console.log(d, i); },\n          onmouseout: function (d, i) { console.log(d, i); },\n          onclick: function (d, i) { console.log(d, i); },\n        }\n      }); }, chart = generate();\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            [\"setosa\", 130],\n          ]\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.unload({\n          ids: 'virginica'\n        });\n      }, 2000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            [\"new data\", 300],\n          ]\n        });\n      }, 3000);\n\n      setTimeout(function () {\n        sort = false;\n        chart = generate();\n      }, 4000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            [\"setosa\", 130],\n          ]\n        });\n      }, 5000);\n\n      setTimeout(function () {\n        chart.unload({\n          ids: 'virginica'\n        });\n      }, 6000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            [\"new data\", 300],\n          ]\n        });\n      }, 7000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_scatter.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          xs: {\n            setosa: 'setosa_x',\n            versicolor: 'versicolor_x',\n            virginica: 'virginica_x'\n          },\n          columns: [\n            [\"setosa_x\", 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.4, 3.0, 3.0, 4.0, 4.4, 3.9, 3.5, 3.8, 3.8, 3.4, 3.7, 3.6, 3.3, 3.4, 3.0, 3.4, 3.5, 3.4, 3.2, 3.1, 3.4, 4.1, 4.2, 3.1, 3.2, 3.5, 3.6, 3.0, 3.4, 3.5, 2.3, 3.2, 3.5, 3.8, 3.0, 3.8, 3.2, 3.7, 3.3],\n            [\"versicolor_x\", 3.2, 3.2, 3.1, 2.3, 2.8, 2.8, 3.3, 2.4, 2.9, 2.7, 2.0, 3.0, 2.2, 2.9, 2.9, 3.1, 3.0, 2.7, 2.2, 2.5, 3.2, 2.8, 2.5, 2.8, 2.9, 3.0, 2.8, 3.0, 2.9, 2.6, 2.4, 2.4, 2.7, 2.7, 3.0, 3.4, 3.1, 2.3, 3.0, 2.5, 2.6, 3.0, 2.6, 2.3, 2.7, 3.0, 2.9, 2.9, 2.5, 2.8],\n            [\"virginica_x\", 3.3, 2.7, 3.0, 2.9, 3.0, 3.0, 2.5, 2.9, 2.5, 3.6, 3.2, 2.7, 3.0, 2.5, 2.8, 3.2, 3.0, 3.8, 2.6, 2.2, 3.2, 2.8, 2.8, 2.7, 3.3, 3.2, 2.8, 3.0, 2.8, 3.0, 2.8, 3.8, 2.8, 2.8, 2.6, 3.0, 3.4, 3.1, 3.0, 3.1, 3.1, 3.1, 2.7, 3.2, 3.3, 3.0, 2.5, 3.0, 3.4, 3.0],\n            [\"setosa\", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],\n            [\"versicolor\", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],\n            [\"virginica\", 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 1.7, 1.8, 1.8, 2.5, 2.0, 1.9, 2.1, 2.0, 2.4, 2.3, 1.8, 2.2, 2.3, 1.5, 2.3, 2.0, 2.0, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2.0, 2.2, 1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 1.9, 2.0, 2.3, 1.8],\n          ],\n          type : 'scatter',\n        },\n        axis: {\n          x: {\n            label: 'Sepal.Width',\n            tick: {\n              fit: false\n            }\n          },\n          y: {\n            label: 'Petal.Width'\n          }\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_spline.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 140, 200, 150, 50]\n          ],\n          types: {\n            data1: 'spline',\n            data2: 'spline'\n          }\n        },\n        spline: {\n          interpolation: {\n            type: 'monotone', // 'cardinal' is default\n          },\n        },\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_stanford.html",
    "content": "<html>\n<head>\n  <meta charset=\"utf-8\">\n  <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n</head>\n<body>\n<div id=\"chart\"></div>\n\n<script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n<script src=\"../js/c3.js\"></script>\n<script>\n  var chart = c3.generate({\n    size: {\n      height: 600,\n      width: 600 * 1.12\n    },\n    data: {\n      url: '/data/c3_stanford_data.json',\n      mimeType: 'json',\n      keys: {\n        x: 'HPE',\n        value: ['HPL', 'epochs']\n      },\n      type: 'stanford'\n    },\n    legend: {\n      hide: true\n    },\n    point: {\n      focus: {\n        expand: {\n          r: 5\n        }\n      },\n      r: 2.5\n    },\n    axis: {\n      x: {\n        show: true,\n        label: {\n          text: 'HPE (m)',\n          position: 'outer-center'\n        },\n        min: 0,\n        max: 61,\n        tick: {\n          values: d3.range(0, 65, 10)\n        },\n        padding: {\n          top: 0,\n          bottom: 0,\n          left: 0,\n          right: 0\n        },\n      },\n      y: {\n        show: true,\n        label: {\n          text: 'HPL (m)',\n          position: 'outer-middle'\n        },\n        min: 0,\n        max: 60,\n        tick: {\n          values: d3.range(0, 65, 10)\n        },\n        padding: {\n          top: 5,\n          bottom: 0,\n          left: 0,\n          right: 0\n        },\n      }\n    },\n    stanford: {\n      scaleMin: 1,\n      scaleMax: 10000,\n      scaleFormat: 'pow10',\n      padding: {\n        top: 15,\n        right: 0,\n        bottom: 0,\n        left: 0\n      }\n    }\n  });\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_stanford_custom_elements.html",
    "content": "<html>\n<head>\n  <meta charset=\"utf-8\">\n  <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  <style>\n    .test-polygon1 {\n      fill: white;\n    }\n\n    .test-polygon1 text {\n      fill: black;\n    }\n\n    .test-polygon2 {\n      fill: orange;\n    }\n\n    .test-polygon2 text {\n      fill: black;\n    }\n\n    .test-polygon3 {\n      fill: red;\n    }\n\n    .test-polygon3 text {\n      fill: black;\n    }\n\n    .test-polygon4 {\n      fill: gray;\n    }\n\n    .test-polygon4 text {\n      fill: black;\n    }\n\n    .test-polygon5 {\n      fill: orange;\n    }\n\n    .test-polygon5 text {\n      fill: black;\n    }\n  </style>\n</head>\n<body>\n<div id=\"chart\"></div>\n\n<script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n<script src=\"../js/c3.js\"></script>\n<script>\n  var chart = c3.generate({\n    size: {\n      height: 600,\n      width: 600 * 1.12\n    },\n    data: {\n      url: '/data/c3_stanford_data.json',\n      mimeType: 'json',\n      keys: {\n        x: 'HPE',\n        value: ['HPL', 'epochs']\n      },\n      type: 'stanford'\n    },\n    legend: {\n      hide: true\n    },\n    point: {\n      focus: {\n        expand: {\n          r: 5\n        }\n      },\n      r: 2.5\n    },\n    axis: {\n      x: {\n        show: true,\n        label: {\n          text: 'HPE (m)',\n          position: 'outer-center'\n        },\n        min: 0,\n        max: 61,\n        tick: {\n          values: d3.range(0, 65, 10)\n        },\n        padding: {\n          top: 0,\n          bottom: 0,\n          left: 0,\n          right: 0\n        },\n      },\n      y: {\n        show: true,\n        label: {\n          text: 'HPL (m)',\n          position: 'outer-middle'\n        },\n        min: 0,\n        max: 60,\n        tick: {\n          values: d3.range(0, 65, 10)\n        },\n        padding: {\n          top: 5,\n          bottom: 0,\n          left: 0,\n          right: 0\n        },\n      }\n    },\n    stanford: {\n      scaleMin: 1,\n      scaleMax: 10000,\n      scaleFormat: 'pow10',\n      padding: {\n        top: 15,\n        right: 0,\n        bottom: 0,\n        left: 0\n      },\n      regions: [\n        {\n          points: [ // add points counter-clockwise\n            {x: 0, y: 0},\n            {x: 40, y: 40},\n            {x: 0, y: 40},\n          ],\n          text: function (value, percentage) {\n            return `Normal Operations: ${value} (${percentage}%)`;\n          },\n          opacity: 0.2, // 0 to 1\n          class: \"test-polygon1\"\n        },\n        {\n          points: [\n            {x: 0, y: 0},\n            {x: 40, y: 0},\n            {x: 40, y: 40},\n          ],\n          text: function (value, percentage) {\n            return `MI: ${value} (${percentage}%)`;\n          },\n          opacity: 0.2, // 0 to 1\n          class: \"test-polygon2\"\n        },\n        {\n          points: [\n            {x: 40, y: 0},\n            {x: 65, y: 0},\n            {x: 65, y: 40},\n            {x: 40, y: 40},\n          ],\n          text: function (value, percentage) {\n            return `HMI: ${value} (${percentage}%)`;\n          },\n          opacity: 0.2, // 0 to 1\n          class: \"test-polygon3\"\n        },\n        {\n          points: [\n            {x: 0, y: 40},\n            {x: 40, y: 40},\n            {x: 65, y: 65},\n            {x: 0, y: 65},\n          ],\n          text: function (value, percentage) {\n            return `Unavailable Epochs: ${value} (${percentage}%)`;\n          },\n          opacity: 0.2, // 0 to 1\n          class: \"test-polygon4\"\n        },\n        {\n          points: [\n            {x: 40, y: 40},\n            {x: 65, y: 40},\n            {x: 65, y: 65}\n          ],\n          text: function (value, percentage) {\n            return `MI:\\n${value} (${percentage}%)`;\n          },\n          opacity: 0.2, // 0 to 1\n          class: \"test-polygon5\"\n        }\n      ],\n      lines: [ // value, text, position and class\n        {value_x1: 0, value_y1: 0, value_x2: 65, value_y2: 65, class: \"line\"},\n        {value_x1: 0, value_x2: 65, value_y1: 40, value_y2: 40, class: \"line\"},\n        {value_x1: 40, value_x2: 40, value_y1: 0, value_y2: 40, class: \"line\"}\n      ]\n    }\n  });\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_step.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 300, 350, 300, 0, 0, 0],\n//            ['data2', 130, 100, 140, 200, 150, 50]\n          ],\n          types: {\n            data1: 'step',\n            data2: 'area-step'\n          },\n          onclick: function (d) { console.log('clicked', d); }\n        },\n        subchart: {\n          show: true\n        },\n      });\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['data2', 130, 100, 140, 200, 150, 50]\n          ]\n        });\n      }, 1000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/chart_step_category.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          x: 'x',\n          columns: [\n            ['x', 'hogehoge', 'aaa', 'aaaaaa', 'a', 'b'],\n            ['data1', 300, 350, 300, 0, 0, 0],\n//            ['data2', 130, 100, 140, 200, 150, 50]\n          ],\n          types: {\n            data1: 'step',\n            data2: 'area-step'\n          },\n          empty: {\n            abort: false,\n            label: {\n              text: 'hoge'\n            }\n          }\n        },\n        axis: {\n          x: {\n            type: 'categorized'\n          }\n        },\n        subchart: {\n          show: true\n        },\n      });\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['data2', 130, 100, 140, 200, 150, 50]\n          ]\n        });\n      }, 1000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/custom_x_categorized.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          x : 'x',\n          columns: [\n            ['x', 'www.google.com', 'www.amazon.com', 'www.facebook.com', 'www.apple.com'],\n            ['download', 30, 200, 100, 400],\n            ['loading', 90, 100, 140, 200],\n          ],\n          groups: [\n            ['download', 'loading']\n          ],\n          type: 'bar'\n        },\n        axis: {\n          x: {\n            type: 'categorized',\n            label: 'X Label'\n          },\n          y: {\n            label: {\n              text: 'Y Label',\n              position: 'outer-middle'\n            }\n          }\n        }\n      });\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['x', 'www.yahoo.com', 'www.rakuten.com', 'www.mixi.com', 'www.sony.com'],\n            ['download', 130, 300, 200, 470],\n            ['loading', 190, 130, 240, 340],\n          ],\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['x', 'www.hogehoge.com', 'www.aaaa.com', 'www.aaaa.com'],\n            ['download', 130, 300, 200],\n            ['loading', 190, 130, 240],\n          ],\n        });\n      }, 2000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['x', 'www.yahoo.com', 'www.rakuten.com', 'www.mixi.com', 'www.sony.com'],\n            ['download', 130, 300, 200, 470],\n            ['loading', 190, 130, 240, 340],\n          ],\n        });\n      }, 3000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['download', 30, 30, 20, 170],\n            ['loading', 90, 30, 40, 40],\n          ],\n        });\n      }, 4000);\n\n      setTimeout(function () {\n        chart.load({\n          url: '/data/c3_test3.csv'\n        });\n      }, 5000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/custom_x_scale.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          x : 'x',\n          columns: [\n            ['x', 100, 120, 130, 200, 240, 500],\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 300, 200, 250, 350],\n          ],\n          selection: {\n            enabled: true\n          },\n          onmouseover: function (d) { console.log(\"onmouseover\", d); },\n          onmouseout: function (d) { console.log(\"onmouseout\", d); }\n        },\n      });\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['data1', 100, 210, 150, 200, 100, 150],\n          ]\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.x([200, 210, 350, 400, 550, 750]);\n      }, 2000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['data3', 300, 410, 350, 400, 500, 350],\n          ]\n        });\n      }, 3000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['x', 130, 140, 200, 300, 450, 550],\n            ['sample', 200, 350, 100, 200, 50, 100]\n          ]\n        })\n      }, 4000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/custom_xs_scale.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          xs : {\n            'data1': 'x1',\n            'data2': 'x2',\n          },\n          columns: [\n            ['x1', 100, 120, 130, 200, 240, 500],\n            ['x2', 150, 220, 230, 400, 540, 600, 800],\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 300, 200, 250, 350, 100],\n          ],\n          selection: {\n            enabled: true\n          },\n          onclick: function (d) { console.log(\"onclick\", d); },\n          onmouseover: function (d) { console.log(\"onmouseover\", d); },\n          onmouseout: function (d) { console.log(\"onmouseout\", d); }\n        }\n      });\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['data1', 100, 210, 150, null, 200, 150],\n            ['data2', 200, 310, 50, 400, 120, 250, 10],\n          ]\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['x2', 150, 220, 230, 400, 540, 600, 800],\n            ['data2', 200, 310, 50, 400, 120, 250, 10],\n            ['data3', 300, 410, 350, 600, 420, 550, 310],\n          ],\n          xs: {\n            data3: 'x2'\n          }\n        });\n      }, 2000);\n\n      setTimeout(function () {\n        chart.xs({\n          'data1': [200, 210, 350, 400, 600, 750],\n          'data2': [200, 210, 350, 400, 550, 750, 900]\n        });\n      }, 3000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/data_columned.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n            ['data2', 200, 130, 90, 240, 130, 220],\n            ['data3', 300, 200, 160, 400, 250, 250]\n          ]\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/data_hide.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n            ['data2', 200, 130, 90, 240, 130, 220],\n            ['data3', 300, 200, 160, 400, 250, 250]\n          ],\n//          hide: ['data1', 'data3']\n          hide: true // hide all data\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/data_json.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart = c3.generate({\n        data: {\n          json: {\n            data1: [30, 20, 50, 40, 60, 50],\n            data2: [200, 130, 90, 240, 130, 220],\n            data3: [300, 200, 160, 400, 250, 250]\n          }\n        }\n      });\n\n    setTimeout(function () {\n      chart = c3.generate({\n        data: {\n          json: [{\n            \"date\": \"2014-06-03\",\n             \"443\": \"3000\",\n             \"995\": \"500\"\n          }, {\n            \"date\": \"2014-06-04\",\n             \"443\": \"1000\",\n          }, {\n            \"date\": \"2014-06-05\",\n             \"443\": \"5000\",\n             \"995\": \"1000\"\n          }],\n          keys: {\n            x: 'date',\n            value: [ \"443\", \"995\" ]\n          }\n        },\n        axis: {\n          x: {\n            type: \"category\"\n          }\n        }\n      });\n    }, 1000);\n\n    setTimeout(function () {\n      chart = c3.generate({\n        data: {\n//          x: 'name',\n          json: [\n            { id: 1, name: 'abc', visits: 200 },\n            { id: 2, name: 'efg', visits: 400 },\n            { id: 3, name: 'pqr', visits: 150 },\n            { id: 4, name: 'xyz', visits: 420 },\n          ],\n          keys: {\n            x: 'name',\n            value: ['visits'],\n          }\n        },\n        axis: {\n          x: {\n            type: 'categorized'\n          }\n        }\n      });\n    }, 2000);\n\n    setTimeout(function () {\n      chart.load({\n          json: [\n            { id: 1, name: 'abc', visits: 1200 },\n            { id: 2, name: 'efg', visits: 900 },\n            { id: 3, name: 'pqr', visits: 1150 },\n            { id: 4, name: 'xyz', visits: 1020 },\n          ],\n          keys: {\n            x: 'name',\n            value: ['visits'],\n          }\n      });\n    }, 3000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/data_label.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n    <div id=\"chart4\"></div>\n    <div id=\"chart5\"></div>\n    <div id=\"chart6\"></div>\n    <div id=\"chart7\"></div>\n    <div id=\"chart8\"></div>\n    <div id=\"chart9\" style=\"width:33%;\"></div>\n    <div id=\"chart10\"></div>\n    <div id=\"chart11\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 190, 200, 190, null],\n          ],\n          type: 'bar',\n          labels: {\n            format: function (v, id) {\n                if (v === null) {\n                    return 'Not Applicable';\n                }\n                return d3.format('$')(v);\n            }\n          }\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['data1', -190, -200, -190, null],\n          ],\n          type: 'bar',\n          labels: {\n            format: function (v, id) {\n                if (v === null) {\n                    return 'Not Applicable';\n                }\n                return d3.format('$')(v);\n            }\n          }\n        }\n      });\n\n      var chart3 = c3.generate({\n        bindto: '#chart3',\n        data: {\n          columns: [\n            ['data1', -190, 200, 190, null],\n          ],\n          type: 'bar',\n          labels: {\n            format: function (v, id) {\n                if (v === null) {\n                    return 'Not Applicable';\n                }\n                return d3.format('$')(v);\n            }\n          }\n        }\n      });\n\n      var chart4 = c3.generate({\n        bindto: '#chart4',\n        data: {\n          columns: [\n            ['data1', 190, 200, 190, null],\n          ],\n          type: 'bar',\n          labels: {\n            format: function (v, id) {\n                if (v === null) {\n                    return 'Not Applicable';\n                }\n                return d3.format('$')(v);\n            }\n          }\n        },\n        axis: {\n          rotated: true\n        }\n      });\n\n      var chart5 = c3.generate({\n        bindto: '#chart5',\n        data: {\n          columns: [\n            ['data1', -190, -200, -190, null],\n          ],\n          type: 'bar',\n          labels: {\n            format: function (v, id) {\n                if (v === null) {\n                    return 'Not Applicable';\n                }\n                return d3.format('$')(v);\n            }\n          }\n        },\n        axis: {\n          rotated: true\n        }\n      });\n\n      var chart6 = c3.generate({\n        bindto: '#chart6',\n        data: {\n          columns: [\n            ['data1', -190, 200, 190, null],\n          ],\n          type: 'bar',\n          labels: {\n            format: function (v, id) {\n                if (v === null) {\n                    return 'Not Applicable';\n                }\n                return d3.format('$')(v);\n            }\n          }\n        },\n        axis: {\n          rotated: true\n        }\n      });\n\n      var chart7 = c3.generate({\n        bindto: '#chart7',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 500, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25],\n            ['data3', 250, 220, 210, 240, 215, 225]\n          ],\n          groups: [['data1', 'data2', 'data3']],\n          labels: true,\n          type: 'bar',\n        },\n        axis: {\n          rotated: true\n        }\n      });\n\n      var chart8 = c3.generate({\n        bindto: '#chart8',\n        data: {\n          columns: [\n            ['data1', -30, -200, -100, -500, -150, -250],\n            ['data2', -50, -20, -10, -40, -15, -25],\n            ['data3', -250, -220, -210, -240, -215, -225]\n          ],\n          groups: [['data1', 'data2', 'data3']],\n          labels: true,\n          type: 'bar',\n        },\n        axis: {\n          rotated: true\n        }\n      });\n\n      var chart9 = c3.generate({\n        bindto: '#chart9',\n        data: {\n          columns: [\n            ['data1', -19000000000000, 200, 19000000000000, null],\n          ],\n          type: 'bar',\n          labels: {\n            format: function (v, id) {\n                if (v === null) {\n                    return 'Not Applicable';\n                }\n                return d3.format('$')(v);\n            }\n          }\n        },\n        axis: {\n          rotated: true\n        }\n      });\n\n      var chart10 = c3.generate({\n        bindto: '#chart10',\n        data: {\n          columns: [\n            ['data1', 300, 350, 300, 0, 0, 100],\n            ['data2', 130, 0, 140, 200, 0, 50],\n            ['data3', 130, 0, 140, 200, 0, 50],\n            ['data4', 130, 0, 140, 200, 0, 50],\n          ],\n          type: 'area',\n          groups: [['data1', 'data2', 'data3', 'data4']],\n          labels: true\n        }\n      });\n\n      var chart11 = c3.generate({\n        bindto: '#chart11',\n        data: {\n          columns: [\n            ['data1', 300, 350, 300, 0, 0, 100],\n            ['data2', 130, 0, 140, 200, 0, 50],\n            ['data3', 130, 0, 140, 200, 0, 50],\n            ['data4', 130, 0, 140, 200, 0, 50],\n          ],\n          groups: [['data1', 'data2', 'data3', 'data4']],\n          labels: true\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/data_label_format.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          labels: {\n//            format: function (v, id) { return \"Default Format on \" + id; },\n            format: {\n              data1: function (v, id) { return \"data1 Format\"; },\n              data2: function (v, id) { return \"data2 Format\"; }\n            }\n          },\n          axes: {\n            data1: 'y',\n            data2: 'y2',\n          }\n        },\n        axis: {\n          y2: {\n            show: true\n          }\n        },\n        tooltip: {\n//          enabled: false\n        },\n        zoom: {\n//          enabled: true\n        },\n        subchart: {\n//          show: true\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/data_load.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart = c3.generate({\n        data: {\n          url: '/data/c3_test.csv',\n          labels: true,\n          filter: function (t) {\n            return t.id !== 'data1';\n          }\n        },\n        subchart: {\n          show: true\n        },\n        zoom: {\n          enabled: true\n        },\n        transition: {\n          duration: 500\n        }\n      });\n\n    var queue = [\n      function () {\n        chart.load({\n          url: '/data/c3_test2.csv',\n          filter: function (t) {\n            return t.id !== 'data1';\n          }\n        });\n      },\n      function () {\n        chart.load({\n          rows: [\n            ['data4', 'data5', 'data6'],\n            [90, 120, 300],\n            [40, 160, 240],\n            [50, 200, 290],\n            [120, 160, 230],\n            [80, 130, 300],\n            [90, 220, 320],\n            [1090, 1220, 1320],\n          ]\n        });\n      },\n      function () {\n        chart.unload({\n          ids: ['data4', 'data5']\n        });\n      },\n      function () {\n        chart.unload({\n          ids: 'data6'\n        });\n      },\n      function () {\n        chart.load({\n          columns:[\n            ['data1', 30, 20, 50, 40, 60, 50, 100, 200],\n            ['data7', 230, 220, 250, 240, 260, 250, 300, 400]\n          ]\n        });\n      },\n      function () {\n        chart.load({\n          json: {\n            data1: [1030, 1020, 1050, 1040, 1060, 1050, 1100, 1200],\n            data7: [430, 420, 450, 440, 460, 550, 400, 200]\n          }\n        });\n      },\n      function () {\n        chart.load({\n          columns: [\n            ['data8', 30, 20, 50, 40, 60, 50],\n          ],\n          unload: true,\n        });\n      },\n      function () {\n        chart.load({\n          columns: [\n            ['data9', 130, 120, 150, 140, 160, 150],\n          ],\n          unload: ['data7', 'data8'],\n        });\n      },\n      function () {\n        chart.load({\n          unload: ['data1', 'data2'],\n        });\n      },\n      function () {\n        chart.unload();\n      },\n      function () {\n        chart.load({\n          rows: [\n            ['data1', 'data2', 'data3'],\n            [90, 120, 300],\n            [40, 160, 240],\n            [50, 200, 290],\n            [120, 160, 230],\n            [80, 130, 300],\n            [90, 220, 320],\n          ]\n        });\n      },\n      function () {\n        chart.unload({\n          ids: ['data2', 'data3']\n        });\n      },\n    ];\n\n    var i = 0;\n    queue.forEach(function (f) {\n      setTimeout(f, 1500 * i++);\n    });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/data_load_timeseries.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          x: 'x',\n          url: '/data/c3_test_ts.csv',\n          labels: true\n        },\n        axis: {\n          x: {\n            type: 'timeseries'\n          }\n        },\n        subchart: {\n          show: true\n        },\n        zoom: {\n          enabled: true\n        },\n      });\n\n      setTimeout(function () {\n        chart.load({\n          url: '/data/c3_test2_ts.csv'\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.unload({\n          ids: 'data2'\n        });\n      }, 2000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n          ],\n          unload: true,\n//          unload: ['data2', 'data3'],\n//          unload: ['data2']\n        });\n      }, 3000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/data_region.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n          ],\n          regions: {\n            sample: [{start:1, end:3}]\n          }\n        },\n        regions: [{start:1, end:3}],\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/data_region_timeseries.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          x : 'date',\n          xFormat : '%Y%m%d',\n          columns: [\n//            ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],\n            ['date', '20130101', '20130102', '20130103', '20130104', '20130105', '20130106'],\n            ['sample', 30, 200, 100, 400, 150, 250]\n          ],\n          regions: {\n            sample: [{start:'20130103', end:'20130105'}]\n          }\n        },\n        regions: [{start:'20130103', end:'20130105'}],\n        axis : {\n          x : {\n            type : 'timeseries'\n          }\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/data_rowed.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          rows: [\n            ['data1', 'data2', 'data3'],\n            [90, 120, 300],\n            [40, 160, 240],\n            [50, 200, 290],\n            [120, 160, 230],\n            [80, 130, 300],\n            [90, 220, 320],\n          ]\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/data_url.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart = c3.generate({\n        data: {\n          url: '/data/c3_test.csv'\n        }\n      });\n\n      setTimeout(function () {\n        chart.load({\n          url: '/data/c3_test2.csv',\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.load({\n          url: '/data/c3_test.tsv',\n          mimeType: 'tsv'\n        });\n      }, 2000);\n\n      setTimeout(function () {\n        chart = c3.generate({\n          data: {\n            url: '/data/c3_test.json',\n            mimeType: 'json'\n          }\n        });\n      }, 3000);\n\n      setTimeout(function () {\n        chart.load({\n          url: '/data/c3_test_2.json',\n          mimeType: 'json'\n        });\n      }, 4000);\n\n      setTimeout(function () {\n        chart.load({\n          url: '/data/c3_test_3.json',\n          mimeType: 'json',\n          keys: {\n            value: ['data1', 'data2']\n          }\n        });\n      }, 5000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/different_category_datasets.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          xs: {\n            data1: \"cat1\",\n            data2: \"cat2\",\n          },\n          columns: [\n            [\"cat1\", \"a\", \"b\", \"c\", \"d\"],\n            [\"data1\", 30, 200, 100, 400],\n            [\"cat2\", \"b\", \"a\", \"c\", \"d\", \"e\", \"f\"],\n            [\"data2\", 400, 60, 200, 800, 10, 10]\n          ]\n        },\n        axis: {\n          x: {\n            type: \"category\"\n          }\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/domain_y.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <button id=\"btn1\">Bar</button>\n    <button id=\"btn2\">Line</button>\n    <button id=\"btn3\">Area</button>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var normalData = {\n          columns: [\n            ['data1', -1030, -1200, 1000],\n            ['data2', -1150, -220, -1110]\n          ],\n          labels: true,\n      },\n      allPositiveData = {\n          columns: [\n            ['data1', 1030, 1200, 1100],\n            ['data2', 2050, 2020, 2010]\n          ],\n          labels: true,\n      },\n      allNegativeData = {\n          columns: [\n            ['data1', -1030, -2200, -2100],\n            ['data2', -1150, -2010, -1200]\n          ],\n          labels: true,\n      }\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: normalData\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: allPositiveData\n      });\n\n      var chart3 = c3.generate({\n        bindto: '#chart3',\n        data: allNegativeData\n      });\n\n      d3.select('#btn1').on('click', function () {\n        chart1.transform('bar');\n        chart2.transform('bar');\n        chart3.transform('bar');\n      });\n      d3.select('#btn2').on('click', function () {\n        chart1.transform('line');\n        chart2.transform('line');\n        chart3.transform('line');\n      });\n      d3.select('#btn3').on('click', function () {\n        chart1.transform('area');\n        chart2.transform('area');\n        chart3.transform('area');\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/element.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n\n    <script src=\"..//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js\"></script>\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        data: {\n          columns: [\n            ['sample', 30, 200, 100, null, 150, 250]\n          ],\n        },\n      });\n\n      var chart2 = c3.generate({\n        data: {\n          columns: [\n            ['sample', 30, 200, 100, null, 150, 250]\n          ],\n          type: 'bar'\n        }\n      });\n\n      document.getElementById('chart1').appendChild(chart1.element);\n\n      $('#chart2').append(chart2.element);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/emptydata.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart = c3.generate({\n        data: {\n          columns: [\n//            ['data1', 100, 200],\n          ],\n          empty: {\n            label: {\n              text: 'No Data'\n            }\n          }\n        },\n        subchart: {\n          show: true\n        }\n      });\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['data1', 100, 200],\n          ],\n        });\n      }, 1000);\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/grid_focus.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 300, 200, 300, 250, 150]\n          ]\n        },\n        grid: {\n          focus: {\n            show: false\n          }\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/grid_x_lines.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250]\n          ],\n          type: 'bar'\n        },\n        grid: {\n          x: {\n            show: true,\n            lines: [{\n               value: 2,\n               text: 'Label 2',\n               class: 'lineFor2'\n            }]\n          },\n          y: {\n            show: true,\n          }\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          x : 'x',\n          columns: [\n            ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05'],\n            ['sample', 30, 200, 100, 400, 150]\n          ],\n        },\n        axis : {\n          x : {\n            type : 'timeseries'\n          }\n        },\n        grid: {\n          x: {\n            lines: [{\n               value: '2013-01-04',\n               text: '2013/01/04',\n               class: 'lineFor20130104'\n            }]\n          },\n          lines: {\n            front: false\n          }\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/grid_x_lines_timeseries.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n    var chart1 = c3.generate({\n      \"bindto\": \"#chart1\",\n      \"axis\": {\n          \"x\": {\n            \"type\": \"timeseries\",\n            \"tick\": {\n              format: '%Y-%m-%d %H:%M:%S'\n            }\n          }\n      },\n      \"grid\": {\n          \"x\": {\n            \"lines\": [\n                { \"value\": 1401883200000, \"text\": new Date(1401883200000), \"color\": \"#f00\" },\n            ]\n          }\n      },\n      \"data\": {\n        \"type\": \"line\",\n        \"columns\": [\n            [\"epoch\", 1401879600000, 1401883200000, 1401886800000],\n            [\"y\", 1955, 2419, 2262]\n        ],\n        \"xs\": {\n            \"y\": \"epoch\"\n        }\n      }\n    });\n\n    var chart2 = c3.generate({\n      \"bindto\": \"#chart2\",\n      \"axis\": {\n          \"x\": {\n            \"type\": \"timeseries\",\n            \"tick\": {\n              format: '%Y-%m-%d %H:%M:%S'\n            }\n          }\n      },\n      \"grid\": {\n          \"x\": {\n            \"lines\": [\n                { \"value\": new Date(1401883200000), \"text\": new Date(1401883200000), \"color\": \"#f00\" },\n            ]\n          }\n      },\n      \"data\": {\n        \"type\": \"line\",\n        \"columns\": [\n            [\"epoch\", 1401879600000, 1401883200000, 1401886800000],\n            [\"y\", 1955, 2419, 2262]\n        ],\n        \"xs\": {\n            \"y\": \"epoch\"\n        }\n      }\n    });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/grids.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n    <div id=\"chart4\"></div>\n    <div id=\"chart5\"></div>\n    <div id=\"chart6\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var smallData = [['sample', 30, 200, 100, 400, 150, 250]],\n          bigData = [['sample', 30, 200, 100, 400, 150, 250, 30, 200, 100, 400, 150, 250]];\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: smallData\n        },\n        grid: {\n          x: {\n            show: true\n          },\n        }\n      });\n\n      c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: smallData\n        },\n        grid: {\n          y: {\n            show: true\n          }\n        }\n      });\n\n      c3.generate({\n        bindto: '#chart3',\n        data: {\n          columns: smallData\n        },\n        axis: {\n          rotated: true,\n        },\n        grid: {\n          x: {\n            show: true\n          },\n        }\n      });\n\n      c3.generate({\n        bindto: '#chart4',\n        data: {\n          columns: smallData\n        },\n        axis: {\n          rotated: true,\n        },\n        grid: {\n          y: {\n            show: true\n          }\n        }\n      });\n\n      c3.generate({\n        bindto: '#chart5',\n        data: {\n          columns: bigData\n        },\n        grid: {\n          x: {\n            show: true\n          },\n          y: {\n            show: true\n          }\n        }\n      });\n\n      c3.generate({\n        bindto: '#chart6',\n        data: {\n          columns: bigData\n        },\n        axis: {\n          x: {\n            type: 'category'\n          }\n        },\n        grid: {\n          x: {\n            show: true\n          },\n          y: {\n            show: true\n          }\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/grids_timeseries.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var smallData = [\n        ['x', '2014-01-01', '2014-02-01', '2014-03-01', '2014-04-01', '2014-05-01', '2014-06-01'],\n        ['sample', 30, 200, 100, 400, 150, 250]\n      ],\n      bigData = [\n        ['x', '2014-01-01', '2014-02-01', '2014-03-01', '2014-04-01', '2014-05-01', '2014-06-01', '2014-07-01', '2014-08-01', '2014-09-01', '2014-10-01', '2014-11-01', '2014-12-01'],\n        ['sample', 30, 200, 100, 400, 150, 250, 30, 200, 100, 400, 150, 250]\n      ];\n\n      c3.generate({\n        bindto: '#chart1',\n        data: {\n          x: 'x',\n          columns: smallData\n        },\n        axis: {\n          x: {\n            type: 'timeseries',\n            tick: {\n              format: \"%Y-%m-%d %H:%M:%S\"\n            }\n          }\n        },\n        grid: {\n          x: {\n            show: true,\n          },\n        }\n      });\n\n      c3.generate({\n        bindto: '#chart2',\n        data: {\n          x: 'x',\n          columns: smallData\n        },\n        axis: {\n          rotated: true,\n          x: {\n            type: 'timeseries',\n            tick: {\n              format: \"%Y-%m-%d %H:%M:%S\"\n            }\n          }\n        },\n        grid: {\n          x: {\n            show: true,\n          },\n        }\n      });\n\n      c3.generate({\n        bindto: '#chart3',\n        data: {\n          x: 'x',\n          columns: bigData\n        },\n        axis: {\n          x: {\n            type: 'timeseries',\n            tick: {\n              format: \"%Y-%m-%d %H:%M:%S\"\n            }\n          }\n        },\n        grid: {\n          x: {\n            show: true\n          }\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/interaction_enabled.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ]\n        },\n        interaction: {\n          enabled: false\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/legend.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n    <div id=\"chart4\"></div>\n    <div id=\"chart5\"></div>\n    <div id=\"chart6\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var columns = [];\n      for (var i = 0; i < 28; i++ ) {\n        columns[i] = ['datahogehogeohgeohoge' + i, 10 * i, 20 * i];\n      }\n\n      c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: columns,\n        },\n      });\n\n      c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: columns,\n        },\n        legend: {\n          position: 'right'\n        },\n      });\n\n      c3.generate({\n        bindto: '#chart3',\n        data: {\n          columns: columns,\n        },\n        legend: {\n          position: 'inset',\n        },\n      });\n\n      c3.generate({\n        bindto: '#chart4',\n        data: {\n          columns: columns,\n        },\n        axis: {\n          rotated: true,\n        },\n      });\n\n      c3.generate({\n        bindto: '#chart5',\n        data: {\n          columns: columns,\n        },\n        legend: {\n          position: 'right'\n        },\n        axis: {\n          rotated: true,\n        },\n      });\n\n      c3.generate({\n        bindto: '#chart6',\n        data: {\n          columns: columns,\n        },\n        legend: {\n          position: 'inset'\n        },\n        axis: {\n          rotated: true,\n        },\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/padding.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n<style type=\"text/css\">\n<!--\n.c3 svg {\n/*    font-size: 13px;*/\n}\n-->\n</style>\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n    <div id=\"chart4\"></div>\n    <div id=\"chart5\"></div>\n    <div id=\"chart6\"></div>\n    <div id=\"chart7\"></div>\n    <div id=\"chart8\"></div>\n    <div id=\"chart9\"></div>\n    <div id=\"chart10\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var option = {\n        padding: {\n          top: 50,\n          right: 200,\n          bottom: 50,\n          left: 200,\n        },\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 200, 100, 150, 150]\n          ],\n          axes: {\n            data2: 'y2'\n          },\n        },\n        axis: {\n          rotated: true,\n          y: {\n            label: {\n              text: 'Y Label',\n              position: 'outer-center'\n            }\n          },\n          y2: {\n            show: true,\n            label: {\n              text: 'Y2 Label',\n              position: 'outer-center'\n            }\n          }\n        },\n        legend: {\n          position: 'bottom'\n        },\n        subchart: {\n          show: false\n        },\n        grid: {\n          x: {\n            show: true,\n          },\n          y: {\n            show: true,\n          }\n        }\n      };\n\n\n      option.bindto = '#chart1';\n      var chart1 = c3.generate(option);\n\n      option.bindto = '#chart2';\n      option.legend.position = 'right'\n      var chart2 = c3.generate(option);\n\n      option.bindto = '#chart3';\n      option.legend.position = 'bottom';\n      option.subchart.show = true;\n      var chart3 = c3.generate(option);\n\n      option.bindto = '#chart4';\n      option.legend.position = 'right';\n      option.subchart.show = true;\n      var chart4 = c3.generate(option);\n\n      option.bindto = '#chart5';\n      option.padding = {\n          top: 0,\n          right: 0,\n          bottom: 0,\n          left: 0,\n      };\n      option.subchart.show = false;\n      option.legend.position = 'bottom';\n      var chart5 = c3.generate(option);\n\n\n      option.axis.rotated = false;\n\n      option.bindto = '#chart6';\n      var chart6 = c3.generate(option);\n\n      option.bindto = '#chart7';\n      option.legend.position = 'right'\n      var chart7 = c3.generate(option);\n\n      option.bindto = '#chart8';\n      option.legend.position = 'bottom';\n      option.subchart.show = true;\n      var chart8 = c3.generate(option);\n\n      option.bindto = '#chart9';\n      option.legend.position = 'right';\n      option.subchart.show = true;\n      var chart9 = c3.generate(option);\n\n      option.bindto = '#chart10';\n      option.padding = {\n          top: 0,\n          right: 0,\n          bottom: 0,\n          left: 0,\n      };\n      option.subchart.show = false;\n      option.legend.position = 'bottom';\n      var chart10 = c3.generate(option);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/padding_update.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n    var axis_rotated = true;\n\n    var generate = function () { return c3.generate({\n      data: {\n        x: 'x',\n        columns: [\n            ['x', '2014-01-01', '2014-02-01', '2014-03-01', '2014-04-01'],\n            ['data1', 190, 200, 190, null],\n        ],\n        type: 'bar',\n        labels: {\n            format: function (v, id) {\n                if (v === null) {\n                    return 'Not Applicable';\n                }\n                return d3.format('$')(v);\n            }\n        }\n      },\n      axis: {\n        x: {\n            type: 'categorized'\n        },\n        rotated: axis_rotated\n      },\n    }); }, chart = generate();\n\n    setTimeout(function () {\n      chart.hide();\n    }, 1000);\n\n    setTimeout(function () {\n      chart.show();\n    }, 2000);\n\n    setTimeout(function () {\n      chart.load({\n        columns: [\n          ['data1', 300, 350, 100]\n        ],\n        categories: ['2014-01-01 10:10:10', '2014-02-01 12:30:00', '2014-03-01 16:30:00']\n      });\n    }, 3000);\n\n    setTimeout(function () {\n      chart.load({\n        columns: [\n          ['data1', 50, 100, 150]\n        ],\n        categories: ['2014', '2015', '2016']\n      });\n    }, 4000);\n\n    setTimeout(function () {\n      axis_rotated = false;\n      chart = generate();\n    }, 5000);\n\n    setTimeout(function () {\n      chart.load({\n        columns: [\n          ['data1', 300, 350, 100000]\n        ],\n      });\n    }, 6000);\n\n    setTimeout(function () {\n      chart.load({\n        columns: [\n          ['data1', 50, 100, 150]\n        ],\n      });\n    }, 7000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/plugin.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script src=\"../js/samples/plugin.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          onclick: function (d, element) { console.log(\"onclick\", d, element); },\n          onmouseover: function (d) { console.log(\"onmouseover\", d); },\n          onmouseout: function (d) { console.log(\"onmouseout\", d); },\n        },\n        test1: 'TEST1',\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/point_r.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 300, 200, 600, 250, 150]\n          ],\n        },\n        point: {\n//          r: 10\n          r: function (d) {\n            return d.id === 'data2' ? 10 : 2.5;\n          }\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/point_show.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 300, 200, 600, 250, 150]\n          ]\n        },\n        point: {\n            show: function(d) {\n                return d.value > 200;\n            }\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/regions.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['sample', 30, 200, 100, 400, 150, 250, 300]\n          ]\n        },\n        axis: {\n          rotated: true,\n          y2: {\n//            show: true,\n          }\n        },\n        regions: [\n          {end: 1, class: 'region1', label: 'Region 1', paddingY: 15},\n          {start: 2, end: 4, class: 'region1', label: 'Region 2', paddingY: 20, paddingX: 10, vertical: true},\n          {start: 5, class: 'region1', label: 'Region 3', paddingY: 15},\n          {end: 50, axis: 'y'},\n          {start: 100, end: 200, axis: 'y'},\n          {start: 300, axis: 'y'},\n        ],\n        zoom: {\n//          enabled: true\n        }\n      });\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['sample', -100, 200, 50, 100, 400, 299]\n          ]\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.regions([]);\n      }, 2000);\n\n      setTimeout(function () {\n        chart.regions([{start:0.5,end:2.5}]);\n      }, 3000);\n\n      setTimeout(function () {\n        chart.regions.add([{start:4.5}]);\n      }, 4000);\n\n      setTimeout(function () {\n        chart.regions.add([{start:3,end:3.5,class:\"region1\"}, {start:4,end:4.5,class:\"region2\"}]);\n      }, 5000);\n\n      setTimeout(function () {\n        chart.regions.remove({classes:['region1', 'region2'], duration: 0});\n      }, 6000);\n\n      setTimeout(function () {\n        chart.regions.add([\n          {start:3,end:3.5,class:\"region3 hoge\"},\n          {start:4,end:4.5,class:\"region4 hoge\",label:\"Region 4\"},\n          {start:0,end:0.5,class:\"region5 hogehoge\"},\n        ]);\n      }, 7000);\n\n      setTimeout(function () {\n        chart.regions.remove({classes:['hoge'], duration: 500});\n      }, 8000);\n\n      setTimeout(function () {\n        chart.regions.remove({classes:['hogehoge']});\n      }, 9000);\n\n      setTimeout(function () {\n        chart.regions.remove({});\n      }, 10000);\n\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/regions_timeseries.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\nvar chart = c3.generate({\n    data: {\n        x: 'date',\n        columns: [\n            ['date', '2014-01-01', '2014-01-10', '2014-01-20', '2014-01-30', '2014-02-01'],\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n    },\n    axis: {\n        x: {\n            type: 'timeseries',\n            tick: {\n                format: '%Y%m%d %H:%M:%S'\n            }\n        },\n    },\n    regions: [\n        {start: '2014-01-05', end: '2014-01-10'},\n//        {start: new Date('2014-01-10'), end: new Date('2014-01-15')},\n        {start: 1390608000000, end: 1391040000000}\n    ]\n});\n\nsetTimeout(function () {\n    chart.load({\n        columns: [\n            ['date', +new Date('2014-01-01'), +new Date('2014-01-10'), +new Date('2014-03-01')],\n            ['sample', 100, 200, 300]\n        ]\n    });\n    chart.regions([\n        {start: +new Date('2014-01-10'), end: +new Date('2014-01-15')}\n    ]);\n}, 1000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/requirejs.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n    <script data-main=\"../js/samples/requirejs.js\" src=\"../js/require.js\"></script>\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/resize.html",
    "content": "<html>\n\n<head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <style>\n        .chartcontainer {\n            background-color: #EEE;\n            height: calc(100% - 150px);\n            width: 90%;\n            border: 1px solid black;\n        }\n    </style>\n</head>\n\n<body>\n    <h3>Please drag the window around to watch the chart resize.</h3>\n    <p>\n    This example illustrates the case which the issue <a href=\"https://github.com/c3js/c3/issues/2467\">#2467</a> reports.\n    </p>\n    <div class=\"chartContainer\">\n        <div id=\"chart\"></div>\n    </div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n        var chart = c3.generate({\n            data: {\n                bindto: '#chart',\n                columns: [\n                    ['data1', 30, 200, 100, 400, 150, 250],\n                    ['data2', 130, 100, 140, 200, 150, 50]\n                ],\n                types: {\n                    data1: 'spline',\n                    data2: 'spline'\n                }\n            },\n            spline: {\n                interpolation: {\n                    type: 'monotone', // 'cardinal' is default\n                },\n            },\n        });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "htdocs/samples/selection.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    grouped => true, multiple => true\n    <div id=\"chart1\"></div>\n\n    grouped => true, multiple => true, tooltip.grouped = false\n    <div id=\"chart1-1\"></div>\n\n    grouped => true, multiple => false\n    <div id=\"chart2\"></div>\n\n    grouped => true, multiple => false, tooltip.grouped = false\n    <div id=\"chart2-1\"></div>\n\n    grouped => false, multiple => true\n    <div id=\"chart3\"></div>\n\n    grouped => false, multiple => true, tooltip.grouped = false\n    <div id=\"chart3-1\"></div>\n\n    grouped => false, multiple => false\n    <div id=\"chart4\"></div>\n\n    grouped => false, multiple => false, tooltip.grouped = false\n    <div id=\"chart4-1\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          selection: {\n            enabled: true,\n            grouped: true,\n            multiple: true,\n          },\n          onclick: function (d, element) { console.log(\"onclick\", d, element); },\n          onselected: function (d, element) { console.log(\"onselected\", d, element); },\n          onunselected: function (d, element) { console.log(\"onunselected\", d, element); },\n          ondragstart: function () { console.log(\"ondragstart\"); },\n          ondragend: function () { console.log(\"ondragend\"); },\n        },\n      });\n\n      var chart11 = c3.generate({\n        bindto: '#chart1-1',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          selection: {\n            enabled: true,\n            grouped: true,\n            multiple: true,\n          },\n        },\n        tooltip: {\n          grouped: false\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          selection: {\n            enabled: true,\n            grouped: true,\n            multiple: false,\n          }\n        }\n      });\n\n      var chart21 = c3.generate({\n        bindto: '#chart2-1',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          selection: {\n            enabled: true,\n            grouped: true,\n            multiple: false,\n          }\n        },\n        tooltip: {\n          grouped: false\n        }\n      });\n\n      var chart3 = c3.generate({\n        bindto: '#chart3',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          selection: {\n            enabled: true,\n            grouped: false,\n            multiple: true,\n          }\n        }\n      });\n\n      var chart31 = c3.generate({\n        bindto: '#chart3-1',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          selection: {\n            enabled: true,\n            grouped: false,\n            multiple: true,\n          }\n        },\n        tooltip: {\n          grouped: false\n        }\n      });\n\n      var chart4 = c3.generate({\n        bindto: '#chart4',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          selection: {\n            enabled: true,\n            grouped: false,\n            multiple: false,\n          }\n        }\n      });\n\n      var chart41 = c3.generate({\n        bindto: '#chart4-1',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          selection: {\n            enabled: true,\n            grouped: false,\n            multiple: false,\n          }\n        },\n        tooltip: {\n          grouped: false\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/simple.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          onclick: function (d, element) { console.log(\"onclick\", d, element); },\n          onmouseover: function (d) { console.log(\"onmouseover\", d); },\n          onmouseout: function (d) { console.log(\"onmouseout\", d); },\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/subchart.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n    <div id=\"chart3\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          labels: true\n        },\n        subchart: {\n          show: true\n        },\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          labels: true\n        },\n        subchart: {\n          show: true\n        },\n        axis: {\n          rotated: true\n        }\n      });\n\n      var chart3 = c3.generate({\n        bindto: '#chart3',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ],\n          labels: true\n        },\n        axis: {\n          x: {\n            default: [3, 5]\n          }\n        },\n        subchart: {\n          show: true\n        },\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/subchart_onbrush.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          x : 'x',\n          columns: [\n            ['x', '2013-01-01', '2013-02-01', '2013-03-01', '2013-04-01', '2013-05-01'],\n            ['sample', 30, 200, 100, 400, 150],\n            ['sample2', 130, 300, 200, 450, 250]\n          ]\n        },\n        axis : {\n          x : {\n            type : 'timeseries',\n            tick : {\n              format : \"%Y-%m-%d\"\n            }\n          }\n        },\n        subchart: {\n          show: true,\n          onbrush: function (domain) {\n            console.log(this, domain);\n          }\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['sample', 30, 200, 100, 400, 150],\n            ['sample2', 130, 300, 200, 450, 250]\n          ]\n        },\n        subchart: {\n          show: true,\n          onbrush: function (domain) {\n            console.log(this, domain);\n          }\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/timeseries.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          x : 'date',\n          xFormat : '%Y%m%d',\n          columns: [\n//            ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],\n            ['date', '20130101', '20130102', '20130103', '20130104', '20130105', '20130106'],\n            ['sample', 30, 200, 100, 400, 150, 250],\n            ['sample2', 130, 300, 200, 450, 250, 350]\n          ]\n        },\n        axis : {\n          x : {\n            type : 'timeseries',\n            tick : {\n//              format : \"%m/%d\" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format\n              format : \"%e %b %y\" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format\n            }\n          }\n        }\n      });\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['sample', 200, 130, 90, 240, 130, 100],\n            ['sample2', 300, 200, 160, 400, 250, 250]\n          ]\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['date', '20140101', '20140201', '20140301', '20140401', '20140501', '20140601'],\n            ['sample', 500, 630, 690, 440, 630, 900],\n            ['sample2', 400, 600, 460, 200, 350, 450]\n          ]\n        });\n      }, 2000);\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/timeseries_date.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          x : 'x',\n          xFormat : '%Y%m%d',\n          columns: [\n            ['x', new Date('2013-01-01T00:00:00Z'), new Date('2013-01-02T00:00:00Z'), new Date('2013-01-03T00:00:00Z'), new Date('2013-01-04T00:00:00Z'), new Date('2013-01-05T00:00:00Z'), new Date('2013-01-06T00:00:00Z')],\n            ['sample', 30, 200, 100, 400, 150, 250],\n            ['sample2', 130, 300, 200, 450, 250, 350]\n          ]\n        },\n        axis : {\n          x : {\n            type : 'timeseries',\n            tick : {\n//              format : \"%m/%d\" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format\n              format : \"%e %b %y\" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format\n            }\n          }\n        }\n      });\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['sample', 200, 130, 90, 240, 130, 100],\n            ['sample2', 300, 200, 160, 400, 250, 250]\n          ]\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['x', '20140101', '20140201', '20140301', '20140401', '20140501', '20140601'],\n            ['sample', 500, 630, 690, 440, 630, 900],\n            ['sample2', 400, 600, 460, 200, 350, 450]\n          ]\n        });\n      }, 2000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['x', new Date('2014-01-02T00:00:00Z'), new Date('2014-02-02T00:00:00Z'), new Date('2014-03-02T00:00:00Z'), new Date('2014-04-02T00:00:00Z'), new Date('2014-05-02T00:00:00Z'), new Date('2014-06-02T00:00:00Z')],\n            ['sample', 500, 630, 690, 440, 630, 900],\n            ['sample2', 400, 600, 460, 200, 350, 450]\n          ]\n        });\n      }, 3000);\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/timeseries_descendent.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var dates = ['date',\n        1401908040000,\n        1401907980000,\n        1401907920000,\n        1401907860000,\n        1401907800000,\n        1401907740000,\n        1401907680000,\n        1401907620000,\n        1401907560000,\n        1401907500000\n      ];\n\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          x : 'date',\n          columns: [\n            dates,\n            ['data1', 30, 200, 100, 400, 150, 250, 30, 200, 100, 400],\n            ['data2', 130, 300, 200, 450, 250, 350, 130, 300, 200, 450]\n          ],\n          types: {\n            data1: 'bar',\n          }\n        },\n        axis : {\n          x : {\n            type : 'timeseries',\n            tick : {\n              format : \"%Y-%m-%d %H:%M:%S\"\n            }\n          }\n        }\n      });\n\n/*\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['sample', 200, 130, 90, 240, 130, 100],\n            ['sample2', 300, 200, 160, 400, 250, 250]\n          ]\n        });\n      }, 1000);\n\n      setTimeout(function () {\n        chart.load({\n          columns: [\n            ['date', '20140101', '20140201', '20140301', '20140401', '20140501', '20140601'],\n            ['sample', 500, 630, 690, 440, 630, 900],\n            ['sample2', 400, 600, 460, 200, 350, 450]\n          ]\n        });\n      }, 2000);\n\n*/\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/timeseries_raw.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var rows = [[\"x\",\"Views\",\"GMV\"]];\n      rows = rows.concat([[1398709800000,780,136],\n              [1398450600000,812,134],\n              [1399401000000,784,154],\n              [1399228200000,786,135],\n              [1399573800000,802,131],\n              [1399487400000,773,166],\n              [1399314600000,787,146],\n              [1399919400000,1496,309],\n              [1399833000000,767,138],\n              [1399746600000,797,141],\n              [1399660200000,796,146],\n              [1398623400000,779,143],\n              [1399055400000,794,140],\n              [1398969000000,791,140],\n              [1398882600000,825,107],\n              [1399141800000,786,136],\n              [1398537000000,773,143],\n              [1398796200000,783,154],\n              [1400005800000,1754,284]].sort(function (a, b) {\n        return a[0] - b[0];\n      }));\n\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          x : 'x',\n          rows: rows\n        },\n        axis : {\n          x : {\n            type : 'timeseries',\n            tick : {\n              format : \"%Y-%m-%d\" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format\n            }\n          }\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/tooltip_grouped.html",
    "content": "<html>\n  <head>\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" type=\"text/css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart = c3.generate({\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ]\n        },\n        tooltip: {\n          grouped: false\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/tooltip_horizontal.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 80, 400, 500, 300, 80, 120, 30, 200, 100, 80, 400, 500, 300, 80],\n          ],\n        },\n        point: {\n          sensitivity: 300\n        },\n        tooltip: {\n          horizontal: true\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/tooltip_show.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 60]\n          ]\n        },\n        tooltip: {\n          init: {\n            show: true,\n            x: 2,\n            position: {\n              top: '145px',\n              left: '290px'\n            }\n          }\n        }\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/zoom.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <button onclick=\"load()\">Load</button>\n    <div id=\"chart2\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          columns: [\n            generateData(100)\n          ],\n        },\n        zoom: {\n          enabled: true,\n          initialRange: [30, 60],\n          onzoomstart: function (event) {\n            console.log(\"onzoomstart\", event);\n          },\n          onzoomend: function (domain) {\n            console.log(\"onzoomend\", domain);\n          },\n        },\n        subchart: { show: true }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            generateData(100)\n          ],\n        },\n        axis: {\n          x: {\n          }\n        },\n        zoom: {\n            enabled: true,\n            initialRange: [30, 60],\n        },\n      });\n\n      function load() {\n        chart1.load({\n          columns: [\n            generateData(Math.random() * 1000)\n          ],\n        });\n      }\n\n      function generateData(n) {\n        var column = ['sample'];\n        for (var i = 0; i < n; i++) {\n          column.push(Math.random() * 500);\n        }\n        return column;\n      }\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/zoom_category.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart\"></div>\n    <button onclick=\"load()\">Load</button>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart = c3.generate({\n        bindto: '#chart',\n        data: {\n          columns: [\n            generateData(100)\n          ],\n        },\n        axis: {\n          x: {\n            type: 'category'\n          }\n        },\n        zoom: { enabled: true },\n        subchart: { show: true }\n      });\n\n      function load() {\n        chart.load({\n          columns: [\n            generateData(Math.random() * 1000)\n          ],\n        });\n      }\n\n      function generateData(n) {\n        var column = ['sample'];\n        for (var i = 0; i < n; i++) {\n          column.push(Math.random() * 500);\n        }\n        return column;\n      }\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/zoom_onzoom.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <div id=\"chart1\"></div>\n    <div id=\"chart2\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n        bindto: '#chart1',\n        data: {\n          x : 'x',\n          columns: [\n            ['x', '2013-01-01', '2013-02-01', '2013-03-01', '2013-04-01', '2013-05-01'],\n            ['sample', 30, 200, 100, 400, 150],\n            ['sample2', 130, 300, 200, 450, 250]\n          ]\n        },\n        axis : {\n          x : {\n            type : 'timeseries',\n            tick : {\n              format : \"%Y-%m-%d\"\n            }\n          }\n        },\n        zoom: {\n          enabled: true,\n          onzoom: function (domain) {\n            console.log(this, domain);\n          }\n        }\n      });\n\n      var chart2 = c3.generate({\n        bindto: '#chart2',\n        data: {\n          columns: [\n            ['sample', 30, 200, 100, 400, 150],\n            ['sample2', 130, 300, 200, 450, 250]\n          ]\n        },\n        zoom: {\n          enabled: true,\n          onzoom: function (domain) {\n            console.log(this, domain);\n          }\n        }\n      });\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/zoom_reduction.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <title>c3ext</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <link rel=\"shortcut icon\" href=\"../images/logo_128.ico\" />\n    <link href=\"../css/c3.css\" rel=\"stylesheet\" />\n    <script src=\"https://code.jquery.com/jquery-2.0.3.min.js\"></script>\n    <script src=\"https://rawgithub.com/brandonaaron/jquery-mousewheel/master/jquery.mousewheel.min.js\"></script>\n    <script src=\"https://d3js.org/d3.v5.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script src=\"../js/extensions/c3ext.js\"></script>\n    <script src=\"../js/samples/zoom_reduction.js\"></script>\n</head>\n<body onload=\"main()\">\n    <div class=\"container-fluid\">\n        <h1>C3 DataSet Reduction by Zoom Level</h1>\n        <h2>Hackathon May 2014</h2>\n        <h4>By Dan-el Khen</h4>\n        <p>Rendering graphs in the browser has many advantages, the downside is that takes a long time to render when having large datasets. </p>\n        <p>This feature allows you reduces the dataset according to your current zoom level.\n        It allows the developer to implement the reduction algorithm in a simple function that accepts an array of values, and returns a reduced single value.\n        The default reducer will take the first item, but avg/sum/first/last or any other algorithm is simple to implement.\n        </p>\n        <h3>Example</h3>\n        <p>\n            In the following example, we'll render 10K data points, each time we'll reduce those to about 100 items (depending on available size on your screen),\n            when zooming in, the resolution of the data will be better and more accurate. This would help in showing the big picture, even when the amount of data is bigger than the numbers of pixels on the screen.\n        </p>\n        <p>Click on the buttons or scroll with your mouse wheel inside the graph to zoom and/or pan.</p>\n        <pre id=\"status\"></pre>\n        <div>\n            <button onclick=\"chart.zoom2.zoomIn()\">zoomIn</button>\n            <button onclick=\"chart.zoom2.zoomOut()\">zoomOut</button>\n            <button onclick=\"chart.zoom2.panLeft()\">panLeft</button>\n            <button onclick=\"chart.zoom2.panRight()\">panRight</button>\n            <button onclick=\"chart.zoom2.enhance()\">enhance</button>\n            <button onclick=\"chart.zoom2.dehance()\">dehance</button>\n            <button onclick=\"chart.zoom2.reset()\">reset</button>\n        </div>\n        <div id=\"divChart\" style=\"height:300px\"></div>\n        <h3>Notes</h3>\n        <p>Only 'columns' data format is supported for now.</p>\n    </div>\n</body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/zoom_type.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <p>Zoom Type Scroll with Default Zoom Behavior</p>\n    <div id=\"chart1\"></div>\n\n    <p>Zoom Type Drag with Default Zoom Behavior</p>\n    <div id=\"chart2\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n          bindto: '#chart1',\n          data: {\n              columns: [\n                  generateData(100)\n              ]\n          },\n          zoom: {\n              enabled: true,\n              type: 'scroll'\n          }\n      });\n\n      var chart2 = c3.generate({\n          bindto: '#chart2',\n          data: {\n              columns: [\n                  generateData(100)\n              ]\n          },\n          zoom: {\n              enabled: true,\n              type: 'drag'\n          }\n      });\n\n      function load() {\n        chart1.load({\n          columns: [\n            generateData(Math.random() * 1000)\n          ]\n        });\n      }\n\n      function generateData(n) {\n        var column = ['sample'];\n        for (var i = 0; i < n; i++) {\n          column.push(Math.random() * 500);\n        }\n        return column;\n      }\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "htdocs/samples/zoom_type_disable_default_behavior.html",
    "content": "<html>\n  <head>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/c3.css\">\n  </head>\n  <body>\n    <p>Zoom Type Scroll with Zoom Behavior Disabled (See the console)</p>\n    <div id=\"chart1\"></div>\n\n    <p>Zoom Type Drag with Zoom Behavior Disabled (See the console)</p>\n    <div id=\"chart2\"></div>\n\n    <script src=\"https://d3js.org/d3.v5.js\" charset=\"utf-8\"></script>\n    <script src=\"../js/c3.js\"></script>\n    <script>\n\n      var chart1 = c3.generate({\n          bindto: '#chart1',\n          data: {\n              columns: [\n                  generateData(100)\n              ]\n          },\n          zoom: {\n              enabled: true,\n              type: 'scroll',\n              disableDefaultBehavior: true,\n              onzoom: (d) => console.log(d),\n              onzoomend: (d) => console.log(d),\n          }\n      });\n\n      var chart2 = c3.generate({\n          bindto: '#chart2',\n          data: {\n              columns: [\n                  generateData(100)\n              ]\n          },\n          zoom: {\n              enabled: true,\n              type: 'drag',\n              disableDefaultBehavior: true,\n              onzoom: (d) => console.log(d),\n              onzoomend: (d) => console.log(d),\n          }\n      });\n\n      function load() {\n        chart1.load({\n          columns: [\n            generateData(Math.random() * 1000)\n          ]\n        });\n      }\n\n      function generateData(n) {\n        var column = ['sample'];\n        for (var i = 0; i < n; i++) {\n          column.push(Math.random() * 500);\n        }\n        return column;\n      }\n\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "karma.conf.js",
    "content": "const path = require('path')\n\nmodule.exports = config =>\n  config.set({\n    frameworks: ['jasmine', 'karma-typescript'],\n    files: ['htdocs/css/c3.css', 'src/**/*.ts', 'spec/**/*'],\n    preprocessors: {\n      'spec/**/*.ts': ['karma-typescript'],\n      'src/**/*.ts': ['karma-typescript']\n    },\n    karmaTypescriptConfig: {\n      coverageOptions: {\n        exclude: /spec/\n      },\n      reports: {\n        lcov: 'coverage'\n      }\n    },\n    reporters: ['spec', 'karma-typescript'],\n    browsers: ['Chrome'],\n    singleRun: true\n  })\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"c3\",\n  \"version\": \"0.7.20\",\n  \"description\": \"D3-based reusable chart library\",\n  \"main\": \"c3.js\",\n  \"files\": [\n    \"c3.js\",\n    \"c3.min.js\",\n    \"c3.esm.js\",\n    \"c3.css\",\n    \"c3.min.css\",\n    \"src\"\n  ],\n  \"scripts\": {\n    \"start\": \"run-p serve-static watch\",\n    \"serve-static\": \"static -p 8080 htdocs/\",\n    \"lint\": \"jshint --reporter=node_modules/jshint-stylish src/ spec/\",\n    \"type\": \"tsc --noEmit\",\n    \"fmt\": \"prettier --write rollup.config.js karma.conf.js \\\"src/**/*.ts\\\" \\\"spec/**/*.ts\\\" *.json\",\n    \"docs\": \"bundle exec middleman\",\n    \"build\": \"run-s build:js build:css\",\n    \"build:js\": \"run-s build:js:rollup build:js:uglify\",\n    \"build:js:rollup\": \"rollup -c\",\n    \"build:js:uglify\": \"uglifyjs htdocs/js/c3.js --compress --mangle --comments -o htdocs/js/c3.min.js\",\n    \"build:css\": \"run-s build:css:sass build:css:min\",\n    \"build:css:sass\": \"sass src/scss/main.scss > htdocs/css/c3.css\",\n    \"build:css:min\": \"cleancss -o htdocs/css/c3.min.css htdocs/css/c3.css\",\n    \"build:docs\": \"bundle exec middleman build\",\n    \"publish-docs\": \"npm run build:docs && gh-pages -d build -m \\\"chore: update gh-pages [skip ci]\\\"\",\n    \"watch\": \"nodemon -e js,scss --watch src -x npm run build:js:rollup && npm run build:css:sass\",\n    \"watch:js\": \"nodemon -e js --watch src --ignore src/scss -x 'npm run build:js:rollup'\",\n    \"watch:css\": \"nodemon -e scss --watch src -x 'npm run build:css:sass'\",\n    \"watch:docs\": \"bundle exec middleman\",\n    \"karma\": \"karma start karma.conf.js\",\n    \"test\": \"run-s build lint karma\",\n    \"dist\": \"run-s build copy-to-root copy-to-docs\",\n    \"copy-to-docs\": \"cp htdocs/js/c3.* docs/js/ && cp htdocs/css/c3.* docs/css/\",\n    \"copy-to-root\": \"cp htdocs/{css,js}/c3.* ./\",\n    \"codecov\": \"codecov\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/c3js/c3.git\"\n  },\n  \"keywords\": [\n    \"d3\",\n    \"chart\",\n    \"graph\"\n  ],\n  \"authors\": [\n    \"Masayuki Tanaka\",\n    \"Ændrew Rininsland\",\n    \"Yoshiya Hinosawa\"\n  ],\n  \"license\": \"MIT\",\n  \"gitHead\": \"84e03109d9a590f9c8ef687c03d751f666080c6f\",\n  \"readmeFilename\": \"README.md\",\n  \"dependencies\": {\n    \"d3\": \"^5.8.0\"\n  },\n  \"devDependencies\": {\n    \"@types/d3\": \"^5.7.2\",\n    \"@types/jasmine\": \"^3.5.10\",\n    \"clean-css-cli\": \"^4.1.11\",\n    \"codecov\": \"^3.0.4\",\n    \"gh-pages\": \"^5.0.0\",\n    \"jasmine-core\": \"^2.3.4\",\n    \"jshint\": \"^2.9.7\",\n    \"jshint-stylish\": \"^2.1.0\",\n    \"karma\": \"^6.3.14\",\n    \"karma-chrome-launcher\": \"^3.0.0\",\n    \"karma-jasmine\": \"^1.1.0\",\n    \"karma-spec-reporter\": \"^0.0.32\",\n    \"karma-typescript\": \"^5.0.3\",\n    \"node-static\": \"^0.7.9\",\n    \"nodemon\": \"^2.0.0\",\n    \"npm-run-all\": \"^4.1.3\",\n    \"prettier\": \"^1.19.1\",\n    \"rollup\": \"^2.79.2\",\n    \"rollup-plugin-typescript2\": \"^0.27.1\",\n    \"sass\": \"^1.10.3\",\n    \"status-back\": \"^1.1.0\",\n    \"typescript\": \"^3.9.5\",\n    \"uglify-js\": \"^3.6.4\",\n    \"watchify\": \"^3.11.1\"\n  },\n  \"nyc\": {\n    \"exclude\": [\n      \"src/polyfill.js\",\n      \"spec/\"\n    ]\n  }\n}\n"
  },
  {
    "path": "rollup.config.js",
    "content": "import typescript from 'rollup-plugin-typescript2'\nimport pkg from './package.json'\n\nexport default [\n  {\n    input: 'src/index.ts',\n    output: {\n      file: 'htdocs/js/c3.js',\n      name: 'c3',\n      format: 'umd',\n      banner: `/* @license C3.js v${pkg.version} | (c) C3 Team and other contributors | http://c3js.org/ */`,\n      globals: { d3: 'd3' }\n    },\n    plugins: [typescript()],\n    external: ['d3']\n  }\n]\n"
  },
  {
    "path": "spec/api.axis-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('c3 api axis', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('axis.labels', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100],\n            ['data2', 50, 20, 10]\n          ],\n          axes: {\n            data1: 'y',\n            data2: 'y2'\n          }\n        },\n        axis: {\n          y: {\n            label: 'Y Axis Label'\n          },\n          y2: {\n            show: true,\n            label: 'Y2 Axis Label'\n          }\n        }\n      }\n    })\n\n    it('updates y axis label', function() {\n      chart.axis.labels({ y: 'New Y Axis Label' })\n      var label = d3.select('.c3-axis-y-label')\n      expect(label.text()).toBe('New Y Axis Label')\n      expect(label.attr('dx')).toBe('-0.5em')\n      expect(label.attr('dy')).toBe('1.2em')\n    })\n\n    it('updates y axis label', function() {\n      chart.axis.labels({ y2: 'New Y2 Axis Label' })\n      var label = d3.select('.c3-axis-y2-label')\n      expect(label.text()).toBe('New Y2 Axis Label')\n      expect(label.attr('dx')).toBe('-0.5em')\n      expect(label.attr('dy')).toBe('-0.5em')\n    })\n\n    it('updates axis max values', function() {\n      chart.axis.max({ x: 100, y: 300, y2: 100 })\n      var max_values = chart.axis.max()\n      expect(max_values.x).toBe(100)\n      expect(max_values.y).toBe(300)\n      expect(max_values.y2).toBe(100)\n    })\n\n    it('updates axis min values', function() {\n      chart.axis.min({ x: 0, y: 20, y2: 50 })\n      var min_values = chart.axis.min()\n      expect(min_values.x).toBe(0)\n      expect(min_values.y).toBe(20)\n      expect(min_values.y2).toBe(50)\n    })\n\n    it('updates axis range', function() {\n      chart.axis.range({ min: 5, max: 250 })\n      var range = chart.axis.range()\n      expect(range.max.y).toBe(250)\n      expect(range.min.y).toBe(5)\n    })\n  })\n\n  describe('axis.types', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100],\n            ['data2', 30, 200, 100]\n          ],\n          axes: {\n            data1: 'y',\n            data2: 'y2'\n          }\n        },\n        axis: {\n          y: {\n            label: 'Y Axis Label'\n          },\n          y2: {\n            show: true,\n            type: 'log',\n            label: 'Y2 Axis Label'\n          }\n        }\n      }\n    })\n\n    it('retrieves y/y2 axis types', function() {\n      expect(chart.axis.types()).toEqual({\n        y: 'linear',\n        y2: 'log'\n      })\n\n      const linearDomain = chart.internal.y.domain()\n      const logDomain = chart.internal.y2.domain()\n\n      chart.axis.types({\n        y: 'log',\n        y2: 'linear'\n      })\n\n      expect(chart.internal.y2.domain()).toEqual(linearDomain)\n      expect(chart.internal.y.domain()).toEqual(logDomain)\n\n      expect(chart.axis.types()).toEqual({\n        y: 'log',\n        y2: 'linear'\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/api.data-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('c3 api data', function() {\n  'use strict'\n\n  var chart\n\n  var args: any = {\n    data: {\n      columns: [\n        ['data1', 30, 200, 100, 400, 150, 250],\n        ['data2', 5000, 2000, 1000, 4000, 1500, 2500]\n      ],\n      names: {\n        data1: 'Data Name 1',\n        data2: 'Data Name 2'\n      },\n      colors: {\n        data1: '#FF0000',\n        data2: '#00FF00'\n      },\n      axes: {\n        data1: 'y',\n        data2: 'y2'\n      }\n    },\n    axis: {\n      y2: {\n        show: true\n      }\n    }\n  }\n\n  beforeEach(function(done) {\n    jasmine.addMatchers(customMatchers as any)\n    chart = initChart(chart, args, done)\n  })\n\n  describe('data()', function() {\n    it('should return all of data if no argument given', function() {\n      var results = chart.data(),\n        expected = ['data1', 'data2']\n      results.forEach(function(result, i) {\n        expect(result.id).toBe(expected[i])\n      })\n    })\n\n    it('should return specified data if string argument given', function() {\n      var results = chart.data('data1')\n      expect(results.length).toBe(1)\n      expect(results[0].id).toBe('data1')\n    })\n\n    it('should return specified data if array argument given', function() {\n      var results = chart.data(['data1', 'data2'])\n      expect(results.length).toBe(2)\n      expect(results[0].id).toBe('data1')\n      expect(results[1].id).toBe('data2')\n    })\n  })\n\n  describe('data.shown()', function() {\n    it('should return only shown targets', function() {\n      var results\n      chart.hide('data1')\n      results = chart.data.shown()\n      expect(results.length).toBe(1)\n      expect(results[0].id).toBe('data2')\n    })\n  })\n\n  describe('data.values()', function() {\n    it('should return values for specified target', function() {\n      var values = chart.data.values('data1'),\n        expectedValues = [30, 200, 100, 400, 150, 250]\n      expect(values.length).toBe(6)\n      values.forEach(function(v, i) {\n        expect(v).toBe(expectedValues[i])\n      })\n    })\n\n    it('should return null when no args', function() {\n      var values = chart.data.values()\n      expect(values).toBeNull()\n    })\n  })\n\n  describe('data.names()', function() {\n    it('should return data.names specified as argument', function() {\n      var results = chart.data.names()\n      expect(results.data1).toBe('Data Name 1')\n      expect(results.data2).toBe('Data Name 2')\n    })\n\n    it('should return data.names specified as api', function() {\n      var results = chart.data.names({\n        data1: 'New Data Name 1',\n        data2: 'New Data Name 2'\n      })\n      expect(results.data1).toBe('New Data Name 1')\n      expect(results.data2).toBe('New Data Name 2')\n    })\n\n    it('should set data.names specified as api', function() {\n      expect(d3.select('.c3-legend-item-data1 text').text()).toBe(\n        'New Data Name 1'\n      )\n      expect(d3.select('.c3-legend-item-data2 text').text()).toBe(\n        'New Data Name 2'\n      )\n    })\n  })\n\n  describe('data.colors()', function() {\n    it('should return data.colors specified as argument', function() {\n      var results = chart.data.colors()\n      ;(expect(results.data1) as any).toBeHexOrRGB('#FF0000')\n      ;(expect(results.data2) as any).toBeHexOrRGB('#00FF00')\n    })\n\n    it('should return data.colors specified as api', function() {\n      var results = chart.data.colors({\n        data1: '#00FF00',\n        data2: '#FF0000'\n      })\n      ;(expect(results.data1) as any).toBeHexOrRGB('#00FF00')\n      ;(expect(results.data2) as any).toBeHexOrRGB('#FF0000')\n    })\n\n    it('should set data.colors specified as api', function() {\n      ;(expect(\n        d3.select('.c3-line-data1').style('stroke')\n      ) as any).toBeHexOrRGB('#00ff00')\n      ;(expect(\n        d3.select('.c3-line-data2').style('stroke')\n      ) as any).toBeHexOrRGB('#ff0000')\n      ;(expect(\n        d3.select('.c3-legend-item-data1 .c3-legend-item-tile').style('stroke')\n      ) as any).toBeHexOrRGB('#00ff00')\n      ;(expect(\n        d3.select('.c3-legend-item-data2 .c3-legend-item-tile').style('stroke')\n      ) as any).toBeHexOrRGB('#ff0000')\n    })\n  })\n\n  describe('data.axes()', function() {\n    it('should return data.axes specified as argument', function() {\n      var results = chart.data.axes()\n      expect(results.data1).toBe('y')\n      expect(results.data2).toBe('y2')\n      expect(d3.select('.c3-axis-y g.tick text').text()).toBe('0')\n      expect(d3.select('.c3-axis-y2 g.tick text').text()).toBe('1000')\n    })\n\n    it('should return data.axes specified as api', function() {\n      var results = chart.data.axes({\n        data1: 'y2',\n        data2: 'y'\n      })\n      expect(results.data1).toBe('y2')\n      expect(results.data2).toBe('y')\n      expect(d3.select('.c3-axis-y g.tick text').text()).toBe('1000')\n      expect(d3.select('.c3-axis-y2 g.tick text').text()).toBe('0')\n    })\n  })\n\n  describe('data.stackNormalized()', function() {\n    beforeEach(function(done) {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 500, 850, 1000, 200, 350, 100]\n          ],\n          groups: [['data1', 'data2']],\n          stack: {\n            normalize: true\n          }\n        }\n      }\n\n      chart = initChart(chart, args, done)\n    })\n\n    it('can toggle option', function(done) {\n      expect(chart.data.stackNormalized()).toBe(true)\n      expect(chart.internal.y.domain()).toEqual([0, 100])\n\n      chart.data.stackNormalized(false)\n\n      setTimeout(function() {\n        expect(chart.data.stackNormalized()).toBe(false)\n        expect(chart.internal.y.domain()).toEqual([0, 1200])\n        done()\n      }, 100)\n    })\n  })\n})\n\ndescribe('c3 api data.x', function() {\n  'use strict'\n\n  var chart\n\n  var args = {\n    data: {\n      x: 'x',\n      columns: [\n        ['x', 10, 30, 45, 50, 70, 100],\n        ['data1', 30, 200, 100, 400, 150, 250],\n        ['data2', 20, 180, 240, 100, 190]\n      ]\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  it('should return values for target data1', function() {\n    var values = chart.data.values('data1'),\n      expectedValues = [30, 200, 100, 400, 150, 250]\n    expect(values.length).toBe(6)\n    values.forEach(function(v, i) {\n      expect(v).toBe(expectedValues[i])\n    })\n  })\n\n  it('should return null when no args', function() {\n    var values = chart.data.values()\n    expect(values).toBeNull()\n  })\n\n  it('should return data values for  data if string argument given', function() {\n    var results = chart.data('data1')\n    expect(results.length).toBe(1)\n    expect(results[0].id).toBe('data1')\n  })\n\n  it('should return specified data if array argument given', function() {\n    var results = chart.data(['data1', 'data2'])\n    expect(results.length).toBe(2)\n    expect(results[0].id).toBe('data1')\n    expect(results[1].id).toBe('data2')\n  })\n})\n\ndescribe('c3 api data.xs', function() {\n  'use strict'\n\n  var chart\n\n  var args = {\n    data: {\n      xs: {\n        data1: 'x1',\n        data2: 'x2'\n      },\n      columns: [\n        ['x1', 10, 30, 45, 50, 70, 100],\n        ['x2', 30, 50, 75, 100, 120],\n        ['data1', 30, 200, 100, 400, 150, 250],\n        ['data2', 20, 180, 240, 100, 190]\n      ]\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  it('should return values for target data1', function() {\n    var values = chart.data.values('data1'),\n      expectedValues = [30, 200, 100, 400, 150, 250]\n    expect(values.length).toBe(6)\n    values.forEach(function(v, i) {\n      expect(v).toBe(expectedValues[i])\n    })\n  })\n\n  it('should return null when no args', function() {\n    var values = chart.data.values()\n    expect(values).toBeNull()\n  })\n\n  it('should return data values for  data if string argument given', function() {\n    var results = chart.data('data1')\n    expect(results.length).toBe(1)\n    expect(results[0].id).toBe('data1')\n  })\n\n  it('should return specified data if array argument given', function() {\n    var results = chart.data(['data1', 'data2'])\n    expect(results.length).toBe(2)\n    expect(results[0].id).toBe('data1')\n    expect(results[1].id).toBe('data2')\n  })\n})\n\nvar customMatchers = {\n  toBeHexOrRGB: function(util, customEqualityTesters) {\n    'use strict'\n\n    function rgb2hex(rgb) {\n      rgb = rgb.match(\n        /^rgba?[\\s+]?\\([\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?,[\\s+]?(\\d+)[\\s+]?/i\n      )\n      return rgb && rgb.length === 4\n        ? '#' +\n            ('0' + parseInt(rgb[1], 10).toString(16)).slice(-2) +\n            ('0' + parseInt(rgb[2], 10).toString(16)).slice(-2) +\n            ('0' + parseInt(rgb[3], 10).toString(16)).slice(-2)\n        : ''\n    }\n\n    return {\n      compare: function(actual, expected) {\n        if (expected === undefined) {\n          expected = ''\n        }\n\n        var result: any = {}\n        actual = actual.match('rgb') ? rgb2hex(actual) : actual\n        expected = expected.match('rgb') ? rgb2hex(expected) : expected\n\n        result.pass = util.equals(actual, expected, customEqualityTesters)\n        if (result.pass) {\n          result.message = 'Expected ' + actual + ' not to be quite so goofy'\n        } else {\n          result.message =\n            'Expected ' + actual + ' to be goofy, but it was not very goofy'\n        }\n\n        return result\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "spec/api.donut-spec.ts",
    "content": "import { initChart } from './c3-helper'\n\ndescribe('c3 api donut', function() {\n  'use strict'\n\n  var chart, args\n\n  args = {\n    data: {\n      columns: [\n        ['data1', 60],\n        ['data2', 40]\n      ],\n      type: 'donut'\n    },\n    donut: {\n      padAngle: 0.5\n    }\n  }\n\n  beforeAll(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  it('can configure padAngle', function(done) {\n    expect(chart.donut.padAngle()).toBe(0.5)\n\n    const path = chart.internal.main.select('.c3-arc-data1').attr('d')\n\n    chart.donut.padAngle(0.2)\n\n    setTimeout(function() {\n      expect(chart.donut.padAngle()).toBe(0.2)\n      expect(chart.internal.main.select('.c3-arc-data1').attr('d')).not.toBe(\n        path\n      )\n      done()\n    }, 500)\n  })\n})\n"
  },
  {
    "path": "spec/api.focus-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('c3 api focus', function() {\n  'use strict'\n\n  var chart\n\n  var args: any = {\n    data: {\n      columns: [\n        ['data1', 30, 200, 100, 400],\n        ['data2', 1000, 800, 500, 2000],\n        ['data3', 5000, 2000, 1000, 4000]\n      ]\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('focus', function() {\n    it('should focus all targets', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.focus()\n      setTimeout(function() {\n        var targets = main.select('.c3-chart-line.c3-target'),\n          legendItems = legend.select('.c3-legend-item')\n        targets.each(function() {\n          var line = d3.select(this)\n          expect(line.classed('c3-focused')).toBeTruthy()\n        })\n        legendItems.each(function() {\n          var item = d3.select(this)\n          expect(item.classed('c3-legend-item-focused')).toBeTruthy()\n        })\n        done()\n      }, 1000)\n    })\n\n    it('should focus one target', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.focus('data2')\n      setTimeout(function() {\n        var targets = {\n            data1: main.select('.c3-chart-line.c3-target.c3-target-data1'),\n            data2: main.select('.c3-chart-line.c3-target.c3-target-data2'),\n            data3: main.select('.c3-chart-line.c3-target.c3-target-data3')\n          },\n          legendItems = {\n            data1: legend.select('.c3-legend-item-data1'),\n            data2: legend.select('.c3-legend-item-data2'),\n            data3: legend.select('.c3-legend-item-data3')\n          }\n        expect(targets.data1.classed('c3-focused')).toBeFalsy()\n        expect(targets.data2.classed('c3-focused')).toBeTruthy()\n        expect(targets.data3.classed('c3-focused')).toBeFalsy()\n        expect(legendItems.data1.classed('c3-legend-item-focused')).toBeFalsy()\n        expect(legendItems.data2.classed('c3-legend-item-focused')).toBeTruthy()\n        expect(legendItems.data3.classed('c3-legend-item-focused')).toBeFalsy()\n        done()\n      }, 1000)\n    })\n\n    it('should focus multiple targets', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.focus(['data1', 'data2'])\n      setTimeout(function() {\n        var targets = {\n            data1: main.select('.c3-chart-line.c3-target.c3-target-data1'),\n            data2: main.select('.c3-chart-line.c3-target.c3-target-data2'),\n            data3: main.select('.c3-chart-line.c3-target.c3-target-data3')\n          },\n          legendItems = {\n            data1: legend.select('.c3-legend-item-data1'),\n            data2: legend.select('.c3-legend-item-data2'),\n            data3: legend.select('.c3-legend-item-data3')\n          }\n        expect(targets.data1.classed('c3-focused')).toBeTruthy()\n        expect(targets.data2.classed('c3-focused')).toBeTruthy()\n        expect(targets.data3.classed('c3-focused')).toBeFalsy()\n        expect(legendItems.data1.classed('c3-legend-item-focused')).toBeTruthy()\n        expect(legendItems.data2.classed('c3-legend-item-focused')).toBeTruthy()\n        expect(legendItems.data3.classed('c3-legend-item-focused')).toBeFalsy()\n        done()\n      }, 1000)\n    })\n  })\n\n  describe('defocus', function() {\n    it('should defocus all targets', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.defocus()\n      setTimeout(function() {\n        var targets = main.select('.c3-chart-line.c3-target'),\n          legendItems = legend.select('.c3-legend-item')\n        targets.each(function() {\n          var line = d3.select(this)\n          expect(line.classed('c3-focused')).toBeFalsy()\n          expect(line.classed('c3-defocused')).toBeTruthy()\n        })\n        legendItems.each(function() {\n          var item = d3.select(this)\n          expect(item.classed('c3-legend-item-focused')).toBeFalsy()\n          expect(+item.style('opacity')).toBeCloseTo(0.3)\n        })\n        done()\n      }, 1000)\n    })\n\n    it('should defocus one target', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.defocus('data2')\n      setTimeout(function() {\n        var targets = {\n            data1: main.select('.c3-chart-line.c3-target.c3-target-data1'),\n            data2: main.select('.c3-chart-line.c3-target.c3-target-data2'),\n            data3: main.select('.c3-chart-line.c3-target.c3-target-data3')\n          },\n          legendItems = {\n            data1: legend.select('.c3-legend-item-data1'),\n            data2: legend.select('.c3-legend-item-data2'),\n            data3: legend.select('.c3-legend-item-data3')\n          }\n        expect(targets.data1.classed('c3-defocused')).toBeFalsy()\n        expect(targets.data2.classed('c3-defocused')).toBeTruthy()\n        expect(targets.data3.classed('c3-defocused')).toBeFalsy()\n        expect(legendItems.data1.classed('c3-legend-item-focused')).toBeFalsy()\n        expect(legendItems.data2.classed('c3-legend-item-focused')).toBeFalsy()\n        expect(legendItems.data3.classed('c3-legend-item-focused')).toBeFalsy()\n        expect(+legendItems.data1.style('opacity')).toBeCloseTo(1)\n        expect(+legendItems.data2.style('opacity')).toBeCloseTo(0.3)\n        expect(+legendItems.data3.style('opacity')).toBeCloseTo(1)\n        done()\n      }, 1000)\n    })\n\n    it('should defocus multiple targets', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.defocus(['data1', 'data2'])\n      setTimeout(function() {\n        var targets = {\n            data1: main.select('.c3-chart-line.c3-target.c3-target-data1'),\n            data2: main.select('.c3-chart-line.c3-target.c3-target-data2'),\n            data3: main.select('.c3-chart-line.c3-target.c3-target-data3')\n          },\n          legendItems = {\n            data1: legend.select('.c3-legend-item-data1'),\n            data2: legend.select('.c3-legend-item-data2'),\n            data3: legend.select('.c3-legend-item-data3')\n          }\n        expect(targets.data1.classed('c3-defocused')).toBeTruthy()\n        expect(targets.data2.classed('c3-defocused')).toBeTruthy()\n        expect(targets.data3.classed('c3-defocused')).toBeFalsy()\n        expect(legendItems.data1.classed('c3-legend-item-focused')).toBeFalsy()\n        expect(legendItems.data2.classed('c3-legend-item-focused')).toBeFalsy()\n        expect(legendItems.data3.classed('c3-legend-item-focused')).toBeFalsy()\n        expect(+legendItems.data1.style('opacity')).toBeCloseTo(0.3)\n        expect(+legendItems.data2.style('opacity')).toBeCloseTo(0.3)\n        expect(+legendItems.data3.style('opacity')).toBeCloseTo(1)\n        done()\n      }, 1000)\n    })\n\n    it('should defocus multiple targets after focused', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.focus()\n      setTimeout(function() {\n        chart.defocus(['data1', 'data2'])\n        setTimeout(function() {\n          var targets = {\n              data1: main.select('.c3-chart-line.c3-target.c3-target-data1'),\n              data2: main.select('.c3-chart-line.c3-target.c3-target-data2'),\n              data3: main.select('.c3-chart-line.c3-target.c3-target-data3')\n            },\n            legendItems = {\n              data1: legend.select('.c3-legend-item-data1'),\n              data2: legend.select('.c3-legend-item-data2'),\n              data3: legend.select('.c3-legend-item-data3')\n            }\n          expect(targets.data1.classed('c3-defocused')).toBeTruthy()\n          expect(targets.data2.classed('c3-defocused')).toBeTruthy()\n          expect(targets.data3.classed('c3-defocused')).toBeFalsy()\n          expect(\n            legendItems.data1.classed('c3-legend-item-focused')\n          ).toBeFalsy()\n          expect(\n            legendItems.data2.classed('c3-legend-item-focused')\n          ).toBeFalsy()\n          expect(\n            legendItems.data3.classed('c3-legend-item-focused')\n          ).toBeTruthy()\n          expect(+legendItems.data1.style('opacity')).toBeCloseTo(0.3)\n          expect(+legendItems.data2.style('opacity')).toBeCloseTo(0.3)\n          expect(+legendItems.data3.style('opacity')).toBeCloseTo(1)\n          done()\n        }, 1000)\n      }, 1000)\n    })\n  })\n\n  describe('revert', function() {\n    it('should revert all targets after focus', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.focus()\n      setTimeout(function() {\n        chart.revert()\n        setTimeout(function() {\n          var targets = main.select('.c3-chart-line.c3-target'),\n            legendItems = legend.select('.c3-legend-item')\n          targets.each(function() {\n            var line = d3.select(this)\n            expect(line.classed('c3-focused')).toBeFalsy()\n          })\n          legendItems.each(function() {\n            var item = d3.select(this)\n            expect(item.classed('c3-legend-item-focused')).toBeFalsy()\n            expect(+item.style('opacity')).toBeCloseTo(1)\n          })\n          done()\n        }, 1000)\n      }, 1000)\n    })\n\n    it('should revert all targets after defocus', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.defocus()\n      setTimeout(function() {\n        chart.revert()\n        setTimeout(function() {\n          var targets = main.select('.c3-chart-line.c3-target'),\n            legendItems = legend.select('.c3-legend-item')\n          targets.each(function() {\n            var line = d3.select(this)\n            expect(line.classed('c3-defocused')).toBeFalsy()\n          })\n          legendItems.each(function() {\n            var item = d3.select(this)\n            expect(item.classed('c3-legend-item-focused')).toBeFalsy()\n            expect(+item.style('opacity')).toBeCloseTo(1)\n          })\n          done()\n        }, 1000)\n      }, 1000)\n    })\n\n    it('should revert one target after focus', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.focus()\n      setTimeout(function() {\n        chart.revert('data2')\n        setTimeout(function() {\n          var targets = {\n              data1: main.select('.c3-chart-line.c3-target.c3-target-data1'),\n              data2: main.select('.c3-chart-line.c3-target.c3-target-data2'),\n              data3: main.select('.c3-chart-line.c3-target.c3-target-data3')\n            },\n            legendItems = {\n              data1: legend.select('.c3-legend-item-data1'),\n              data2: legend.select('.c3-legend-item-data2'),\n              data3: legend.select('.c3-legend-item-data3')\n            }\n          expect(targets.data1.classed('c3-focused')).toBeTruthy()\n          expect(targets.data2.classed('c3-focused')).toBeFalsy()\n          expect(targets.data3.classed('c3-focused')).toBeTruthy()\n          expect(+legendItems.data1.style('opacity')).toBeCloseTo(1)\n          expect(+legendItems.data2.style('opacity')).toBeCloseTo(1)\n          expect(+legendItems.data3.style('opacity')).toBeCloseTo(1)\n          expect(\n            legendItems.data1.classed('c3-legend-item-focused')\n          ).toBeTruthy()\n          expect(\n            legendItems.data2.classed('c3-legend-item-focused')\n          ).toBeFalsy()\n          expect(\n            legendItems.data3.classed('c3-legend-item-focused')\n          ).toBeTruthy()\n          done()\n        }, 1000)\n      }, 1000)\n    })\n\n    it('should revert one target after defocus', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.defocus()\n      setTimeout(function() {\n        chart.revert('data2')\n        setTimeout(function() {\n          var targets = {\n              data1: main.select('.c3-chart-line.c3-target.c3-target-data1'),\n              data2: main.select('.c3-chart-line.c3-target.c3-target-data2'),\n              data3: main.select('.c3-chart-line.c3-target.c3-target-data3')\n            },\n            legendItems = {\n              data1: legend.select('.c3-legend-item-data1'),\n              data2: legend.select('.c3-legend-item-data2'),\n              data3: legend.select('.c3-legend-item-data3')\n            }\n          expect(targets.data1.classed('c3-defocused')).toBeTruthy()\n          expect(targets.data2.classed('c3-defocused')).toBeFalsy()\n          expect(targets.data3.classed('c3-defocused')).toBeTruthy()\n          expect(+legendItems.data1.style('opacity')).toBeCloseTo(0.3)\n          expect(+legendItems.data2.style('opacity')).toBeCloseTo(1)\n          expect(+legendItems.data3.style('opacity')).toBeCloseTo(0.3)\n          expect(\n            legendItems.data1.classed('c3-legend-item-focused')\n          ).toBeFalsy()\n          expect(\n            legendItems.data2.classed('c3-legend-item-focused')\n          ).toBeFalsy()\n          expect(\n            legendItems.data3.classed('c3-legend-item-focused')\n          ).toBeFalsy()\n          done()\n        }, 1000)\n      }, 1000)\n    })\n\n    it('should focus multiple targets after focus', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.focus()\n      setTimeout(function() {\n        chart.revert(['data1', 'data2'])\n        setTimeout(function() {\n          var targets = {\n              data1: main.select('.c3-chart-line.c3-target.c3-target-data1'),\n              data2: main.select('.c3-chart-line.c3-target.c3-target-data2'),\n              data3: main.select('.c3-chart-line.c3-target.c3-target-data3')\n            },\n            legendItems = {\n              data1: legend.select('.c3-legend-item-data1'),\n              data2: legend.select('.c3-legend-item-data2'),\n              data3: legend.select('.c3-legend-item-data3')\n            }\n          expect(targets.data1.classed('c3-focused')).toBeFalsy()\n          expect(targets.data2.classed('c3-focused')).toBeFalsy()\n          expect(targets.data3.classed('c3-focused')).toBeTruthy()\n          expect(+legendItems.data1.style('opacity')).toBeCloseTo(1)\n          expect(+legendItems.data2.style('opacity')).toBeCloseTo(1)\n          expect(+legendItems.data3.style('opacity')).toBeCloseTo(1)\n          expect(\n            legendItems.data1.classed('c3-legend-item-focused')\n          ).toBeFalsy()\n          expect(\n            legendItems.data2.classed('c3-legend-item-focused')\n          ).toBeFalsy()\n          expect(\n            legendItems.data3.classed('c3-legend-item-focused')\n          ).toBeTruthy()\n          done()\n        }, 1000)\n      }, 1000)\n    })\n\n    it('should focus multiple targets after defocus', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.defocus()\n      setTimeout(function() {\n        chart.revert(['data1', 'data2'])\n        setTimeout(function() {\n          var targets = {\n              data1: main.select('.c3-chart-line.c3-target.c3-target-data1'),\n              data2: main.select('.c3-chart-line.c3-target.c3-target-data2'),\n              data3: main.select('.c3-chart-line.c3-target.c3-target-data3')\n            },\n            legendItems = {\n              data1: legend.select('.c3-legend-item-data1'),\n              data2: legend.select('.c3-legend-item-data2'),\n              data3: legend.select('.c3-legend-item-data3')\n            }\n          expect(targets.data1.classed('c3-defocused')).toBeFalsy()\n          expect(targets.data2.classed('c3-defocused')).toBeFalsy()\n          expect(targets.data3.classed('c3-defocused')).toBeTruthy()\n          expect(+legendItems.data1.style('opacity')).toBeCloseTo(1)\n          expect(+legendItems.data2.style('opacity')).toBeCloseTo(1)\n          expect(+legendItems.data3.style('opacity')).toBeCloseTo(0.3)\n          expect(\n            legendItems.data1.classed('c3-legend-item-focused')\n          ).toBeFalsy()\n          expect(\n            legendItems.data2.classed('c3-legend-item-focused')\n          ).toBeFalsy()\n          expect(\n            legendItems.data3.classed('c3-legend-item-focused')\n          ).toBeFalsy()\n          done()\n        }, 1000)\n      }, 1000)\n    })\n  })\n\n  describe('when legend.show = false', function() {\n    beforeAll(function() {\n      args.legend = {\n        show: false\n      }\n    })\n\n    it('should focus all targets without showing legend', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.focus()\n      setTimeout(function() {\n        var targets = main.select('.c3-chart-line.c3-target'),\n          legendItems = legend.select('.c3-legend-item')\n        targets.each(function() {\n          var line = d3.select(this)\n          expect(line.classed('c3-focused')).toBeTruthy()\n        })\n        expect(legendItems.size()).toBeCloseTo(0)\n        done()\n      }, 1000)\n    })\n\n    it('should defocus all targets without showing legend', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.defocus()\n      setTimeout(function() {\n        var targets = main.select('.c3-chart-line.c3-target'),\n          legendItems = legend.select('.c3-legend-item')\n        targets.each(function() {\n          var line = d3.select(this)\n          expect(line.classed('c3-defocused')).toBeTruthy()\n        })\n        expect(legendItems.size()).toBeCloseTo(0)\n        done()\n      }, 1000)\n    })\n\n    it('should revert all targets after focus', function(done) {\n      var main = chart.internal.main,\n        legend = chart.internal.legend\n      chart.focus()\n      setTimeout(function() {\n        chart.revert()\n        setTimeout(function() {\n          var targets = main.select('.c3-chart-line.c3-target'),\n            legendItems = legend.select('.c3-legend-item')\n          targets.each(function() {\n            var line = d3.select(this)\n            expect(line.classed('c3-focused')).toBeFalsy()\n          })\n          expect(legendItems.size()).toBeCloseTo(0)\n          done()\n        }, 1000)\n      }, 1000)\n    })\n  })\n})\n"
  },
  {
    "path": "spec/api.grid-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('c3 api grid', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('ygrid.add and ygrid.remove', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [['data1', 30, 200, 100, 400, 150, 250]]\n        }\n      }\n    })\n\n    it('updates y grids', function(done) {\n      var main = chart.internal.main,\n        expectedGrids = [\n          {\n            value: 100,\n            text: 'Pressure Low'\n          },\n          {\n            value: 200,\n            text: 'Pressure High'\n          }\n        ],\n        grids\n\n      // Call ygrids.add\n      chart.ygrids.add(expectedGrids)\n      setTimeout(function() {\n        grids = main.selectAll('.c3-ygrid-line')\n        expect(grids.size()).toBe(expectedGrids.length)\n        grids.each(function(d, i) {\n          var y = +d3\n              .select(this)\n              .select('line')\n              .attr('y1'),\n            text = d3\n              .select(this)\n              .select('text')\n              .text(),\n            expectedY = Math.round(chart.internal.y(expectedGrids[i].value)),\n            expectedText = expectedGrids[i].text\n          expect(y).toBe(expectedY)\n          expect(text).toBe(expectedText)\n        })\n\n        // Call ygrids.remove\n        chart.ygrids.remove(expectedGrids)\n        setTimeout(function() {\n          grids = main.selectAll('.c3-ygrid-line')\n          expect(grids.size()).toBe(0)\n        }, 500)\n      }, 500)\n\n      setTimeout(function() {\n        done()\n      }, 1200)\n    })\n\n    it('updates x ygrids even if zoomed', function(done) {\n      var main = chart.internal.main,\n        expectedGrids = [\n          {\n            value: 0,\n            text: 'Pressure Low'\n          },\n          {\n            value: 1,\n            text: 'Pressure High'\n          }\n        ],\n        grids,\n        domain\n\n      chart.zoom([0, 2])\n      setTimeout(function() {\n        // Call xgrids\n        chart.xgrids(expectedGrids)\n        setTimeout(function() {\n          grids = main.selectAll('.c3-xgrid-line')\n          expect(grids.size()).toBe(expectedGrids.length)\n          grids.each(function(d, i) {\n            var x = +d3\n                .select(this)\n                .select('line')\n                .attr('x1'),\n              text = d3\n                .select(this)\n                .select('text')\n                .text(),\n              expectedX = Math.round(chart.internal.x(expectedGrids[i].value)),\n              expectedText = expectedGrids[i].text\n            expect(x).toBe(expectedX)\n            expect(text).toBe(expectedText)\n          })\n\n          // check if it was not rescaled\n          domain = chart.internal.y.domain()\n          expect(domain[0]).toBeLessThan(0)\n          expect(domain[1]).toBeGreaterThan(400)\n\n          // Call xgrids.remove\n          chart.xgrids.remove(expectedGrids)\n          setTimeout(function() {\n            grids = main.selectAll('.c3-xgrid-line')\n            expect(grids.size()).toBe(0)\n          }, 500) // for xgrids.remove()\n        }, 500) // for xgrids()\n      }, 500) // for zoom\n\n      setTimeout(function() {\n        done()\n      }, 1700)\n    })\n  })\n})\n"
  },
  {
    "path": "spec/api.load-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('c3 api load', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('indexed data', function() {\n    describe('as column', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, 200, 100, 400, 150, 250],\n              ['data2', 5000, 2000, 1000, 4000, 1500, 2500]\n            ]\n          }\n        }\n      })\n\n      it('should load additional data', function(done) {\n        var main = chart.internal.main,\n          legend = chart.internal.legend\n        chart.load({\n          columns: [['data3', 800, 500, 900, 500, 1000, 700]]\n        })\n        setTimeout(function() {\n          var target = main.select('.c3-chart-line.c3-target.c3-target-data3'),\n            legendItem = legend.select('.c3-legend-item.c3-legend-item-data3')\n          expect(target.size()).toBe(1)\n          expect(legendItem.size()).toBe(1)\n          done()\n        }, 500)\n      })\n    })\n  })\n\n  describe('category data', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          x: 'x',\n          columns: [\n            ['x', 'cat1', 'cat2', 'cat3', 'cat4', 'cat5', 'cat6'],\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 5000, 2000, 1000, 4000, 1500, 2500]\n          ]\n        },\n        axis: {\n          x: {\n            type: 'category'\n          }\n        }\n      }\n    })\n\n    describe('as column', function() {\n      it('should load additional data', function(done) {\n        var main = chart.internal.main,\n          legend = chart.internal.legend\n        chart.load({\n          columns: [['data3', 800, 500, 900, 500, 1000, 700]]\n        })\n        setTimeout(function() {\n          var target = main.select('.c3-chart-line.c3-target.c3-target-data3'),\n            legendItem = legend.select('.c3-legend-item.c3-legend-item-data3'),\n            tickTexts = main.selectAll('.c3-axis-x g.tick text'),\n            expected = ['cat1', 'cat2', 'cat3', 'cat4', 'cat5', 'cat6']\n          expect(target.size()).toBe(1)\n          expect(legendItem.size()).toBe(1)\n          tickTexts.each(function(d, i) {\n            var text = d3\n              .select(this)\n              .select('tspan')\n              .text()\n            expect(text).toBe(expected[i])\n          })\n          done()\n        }, 500)\n      })\n\n      it('should load additional data', function(done) {\n        var main = chart.internal.main,\n          legend = chart.internal.legend\n        chart.load({\n          columns: [\n            ['x', 'new1', 'new2', 'new3', 'new4', 'new5', 'new6'],\n            ['data3', 800, 500, 900, 500, 1000, 700]\n          ]\n        })\n        setTimeout(function() {\n          var target = main.select('.c3-chart-line.c3-target.c3-target-data3'),\n            legendItem = legend.select('.c3-legend-item.c3-legend-item-data3'),\n            tickTexts = main.selectAll('.c3-axis-x g.tick text'),\n            expected = ['new1', 'new2', 'new3', 'new4', 'new5', 'new6']\n          expect(target.size()).toBe(1)\n          expect(legendItem.size()).toBe(1)\n          tickTexts.each(function(d, i) {\n            var text = d3\n              .select(this)\n              .select('tspan')\n              .text()\n            expect(text).toBe(expected[i])\n          })\n          done()\n        }, 500)\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/api.pie-spec.ts",
    "content": "import { initChart } from './c3-helper'\n\ndescribe('c3 api pie', function() {\n  'use strict'\n\n  var chart, args\n\n  args = {\n    data: {\n      columns: [\n        ['data1', 60],\n        ['data2', 40]\n      ],\n      type: 'pie'\n    },\n    pie: {\n      padAngle: 0.5\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('padAngle', function() {\n    it('can configure padAngle', function(done) {\n      expect(chart.pie.padAngle()).toBe(0.5)\n\n      const path = chart.internal.main.select('.c3-arc-data1').attr('d')\n\n      chart.pie.padAngle(0.2)\n\n      setTimeout(function() {\n        expect(chart.pie.padAngle()).toBe(0.2)\n        expect(chart.internal.main.select('.c3-arc-data1').attr('d')).not.toBe(\n          path\n        )\n        done()\n      }, 500)\n    })\n  })\n\n  describe('load data', function() {\n    beforeAll(() => {\n      args = {\n        data: {\n          columns: ['r', 'l', 'd'],\n          type: 'pie',\n          colors: {\n            r: 'red',\n            l: 'green',\n            d: 'blue'\n          }\n        }\n      }\n    })\n\n    it('can add data point to existing data', () => {\n      chart.load({\n        columns: [\n          ['r', 75],\n          ['l', 20],\n          ['d', 5]\n        ]\n      })\n\n      expect(chart.internal.getTotalDataSum()).toEqual(100)\n      expect(chart.internal.main.selectAll('.c3-arc').size()).toEqual(3)\n    })\n  })\n})\n"
  },
  {
    "path": "spec/api.region-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('c3 api region', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('api.region', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [['data1', 30, 200, 100, 400, 150, 250]]\n        },\n        regions: [\n          {\n            axis: 'y',\n            start: 300,\n            end: 400,\n            class: 'green',\n            label: 'Region 1'\n          },\n          {\n            axis: 'y',\n            start: 0,\n            end: 100,\n            class: 'green'\n          }\n        ]\n      }\n    })\n\n    it('updates regions', function(done) {\n      var main = chart.internal.main,\n        expectedRegions = [\n          {\n            axis: 'y',\n            start: 250,\n            end: 350,\n            class: 'red',\n            label: 'Region 1'\n          },\n          {\n            axis: 'y',\n            start: 25,\n            end: 75,\n            class: 'red',\n            label: ''\n          }\n        ],\n        regions\n\n      // Call regions API\n      chart.regions(expectedRegions)\n      setTimeout(function() {\n        regions = main.selectAll('.c3-region')\n        expect(regions.size()).toBe(expectedRegions.length)\n\n        regions.each(function(d, i) {\n          var region = d3.select(this),\n            label = region.select('text'),\n            y = +region.attr('y'),\n            height = +region.attr('height'),\n            expectedClass = 'red',\n            expectedLabel = expectedRegions[i].label,\n            unexpectedClass = 'green',\n            expectedStart = Math.round(\n              chart.internal.y(expectedRegions[i].start)\n            ),\n            expectedEnd = Math.round(chart.internal.y(expectedRegions[i].end)),\n            expectedY = expectedEnd,\n            expectedHeight = expectedStart - expectedEnd\n\n          expect(y).toBeCloseTo(expectedY, -1)\n          expect(height).toBeCloseTo(expectedHeight, -1)\n          expect(region.classed(expectedClass)).toBeTruthy()\n          expect(region.classed(unexpectedClass)).toBeFalsy()\n          expect(label.text()).toBe(expectedLabel)\n        })\n      }, 500)\n\n      setTimeout(function() {\n        done()\n      }, 1000)\n    })\n  })\n\n  describe('api.region.add', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [['data1', 30, 200, 100, 400, 150, 250]]\n        },\n        regions: [\n          {\n            axis: 'y',\n            start: 300,\n            end: 400,\n            class: 'green'\n          },\n          {\n            axis: 'y',\n            start: 0,\n            end: 100,\n            class: 'green'\n          }\n        ]\n      }\n    })\n\n    it('should add regions', function(done) {\n      var main = chart.internal.main,\n        expectedRegions = [\n          {\n            axis: 'y',\n            start: 300,\n            end: 400,\n            class: 'green'\n          },\n          {\n            axis: 'y',\n            start: 0,\n            end: 100,\n            class: 'green'\n          },\n          {\n            axis: 'y',\n            start: 250,\n            end: 350,\n            class: 'red'\n          },\n          {\n            axis: 'y',\n            start: 25,\n            end: 75,\n            class: 'red'\n          }\n        ],\n        expectedClasses = ['green', 'green', 'red', 'red'],\n        regions\n\n      // Call regions API\n      chart.regions(expectedRegions)\n      setTimeout(function() {\n        regions = main.selectAll('.c3-region')\n        expect(regions.size()).toBe(expectedRegions.length)\n\n        regions.each(function(d, i) {\n          var region = d3.select(this),\n            y = +region.attr('y'),\n            height = +region.attr('height'),\n            expectedClass = expectedClasses[i],\n            expectedStart = Math.round(\n              chart.internal.y(expectedRegions[i].start)\n            ),\n            expectedEnd = Math.round(chart.internal.y(expectedRegions[i].end)),\n            expectedY = expectedEnd,\n            expectedHeight = expectedStart - expectedEnd\n          expect(y).toBeCloseTo(expectedY, -1)\n          expect(height).toBeCloseTo(expectedHeight, -1)\n          expect(region.classed(expectedClass)).toBeTruthy()\n        })\n      }, 500)\n\n      setTimeout(function() {\n        done()\n      }, 1000)\n    })\n  })\n\n  describe('api.region.remove', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [['data1', 30, 200, 100, 400, 150, 250]]\n        },\n        regions: [\n          {\n            axis: 'y',\n            start: 300,\n            end: 400,\n            class: 'green'\n          },\n          {\n            axis: 'y',\n            start: 0,\n            end: 100,\n            class: 'green'\n          },\n          {\n            axis: 'y',\n            start: 250,\n            end: 350,\n            class: 'red'\n          }\n        ]\n      }\n    })\n\n    it('should remove regions', function(done) {\n      var main = chart.internal.main,\n        expectedRegions = [\n          {\n            axis: 'y',\n            start: 250,\n            end: 350,\n            class: 'red'\n          }\n        ],\n        expectedClasses = ['red'],\n        regions\n\n      // Call regions API\n      chart.regions(expectedRegions)\n      setTimeout(function() {\n        regions = main.selectAll('.c3-region')\n        expect(regions.size()).toBe(expectedRegions.length)\n\n        regions.each(function(d, i) {\n          var region = d3.select(this),\n            y = +region.attr('y'),\n            height = +region.attr('height'),\n            expectedClass = expectedClasses[i],\n            expectedStart = Math.round(\n              chart.internal.y(expectedRegions[i].start)\n            ),\n            expectedEnd = Math.round(chart.internal.y(expectedRegions[i].end)),\n            expectedY = expectedEnd,\n            expectedHeight = expectedStart - expectedEnd\n          expect(y).toBeCloseTo(expectedY, -1)\n          expect(height).toBeCloseTo(expectedHeight, -1)\n          expect(region.classed(expectedClass)).toBeTruthy()\n        })\n      }, 500)\n\n      setTimeout(function() {\n        done()\n      }, 1000)\n    })\n  })\n})\n"
  },
  {
    "path": "spec/api.x-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('c3 api.x', function() {\n  'use strict'\n\n  var chart\n\n  var args = {\n    data: {\n      x: 'x',\n      columns: [\n        ['x', 10, 30, 45, 50, 70, 100],\n        ['data1', 30, 200, 100, 400, 150, 250],\n        ['data2', 20, 180, 240, 100, 190]\n      ]\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  it('should return initial ticks for axis x', function() {\n    var expectedValues = [10, 30, 45, 50, 70, 100]\n    d3.select('.c3-axis-x')\n      .selectAll('g.tick')\n      .each(function(d, i) {\n        var text = d3\n          .select(this)\n          .select('text')\n          .text()\n        expect(+text).toBe(expectedValues[i])\n      })\n  })\n\n  it('should return new ticks for axis x after calling chart.x', function() {\n    var expectedValues = [16, 26, 55, 60, 75, 90]\n    chart.x(expectedValues)\n    d3.select('.c3-axis-x')\n      .selectAll('g.tick')\n      .each(function(d, i) {\n        var text = d3\n          .select(this)\n          .select('text')\n          .text()\n        expect(+text).toBe(expectedValues[i])\n      })\n  })\n})\n\ndescribe('c3 api.xs', function() {\n  'use strict'\n\n  var chart\n\n  var args = {\n    data: {\n      xs: {\n        data1: 'x1',\n        data2: 'x2'\n      },\n      columns: [\n        ['x1', 10, 30, 50, 70, 90, 110],\n        ['x2', 20, 40, 60, 80, 100],\n        ['data1', 30, 200, 100, 400, 150, 250],\n        ['data2', 20, 180, 240, 100, 190]\n      ]\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  it('should return initial ticks for axis x', function() {\n    var expectedValues = [\n      '10',\n      '20',\n      '30',\n      '40',\n      '50',\n      '60',\n      '70',\n      '80',\n      '90',\n      '100',\n      '110'\n    ]\n    d3.select('.c3-axis-x')\n      .selectAll('g.tick')\n      .each(function(d, i) {\n        var text = d3\n          .select(this)\n          .select('text')\n          .text()\n        expect(text).toBe(expectedValues[i])\n      })\n  })\n\n  it('should return new ticks for axis x after calling chart.xs', function() {\n    var expectedValues = [\n      '15',\n      '25',\n      '35',\n      '45',\n      '55',\n      '65',\n      '75',\n      '85',\n      '95',\n      '105',\n      '115'\n    ]\n    chart.xs({\n      data1: [15, 35, 55, 75, 95, 115],\n      data2: [25, 45, 65, 85, 105]\n    })\n    d3.select('.c3-axis-x')\n      .selectAll('g.tick')\n      .each(function(d, i) {\n        var text = d3\n          .select(this)\n          .select('text')\n          .text()\n        expect(text).toBe(expectedValues[i])\n      })\n  })\n})\n"
  },
  {
    "path": "spec/api.zoom-spec.ts",
    "content": "import { initChart } from './c3-helper'\n\ndescribe('c3 api zoom', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('zoom', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25],\n            ['data3', 150, 120, 110, 140, 115, 125]\n          ]\n        },\n        zoom: {\n          enabled: true\n        }\n      }\n    })\n\n    it('should return the correct extent', function() {\n      var zoomDomain = chart.zoom(),\n        expectedDomain = chart.internal.x.domain()\n\n      expect(+zoomDomain[0]).toBe(+expectedDomain[0])\n      expect(+zoomDomain[1]).toBe(+expectedDomain[1])\n    })\n\n    it('should be zoomed properly', function() {\n      var target = [3, 5],\n        domain\n      chart.zoom(target)\n      domain = chart.internal.x.domain()\n      expect(domain[0]).toBe(target[0])\n      expect(domain[1]).toBe(target[1])\n    })\n\n    it('should be zoomed properly again', function() {\n      var target = [1, 4],\n        domain\n      chart.zoom(target)\n      domain = chart.internal.x.domain()\n      expect(domain[0]).toBe(target[0])\n      expect(domain[1]).toBe(target[1])\n    })\n\n    it('should set the max zoom properly', function() {\n      chart.zoom.max(100)\n      expect(chart.zoom.max()).toBe(100)\n    })\n\n    it('should set the min zoom properly', function() {\n      chart.zoom.min(-1)\n      expect(chart.zoom.min()).toBe(-1)\n    })\n\n    describe('with timeseries data', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            x: 'date',\n            columns: [\n              ['date', '2014-01-01', '2014-01-02', '2014-08-01', '2014-10-19'],\n              ['data1', 30, 200, 100, 400]\n            ]\n          },\n          axis: {\n            x: {\n              type: 'timeseries'\n            }\n          },\n          zoom: {\n            enabled: true\n          }\n        }\n      })\n\n      it('should be zoomed properly', function() {\n        var target = [new Date(2014, 7, 1), new Date(2014, 8, 1)],\n          domain\n        chart.zoom(target)\n        domain = chart.internal.x.domain()\n        expect(+domain[0]).toBe(+target[0])\n        expect(+domain[1]).toBe(+target[1])\n      })\n\n      it('should be zoomed properly', function() {\n        var target = ['2014-08-01', '2014-09-01'],\n          domain\n        chart.zoom(target)\n        domain = chart.internal.x.domain()\n        expect(+domain[0]).toBe(+chart.internal.parseDate(target[0]))\n        expect(+domain[1]).toBe(+chart.internal.parseDate(target[1]))\n      })\n    })\n  })\n\n  describe('unzoom', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [['data1', 30, 200, 100, 400, 150, 250]]\n        },\n        zoom: {\n          enabled: true\n        }\n      }\n    })\n\n    it('should be unzoomed properly', function() {\n      var target = [1, 4],\n        orginal = chart.internal.x.domain(),\n        domain\n\n      chart.zoom(target)\n      domain = chart.internal.x.domain()\n      expect(domain[0]).toBe(target[0])\n      expect(domain[1]).toBe(target[1])\n\n      chart.unzoom()\n      domain = chart.internal.x.domain()\n      expect(domain[0]).toBe(orginal[0])\n      expect(domain[1]).toBe(orginal[1])\n    })\n  })\n})\n"
  },
  {
    "path": "spec/arc-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('c3 chart arc', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('unloads correctly', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30],\n            ['data2', 150],\n            ['data3', 120]\n          ],\n          type: 'pie'\n        },\n        transition: {\n          duration: 500\n        }\n      }\n    })\n\n    it('unloads without error', function(done) {\n      chart.load({\n        columns: [['data2', 30, 20, 50, 40, 60, 50]]\n      })\n\n      setTimeout(function() {\n        chart.destroy()\n      }, 200)\n\n      setTimeout(function() {\n        expect(chart.internal.config).toBeNull()\n        done()\n      }, 501)\n    })\n  })\n\n  describe('show pie chart', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30],\n            ['data2', 150],\n            ['data3', 120]\n          ],\n          type: 'pie'\n        }\n      }\n    })\n\n    it('should have correct classes', function() {\n      var chartArc = d3.select('.c3-chart-arcs'),\n        arcs = {\n          data1: chartArc\n            .select('.c3-chart-arc.c3-target.c3-target-data1')\n            .select('g.c3-shapes.c3-shapes-data1.c3-arcs.c3-arcs-data1')\n            .select('path.c3-shape.c3-shape.c3-arc.c3-arc-data1'),\n          data2: chartArc\n            .select('.c3-chart-arc.c3-target.c3-target-data2')\n            .select('g.c3-shapes.c3-shapes-data2.c3-arcs.c3-arcs-data2')\n            .select('path.c3-shape.c3-shape.c3-arc.c3-arc-data2'),\n          data3: chartArc\n            .select('.c3-chart-arc.c3-target.c3-target-data3')\n            .select('g.c3-shapes.c3-shapes-data3.c3-arcs.c3-arcs-data3')\n            .select('path.c3-shape.c3-shape.c3-arc.c3-arc-data3')\n        }\n      expect(arcs.data1.size()).toBe(1)\n      expect(arcs.data2.size()).toBe(1)\n      expect(arcs.data3.size()).toBe(1)\n    })\n\n    it('should have correct d', function() {\n      expect(d3.select('.c3-arc-data1').attr('d')).toMatch(\n        /M-124\\..+,-171\\..+A211\\..+,211\\..+,0,0,1,-3\\..+,-211\\..+L0,0Z/\n      )\n      expect(d3.select('.c3-arc-data2').attr('d')).toMatch(\n        /M1\\..+,-211\\..+211\\..+,211\\..+,0,0,1,1\\..+,211\\..+L0,0Z/\n      )\n      expect(d3.select('.c3-arc-data3').attr('d')).toMatch(\n        /M1\\..+,211\\..+211\\..+,211\\..+,0,0,1,-124\\..+,-171\\..+L0,0Z/\n      )\n    })\n\n    describe('with data id that can be converted to a color', function() {\n      beforeAll(function() {\n        args.data.columns = [\n          ['black', 30],\n          ['data2', 150],\n          ['data3', 120]\n        ]\n      })\n\n      it('should have correct d even if data id can be converted to a color', function(done) {\n        setTimeout(function() {\n          expect(d3.select('.c3-arc-black').attr('d')).toMatch(\n            /M-124\\..+,-171\\..+A211\\..+,211\\..+,0,0,1,-3\\..+,-211\\..+L0,0Z/\n          )\n          done()\n        }, 500)\n      })\n\n      describe('with empty pie chart', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              columns: [\n                ['data1', null],\n                ['data2', null],\n                ['data3', null]\n              ],\n              type: 'pie'\n            }\n          }\n        })\n\n        it('should have correct d attribute', function() {\n          var chartArc = d3.select('.c3-chart-arcs'),\n            arcs = {\n              data1: chartArc\n                .select('.c3-chart-arc.c3-target.c3-target-data1')\n                .select('g.c3-shapes.c3-shapes-data1.c3-arcs.c3-arcs-data1')\n                .select('path.c3-shape.c3-shape.c3-arc.c3-arc-data1'),\n              data2: chartArc\n                .select('.c3-chart-arc.c3-target.c3-target-data2')\n                .select('g.c3-shapes.c3-shapes-data2.c3-arcs.c3-arcs-data2')\n                .select('path.c3-shape.c3-shape.c3-arc.c3-arc-data2'),\n              data3: chartArc\n                .select('.c3-chart-arc.c3-target.c3-target-data3')\n                .select('g.c3-shapes.c3-shapes-data3.c3-arcs.c3-arcs-data3')\n                .select('path.c3-shape.c3-shape.c3-arc.c3-arc-data3')\n            }\n          expect(arcs.data1.attr('d').indexOf('NaN')).toBe(-1)\n          expect(arcs.data2.attr('d').indexOf('NaN')).toBe(-1)\n          expect(arcs.data3.attr('d').indexOf('NaN')).toBe(-1)\n        })\n      })\n    })\n  })\n\n  describe('sort pie chart', function() {\n    var createPie = function(order) {\n      return {\n        data: {\n          order: order,\n          columns: [\n            ['data1', 30],\n            ['data2', 150],\n            ['data3', 120]\n          ],\n          type: 'pie'\n        }\n      }\n    }\n\n    var collectArcs = function() {\n      return d3\n        .selectAll('.c3-arc')\n        .data()\n        .sort(function(a: any, b: any) {\n          return a.startAngle - b.startAngle\n        })\n        .map(function(item: any) {\n          return item.data.id\n        })\n    }\n\n    it('should update data_order to desc', function() {\n      args = createPie('desc')\n      expect(true).toBeTruthy()\n    })\n\n    it('it should have descending ordering', function() {\n      expect(collectArcs()).toEqual(['data2', 'data3', 'data1'])\n    })\n\n    it('should update data_order to asc', function() {\n      args = createPie('asc')\n      expect(true).toBeTruthy()\n    })\n\n    it('it should have ascending ordering', function() {\n      expect(collectArcs()).toEqual(['data1', 'data3', 'data2'])\n    })\n\n    it('should update data_order to NULL', function() {\n      args = createPie(null)\n      expect(true).toBeTruthy()\n    })\n\n    it('it should have no ordering', function() {\n      expect(collectArcs()).toEqual(['data1', 'data2', 'data3'])\n    })\n\n    it('should update data_order to Array', function() {\n      args = createPie(['data3', 'data2', 'data1'])\n      expect(true).toBeTruthy()\n    })\n\n    it('it should have array specified ordering', function() {\n      expect(collectArcs()).toEqual(['data3', 'data2', 'data1'])\n    })\n\n    it('should update data_order to Function', function() {\n      var names = ['data2', 'data1', 'data3']\n      args = createPie(function(a, b) {\n        return names.indexOf(a.id) - names.indexOf(b.id)\n      })\n      expect(true).toBeTruthy()\n    })\n\n    it('it should have array specified ordering', function() {\n      expect(collectArcs()).toEqual(['data2', 'data1', 'data3'])\n    })\n  })\n\n  describe('config donut chart', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30],\n            ['data2', 150],\n            ['data3', 120]\n          ],\n          type: 'donut'\n        },\n        donut: {\n          padAngle: 0.05\n        }\n      }\n    })\n\n    it('can configure padAngle', function() {\n      expect(chart.internal.pie.padAngle()()).toBe(0.05)\n    })\n  })\n\n  describe('config pie chart', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30],\n            ['data2', 150],\n            ['data3', 120]\n          ],\n          type: 'pie'\n        },\n        pie: {\n          padAngle: 0.05\n        }\n      }\n    })\n\n    it('can configure padAngle', function() {\n      expect(chart.internal.pie.padAngle()()).toBe(0.05)\n    })\n  })\n\n  describe('show gauge', function() {\n    describe('with a 180 degree gauge', function() {\n      beforeAll(function() {\n        args = {\n          gauge: {\n            width: 10,\n            max: 10,\n            expand: true\n          },\n          data: {\n            columns: [['data', 8]],\n            type: 'gauge'\n          }\n        }\n      })\n\n      it('should have correct d for Pi radian gauge', function() {\n        var chartArc = d3.select('.c3-chart-arcs'),\n          data = chartArc\n            .select('.c3-chart-arc.c3-target.c3-target-data')\n            .select('g.c3-shapes.c3-shapes-data.c3-arcs.c3-arcs-data')\n            .select('path.c3-shape.c3-shape.c3-arc.c3-arc-data')\n\n        expect(data.attr('d')).toMatch(\n          /-258.4,-3\\..+A258.4,258.4,0,0,1,209\\..+,-151\\..+L200\\..+,-146\\..+A248.39999999999998,248.39999999999998,0,0,0,-248.39999999999998,-3\\..+Z/\n        )\n      })\n    })\n\n    describe('with a 2 Pi radian gauge that starts at Pi/2', function() {\n      beforeAll(function() {\n        args = {\n          gauge: {\n            width: 10,\n            max: 10,\n            expand: true,\n            fullCircle: true,\n            startingAngle: Math.PI / 2\n          },\n          data: {\n            columns: [['data', 8]],\n            type: 'gauge'\n          }\n        }\n      })\n\n      it('should have correct d for 2 Pi radian gauge starting at Pi/2', function() {\n        var chartArc = d3.select('.c3-chart-arcs'),\n          data = chartArc\n            .select('.c3-chart-arc.c3-target.c3-target-data')\n            .select('g.c3-shapes.c3-shapes-data.c3-arcs.c3-arcs-data')\n            .select('path.c3-shape.c3-shape.c3-arc.c3-arc-data')\n\n        expect(data.attr('d')).toMatch(/^M180/)\n      })\n\n      describe('with labels use custom text', function() {\n        beforeAll(function() {\n          args = {\n            gauge: {\n              width: 10,\n              max: 100,\n              expand: true,\n              label: {\n                extents: function(value, isMax) {\n                  if (isMax) {\n                    return 'Max: ' + value + '%'\n                  }\n\n                  return 'Min: ' + value + '%'\n                }\n              }\n            },\n            data: {\n              columns: [['data', 8]],\n              type: 'gauge'\n            }\n          }\n        })\n        it('should show custom min/max guage labels', function() {\n          var chartArc = d3.select('.c3-chart-arcs'),\n            min = chartArc.select('.c3-chart-arcs-gauge-min'),\n            max = chartArc.select('.c3-chart-arcs-gauge-max')\n\n          expect(min.text()).toMatch('Min: 0%')\n          expect(max.text()).toMatch('Max: 100%')\n        })\n      })\n    })\n\n    describe('with more than one data_column ', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['padded1', 100],\n              ['padded2', 90],\n              ['padded3', 50],\n              ['padded4', 20]\n            ],\n            type: 'gauge'\n          },\n          color: {\n            pattern: ['#FF0000', '#F97600', '#F6C600', '#60B044'],\n            threshold: {\n              values: [30, 80, 95]\n            }\n          }\n        }\n      })\n      var arcColor = [\n        'rgb(96, 176, 68)',\n        'rgb(246, 198, 0)',\n        'rgb(249, 118, 0)',\n        'rgb(255, 0, 0)'\n      ]\n\n      describe('should contain arcs ', function() {\n        it('each data_column should have one arc', function() {\n          chart.internal.main\n            .selectAll('.c3-chart-arc .c3-arc')\n            .each(function(d, i) {\n              expect(\n                d3.select(this).classed('c3-arc-' + args.data.columns[i][0])\n              ).toBeTruthy()\n            })\n        })\n\n        it('each arc should have the color from color_pattern if color_treshold is given ', function() {\n          chart.internal.main\n            .selectAll('.c3-chart-arc .c3-arc')\n            .each(function(d, i) {\n              expect(d3.select(this).style('fill')).toBe(arcColor[i])\n            })\n        })\n      })\n\n      describe('should contain backgrounds ', function() {\n        it('each data_column should have one background', function() {\n          chart.internal.main\n            .selectAll('.c3-chart-arcs path.c3-chart-arcs-background')\n            .each(function(d, i) {\n              expect(\n                d3.select(this).classed('c3-chart-arcs-background-' + i)\n              ).toBeTruthy()\n            })\n        })\n\n        it('each background should have tbe same color', function() {\n          chart.internal.main\n            .selectAll('.c3-chart-arcs path.c3-chart-arcs-background')\n            .each(function() {\n              expect(d3.select(this).style('fill')).toBe('rgb(224, 224, 224)')\n            })\n        })\n      })\n\n      describe('should contain labels', function() {\n        it('each data_column should have a label', function() {\n          chart.internal.main\n            .selectAll('.c3-chart-arc .c3-gauge-value')\n            .each(function(d, i) {\n              expect(d3.select(this).text()).toBe(\n                chart.internal.defaultArcValueFormat(\n                  null,\n                  args.data.columns[i][1] / 100\n                )\n              )\n            })\n        })\n\n        it('each label should have the same color', function() {\n          chart.internal.main\n            .selectAll('.c3-chart-arc .c3-gauge-value')\n            .each(function() {\n              expect(d3.select(this).style('fill')).toBe('rgb(0, 0, 0)')\n            })\n        })\n\n        it('if only one data_column is visible the label should have \"\" for transform', function(done) {\n          var textBeforeHide = chart.internal.main.select(\n            '.c3-chart-arc.c3-target.c3-target-padded4 text'\n          )\n          expect(textBeforeHide.attr('transform')).not.toBe('')\n          chart.hide(['padded1', 'padded2', 'padded3'])\n          setTimeout(function() {\n            var textAfterHide = chart.internal.main.select(\n              '.c3-chart-arc.c3-target.c3-target-padded4 text'\n            )\n            expect(textAfterHide.attr('transform')).toBe('')\n            done()\n          }, 1000)\n        })\n      })\n\n      describe('should contain labellines', function() {\n        it('each data_column should have a labelline', function() {\n          chart.internal.main\n            .selectAll('.c3-chart-arc .c3-arc-label-line')\n            .each(function(d, i) {\n              expect(\n                d3.select(this).classed('c3-target-' + args.data.columns[i][0])\n              ).toBeTruthy()\n            })\n        })\n\n        it('each labelline should have the color from color_pattern if color_treshold is given', function() {\n          chart.internal.main\n            .selectAll('.c3-chart-arc .c3-arc-label-line')\n            .each(function(d, i) {\n              expect(d3.select(this).style('fill')).toBe(arcColor[i])\n            })\n        })\n      })\n    })\n\n    describe('with more than one data value ', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['padded1', 40, 60],\n              ['padded2', 100, -10],\n              ['padded3', 0, 50],\n              ['padded4', 20, 0]\n            ],\n            type: 'gauge'\n          },\n          color: {\n            pattern: ['#FF0000', '#F97600', '#F6C600', '#60B044'],\n            threshold: {\n              values: [30, 80, 95]\n            }\n          }\n        }\n      })\n      var arcColor = [\n        'rgb(96, 176, 68)',\n        'rgb(246, 198, 0)',\n        'rgb(249, 118, 0)',\n        'rgb(255, 0, 0)'\n      ]\n\n      describe('should contain arcs ', function() {\n        it('each data_column should have one arc', function() {\n          chart.internal.main\n            .selectAll('.c3-chart-arc .c3-arc')\n            .each(function(d, i) {\n              expect(\n                d3.select(this).classed('c3-arc-' + args.data.columns[i][0])\n              ).toBeTruthy()\n            })\n        })\n\n        it('each arc should have the color from color_pattern if color_treshold is given ', function() {\n          chart.internal.main\n            .selectAll('.c3-chart-arc .c3-arc')\n            .each(function(d, i) {\n              expect(d3.select(this).style('fill')).toBe(arcColor[i])\n            })\n        })\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/axis-spec.ts",
    "content": "import { d3, c3, initChart } from './c3-helper'\n\ndescribe('c3 chart axis', function() {\n  'use strict'\n\n  var chart\n\n  var args: any = {\n    data: {\n      columns: [\n        ['data1', 30, 200, 100, 400, 150, 250],\n        ['data2', 50, 20, 10, 40, 15, 25],\n        ['data3', 150, 120, 110, 140, 115, 125]\n      ]\n    },\n    axis: {\n      y: {\n        tick: {\n          values: null,\n          count: undefined\n        }\n      },\n      y2: {\n        tick: {\n          values: null,\n          count: undefined\n        }\n      }\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('axis.y.tick.count', function() {\n    describe('with only 1 tick on y axis', function() {\n      beforeAll(function() {\n        args.axis.y.tick.count = 1\n      })\n\n      it('should have only 1 tick on y axis', function() {\n        var ticksSize = d3\n          .select('.c3-axis-y')\n          .selectAll('g.tick')\n          .size()\n        expect(ticksSize).toBe(1)\n      })\n    })\n\n    describe('with 2 ticks on y axis', function() {\n      beforeAll(function() {\n        args.axis.y.tick.count = 2\n      })\n\n      it('should have 2 ticks on y axis', function() {\n        var ticksSize = d3\n          .select('.c3-axis-y')\n          .selectAll('g.tick')\n          .size()\n        expect(ticksSize).toBe(2)\n      })\n    })\n\n    describe('with 3 ticks on y axis', function() {\n      beforeAll(function() {\n        args.axis.y.tick.count = 3\n      })\n\n      it('should have 3 ticks on y axis', function() {\n        var ticksSize = d3\n          .select('.c3-axis-y')\n          .selectAll('g.tick')\n          .size()\n        expect(ticksSize).toBe(3)\n      })\n    })\n  })\n\n  describe('axis.y.tick.values', function() {\n    var values = [100, 500]\n\n    describe('with only 2 ticks on y axis', function() {\n      beforeAll(function() {\n        args.axis.y.tick.values = values\n      })\n\n      it('should have only 2 tick on y axis', function() {\n        var ticksSize = d3\n          .select('.c3-axis-y')\n          .selectAll('g.tick')\n          .size()\n        expect(ticksSize).toBe(2)\n      })\n\n      it('should have specified tick texts', function() {\n        d3.select('.c3-axis-y')\n          .selectAll('g.tick')\n          .each(function(d, i) {\n            var text = d3\n              .select(this)\n              .select('text')\n              .text()\n            expect(+text).toBe(values[i])\n          })\n      })\n    })\n  })\n\n  describe('axis x timeseries with seconds', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          type: 'line',\n          columns: [\n            ['epoch', 1401879600000, 1401883200000, 1401886800000],\n            ['y', 1955, 2419, 2262]\n          ],\n          xs: {\n            y: 'epoch'\n          }\n        },\n        axis: {\n          x: {\n            type: 'timeseries',\n            min: new Date(1401879600000),\n            max: new Date(1401969600000),\n            localtime: false\n          }\n        }\n      }\n    })\n\n    it('should have 3 ticks on x axis', function() {\n      var ticksSize = d3\n        .select('.c3-axis-x')\n        .selectAll('g.tick')\n        .size()\n      expect(ticksSize).toBe(3)\n    })\n\n    it('should have specified 1 hour intervals', function() {\n      var prevValue\n      d3.select('.c3-axis-x')\n        .selectAll('g.tick')\n        .each(function(d: any, i) {\n          if (i !== 0) {\n            var result = d - prevValue\n            expect(result).toEqual(3600000) // expressed in milliseconds\n          }\n          prevValue = d\n        })\n    })\n\n    describe('changing min x time and columns', function() {\n      beforeAll(function() {\n        args.axis.x.min = new Date(1401876000000)\n        args.axis.x.max = new Date(1401876075000)\n        args.data.columns = [\n          [\n            'epoch',\n            1401876000000,\n            1401876015000,\n            1401876030000,\n            1401876045000,\n            1401876060000,\n            1401876075000\n          ],\n          ['y', 1968, 1800, 1955, 2419, 2262, 1940]\n        ]\n      })\n\n      it('should have 6 ticks on x axis', function() {\n        var ticksSize = d3\n          .select('.c3-axis-x')\n          .selectAll('g.tick')\n          .size()\n        expect(ticksSize).toBe(6) // the count starts at initial value and increments by the set interval\n      })\n\n      it('should have specified 15 seconds intervals', function() {\n        var prevValue\n        d3.select('.c3-axis-x')\n          .selectAll('g.tick')\n          .each(function(d: any, i) {\n            if (i !== 0) {\n              var result = d - prevValue\n              expect(result).toEqual(15000) // expressed in milliseconds\n            }\n            prevValue = d\n          })\n      })\n\n      describe('with axis.x.time.format %Y-%m-%d %H:%M:%S', function() {\n        beforeAll(function() {\n          args.axis.x.tick = {\n            format: '%M:%S' // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format\n          }\n        })\n\n        var textDates = ['00:00', '00:15', '00:30', '00:45', '01:00', '01:15']\n\n        it('should format x ticks as dates with time', function() {\n          var ticks = d3\n            .select('.c3-axis-x')\n            .selectAll('g.tick')\n            .selectAll('tspan')\n            .each(function(d: any) {\n              expect(d.splitted).toEqual(textDates[d.index])\n            })\n          expect(ticks.size()).toBe(6)\n        })\n      })\n    })\n  })\n\n  describe('axis x timeseries with iso dates', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          type: 'line',\n          columns: [\n            ['epoch', 1527811200000, 1527897600000, 1527984000000],\n            ['y', 1955, 2419, 2262]\n          ],\n          xs: {\n            y: 'epoch'\n          }\n        },\n        axis: {\n          x: {\n            type: 'timeseries',\n            min: new Date('2018-06-01'),\n            max: new Date('2018-06-03'),\n            localtime: false,\n            tick: {\n              format: '%Y-%m-%dT%H:%M:%S' // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format\n            }\n          }\n        }\n      }\n    })\n    var textDates = [\n      '2018-06-01T00:00:00',\n      '2018-06-02T00:00:00',\n      '2018-06-03T00:00:00'\n    ]\n\n    it('should format x ticks as dates', function() {\n      var ticks = d3\n        .select('.c3-axis-x')\n        .selectAll('g.tick')\n        .selectAll('tspan')\n        .each(function(d: any) {\n          expect(d.splitted).toEqual(textDates[d.index])\n        })\n      expect(ticks.size()).toBe(3)\n    })\n  })\n\n  describe('axis y timeseries', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [['times', 60000, 120000, 180000, 240000]]\n        },\n        axis: {\n          y: {\n            type: 'timeseries',\n            tick: {\n              time: {}\n            }\n          }\n        }\n      }\n    })\n\n    it('should have 7 ticks on y axis', function() {\n      var ticksSize = d3\n        .select('.c3-axis-y')\n        .selectAll('g.tick')\n        .size()\n      expect(ticksSize).toBe(7) // the count starts at initial value and increments by the set interval\n    })\n\n    it('should have specified 30 second intervals', function() {\n      var prevValue\n      d3.select('.c3-axis-y')\n        .selectAll('g.tick')\n        .each(function(d: any, i) {\n          if (i !== 0) {\n            var result = d - prevValue\n            expect(result).toEqual(30000) // expressed in milliseconds\n          }\n          prevValue = d\n        })\n    })\n\n    describe('with axis.y.time', function() {\n      beforeAll(function() {\n        args.axis.y.tick.time = {\n          type: d3.timeSecond,\n          interval: 60\n        }\n      })\n\n      it('should have 4 ticks on y axis', function() {\n        var ticksSize = d3\n          .select('.c3-axis-y')\n          .selectAll('g.tick')\n          .size()\n        expect(ticksSize).toBe(4) // the count starts at initial value and increments by the set interval\n      })\n\n      it('should have specified 60 second intervals', function() {\n        var prevValue\n        d3.select('.c3-axis-y')\n          .selectAll('g.tick')\n          .each(function(d: any, i) {\n            if (i !== 0) {\n              var result = d - prevValue\n              expect(result).toEqual(60000) // expressed in milliseconds\n            }\n            prevValue = d\n          })\n      })\n    })\n  })\n\n  describe('axis.y.type', function() {\n    describe('type=log', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['linear', 318, 37, 0, 4, 0, 1],\n              ['log', 318, 37, 0, 4, 0, 1]\n            ],\n            type: 'bar',\n            axes: {\n              log: 'y',\n              linear: 'y2'\n            },\n            labels: true\n          },\n          axis: {\n            y: {\n              type: 'log'\n            },\n            y2: {\n              show: true\n            }\n          }\n        }\n      })\n\n      it('should have bars from y bigger than y2', function() {\n        expect(\n          (d3.select('.c3-bars-log .c3-bar-5').node() as any).getBBox().height\n        ).toBeGreaterThan(\n          (d3.select('.c3-bars-linear .c3-bar-5').node() as any).getBBox()\n            .height\n        )\n      })\n\n      it('should not have truncated data label', () => {\n        const text = d3.select('.c3-texts-log .c3-text-0').node() as any\n\n        expect(text).not.toBeUndefined()\n\n        const bbox = text.getBBox()\n\n        expect(Math.abs(bbox.y) - bbox.height).toBeGreaterThan(0)\n      })\n    })\n  })\n\n  describe('axis.x.tick.values', function() {\n    describe('formatted correctly when negative', function() {\n      var xValues = [-3.3, -2.2, -1.1, 1.1, 2.2, 3.3]\n      beforeEach(function() {\n        args.data = {\n          x: 'x',\n          columns: [\n            ['x'].concat(xValues as any),\n            ['data1', 30, 200, 100, 400, 150, 250]\n          ]\n        }\n      })\n\n      it('should not generate whole number for negative values', function() {\n        var tickValues = []\n        d3.select('.c3-axis-x')\n          .selectAll('g.tick')\n          .selectAll('tspan')\n          .each(function(d: any, i) {\n            expect(tickValues.push(parseFloat(d.splitted)) === xValues[i])\n          })\n      })\n    })\n\n    describe('function is provided', function() {\n      var tickGenerator = function() {\n        var values = []\n        for (var i = 0; i <= 300; i += 50) {\n          values.push(i)\n        }\n        return values\n      }\n      beforeEach(function() {\n        args.axis.x = {\n          tick: {\n            values: tickGenerator\n          }\n        }\n        chart = c3.generate(args)\n        ;(window as any).generatedTicks = tickGenerator() // This should be removed from window\n      })\n\n      it('should use function to generate ticks', function() {\n        d3.select('.c3-axis-x')\n          .selectAll('g.tick')\n          .each(function(d, i) {\n            var tick = d3\n              .select(this)\n              .select('text')\n              .text()\n            expect(+tick).toBe((window as any).generatedTicks[i])\n          })\n      })\n    })\n  })\n\n  describe('axis.x.tick.width', function() {\n    describe('indexed x axis and y/y2 axis', function() {\n      describe('not rotated', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              columns: [\n                ['data1', 30, 200, 100, 400, 150, 250],\n                ['data2', 50, 20, 10, 40, 15, 25]\n              ],\n              axes: {\n                data2: 'y2'\n              }\n            },\n            axis: {\n              y2: {\n                show: true\n              }\n            }\n          }\n        })\n\n        it('should construct indexed x axis properly', function() {\n          var ticks = chart.internal.main\n              .select('.c3-axis-x')\n              .selectAll('g.tick'),\n            expectedX = '0',\n            expectedDy = '.71em'\n          expect(ticks.size()).toBe(6)\n          ticks.each(function(d, i) {\n            var tspans = d3.select(this).selectAll('tspan')\n            expect(tspans.size()).toBe(1)\n            tspans.each(function() {\n              var tspan = d3.select(this)\n              expect(tspan.text()).toBe(i + '')\n              expect(tspan.attr('x')).toBe(expectedX)\n              expect(tspan.attr('dy')).toBe(expectedDy)\n            })\n          })\n        })\n\n        describe('should set axis.x.tick.format', function() {\n          beforeAll(function() {\n            args.axis.x = {\n              tick: {\n                format: function() {\n                  return 'very long tick text on x axis'\n                }\n              }\n            }\n          })\n\n          it('should split x axis tick text to multiple lines', function() {\n            var ticks = chart.internal.main\n                .select('.c3-axis-x')\n                .selectAll('g.tick'),\n              expectedTexts = ['very long tick text', 'on x axis'],\n              expectedX = '0'\n            expect(ticks.size()).toBe(6)\n            ticks.each(function() {\n              var tspans = d3.select(this).selectAll('tspan')\n              expect(tspans.size()).toBe(2)\n              tspans.each(function(d, i) {\n                var tspan = d3.select(this)\n                expect(tspan.text()).toBe(expectedTexts[i])\n                expect(tspan.attr('x')).toBe(expectedX)\n                if (i === 0) {\n                  expect(tspan.attr('dy')).toBe('.71em')\n                } else {\n                  expect(tspan.attr('dy')).toBeGreaterThan(8)\n                }\n              })\n            })\n          })\n\n          it('should construct y axis properly', function() {\n            var ticks = chart.internal.main\n                .select('.c3-axis-y')\n                .selectAll('g.tick'),\n              expectedX = '-9',\n              expectedDy = '3'\n            expect(ticks.size()).toBe(9)\n            ticks.each(function(d) {\n              var tspans = d3.select(this).selectAll('tspan')\n              expect(tspans.size()).toBe(1)\n              tspans.each(function() {\n                var tspan = d3.select(this)\n                expect(tspan.text()).toBe(d + '')\n                expect(tspan.attr('x')).toBe(expectedX)\n                expect(tspan.attr('dy')).toBe(expectedDy)\n              })\n            })\n          })\n\n          it('should construct y2 axis properly', function() {\n            var ticks = chart.internal.main\n                .select('.c3-axis-y2')\n                .selectAll('g.tick'),\n              expectedX = '9',\n              expectedDy = '3'\n            expect(ticks.size()).toBe(9)\n            ticks.each(function(d) {\n              var tspans = d3.select(this).selectAll('tspan')\n              expect(tspans.size()).toBe(1)\n              tspans.each(function() {\n                var tspan = d3.select(this)\n                expect(tspan.text()).toBe(d + '')\n                expect(tspan.attr('x')).toBe(expectedX)\n                expect(tspan.attr('dy')).toBe(expectedDy)\n              })\n            })\n          })\n        })\n\n        describe('should set big values in y', function() {\n          beforeAll(function() {\n            args.data.columns = [\n              ['data1', 3000000000000000, 200, 100, 400, 150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25]\n            ]\n          })\n\n          it('should not split y axis tick text to multiple lines', function() {\n            var ticks = chart.internal.main\n              .select('.c3-axis-y2')\n              .selectAll('g.tick')\n            ticks.each(function() {\n              var tspans = d3.select(this).selectAll('tspan')\n              expect(tspans.size()).toBe(1)\n            })\n          })\n        })\n      })\n\n      describe('rotated', function() {\n        beforeAll(function() {\n          args.axis.rotated = true\n        })\n\n        it('should split x axis tick text to multiple lines', function() {\n          var ticks = chart.internal.main\n              .select('.c3-axis-x')\n              .selectAll('g.tick'),\n            expectedTexts = ['very long tick text on', 'x axis'],\n            expectedX = '-9'\n          expect(ticks.size()).toBe(6)\n          ticks.each(function() {\n            var tspans = d3.select(this).selectAll('tspan')\n            expect(tspans.size()).toBe(2)\n            tspans.each(function(d, i) {\n              var tspan = d3.select(this)\n              expect(tspan.text()).toBe(expectedTexts[i])\n              expect(tspan.attr('x')).toBe(expectedX)\n              if (i === 0) {\n                expect(tspan.attr('dy')).toBeLessThan(0)\n              } else {\n                expect(tspan.attr('dy')).toBeGreaterThan(9)\n              }\n            })\n          })\n        })\n\n        it('should not split y axis tick text to multiple lines', function() {\n          var ticks = chart.internal.main\n              .select('.c3-axis-y')\n              .selectAll('g.tick'),\n            expectedTexts = [\n              '0',\n              '500000000000000',\n              '1000000000000000',\n              '1500000000000000',\n              '2000000000000000',\n              '2500000000000000',\n              '3000000000000000'\n            ],\n            expectedX = '0',\n            expectedDy = '.71em'\n          expect(ticks.size()).toBe(7)\n          ticks.each(function(d, i) {\n            var tspans = d3.select(this).selectAll('tspan')\n            expect(tspans.size()).toBe(1)\n            tspans.each(function() {\n              var tspan = d3.select(this)\n              expect(tspan.text()).toBe(expectedTexts[i])\n              expect(tspan.attr('x')).toBe(expectedX)\n              expect(tspan.attr('dy')).toBe(expectedDy)\n            })\n          })\n        })\n      })\n    })\n\n    describe('category axis', function() {\n      describe('not rotated', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              x: 'x',\n              columns: [\n                [\n                  'x',\n                  'this is a very long tick text on category axis',\n                  'cat1',\n                  'cat2',\n                  'cat3',\n                  'cat4',\n                  'cat5'\n                ],\n                ['data1', 30, 200, 100, 400, 150, 250],\n                ['data2', 50, 20, 10, 40, 15, 25]\n              ]\n            },\n            axis: {\n              x: {\n                type: 'category'\n              }\n            }\n          }\n        })\n\n        it('should locate ticks properly', function() {\n          var ticks = chart.internal.main\n            .select('.c3-axis-x')\n            .selectAll('g.tick')\n          ticks.each(function(d, i) {\n            var tspans = d3.select(this).selectAll('tspan'),\n              expectedX = '0',\n              expectedDy = '.71em'\n            if (i > 0) {\n              // i === 0 should be checked in next test\n              expect(tspans.size()).toBe(1)\n              tspans.each(function() {\n                var tspan = d3.select(this)\n                expect(tspan.attr('x')).toBe(expectedX)\n                expect(tspan.attr('dy')).toBe(expectedDy)\n              })\n            }\n          })\n        })\n\n        xit('should split tick text properly', function() {\n          var tick = chart.internal.main.select('.c3-axis-x').select('g.tick'),\n            tspans = tick.selectAll('tspan'),\n            expectedTickTexts = [\n              'this is a very long',\n              'tick text on category',\n              'axis'\n            ],\n            expectedX = '0'\n          expect(tspans.size()).toBe(3)\n          tspans.each(function(d, i) {\n            var tspan = d3.select(this)\n            expect(tspan.text()).toBe(expectedTickTexts[i])\n            expect(tspan.attr('x')).toBe(expectedX)\n            // unable to define pricise number because it differs depends on environment..\n            if (i === 0) {\n              expect(tspan.attr('dy')).toBe('.71em')\n            } else {\n              expect(tspan.attr('dy')).toBeGreaterThan(8)\n            }\n          })\n        })\n      })\n\n      describe('rotated', function() {\n        beforeAll(function() {\n          args.axis.rotated = true\n        })\n\n        it('should locate ticks on rotated axis properly', function() {\n          var ticks = chart.internal.main\n            .select('.c3-axis-x')\n            .selectAll('g.tick')\n          ticks.each(function(d, i) {\n            var tspans = d3.select(this).selectAll('tspan'),\n              expectedX = '-9',\n              expectedDy = '3'\n            if (i > 0) {\n              // i === 0 should be checked in next test\n              expect(tspans.size()).toBe(1)\n              tspans.each(function() {\n                var tspan = d3.select(this)\n                expect(tspan.attr('x')).toBe(expectedX)\n                expect(tspan.attr('dy')).toBe(expectedDy)\n              })\n            }\n          })\n        })\n\n        it('should split tick text on rotated axis properly', function() {\n          var tick = chart.internal.main.select('.c3-axis-x').select('g.tick'),\n            tspans = tick.selectAll('tspan'),\n            expectedTickTexts = [\n              'this is a very long',\n              'tick text on category',\n              'axis'\n            ],\n            expectedX = '-9'\n          expect(tspans.size()).toBe(3)\n          tspans.each(function(d, i) {\n            var tspan = d3.select(this)\n            expect(tspan.text()).toBe(expectedTickTexts[i])\n            expect(tspan.attr('x')).toBe(expectedX)\n            // unable to define pricise number because it differs depends on environment..\n            if (i === 0) {\n              expect(tspan.attr('dy')).toBeLessThan(0)\n            } else {\n              expect(tspan.attr('dy')).toBeGreaterThan(8)\n            }\n          })\n        })\n      })\n\n      describe('option used', function() {\n        describe('as null', function() {\n          beforeAll(function() {\n            //'without split ticks',\n            args.axis.x.tick = {\n              multiline: false\n            }\n          })\n\n          it('should split x tick', function() {\n            var tick = chart.internal.main\n                .select('.c3-axis-x')\n                .select('g.tick'),\n              tspans = tick.selectAll('tspan')\n            expect(tspans.size()).toBe(1)\n          })\n        })\n\n        describe('as value', function() {\n          beforeAll(function() {\n            // 'without split ticks',\n            args.axis.x.tick = {\n              width: 150\n            }\n          })\n\n          it('should split x tick to 2 lines properly', function() {\n            var tick = chart.internal.main\n                .select('.c3-axis-x')\n                .select('g.tick'),\n              tspans = tick.selectAll('tspan'),\n              expectedTickTexts = [\n                'this is a very long tick text on',\n                'category axis'\n              ],\n              expectedX = '-9'\n            expect(tspans.size()).toBe(2)\n            tspans.each(function(d, i) {\n              var tspan = d3.select(this)\n              expect(tspan.text()).toBe(expectedTickTexts[i])\n              expect(tspan.attr('x')).toBe(expectedX)\n              // unable to define pricise number because it differs depends on environment..\n              if (i === 0) {\n                expect(tspan.attr('dy')).toBeLessThan(0)\n              } else {\n                expect(tspan.attr('dy')).toBeGreaterThan(8)\n              }\n            })\n          })\n        })\n\n        describe('with multilineMax', function() {\n          beforeAll(function() {\n            args.axis.x.tick = {\n              multiline: true,\n              multilineMax: 2\n            }\n          })\n\n          it('should ellipsify x tick properly', function() {\n            var tick = chart.internal.main.select('.c3-axis-x').select('g.tick')\n            var tspans = tick.selectAll('tspan')\n            var expectedTickText = [\n              'this is a very long',\n              'tick text on categ...'\n            ]\n\n            expect(tspans.size()).toBe(2)\n\n            tspans.each(function(d, i) {\n              var tspan = d3.select(this)\n              expect(tspan.text()).toBe(expectedTickText[i])\n            })\n          })\n        })\n      })\n    })\n\n    describe('with axis.x.tick.format', function() {\n      beforeAll(function() {\n        // 'with axis.x.tick.format',\n        args.axis.x.tick.format = function() {\n          return ['this is a very long tick text', 'on category axis']\n        }\n      })\n\n      it('should have multiline tick text', function() {\n        var tick = chart.internal.main.select('.c3-axis-x').select('g.tick'),\n          tspans = tick.selectAll('tspan'),\n          expectedTickTexts = [\n            'this is a very long tick text',\n            'on category axis'\n          ]\n        expect(tspans.size()).toBe(2)\n        tspans.each(function(d, i) {\n          var tspan = d3.select(this)\n          expect(tspan.text()).toBe(expectedTickTexts[i])\n        })\n      })\n    })\n  })\n\n  describe('axis.x.tick.rotate', function() {\n    describe('not rotated', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            x: 'x',\n            columns: [\n              [\n                'x',\n                'category 1',\n                'category 2',\n                'category 3',\n                'category 4',\n                'category 5',\n                'category 6'\n              ],\n              ['data1', 30, 200, 100, 400, 150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25]\n            ]\n          },\n          axis: {\n            x: {\n              type: 'category',\n              tick: {\n                rotate: 60\n              }\n            }\n          }\n        }\n      })\n\n      it('should rotate tick texts', function() {\n        chart.internal.main.selectAll('.c3-axis-x g.tick').each(function() {\n          var tick = d3.select(this),\n            text = tick.select('text'),\n            tspan = text.select('tspan')\n          expect(text.attr('transform')).toBe('rotate(60)')\n          expect(text.attr('y')).toBe('1.5')\n          expect(tspan.attr('dx')).toBe('6.928203230275509')\n        })\n      })\n\n      it('should have automatically calculated x axis height', function() {\n        var box = chart.internal.main\n            .select('.c3-axis-x')\n            .node()\n            .getBoundingClientRect(),\n          height = chart.internal.getHorizontalAxisHeight('x')\n        expect(box.height).toBeGreaterThan(50)\n        expect(height).toBeCloseTo(76, -1.3) // @TODO make this test better\n      })\n    })\n  })\n\n  describe('axis.y.tick.rotate', function() {\n    describe('not rotated', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, 200, 100, 400, 150, 250, 100, 600],\n              ['data2', 50, 20, 10, 40, 15, 25]\n            ]\n          },\n          axis: {\n            rotated: true,\n            y: {\n              tick: {\n                rotate: 45\n              }\n            }\n          }\n        }\n      })\n\n      it('should rotate tick texts', function() {\n        chart.internal.main.selectAll('.c3-axis-y g.tick').each(function() {\n          var tick = d3.select(this),\n            text = tick.select('text'),\n            tspan = text.select('tspan')\n          expect(text.attr('transform')).toBe('rotate(45)')\n          expect(text.attr('y')).toBe('4')\n          expect(tspan.attr('dx')).toBeCloseTo(5.6, 0)\n        })\n      })\n\n      it('should have automatically calculated y axis width', function() {\n        var box = chart.internal.main\n          .select('.c3-axis-y')\n          .node()\n          .getBoundingClientRect()\n        expect(box.width).toBeCloseTo(590, 1)\n      })\n    })\n  })\n\n  describe('axis.x.tick.fit', function() {\n    describe('axis.x.tick.fit = true', function() {\n      beforeAll(function() {\n        // 'should set args for indexed data',\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, 200, 100, 400, 150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25],\n              ['data3', 150, 120, 110, 140, 115, 125]\n            ]\n          }\n        }\n      })\n\n      it('should show fitted ticks on indexed data', function() {\n        var ticks = chart.internal.main.selectAll('.c3-axis-x g.tick')\n        expect(ticks.size()).toBe(6)\n      })\n\n      describe('should set args for x-based data', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              x: 'x',\n              columns: [\n                ['x', 10, 20, 100, 110, 200, 1000],\n                ['data1', 30, 200, 100, 400, 150, 250],\n                ['data2', 50, 20, 10, 40, 15, 25],\n                ['data3', 150, 120, 110, 140, 115, 125]\n              ]\n            }\n          }\n        })\n\n        it('should show fitted ticks on indexed data', function() {\n          var ticks = chart.internal.main.selectAll('.c3-axis-x g.tick')\n          expect(ticks.size()).toBe(6)\n        })\n\n        it('should show fitted ticks after hide and show', function() {\n          chart.hide()\n          chart.show()\n          var ticks = chart.internal.main.selectAll('.c3-axis-x g.tick')\n          expect(ticks.size()).toBe(6)\n        })\n      })\n    })\n\n    describe('axis.x.tick.fit = false', function() {\n      describe('should set args for indexed data', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              columns: [\n                ['data1', 30, 200, 100, 400, 150, 250],\n                ['data2', 50, 20, 10, 40, 15, 25],\n                ['data3', 150, 120, 110, 140, 115, 125]\n              ]\n            },\n            axis: {\n              x: {\n                tick: {\n                  fit: false\n                }\n              }\n            }\n          }\n        })\n\n        it('should show fitted ticks on indexed data', function() {\n          var ticks = chart.internal.main.selectAll('.c3-axis-x g.tick')\n          expect(ticks.size()).toBe(11)\n        })\n      })\n\n      describe('should set args for x-based data', function() {\n        beforeAll(function() {\n          args.data = {\n            x: 'x',\n            columns: [\n              ['x', 10, 20, 100, 110, 200, 1000],\n              ['data1', 30, 200, 100, 400, 150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25],\n              ['data3', 150, 120, 110, 140, 115, 125]\n            ]\n          }\n        })\n\n        it('should show fitted ticks on indexed data', function() {\n          var ticks = chart.internal.main.selectAll('.c3-axis-x g.tick')\n          expect(ticks.size()).toBe(10)\n        })\n\n        it('should show fitted ticks after hide and show', function() {\n          chart.hide()\n          chart.show()\n          var ticks = chart.internal.main.selectAll('.c3-axis-x g.tick')\n          expect(ticks.size()).toBe(10)\n        })\n      })\n    })\n  })\n\n  describe('axis.y.inner', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ]\n        },\n        axis: {\n          y: {\n            inner: false\n          }\n        }\n      }\n    })\n\n    it('should not have inner y axis', function() {\n      var paddingLeft = chart.internal.getCurrentPaddingLeft(),\n        tickTexts = chart.internal.main.selectAll('.c3-axis-y g.tick text')\n      expect(paddingLeft).toBeGreaterThan(19)\n      tickTexts.each(function() {\n        expect(+d3.select(this).attr('x')).toBeLessThan(0)\n      })\n    })\n\n    describe('with inner y axis', function() {\n      beforeAll(function() {\n        args.axis.y.inner = true\n      })\n\n      it('should have inner y axis', function() {\n        var paddingLeft = chart.internal.getCurrentPaddingLeft(),\n          tickTexts = chart.internal.main.selectAll('.c3-axis-y g.tick text')\n        expect(paddingLeft).toBe(1)\n        tickTexts.each(function() {\n          expect(+d3.select(this).attr('x')).toBeGreaterThan(0)\n        })\n      })\n    })\n  })\n\n  describe('axis.y2.inner', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ]\n        },\n        axis: {\n          y2: {\n            show: true,\n            inner: false\n          }\n        }\n      }\n    })\n\n    it('should not have inner y axis', function() {\n      var paddingRight = chart.internal.getCurrentPaddingRight(),\n        tickTexts = chart.internal.main.selectAll('.c3-axis-2y g.tick text')\n      expect(paddingRight).toBeGreaterThan(19)\n      tickTexts.each(function() {\n        expect(+d3.select(this).attr('x')).toBeGreaterThan(0)\n      })\n    })\n\n    describe('with inner y axis', function() {\n      beforeAll(function() {\n        args.axis.y2.inner = true\n      })\n\n      it('should have inner y axis', function() {\n        var paddingRight = chart.internal.getCurrentPaddingRight(),\n          tickTexts = chart.internal.main.selectAll('.c3-axis-2y g.tick text')\n        expect(paddingRight).toBe(2)\n        tickTexts.each(function() {\n          expect(+d3.select(this).attr('x')).toBeLessThan(0)\n        })\n      })\n    })\n  })\n\n  describe('axis.x.label', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['somewhat long 1', 30, 200, 100, 400, 150, 250],\n            ['somewhat long 2', 50, 20, 10, 40, 15, 25]\n          ]\n        },\n        axis: {\n          x: {\n            show: true,\n            label: {\n              text: 'Label of X axis'\n            }\n          }\n        }\n      }\n    })\n\n    it('renders label text properly', () => {\n      expect(d3.select('.c3-axis-x-label').text()).toEqual('Label of X axis')\n    })\n\n    describe('outer label position', function() {\n      beforeAll(function() {\n        args.axis.x.label.position = 'outer-center'\n      })\n\n      it('renders position properly', () => {\n        const label = d3.select('.c3-axis-x-label')\n\n        expect(label.attr('dy')).toEqual('30')\n      })\n\n      describe('with rotated tick', function() {\n        beforeAll(function() {\n          args.axis.x.tick = {\n            rotate: 90\n          }\n        })\n\n        it('renders position properly', () => {\n          const label = d3.select('.c3-axis-x-label')\n\n          expect(label.attr('dy')).toBeGreaterThan(30)\n        })\n      })\n    })\n\n    describe('inner label position', function() {\n      beforeAll(function() {\n        args.axis.x.label.position = 'inner-center'\n      })\n\n      it('renders position properly', () => {\n        const label = d3.select('.c3-axis-x-label')\n\n        expect(label.attr('dy')).toEqual('-0.5em')\n      })\n\n      describe('with rotated tick', function() {\n        beforeAll(function() {\n          args.axis.x.tick = {\n            rotate: 90\n          }\n        })\n\n        it('renders position properly', () => {\n          const label = d3.select('.c3-axis-x-label')\n\n          expect(label.attr('dy')).toEqual('-0.5em')\n        })\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/c3-helper.ts",
    "content": "import c3 from '../src/index'\n;(window as any).c3 = c3\nconst d3 = (window.d3 = require('d3'))\n\nconst initDom = ((window as any).initDom = function() {\n  var div = document.createElement('div')\n  div.id = 'chart'\n  div.style.width = '640px'\n  div.style.height = '480px'\n  document.body.appendChild(div)\n  document.body.style.margin = '0px'\n})\n\nconst setMouseEvent = ((window as any).setMouseEvent = function(\n  chart,\n  name,\n  x,\n  y,\n  element\n) {\n  var paddingLeft = chart.internal.main.node().transform.baseVal.getItem(0)\n      .matrix.e,\n    event = document.createEvent('MouseEvents')\n  event.initMouseEvent(\n    name,\n    true,\n    true,\n    window,\n    0,\n    0,\n    0,\n    x + paddingLeft,\n    y + 5,\n    false,\n    false,\n    false,\n    false,\n    0,\n    null\n  )\n  if (element) {\n    element.dispatchEvent(event)\n  }\n})\n\nconst initChart = ((window as any).initChart = function(chart, args, done) {\n  if (typeof chart === 'undefined') {\n    initDom()\n  }\n  if (args) {\n    chart = c3.generate(args)\n    window.d3 = chart.internal.d3\n    window.d3\n      .select('.jasmine_html-reporter')\n      .style('position', 'absolute')\n      .style('width', '640px')\n      .style('right', 0)\n\n    // when using Karma debug in browser the `window.chart` reference the DOM element\n    // instead of the actual chart instance here so let's keep it here\n    ;(window as any).chartInstance = chart\n  }\n\n  window.setTimeout(function() {\n    done()\n  }, 10)\n\n  return chart\n})\n\nexport { d3, c3, initDom, setMouseEvent, initChart }\n"
  },
  {
    "path": "spec/cache-spec.ts",
    "content": "import { initChart } from './c3-helper'\n\ndescribe('c3 cache', function() {\n  'use strict'\n\n  var chart\n\n  var args = {\n    data: {\n      columns: [\n        ['data1', 30, 200, 100, 400, 150, 250],\n        ['data2', 50, 20, 10, 40, 15, 25],\n        ['data3', 150, 120, 110, 140, 115, 125]\n      ]\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  it('returns undefined for unknown values', function() {\n    expect(chart.internal.getFromCache('undefined')).toBeUndefined()\n  })\n\n  it('returns cached value', function() {\n    chart.internal.addToCache('cached', 1)\n\n    expect(chart.internal.getFromCache('cached')).toEqual(1)\n\n    chart.internal.addToCache('cached', { x: 1 })\n\n    expect(chart.internal.getFromCache('cached')).toEqual({ x: 1 })\n  })\n\n  it('can clear cached values', function() {\n    chart.internal.addToCache('cached', 1)\n\n    expect(chart.internal.getFromCache('cached')).toEqual(1)\n\n    chart.internal.resetCache()\n\n    expect(chart.internal.getFromCache('cached')).toBeUndefined()\n  })\n})\n"
  },
  {
    "path": "spec/class-spec.ts",
    "content": "import { initChart } from './c3-helper'\n\ndescribe('c3 chart class', function() {\n  'use strict'\n\n  var chart\n\n  var args = {\n    data: {\n      columns: [\n        ['data1', 30, 200, 100, 400, 150, 250],\n        ['data2 prefix', 50, 20, 10, 40, 15, 25],\n        ['data3 мужчины', 150, 120, 110, 140, 115, 125],\n        ['my\\u007fapp', 10, 20, 40, 20, 65, 55]\n      ]\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('internal.generateTargetClass', function() {\n    it('should not replace any characters', function() {\n      var input = 'data1',\n        expected = '-' + input,\n        suffix = chart.internal.generateTargetClass(input)\n      expect(suffix).toBe(expected)\n    })\n\n    it('should replace space to \"-\"', function() {\n      var input = 'data1 suffix',\n        expected = '-data1-suffix',\n        suffix = chart.internal.generateTargetClass(input)\n      expect(suffix).toBe(expected)\n    })\n\n    it('should replace space to \"-\" with multibyte characters', function() {\n      var input = 'data1 suffix 日本語',\n        expected = '-data1-suffix-日本語',\n        suffix = chart.internal.generateTargetClass(input)\n      expect(suffix).toBe(expected)\n    })\n\n    it('should not replace special characters', function() {\n      var input = 'data1 !@#$%^&*()_=+,.<>\"\\':;[]/|?~`{}\\\\',\n        expected = '-data1-!@#$%^&*()_=+,.<>\"\\':;[]/|?~`{}\\\\',\n        suffix = chart.internal.generateTargetClass(input)\n      expect(suffix).toBe(expected)\n    })\n  })\n\n  describe('internal.getTargetSelectorSuffix', function() {\n    it('should escape special characters', function() {\n      var input = 'data1 !@#$%^&*()_=+,.<>\"\\':;[]/|?~`{}\\\\',\n        expected =\n          '-data1-\\\\!\\\\@\\\\#\\\\$\\\\%\\\\^\\\\&\\\\*\\\\(\\\\)_\\\\=\\\\+\\\\,\\\\.\\\\<\\\\>\\\\\"\\\\\\'\\\\:\\\\;\\\\[\\\\]\\\\/\\\\|\\\\?\\\\~\\\\`\\\\{\\\\}\\\\\\\\',\n        suffix = chart.internal.getTargetSelectorSuffix(input)\n      expect(suffix).toBe(expected)\n    })\n  })\n\n  describe('select target in chart', function() {\n    it('should replace space to \"-\" with multibyte characters', function() {\n      var selector = '.c3-target-data3-мужчины'\n      expect(chart.internal.main.select(selector).size()).toBe(1)\n    })\n\n    it('should be able to select class with unicode characters', () => {\n      const selector = `.c3-target${chart.internal.getTargetSelectorSuffix(\n        args.data.columns[3][0]\n      )}`\n\n      expect(chart.internal.main.select(selector).size()).toBe(1)\n    })\n  })\n})\n"
  },
  {
    "path": "spec/core-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('c3 chart', function() {\n  'use strict'\n\n  var chart\n\n  var args: any = {\n    svg: {\n      classname: 'customclass'\n    },\n    data: {\n      columns: [\n        ['data1', 30, 200, 100, 400, 150, 250],\n        ['data2', 50, 20, 10, 40, 15, 25],\n        ['data3', 150, 120, 110, 140, 115, 125]\n      ]\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('init', function() {\n    it('should be created', function() {\n      var svg = d3.select('#chart svg')\n      expect(svg).not.toBeNull()\n    })\n\n    it('should bind to window focus event', done => {\n      const addEventListener = window.addEventListener\n      window.addEventListener = (event, handler) => {\n        if (event === 'focus') {\n          setTimeout(() => {\n            expect(handler).toBe(chart.internal.windowFocusHandler)\n            window.addEventListener = addEventListener // restore the original\n            done()\n          }, 10)\n        }\n      }\n      chart = initChart(chart, args, () => {})\n    })\n\n    describe('should set 3rd party property to Function', function() {\n      beforeAll(function() {\n        ;(Function.prototype as any).$extIsFunction = true\n      })\n\n      it('should be created even if 3rd party property has been set', function() {\n        var svg = d3.select('#chart svg')\n        expect(svg).not.toBeNull()\n      })\n\n      it('should be created with a custom class', function() {\n        var svg = d3.select('#chart svg')\n        expect(svg.attr('class')).not.toBeNull()\n        expect(svg.attr('class')).toBe('customclass')\n      })\n    })\n  })\n\n  describe('size', function() {\n    it('should have same width', function() {\n      var svg = d3.select('#chart svg')\n      expect(+svg.attr('width')).toBe(640)\n    })\n\n    it('should have same height', function() {\n      var svg = d3.select('#chart svg')\n      expect(+svg.attr('height')).toBe(480)\n    })\n  })\n\n  describe('call resize and resized callbacks', function() {\n    beforeAll(function() {\n      args.bindto = '#chart'\n      args.axis = {\n        rotated: true\n      }\n      args.resize_var = false\n      args.resized_var = false\n\n      args.onresize = function() {\n        args.resize_var = true\n      }\n      args.onresized = function() {\n        args.resized_var = true\n      }\n    })\n\n    it('arbitrary parameters should be false before resize', function() {\n      expect(args.resize_var).toBe(false)\n      expect(args.resized_var).toBe(false)\n    })\n\n    it('arbitrary parameters should be true after resize', function() {\n      window.dispatchEvent(new Event('resize'))\n      expect(args.resize_var).toBe(true)\n      expect(args.resized_var).toBe(true)\n    })\n  })\n\n  describe('bindto', function() {\n    describe('selector', function() {\n      beforeAll(function() {\n        d3.select('#chart').html('')\n        args.bindto = '#chart'\n      })\n\n      it('should be created', function() {\n        var svg = d3.select('#chart svg')\n        expect(svg.size()).toBe(1)\n      })\n    })\n\n    describe('d3.selection object', function() {\n      beforeAll(function() {\n        d3.select('#chart').html('')\n        args.bindto = d3.select('#chart')\n      })\n      it('should be created', function() {\n        var svg = d3.select('#chart svg')\n        expect(svg.size()).toBe(1)\n      })\n    })\n\n    describe('null', function() {\n      beforeAll(function() {\n        d3.select('#chart').html('')\n        args.bindto = null\n      })\n\n      it('should not be created', function() {\n        var svg = d3.select('#chart svg')\n        expect(svg.size()).toBe(0)\n      })\n    })\n\n    describe('empty string', function() {\n      beforeAll(function() {\n        d3.select('#chart').html('')\n        args.bindto = ''\n      })\n\n      it('should not be created', function() {\n        var svg = d3.select('#chart svg')\n        expect(svg.size()).toBe(0)\n      })\n    })\n    describe('bind to selector with rotated axis', function() {\n      beforeAll(function() {\n        args.bindto = '#chart'\n        args.axis = {\n          rotated: true\n        }\n      })\n\n      it('should be created', function() {\n        var svg = d3.select('#chart svg')\n        expect(svg.size()).toBe(1)\n      })\n    })\n  })\n\n  describe('empty data', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [['data1'], ['data2']]\n        }\n      }\n    })\n\n    it('should generate a chart', function() {\n      var ticks = chart.internal.main.select('.c3-axis-x').selectAll('g.tick')\n      expect(ticks.size()).toBe(0)\n    })\n\n    describe('more empty data', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            x: 'x',\n            columns: [['x'], ['data1'], ['data2']]\n          },\n          axis: {\n            x: {\n              type: 'timeseries'\n            }\n          }\n        }\n      })\n\n      it('should generate a chart', function() {\n        var ticks = chart.internal.main.select('.c3-axis-x').selectAll('g.tick')\n        expect(ticks.size()).toBe(0)\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/data-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('load without data', function() {\n  var chart, args\n\n  beforeAll(function() {\n    args = {\n      data: {}\n    }\n  })\n\n  it('throws when data is an empty object', () => {\n    expect(() => initChart(chart, args, () => {})).toThrowError(\n      Error,\n      /url or json or rows or columns is required/\n    )\n  })\n})\n\ndescribe('c3 chart data', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('load json', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          json: {\n            data1: [30, 20, 50],\n            data2: [200, 130, 90]\n          }\n        }\n      }\n    })\n\n    it('should draw correctly', function() {\n      var expectedCx = [6, 299, 593],\n        expectedCy = [371, 391, 332]\n      d3.selectAll('.c3-circles-data1 .c3-circle').each(function(d, i) {\n        var circle = d3.select(this)\n        expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)\n        expect(+circle.attr('cy')).toBeCloseTo(expectedCy[i], 0)\n      })\n    })\n\n    describe('more data', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            json: [\n              {\n                date: '2014-06-03',\n                '443': '3000',\n                '995': '500'\n              },\n              {\n                date: '2014-06-04',\n                '443': '1000'\n              },\n              {\n                date: '2014-06-05',\n                '443': '5000',\n                '995': '1000'\n              }\n            ],\n            keys: {\n              x: 'date',\n              value: ['443', '995']\n            }\n          },\n          axis: {\n            x: {\n              type: 'category'\n            }\n          }\n        }\n      })\n\n      it('should draw correctly', function() {\n        var expectedCx = { 443: [98, 294, 490], 995: [98, 294, 490] },\n          expectedCy = { 443: [194, 351, 36], 995: [391, 430, 351] }\n        d3.selectAll('.c3-circles-443 .c3-circle').each(function(d, i) {\n          var circle = d3.select(this)\n          expect(+circle.attr('cx')).toBeCloseTo(expectedCx[443][i], 0)\n          expect(+circle.attr('cy')).toBeCloseTo(expectedCy[443][i], 0)\n        })\n        d3.selectAll('.c3-circles-995 .c3-circle').each(function(d, i) {\n          var circle = d3.select(this)\n          expect(+circle.attr('cx')).toBeCloseTo(expectedCx[995][i], 0)\n          expect(+circle.attr('cy')).toBeCloseTo(expectedCy[995][i], 0)\n        })\n      })\n    })\n\n    describe('with nested JSON args', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            json: [\n              {\n                date: '2014-06-03',\n                '443': '3000',\n                '995': { '996': '500' },\n                '112': ['600'],\n                '223': [{ '224': '100' }],\n                '334': [[], [{ '335': '300' }]],\n                '556': { '557': { '558': ['1000'] } },\n                '778.889': '700'\n              },\n              {\n                date: '2014-06-04',\n                '443': '1000',\n                '112': ['700'],\n                '223': [{ '224': '200' }],\n                '556': { '557': { '558': ['2000'] } },\n                '778.889': '300'\n              },\n              {\n                date: '2014-06-05',\n                '995': { '996': '1000' },\n                '112': ['800'],\n                '223': [{ '224': '300' }],\n                '443': '5000',\n                '334': [[], [{ '335': '500' }]],\n                '556': { '557': { '558': ['3000'] } },\n                '778.889': '800'\n              }\n            ],\n            keys: {\n              x: 'date',\n              value: [\n                '443',\n                '995.996',\n                '112[0]',\n                '223[0].224',\n                '334[1][0].335',\n                '556.557.558[0]',\n                '778.889'\n              ]\n            }\n          },\n          axis: {\n            x: {\n              type: 'category'\n            }\n          }\n        }\n      })\n\n      it('should draw nested JSON correctly', function() {\n        var expectedCx = [98, 294, 490],\n          expectedCy = {\n            443: [181, 326, 36],\n            995: [362, 398, 326],\n            112: [354, 347, 340],\n            223: [391, 383, 376],\n            334: [376, 398, 362],\n            556: [326, 253, 181],\n            '778.889': [347, 376, 340]\n          }\n\n        d3.selectAll('.c3-circles-443 .c3-circle').each(function(d, i) {\n          var circle = d3.select(this)\n          expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)\n          expect(+circle.attr('cy')).toBeCloseTo(expectedCy[443][i], 0)\n        })\n\n        d3.selectAll('.c3-circles-995-996 .c3-circle').each(function(d, i) {\n          var circle = d3.select(this)\n          expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)\n          expect(+circle.attr('cy')).toBeCloseTo(expectedCy[995][i], 0)\n        })\n\n        d3.selectAll('.c3-circles-112-0- .c3-circle').each(function(d, i) {\n          var circle = d3.select(this)\n          expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)\n          expect(+circle.attr('cy')).toBeCloseTo(expectedCy[112][i], 0)\n        })\n\n        d3.selectAll('.c3-circles-223-0--224 .c3-circle').each(function(d, i) {\n          var circle = d3.select(this)\n          expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)\n          expect(+circle.attr('cy')).toBeCloseTo(expectedCy[223][i], 0)\n        })\n\n        d3.selectAll('.c3-circles-334-1--0--335 .c3-circle').each(function(\n          d,\n          i\n        ) {\n          var circle = d3.select(this)\n          expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)\n          expect(+circle.attr('cy')).toBeCloseTo(expectedCy[334][i], 0)\n        })\n\n        d3.selectAll('.c3-circles-556-557-558-0- .c3-circle').each(function(\n          d,\n          i\n        ) {\n          var circle = d3.select(this)\n          expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)\n          expect(+circle.attr('cy')).toBeCloseTo(expectedCy[556][i], 0)\n        })\n\n        d3.selectAll('.c3-circles-778-889 .c3-circle').each(function(d, i) {\n          var circle = d3.select(this)\n          expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)\n          expect(+circle.attr('cy')).toBeCloseTo(expectedCy['778.889'][i], 0)\n        })\n      })\n    })\n  })\n\n  describe('load rows', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          rows: [\n            ['data1', 'data2', 'data3'],\n            [90, 120, 300],\n            [40, 160, 240],\n            [50, 200, 290],\n            [120, 160, 230],\n            [80, 130, 300],\n            [90, 220, 320]\n          ]\n        }\n      }\n    })\n\n    it('should draw correctly', function() {\n      var expectedCx = [6, 124, 241, 358, 475, 593],\n        expectedCy = [327, 391, 378, 289, 340, 327]\n      d3.selectAll('.c3-circles-data1 .c3-circle').each(function(d, i) {\n        var circle = d3.select(this)\n        expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0)\n        expect(+circle.attr('cy')).toBeCloseTo(expectedCy[i], 0)\n      })\n    })\n  })\n\n  describe('function in data.order', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25],\n            ['data3', 150, 120, 110, 140, 115, 125]\n          ],\n          order: function() {\n            return 0\n          }\n        }\n      }\n    })\n\n    it('should return false in isOrderAsc and isOrderDesc functions', function() {\n      expect(chart.internal.isOrderAsc() || chart.internal.isOrderDesc()).toBe(\n        false\n      )\n    })\n  })\n\n  describe('addHiddenTargetIds if not already hidden', function() {\n    it('should update args', function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 150, 120, 110, 140, 115, 125]\n          ]\n        }\n      }\n      expect(true).toBeTruthy()\n    })\n\n    it('length of hiddenTargetIds should not change if same key added twice', function() {\n      chart.internal.addHiddenTargetIds('data1')\n      expect(chart.internal.hiddenTargetIds.length).toBe(1)\n      chart.internal.addHiddenTargetIds('data1')\n      expect(chart.internal.hiddenTargetIds.length).toBe(1)\n      chart.hide('data1')\n      expect(chart.internal.hiddenTargetIds.length).toBe(1)\n      chart.internal.addHiddenTargetIds('data2')\n      expect(chart.internal.hiddenTargetIds.length).toBe(2)\n      chart.show()\n      chart.hide(['data1', 'data2'])\n      expect(chart.internal.hiddenTargetIds.length).toBe(2)\n      chart.show()\n      chart.hide()\n      expect(chart.internal.hiddenTargetIds.length).toBe(2)\n    })\n  })\n\n  describe('addHiddenLegendIds if not already hidden', function() {\n    it('should update args', function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 150, 120, 110, 140, 115, 125]\n          ]\n        }\n      }\n      expect(true).toBeTruthy()\n    })\n\n    it('length of hiddenLegendIds should not change if same key added twice', function() {\n      chart.internal.addHiddenLegendIds('data1')\n      expect(chart.internal.hiddenLegendIds.length).toBe(1)\n      chart.internal.addHiddenLegendIds('data1')\n      expect(chart.internal.hiddenLegendIds.length).toBe(1)\n      chart.hide('data1', { withLegend: true })\n      expect(chart.internal.hiddenLegendIds.length).toBe(1)\n      chart.hide('data2', { withLegend: true })\n      expect(chart.internal.hiddenLegendIds.length).toBe(2)\n      chart.show(['data1', 'data2'], { withLegend: true })\n      chart.hide(['data1', 'data2'], { withLegend: true })\n      expect(chart.internal.hiddenLegendIds.length).toBe(2)\n    })\n  })\n\n  describe('data.xs', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25],\n            ['data3', 150, 120, 110, 140, 115, 125]\n          ]\n        }\n      }\n    })\n\n    describe('normal x', function() {\n      it('should have correct number of xs for each', function() {\n        expect(Object.keys(chart.internal.data.xs).length).toBe(3)\n        expect(chart.internal.data.xs.data1.length).toBe(6)\n        expect(chart.internal.data.xs.data2.length).toBe(6)\n        expect(chart.internal.data.xs.data3.length).toBe(6)\n      })\n\n      it('should have integer index as x', function() {\n        for (var i = 0; i < chart.internal.data.xs.data3.length; i++) {\n          expect(chart.internal.data.xs.data1[i]).toBe(i)\n          expect(chart.internal.data.xs.data2[i]).toBe(i)\n          expect(chart.internal.data.xs.data3[i]).toBe(i)\n        }\n      })\n    })\n\n    describe('timeseries x', function() {\n      describe('without xFormat', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              x: 'date',\n              columns: [\n                ['date', '2013-01-01', '2013-01-02', '2013-01-03'],\n                ['data1', 30, 200, 100],\n                ['data2', 130, 300, 200]\n              ]\n            },\n            axis: {\n              x: {\n                type: 'timeseries'\n              }\n            }\n          }\n        })\n\n        it('should have correct number of xs', function() {\n          expect(Object.keys(chart.internal.data.xs).length).toBe(2)\n          expect(chart.internal.data.xs.data1.length).toBe(3)\n          expect(chart.internal.data.xs.data2.length).toBe(3)\n        })\n\n        it('should have Date object as x', function() {\n          var xs = chart.internal.data.xs\n          expect(+xs.data1[0]).toBe(+new Date(2013, 0, 1, 0, 0, 0))\n          expect(+xs.data1[1]).toBe(+new Date(2013, 0, 2, 0, 0, 0))\n          expect(+xs.data1[2]).toBe(+new Date(2013, 0, 3, 0, 0, 0))\n          expect(+xs.data2[0]).toBe(+new Date(2013, 0, 1, 0, 0, 0))\n          expect(+xs.data2[1]).toBe(+new Date(2013, 0, 2, 0, 0, 0))\n          expect(+xs.data2[2]).toBe(+new Date(2013, 0, 3, 0, 0, 0))\n        })\n      })\n\n      describe('with xFormat', function() {\n        describe('timeseries x with xFormat', function() {\n          beforeAll(function() {\n            args = {\n              data: {\n                x: 'date',\n                xFormat: '%Y%m%d',\n                columns: [\n                  ['date', '20130101', '20130102', '20130103'],\n                  ['data1', 30, 200, 100],\n                  ['data2', 130, 300, 200]\n                ]\n              },\n              axis: {\n                x: {\n                  type: 'timeseries'\n                }\n              }\n            }\n          })\n\n          it('should have correct number of xs', function() {\n            expect(Object.keys(chart.internal.data.xs).length).toBe(2)\n            expect(chart.internal.data.xs.data1.length).toBe(3)\n            expect(chart.internal.data.xs.data2.length).toBe(3)\n          })\n\n          it('should have Date object as x', function() {\n            var xs = chart.internal.data.xs\n            expect(+xs.data1[0]).toBe(+new Date(2013, 0, 1, 0, 0, 0))\n            expect(+xs.data1[1]).toBe(+new Date(2013, 0, 2, 0, 0, 0))\n            expect(+xs.data1[2]).toBe(+new Date(2013, 0, 3, 0, 0, 0))\n            expect(+xs.data2[0]).toBe(+new Date(2013, 0, 1, 0, 0, 0))\n            expect(+xs.data2[1]).toBe(+new Date(2013, 0, 2, 0, 0, 0))\n            expect(+xs.data2[2]).toBe(+new Date(2013, 0, 3, 0, 0, 0))\n          })\n        })\n      })\n    })\n\n    describe('milliseconds timeseries x', function() {\n      describe('as date string', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              x: 'date',\n              xFormat: '%Y-%m-%d %H:%M:%S.%L',\n              columns: [\n                ['date', '2014-05-20 17:25:00.123', '2014-05-20 17:30:00.345'],\n                ['data1', 30, 200],\n                ['data2', 130, 300]\n              ]\n            },\n            axis: {\n              x: {\n                type: 'timeseries',\n                tick: {\n                  format: '%Y-%m-%d %H:%M:%S.%L',\n                  multiline: false\n                }\n              }\n            }\n          }\n        })\n\n        it('should have correct number of xs', function() {\n          expect(Object.keys(chart.internal.data.xs).length).toBe(2)\n          expect(chart.internal.data.xs.data1.length).toBe(2)\n          expect(chart.internal.data.xs.data2.length).toBe(2)\n        })\n\n        it('should have Date object as x', function() {\n          var xs = chart.internal.data.xs\n          expect(+xs.data1[0]).toBe(+new Date(2014, 4, 20, 17, 25, 0, 123))\n          expect(+xs.data1[1]).toBe(+new Date(2014, 4, 20, 17, 30, 0, 345))\n          expect(+xs.data2[0]).toBe(+new Date(2014, 4, 20, 17, 25, 0, 123))\n          expect(+xs.data2[1]).toBe(+new Date(2014, 4, 20, 17, 30, 0, 345))\n        })\n\n        it('should have milliseconds tick format', function() {\n          var expected = ['2014-05-20 17:25:00.123', '2014-05-20 17:30:00.345']\n          chart.internal.main\n            .selectAll('.c3-axis-x g.tick text')\n            .each(function(d, i) {\n              expect(d3.select(this).text()).toBe(expected[i])\n            })\n        })\n      })\n\n      describe('as unixtime number', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              x: 'date',\n              columns: [\n                ['date', 1417622461123, 1417622522345],\n                ['data1', 30, 200],\n                ['data2', 130, 300]\n              ]\n            },\n            axis: {\n              x: {\n                type: 'timeseries',\n                tick: {\n                  format: '%Y-%m-%d %H:%M:%S.%L'\n                }\n              }\n            }\n          }\n        })\n\n        it('should have correct number of xs', function() {\n          expect(Object.keys(chart.internal.data.xs).length).toBe(2)\n          expect(chart.internal.data.xs.data1.length).toBe(2)\n          expect(chart.internal.data.xs.data2.length).toBe(2)\n        })\n\n        it('should have Date object as x', function() {\n          var xs = chart.internal.data.xs\n          expect(+xs.data1[0]).toBe(1417622461123)\n          expect(+xs.data1[1]).toBe(1417622522345)\n          expect(+xs.data2[0]).toBe(1417622461123)\n          expect(+xs.data2[1]).toBe(1417622522345)\n        })\n      })\n    })\n  })\n\n  describe('data.label', function() {\n    describe('on line chart', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 1030, 2200, 2100],\n              ['data2', 1150, 2010, 1200],\n              ['data3', -1150, -2010, -1200],\n              ['data4', -1030, -2200, -2100]\n            ],\n            type: 'line',\n            labels: true\n          }\n        }\n      })\n\n      it('should locate data labels in correct position', function() {\n        var expectedTextY = {\n          data1: [128, 38, 46],\n          data2: [119, 53, 115],\n          data3: [311, 377, 315],\n          data4: [302, 392, 384]\n        }\n        var expectedTextX = {\n          data1: [6, 294, 583],\n          data2: [6, 294, 583],\n          data3: [6, 294, 583],\n          data4: [6, 294, 583]\n        }\n        Object.keys(expectedTextY).forEach(function(key) {\n          d3.selectAll('.c3-texts-' + key + ' text.c3-text').each(function(\n            d,\n            i\n          ) {\n            var text = d3.select(this)\n            expect(+text.attr('y')).toBeCloseTo(expectedTextY[key][i], -2)\n            expect(+text.attr('x')).toBeCloseTo(expectedTextX[key][i], -2)\n          })\n        })\n      })\n\n      describe('with stacked', function() {\n        beforeAll(function() {\n          args.data.groups = [\n            ['data1', 'data2'],\n            ['data3', 'data4']\n          ]\n        })\n\n        it('should locate data labels in correct position', function() {\n          var expectedTextY = {\n            data1: [120, 38, 75],\n            data2: [161, 127, 159],\n            data3: [269, 303, 271],\n            data4: [310, 392, 355]\n          }\n          var expectedTextX = {\n            data1: [6, 294, 583],\n            data2: [6, 294, 583],\n            data3: [6, 294, 583],\n            data4: [6, 294, 583]\n          }\n          Object.keys(expectedTextY).forEach(function(key) {\n            d3.selectAll('.c3-texts-' + key + ' text.c3-text').each(function(\n              d,\n              i\n            ) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedTextY[key][i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedTextX[key][i], -2)\n            })\n          })\n        })\n      })\n    })\n\n    describe('on area chart', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 1030, 2200, 2100],\n              ['data2', 1150, 2010, 1200],\n              ['data3', -1150, -2010, -1200],\n              ['data4', -1030, -2200, -2100]\n            ],\n            type: 'area',\n            labels: true\n          }\n        }\n      })\n\n      it('should locate data labels in correct position', function() {\n        var expectedTextY = {\n          data1: [128, 38, 46],\n          data2: [119, 53, 115],\n          data3: [311, 377, 315],\n          data4: [302, 392, 384]\n        }\n        var expectedTextX = {\n          data1: [6, 294, 583],\n          data2: [6, 294, 583],\n          data3: [6, 294, 583],\n          data4: [6, 294, 583]\n        }\n        Object.keys(expectedTextY).forEach(function(key) {\n          d3.selectAll('.c3-texts-' + key + ' text.c3-text').each(function(\n            d,\n            i\n          ) {\n            var text = d3.select(this)\n            expect(+text.attr('y')).toBeCloseTo(expectedTextY[key][i], -2)\n            expect(+text.attr('x')).toBeCloseTo(expectedTextX[key][i], -2)\n          })\n        })\n      })\n\n      describe('with stacked', function() {\n        beforeAll(function() {\n          args.data.groups = [\n            ['data1', 'data2'],\n            ['data3', 'data4']\n          ]\n        })\n\n        it('should locate data labels in correct position', function() {\n          var expectedTextY = {\n            data1: [120, 38, 75],\n            data2: [161, 127, 159],\n            data3: [269, 303, 271],\n            data4: [310, 392, 355]\n          }\n          var expectedTextX = {\n            data1: [6, 294, 583],\n            data2: [6, 294, 583],\n            data3: [6, 294, 583],\n            data4: [6, 294, 583]\n          }\n          Object.keys(expectedTextY).forEach(function(key) {\n            d3.selectAll('.c3-texts-' + key + ' text.c3-text').each(function(\n              d,\n              i\n            ) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedTextY[key][i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedTextX[key][i], -2)\n            })\n          })\n        })\n      })\n    })\n\n    describe('on bar chart', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 1030, 2200, 2100],\n              ['data2', 1150, 2010, 1200],\n              ['data3', -1150, -2010, -1200],\n              ['data4', -1030, -2200, -2100]\n            ],\n            type: 'bar',\n            labels: true\n          }\n        }\n      })\n\n      it('should locate data labels in correct position', function() {\n        var expectedTextY = {\n          data1: [128, 38, 46],\n          data2: [119, 53, 115],\n          data3: [311, 377, 315],\n          data4: [302, 392, 384]\n        }\n        var expectedTextX = {\n          data1: [53, 249, 445],\n          data2: [83, 279, 475],\n          data3: [112, 308, 504],\n          data4: [142, 338, 534]\n        }\n        Object.keys(expectedTextY).forEach(function(key) {\n          d3.selectAll('.c3-texts-' + key + ' text.c3-text').each(function(\n            d,\n            i\n          ) {\n            var text = d3.select(this)\n            expect(+text.attr('y')).toBeCloseTo(expectedTextY[key][i], -2)\n            expect(+text.attr('x')).toBeCloseTo(expectedTextX[key][i], -2)\n          })\n        })\n      })\n\n      describe('with stacked', function() {\n        beforeAll(function() {\n          args.data.groups = [\n            ['data1', 'data2'],\n            ['data3', 'data4']\n          ]\n        })\n\n        it('should locate data labels in correct position', function() {\n          var expectedTextY = {\n            data1: [120, 38, 75],\n            data2: [161, 127, 159],\n            data3: [269, 303, 271],\n            data4: [310, 392, 355]\n          }\n          var expectedTextX = {\n            data1: [68.6, 264, 460],\n            data2: [68.6, 264, 460],\n            data3: [127, 323, 519],\n            data4: [127, 323, 519]\n          }\n          Object.keys(expectedTextY).forEach(function(key) {\n            d3.selectAll('.c3-texts-' + key + ' text.c3-text').each(function(\n              d,\n              i\n            ) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedTextY[key][i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedTextX[key][i], -2)\n            })\n          })\n        })\n      })\n    })\n\n    describe('for all targets', function() {\n      describe('with data label for all data', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              columns: [\n                ['data1', 100, 200, 100, 400, 150, 250],\n                ['data2', 10, 20, 10, 40, 15, 25],\n                ['data3', 1000, 2000, 1000, 4000, 1500, 2500]\n              ],\n              labels: true\n            }\n          }\n        })\n\n        it('should have data labels on all data', function() {\n          d3.selectAll('.c3-texts-data1 text').each(function(d, i) {\n            expect(d3.select(this).text()).toBe(\n              args.data.columns[0][i + 1] + ''\n            )\n          })\n          d3.selectAll('.c3-texts-data2 text').each(function(d, i) {\n            expect(d3.select(this).text()).toBe(\n              args.data.columns[1][i + 1] + ''\n            )\n          })\n          d3.selectAll('.c3-texts-data3 text').each(function(d, i) {\n            expect(d3.select(this).text()).toBe(\n              args.data.columns[2][i + 1] + ''\n            )\n          })\n        })\n      })\n    })\n\n    describe('for each target', function() {\n      describe('as true', function() {\n        describe('with data label for only data1', function() {\n          beforeAll(function() {\n            args = {\n              data: {\n                columns: [\n                  ['data1', 100, 200, 100, 400, 150, 250],\n                  ['data2', 10, 20, 10, 40, 15, 25],\n                  ['data3', 1000, 2000, 1000, 4000, 1500, 2500]\n                ],\n                labels: {\n                  format: {\n                    data1: true\n                  }\n                }\n              }\n            }\n          })\n\n          it('should have data labels on all data', function() {\n            d3.selectAll('.c3-texts-data1 text').each(function(d, i) {\n              expect(d3.select(this).text()).toBe(\n                args.data.columns[0][i + 1] + ''\n              )\n            })\n            d3.selectAll('.c3-texts-data2 text').each(function() {\n              expect(d3.select(this).text()).toBe('')\n            })\n            d3.selectAll('.c3-texts-data3 text').each(function() {\n              expect(d3.select(this).text()).toBe('')\n            })\n          })\n        })\n      })\n\n      describe('as function', function() {\n        describe('with data label for only data1', function() {\n          beforeAll(function() {\n            args = {\n              data: {\n                columns: [\n                  ['data1', 100, 200, 100, 400, 150, 250],\n                  ['data2', 10, 20, 10, 40, 15, 25],\n                  ['data3', 1000, 2000, 1000, 4000, 1500, 2500]\n                ],\n                labels: {\n                  format: {\n                    data1: d3.format('$')\n                  }\n                }\n              }\n            }\n          })\n\n          it('should have data labels on all data', function() {\n            d3.selectAll('.c3-texts-data1 text').each(function(d, i) {\n              expect(d3.select(this).text()).toBe(\n                '$' + args.data.columns[0][i + 1]\n              )\n            })\n            d3.selectAll('.c3-texts-data2 text').each(function() {\n              expect(d3.select(this).text()).toBe('')\n            })\n            d3.selectAll('.c3-texts-data3 text').each(function() {\n              expect(d3.select(this).text()).toBe('')\n            })\n          })\n        })\n      })\n    })\n\n    describe('with small values', function() {\n      describe('with data label', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              columns: [['data1', 0.03, 0.2, 0.1, 0.4, 0.15, 0.25]],\n              labels: true\n            }\n          }\n        })\n\n        it('should have proper y domain', function() {\n          var domain = chart.internal.y.domain()\n          expect(domain[0]).toBeCloseTo(-0.02)\n          expect(domain[1]).toBeCloseTo(0.45)\n        })\n      })\n    })\n\n    describe('with positive values and null', function() {\n      describe('on not rotated axis', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              columns: [['data1', 190, 200, 190, null]],\n              type: 'bar',\n              labels: {\n                format: function(v) {\n                  if (v === null) {\n                    return 'Not Applicable'\n                  }\n                  return d3.format('$')(v)\n                }\n              }\n            }\n          }\n        })\n\n        it('should have y domain with proper padding', function() {\n          var domain = chart.internal.y.domain()\n          expect(domain[0]).toBeCloseTo(0, -1)\n          expect(domain[1]).toBeCloseTo(227, -1)\n        })\n\n        it('should locate labels above each data point', function() {\n          var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n            expectedYs = [67, 49, 67, 423],\n            expectedXs = [74, 221, 368, 515]\n          texts.each(function(d, i) {\n            var text = d3.select(this)\n            expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n            expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n          })\n        })\n\n        describe('data type line', function() {\n          beforeAll(function() {\n            args.data.type = 'line'\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(189, -1)\n            expect(domain[1]).toBeCloseTo(201, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [375, 40, 375, 422],\n              expectedXs = [6, 198, 391, 583]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n      })\n\n      describe('on rotated axis', function() {\n        describe('data type bar', function() {\n          beforeAll(function() {\n            args.data.type = 'bar'\n            args.axis = {\n              rotated: true\n            }\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(0, -1)\n            expect(domain[1]).toBeCloseTo(231, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [57, 163, 269, 375],\n              expectedXs = [490, 516, 490, 4]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n\n        describe('data type line', function() {\n          beforeAll(function() {\n            args.data.type = 'line'\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(188, -1)\n            expect(domain[1]).toBeCloseTo(202, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [9, 147, 286, 424],\n              expectedXs = [76, 526, 76, 4]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n      })\n    })\n\n    describe('with negative values and null', function() {\n      describe('on not rotated axis', function() {\n        describe('type bar', function() {\n          beforeAll(function() {\n            args = {\n              data: {\n                columns: [['data1', -190, 0, -190, null]],\n                type: 'bar',\n                labels: {\n                  format: function(v) {\n                    if (v === null) {\n                      return 'Not Applicable'\n                    }\n                    return d3.format('$')(v)\n                  }\n                }\n              }\n            }\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-215, -1)\n            expect(domain[1]).toBeCloseTo(0, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [368, 12, 368, 12],\n              expectedXs = [74, 221, 368, 515]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n\n        describe('data type line', function() {\n          beforeAll(function() {\n            args.data.type = 'line'\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-215, -1)\n            expect(domain[1]).toBeCloseTo(25, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [395, 60, 395, 12],\n              expectedXs = [6, 198, 391, 583]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n      })\n\n      describe('on rotated axis', function() {\n        describe('data type bar', function() {\n          beforeAll(function() {\n            args.data.type = 'bar'\n            args.axis = {\n              rotated: true\n            }\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-220, -1)\n            expect(domain[1]).toBeCloseTo(0, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [57, 163, 269, 375],\n              expectedXs = [103, 594, 103, 526]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n\n        describe('data type line', function() {\n          beforeAll(function() {\n            args.data.type = 'line'\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-220, -1)\n            expect(domain[1]).toBeCloseTo(24, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [9, 147, 286, 424],\n              expectedXs = [67, 537, 67, 526]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n      })\n    })\n\n    describe('with positive and negative values and null', function() {\n      describe('on non rotated axis', function() {\n        describe('data type bar', function() {\n          beforeAll(function() {\n            args = {\n              data: {\n                columns: [['data1', -190, 200, 190, null]],\n                type: 'bar',\n                labels: {\n                  format: function(v) {\n                    if (v === null) {\n                      return 'Not Applicable'\n                    }\n                    return d3.format('$')(v)\n                  }\n                }\n              }\n            }\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-243, -1)\n            expect(domain[1]).toBeCloseTo(253, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [392, 43, 52, 215],\n              expectedXs = [74, 221, 368, 515]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n\n        describe('data type line', function() {\n          beforeAll(function() {\n            args.data.type = 'line'\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-243, -1)\n            expect(domain[1]).toBeCloseTo(253, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [392, 40, 49, 212],\n              expectedXs = [6, 198, 391, 583]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n      })\n\n      describe('on rotated axis', function() {\n        describe('data type bar', function() {\n          beforeAll(function() {\n            args.data.type = 'bar'\n            args.axis = {\n              rotated: true\n            }\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-253, -1)\n            expect(domain[1]).toBeCloseTo(260, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [57, 163, 269, 375],\n              expectedXs = [69, 525, 513, 295]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n\n        describe('data type line', function() {\n          beforeAll(function() {\n            args.data.type = 'line'\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-253, -1)\n            expect(domain[1]).toBeCloseTo(260, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [9, 147, 286, 424],\n              expectedXs = [67, 527, 515, 297]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n      })\n    })\n\n    describe('with positive grouped values', function() {\n      describe('on non rotated axis', function() {\n        describe('data type bar', function() {\n          beforeAll(function() {\n            args = {\n              data: {\n                columns: [\n                  ['data1', 30, 200, 100, 500],\n                  ['data2', 50, 20, 10, 40],\n                  ['data3', 250, 220, 210, 240]\n                ],\n                groups: [['data1', 'data2', 'data3']],\n                labels: true,\n                type: 'bar'\n              }\n            }\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(0, -1)\n            expect(domain[1]).toBeCloseTo(885, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [385, 317, 370, 164],\n              expectedXs = [74, 221, 368, 515]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n\n        describe('data type line', function() {\n          beforeAll(function() {\n            args.data.type = 'line'\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-94, -1)\n            expect(domain[1]).toBeCloseTo(884, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [344, 284, 331, 144],\n              expectedXs = [6, 198, 391, 583]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n      })\n\n      describe('on rotated axis', function() {\n        describe('data type bar', function() {\n          beforeAll(function() {\n            args.data.type = 'bar'\n            args.axis = {\n              rotated: true\n            }\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(0, -1)\n            expect(domain[1]).toBeCloseTo(888, -1.2)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [57, 163, 269, 375],\n              expectedXs = [57, 150, 77, 363]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n\n        describe('data type line', function() {\n          beforeAll(function() {\n            args.data.type = 'line'\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-87, -1)\n            expect(domain[1]).toBeCloseTo(887, -1.2)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [9, 147, 286, 424],\n              expectedXs = [107, 192, 125, 386]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n      })\n    })\n\n    describe('with negative grouped values', function() {\n      describe('on non rotated axis', function() {\n        describe('data type bar', function() {\n          beforeAll(function() {\n            args = {\n              data: {\n                columns: [\n                  ['data1', -30, -200, -100, -500],\n                  ['data2', -50, -20, -10, -40],\n                  ['data3', -250, -220, -210, -240]\n                ],\n                groups: [['data1', 'data2', 'data3']],\n                labels: true,\n                type: 'bar'\n              }\n            }\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-885, -1)\n            expect(domain[1]).toBeCloseTo(0, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [51, 118, 65, 272],\n              expectedXs = [74, 221, 368, 515]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n\n        describe('data type line', function() {\n          beforeAll(function() {\n            args.data.type = 'line'\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-884, -1)\n            expect(domain[1]).toBeCloseTo(94, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [88, 149, 101, 288],\n              expectedXs = [6, 198, 391, 583]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n      })\n\n      describe('on rotated axis', function() {\n        describe('data type bar', function() {\n          beforeAll(function() {\n            args.data.type = 'bar'\n            args.axis = {\n              rotated: true\n            }\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-899, -1)\n            expect(domain[1]).toBeCloseTo(0, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [57, 163, 269, 375],\n              expectedXs = [533, 440, 513, 230]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n\n        describe('data type line', function() {\n          beforeAll(function() {\n            args.data.type = 'line'\n          })\n\n          it('should have y domain with proper padding', function() {\n            var domain = chart.internal.y.domain()\n            expect(domain[0]).toBeCloseTo(-893, -1)\n            expect(domain[1]).toBeCloseTo(93, -1)\n          })\n\n          it('should locate labels above each data point', function() {\n            var texts = chart.internal.main.selectAll('.c3-texts-data1 text'),\n              expectedYs = [9, 147, 286, 424],\n              expectedXs = [480, 397, 462, 205]\n            texts.each(function(d, i) {\n              var text = d3.select(this)\n              expect(+text.attr('y')).toBeCloseTo(expectedYs[i], -2)\n              expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2)\n            })\n          })\n        })\n      })\n    })\n  })\n\n  describe('data.stack', function() {\n    beforeAll(() => {\n      args = {\n        data: {\n          columns: [\n            ['data1', 230, 50, 300],\n            ['data2', 198, 87, 580]\n          ],\n          type: 'bar',\n          groups: [['data1', 'data2']],\n          stack: {\n            normalize: true\n          }\n        }\n      }\n    })\n\n    const getChartHeight = () =>\n      +chart.internal.main.select(`.c3-event-rect`).attr('height') - 1\n\n    it('check for the normalized y axis tick in percentage', () => {\n      const tick = chart.internal.main.selectAll(`.c3-axis-y .tick tspan`)\n\n      // check for the y axis to be in percentage\n      tick.each(function(v, i) {\n        expect(this.textContent).toEqual(`${i * 10}%`)\n      })\n    })\n\n    it(\"check for the normalized bar's height\", () => {\n      const chartHeight = getChartHeight()\n      const bars = chart.internal.main.selectAll('.c3-bar').nodes()\n\n      bars.splice(0, 3).forEach((v, i) => {\n        expect(v.getBBox().height + bars[i].getBBox().height).toEqual(\n          chartHeight\n        )\n      })\n    })\n\n    it('check when hiding data', done => {\n      const chartHeight = getChartHeight()\n\n      // when\n      chart.hide('data1')\n\n      setTimeout(() => {\n        chart.internal.main.selectAll(`.c3-target-data2 path`).each(function() {\n          expect(this.getBBox().height).toBe(chartHeight)\n        })\n\n        done()\n      }, 500)\n    })\n\n    describe('timeseries chart', () => {\n      beforeAll(function() {\n        args = {\n          data: {\n            x: 'date',\n            columns: [\n              ['date', '2012-12-24', '2012-12-25', '2012-12-26'],\n              ['data1', 30, 200, 400],\n              ['data2', 50, 60, 50]\n            ],\n            groups: [['data1', 'data2']],\n            type: 'bar',\n            stack: {\n              normalize: true\n            }\n          },\n          axis: {\n            x: {\n              type: 'timeseries'\n            }\n          }\n        }\n      })\n\n      it(\"check for the normalized bar's height\", () => {\n        const chartHeight = getChartHeight()\n        const bars = chart.internal.main.selectAll('.c3-bar').nodes()\n\n        expect(document.hidden).toBeFalsy()\n\n        bars.splice(0, 3).forEach((v, i) => {\n          expect(v.getBBox().height + bars[i].getBBox().height).toEqual(\n            chartHeight\n          )\n        })\n      })\n    })\n\n    describe('area chart', () => {\n      beforeAll(() => {\n        args = {\n          data: {\n            columns: [\n              ['data1', 200, 387, 123],\n              ['data2', 200, 387, 123]\n            ],\n            type: 'area',\n            groups: [['data1', 'data2']],\n            stack: {\n              normalize: true\n            }\n          }\n        }\n      })\n\n      it(\"check for the normalized area's height\", () => {\n        const chartHeight = getChartHeight()\n\n        let areaHeight = 0\n        chart.internal.main.selectAll('.c3-area').each(function() {\n          areaHeight += this.getBBox().height\n        })\n\n        expect(document.hidden).toBeFalsy()\n        expect(areaHeight).toEqual(chartHeight)\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/data.convert-spec.ts",
    "content": "import { c3, initChart } from './c3-helper'\n\nconst $$ = c3.chart.internal.fn\n$$.d3 = require('d3')\n\ndescribe('data.convert', () => {\n  describe('$$.convertColumnsToData', () => {\n    it('converts column data to normalized data', () => {\n      const data = $$.convertColumnsToData([\n        ['cat1', 'a', 'b', 'c', 'd'],\n        ['data1', 30, 200, 100, 400],\n        ['cat2', 'b', 'a', 'c', 'd', 'e', 'f'],\n        ['data2', 400, 60, 200, 800, 10, 10]\n      ])\n\n      expect(data).toEqual({\n        keys: ['cat1', 'data1', 'cat2', 'data2'],\n        rows: [\n          {\n            cat1: 'a',\n            data1: 30,\n            cat2: 'b',\n            data2: 400\n          },\n          {\n            cat1: 'b',\n            data1: 200,\n            cat2: 'a',\n            data2: 60\n          },\n          {\n            cat1: 'c',\n            data1: 100,\n            cat2: 'c',\n            data2: 200\n          },\n          {\n            cat1: 'd',\n            data1: 400,\n            cat2: 'd',\n            data2: 800\n          },\n          {\n            cat2: 'e',\n            data2: 10\n          },\n          {\n            cat2: 'f',\n            data2: 10\n          }\n        ]\n      })\n    })\n\n    it('throws when the column data contains undefined', () => {\n      expect(() =>\n        $$.convertColumnsToData([\n          ['cat1', 'a', 'b', 'c', 'd'],\n          ['data1', undefined]\n        ])\n      ).toThrowError(Error, /Source data is missing a component/)\n    })\n  })\n\n  describe('$$.convertRowsToData', () => {\n    it('converts the row data to normalized data', () => {\n      const data = $$.convertRowsToData([\n        ['data1', 'data2', 'data3'],\n        [90, 120, 300],\n        [40, 160, 240],\n        [50, 200, 290],\n        [120, 160, 230],\n        [80, 130, 300],\n        [90, 220, 320]\n      ])\n\n      expect(data).toEqual({\n        keys: ['data1', 'data2', 'data3'],\n        rows: [\n          {\n            data1: 90,\n            data2: 120,\n            data3: 300\n          },\n          {\n            data1: 40,\n            data2: 160,\n            data3: 240\n          },\n          {\n            data1: 50,\n            data2: 200,\n            data3: 290\n          },\n          {\n            data1: 120,\n            data2: 160,\n            data3: 230\n          },\n          {\n            data1: 80,\n            data2: 130,\n            data3: 300\n          },\n          {\n            data1: 90,\n            data2: 220,\n            data3: 320\n          }\n        ]\n      })\n    })\n\n    it('throws when the row data contains undefined', () => {\n      expect(() =>\n        $$.convertRowsToData([\n          ['data1', 'data2', 'data3'],\n          [40, 160, 240],\n          [90, 120, undefined]\n        ])\n      ).toThrowError(Error, /Source data is missing a component/)\n    })\n  })\n\n  describe('$$.convertXsvToData', () => {\n    it('converts the csv data to normalized data', () => {\n      const data = [\n        {\n          data1: '90',\n          data2: '120',\n          data3: '300'\n        },\n        {\n          data1: '40',\n          data2: '160',\n          data3: '240'\n        },\n        {\n          data1: '50',\n          data2: '200',\n          data3: '290'\n        },\n        {\n          data1: '120',\n          data2: '160',\n          data3: '230'\n        },\n        {\n          data1: '80',\n          data2: '130',\n          data3: '300'\n        },\n        {\n          data1: '90',\n          data2: '220',\n          data3: '320'\n        }\n      ]\n      ;(data as any).columns = ['data1', 'data2', 'data3']\n      expect($$.convertXsvToData(data)).toEqual({\n        keys: ['data1', 'data2', 'data3'],\n        rows: [\n          {\n            data1: '90',\n            data2: '120',\n            data3: '300'\n          },\n          {\n            data1: '40',\n            data2: '160',\n            data3: '240'\n          },\n          {\n            data1: '50',\n            data2: '200',\n            data3: '290'\n          },\n          {\n            data1: '120',\n            data2: '160',\n            data3: '230'\n          },\n          {\n            data1: '80',\n            data2: '130',\n            data3: '300'\n          },\n          {\n            data1: '90',\n            data2: '220',\n            data3: '320'\n          }\n        ]\n      })\n    })\n\n    it('converts one lined CSV data', () => {\n      const data = []\n      ;(data as any).columns = ['data1', 'data2', 'data3']\n      expect($$.convertXsvToData(data)).toEqual({\n        keys: ['data1', 'data2', 'data3'],\n        rows: [\n          {\n            data1: null,\n            data2: null,\n            data3: null\n          }\n        ]\n      })\n    })\n  })\n\n  describe('$$.convertDataToTargets', () => {\n    beforeEach(() => {\n      $$.cache = {}\n\n      $$.data = {\n        xs: []\n      }\n\n      $$.config = {\n        data_idConverter: v => v\n      }\n    })\n\n    it('converts the legacy data format into targets', () => {\n      const targets = $$.convertDataToTargets([\n        {\n          data1: 90,\n          data2: 120,\n          data3: 300\n        },\n        {\n          data1: 40,\n          data2: 160,\n          data3: 240\n        }\n      ])\n\n      expect(targets).toEqual([\n        {\n          id: 'data1',\n          id_org: 'data1',\n          values: [\n            { x: 0, value: 90, id: 'data1', index: 0 },\n            { x: 1, value: 40, id: 'data1', index: 1 }\n          ]\n        },\n        {\n          id: 'data2',\n          id_org: 'data2',\n          values: [\n            { x: 0, value: 120, id: 'data2', index: 0 },\n            { x: 1, value: 160, id: 'data2', index: 1 }\n          ]\n        },\n        {\n          id: 'data3',\n          id_org: 'data3',\n          values: [\n            { x: 0, value: 300, id: 'data3', index: 0 },\n            { x: 1, value: 240, id: 'data3', index: 1 }\n          ]\n        }\n      ])\n    })\n\n    it('converts the data into targets', () => {\n      const targets = $$.convertDataToTargets({\n        keys: ['data1', 'data2', 'data3'],\n        rows: [\n          {\n            data1: 90,\n            data2: 120,\n            data3: 300\n          },\n          {\n            data1: 40,\n            data2: 160,\n            data3: 240\n          }\n        ]\n      })\n\n      expect(targets).toEqual([\n        {\n          id: 'data1',\n          id_org: 'data1',\n          values: [\n            { x: 0, value: 90, id: 'data1', index: 0 },\n            { x: 1, value: 40, id: 'data1', index: 1 }\n          ]\n        },\n        {\n          id: 'data2',\n          id_org: 'data2',\n          values: [\n            { x: 0, value: 120, id: 'data2', index: 0 },\n            { x: 1, value: 160, id: 'data2', index: 1 }\n          ]\n        },\n        {\n          id: 'data3',\n          id_org: 'data3',\n          values: [\n            { x: 0, value: 300, id: 'data3', index: 0 },\n            { x: 1, value: 240, id: 'data3', index: 1 }\n          ]\n        }\n      ])\n    })\n  })\n\n  describe('$$.convertJsonToData', () => {\n    it('converts JSON as object (no keys provided)', () => {\n      const data = $$.convertJsonToData({\n        data1: [90, 40, 50, 120, 80, 90],\n        data2: [120, 160, 200, 160, 130, 220],\n        data3: [300, 240, 290, 230, 300, 320]\n      })\n\n      expect(data).toEqual({\n        keys: ['data1', 'data2', 'data3'],\n        rows: [\n          {\n            data1: 90,\n            data2: 120,\n            data3: 300\n          },\n          {\n            data1: 40,\n            data2: 160,\n            data3: 240\n          },\n          {\n            data1: 50,\n            data2: 200,\n            data3: 290\n          },\n          {\n            data1: 120,\n            data2: 160,\n            data3: 230\n          },\n          {\n            data1: 80,\n            data2: 130,\n            data3: 300\n          },\n          {\n            data1: 90,\n            data2: 220,\n            data3: 320\n          }\n        ]\n      })\n    })\n\n    it('converts JSON as rows (keys provided)', () => {\n      const data = $$.convertJsonToData(\n        [\n          {\n            data1: 90,\n            data2: 120,\n            data3: 300,\n            unused: 42\n          },\n          {\n            data1: 40,\n            data2: 160,\n            data3: 240,\n            unused: 42\n          },\n          {\n            data1: 50,\n            data2: 200,\n            data3: 290,\n            unused: 42\n          },\n          {\n            data1: 120,\n            data2: 160,\n            data3: 230,\n            unused: 42\n          },\n          {\n            data1: 80,\n            data2: 130,\n            data3: 300,\n            unused: 42\n          },\n          {\n            data1: 90,\n            data2: 220,\n            data3: 320,\n            unused: 42\n          }\n        ],\n        {\n          value: ['data1', 'data2', 'data3']\n        }\n      )\n\n      expect(data).toEqual({\n        keys: ['data1', 'data2', 'data3'],\n        rows: [\n          {\n            data1: 90,\n            data2: 120,\n            data3: 300\n          },\n          {\n            data1: 40,\n            data2: 160,\n            data3: 240\n          },\n          {\n            data1: 50,\n            data2: 200,\n            data3: 290\n          },\n          {\n            data1: 120,\n            data2: 160,\n            data3: 230\n          },\n          {\n            data1: 80,\n            data2: 130,\n            data3: 300\n          },\n          {\n            data1: 90,\n            data2: 220,\n            data3: 320\n          }\n        ]\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/domain-spec.ts",
    "content": "import { initChart } from './c3-helper'\n\ndescribe('c3 chart domain', function() {\n  'use strict'\n\n  var chart\n\n  var args = {\n    data: {\n      columns: [\n        ['data1', 30, 200, 100, 400, 150, 250],\n        ['data2', 50, 20, 10, 40, 15, 25]\n      ]\n    },\n    axis: {\n      y: {},\n      y2: {}\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('axis.y.min', function() {\n    describe('should change axis.y.min to -100', function() {\n      beforeAll(function() {\n        ;(args.axis.y as any).min = -100\n      })\n\n      it('should be set properly when smaller than max of data', function() {\n        var domain = chart.internal.y.domain()\n        expect(domain[0]).toBe(-150)\n        expect(domain[1]).toBe(450)\n      })\n    })\n\n    describe('should change axis.y.min to 500', function() {\n      beforeAll(function() {\n        ;(args.axis.y as any).min = 500\n      })\n\n      it('should be set properly when bigger than max of data', function() {\n        var domain = chart.internal.y.domain()\n        expect(domain[0]).toBe(499)\n        expect(domain[1]).toBe(511)\n      })\n    })\n\n    afterAll(function() {\n      ;(args.axis.y as any).min = undefined\n    })\n  })\n\n  describe('axis.y.max', function() {\n    describe('should change axis.y.max to 1000', function() {\n      beforeAll(function() {\n        ;(args.axis.y as any).max = 1000\n      })\n\n      it('should be set properly when bigger than min of data', function() {\n        var domain = chart.internal.y.domain()\n        expect(domain[0]).toBe(-89)\n        expect(domain[1]).toBe(1099)\n      })\n    })\n\n    describe('should change axis.y.max to 0', function() {\n      beforeAll(function() {\n        ;(args.axis.y as any).max = 0\n      })\n\n      it('should be set properly when smaller than min of data', function() {\n        var domain = chart.internal.y.domain()\n        expect(domain[0]).toBe(-11)\n        expect(domain[1]).toBe(1)\n      })\n    })\n  })\n\n  describe('axis.y.padding', function() {\n    describe('should change axis.y.max to 1000', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 10, 20, 10, 40, 15, 25],\n              ['data2', 50, 40, 30, 45, 25, 45]\n            ]\n          },\n          axis: {\n            y: {\n              padding: 200\n            },\n            y2: {}\n          }\n        }\n      })\n\n      it('should be set properly when bigger than min of data', function() {\n        var domain = chart.internal.y.domain()\n        expect(domain[0]).toBeCloseTo(-9, -1)\n        expect(domain[1]).toBeCloseTo(69, -1)\n      })\n    })\n\n    describe('should change axis.y.max to 1000 with top/bottom padding', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 10, 20, 10, 40, 15, 25],\n              ['data2', 50, 40, 30, 45, 25, 45]\n            ]\n          },\n          axis: {\n            y: {\n              padding: {\n                top: 200,\n                bottom: 200\n              }\n            },\n            y2: {}\n          }\n        }\n      })\n\n      it('should be set properly when bigger than min of data', function() {\n        var domain = chart.internal.y.domain()\n        expect(domain[0]).toBeCloseTo(-9, -1)\n        expect(domain[1]).toBeCloseTo(69, -1)\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/drag-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('drag behavior', function() {\n  'use strict'\n\n  var chart, shapes, $$, totalshapes\n\n  var args = {\n    data: {\n      x: 'x',\n      columns: [\n        ['x', 10, 30, 45, 50, 70, 100],\n        ['data1', 30, 200, 100, 400, 150, 250],\n        ['data2', 20, 180, 240, 100, 190]\n      ],\n      selection: {\n        enabled: true,\n        grouped: true,\n        multiple: true,\n        draggable: true\n      }\n    }\n  }\n\n  beforeAll(function(done) {\n    chart = initChart(chart, args, done)\n    $$ = chart.internal\n    shapes = $$.main\n      .selectAll('.' + $$.CLASS.shapes)\n      .selectAll('.' + $$.CLASS.shape)\n    totalshapes = shapes.size()\n  })\n\n  it('should contain 15 shapes', function() {\n    expect(totalshapes).toBe(15)\n  })\n\n  it('should have no selected shapes', function() {\n    var selected = shapes\n      .filter(function() {\n        return d3.select(this).classed($$.CLASS.SELECTED)\n      })\n      .size()\n\n    expect(selected).toBe(0)\n  })\n\n  describe('Trigger drag events', function() {\n    beforeAll(function() {\n      var s = chart.internal.eventRect,\n        coords1 = [\n          (s.attr('width') - s.attr('x')) / 3,\n          (s.attr('height') - s.attr('y')) / 3\n        ],\n        coords2 = [\n          (2 * (s.attr('width') - s.attr('x'))) / 3,\n          (2 * (s.attr('height') - s.attr('y'))) / 3\n        ]\n      $$.dragstart(coords1)\n      $$.drag(coords2)\n      $$.dragend()\n    })\n\n    it('should select 6 shapes', function() {\n      var selected = shapes\n        .filter(function() {\n          return d3.select(this).classed($$.CLASS.SELECTED)\n        })\n        .size()\n\n      expect(selected).toBe(6)\n    })\n\n    it('should select 9 unselected shapes', function() {\n      var unselected = shapes\n        .filter(function() {\n          return !d3.select(this).classed($$.CLASS.SELECTED)\n        })\n        .size()\n\n      expect(unselected).toBe(9)\n    })\n\n    describe('Selected api', function() {\n      it('should return 6 selected shapes', function() {\n        var selected = chart.selected()\n        expect(selected.length).toBe(6)\n      })\n\n      it('should return 3 selected shapes with targetId = data1', function() {\n        var selected = chart.selected('data1')\n        expect(selected.length).toBe(3)\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/grid-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\ndescribe('c3 chart grid', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('y grid show', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [['data1', 30, 200, 100, 400, 150, 250]]\n        },\n        axis: {\n          y: {\n            tick: {}\n          }\n        },\n        grid: {\n          y: {\n            show: false\n          }\n        }\n      }\n    })\n\n    it('should not show y grids', function() {\n      expect(chart.internal.main.select('.c3-ygrids').size()).toBe(0)\n    })\n\n    describe('with y grids', function() {\n      beforeAll(function() {\n        args.grid.y.show = true\n      })\n\n      it('should show y grids', function() {\n        var ygrids = chart.internal.main.select('.c3-ygrids')\n        expect(ygrids.size()).toBe(1)\n        expect(ygrids.selectAll('.c3-ygrid').size()).toBe(9)\n      })\n    })\n\n    describe('with only 3 y grids', function() {\n      beforeAll(function() {\n        args.grid.y.ticks = 3\n      })\n\n      it('should show only 3 y grids', function() {\n        var ygrids = chart.internal.main.select('.c3-ygrids')\n        expect(ygrids.size()).toBe(1)\n        expect(ygrids.selectAll('.c3-ygrid').size()).toBe(3)\n      })\n    })\n\n    describe('with y grids depending on y axis ticks', function() {\n      beforeAll(function() {\n        args.axis.y.tick.count = 5\n      })\n\n      it('should show grids depending on y axis ticks', function() {\n        var ygrids = chart.internal.main.select('.c3-ygrids'),\n          expectedYs = []\n        ygrids.selectAll('.c3-ygrid').each(function(d, i) {\n          expectedYs[i] = Math.ceil(+d3.select(this).attr('y1'))\n        })\n        expect(ygrids.size()).toBe(1)\n        expect(ygrids.selectAll('.c3-ygrid').size()).toBe(5)\n        chart.internal.main\n          .select('.c3-axis-y')\n          .selectAll('.tick')\n          .each(function(d, i) {\n            var t = d3.select(this).attr('transform')\n            expect(t).toBe('translate(0,' + expectedYs[i] + ')')\n          })\n      })\n    })\n  })\n\n  describe('y grid lines', function() {\n    describe('position', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [['data1', 10, 200, 100, 400, 150, 250]]\n          },\n          grid: {\n            y: {\n              lines: [\n                {\n                  value: 30,\n                  text: 'Label 30',\n                  position: 'start'\n                },\n                {\n                  value: 145,\n                  text: 'Label 145',\n                  position: 'middle'\n                },\n                { value: 225, text: 'Label 225' }\n              ]\n            }\n          }\n        }\n      })\n\n      it('should show 3 grid lines', function() {\n        expect(\n          chart.internal.main.selectAll('.c3-ygrid-lines .c3-ygrid-line').size()\n        ).toBe(3)\n      })\n\n      it('should locate grid lines properly', function() {\n        var lines = chart.internal.main.selectAll(\n            '.c3-ygrid-lines .c3-ygrid-line'\n          ),\n          expectedY1s = [373, 268, 196]\n        lines.each(function(d, i) {\n          var y1 = d3\n            .select(this)\n            .select('line')\n            .attr('y1')\n          expect(y1).toBeCloseTo(expectedY1s[i], -2)\n        })\n      })\n\n      it('should locate grid texts properly', function() {\n        var lines = chart.internal.main.selectAll(\n            '.c3-ygrid-lines .c3-ygrid-line'\n          ),\n          expectedPositions = ['start', 'middle', 'end'],\n          expectedDxs = [4, 0, -4]\n        lines.each(function(d, i) {\n          var text = d3.select(this).select('text'),\n            textAnchor = text.attr('text-anchor'),\n            dx = text.attr('dx')\n          expect(textAnchor).toBe(expectedPositions[i])\n          expect(+dx).toBe(expectedDxs[i])\n        })\n      })\n\n      describe('three gridlines', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              columns: [['data1', 10, 200, 100, 400, 150, 250]]\n            },\n            axis: {\n              rotated: true\n            },\n            grid: {\n              y: {\n                lines: [\n                  {\n                    value: 30,\n                    text: 'Label 30',\n                    position: 'start'\n                  },\n                  {\n                    value: 145,\n                    text: 'Label 145',\n                    position: 'middle'\n                  },\n                  { value: 225, text: 'Label 225' }\n                ]\n              }\n            }\n          }\n        })\n\n        it('should show 3 grid lines', function() {\n          expect(\n            chart.internal.main\n              .selectAll('.c3-ygrid-lines .c3-ygrid-line')\n              .size()\n          ).toBe(3)\n        })\n\n        it('should locate grid lines properly', function() {\n          var lines = chart.internal.main.selectAll(\n              '.c3-ygrid-lines .c3-ygrid-line'\n            ),\n            expectedX1s = [75, 220, 321]\n          lines.each(function(d, i) {\n            var x1 = d3\n              .select(this)\n              .select('line')\n              .attr('x1')\n            expect(x1).toBeCloseTo(expectedX1s[i], -2)\n          })\n        })\n\n        it('should locate grid texts properly', function() {\n          var lines = chart.internal.main.selectAll(\n              '.c3-ygrid-lines .c3-ygrid-line'\n            ),\n            expectedPositions = ['start', 'middle', 'end'],\n            expectedDxs = [4, 0, -4]\n          lines.each(function(d, i) {\n            var text = d3.select(this).select('text'),\n              textAnchor = text.attr('text-anchor'),\n              dx = text.attr('dx')\n            expect(textAnchor).toBe(expectedPositions[i])\n            expect(+dx).toBe(expectedDxs[i])\n          })\n        })\n      })\n    })\n  })\n\n  describe('x grid lines', function() {\n    describe('position', function() {\n      beforeAll(function() {\n        // 'should have correct height',\n        args = {\n          data: {\n            columns: [['data1', 30, 200, 100, 400]]\n          },\n          grid: {\n            x: {\n              lines: [\n                {\n                  value: 1,\n                  text: 'Label 1',\n                  position: 'start'\n                },\n                {\n                  value: 2,\n                  text: 'Label 2',\n                  position: 'middle'\n                },\n                { value: 3, text: 'Label 3' }\n              ]\n            }\n          }\n        }\n      })\n\n      it('should show 3 grid lines', function() {\n        expect(\n          chart.internal.main.selectAll('.c3-xgrid-lines .c3-xgrid-line').size()\n        ).toBe(3)\n      })\n\n      it('should locate grid lines properly', function() {\n        var lines = chart.internal.main.selectAll(\n            '.c3-xgrid-lines .c3-xgrid-line'\n          ),\n          expectedX1s = [202, 397, 593]\n        lines.each(function(d, i) {\n          var x1 = d3\n            .select(this)\n            .select('line')\n            .attr('x1')\n          expect(x1).toBeCloseTo(expectedX1s[i], -2)\n        })\n      })\n\n      it('should locate grid texts properly', function() {\n        var lines = chart.internal.main.selectAll(\n            '.c3-xgrid-lines .c3-xgrid-line'\n          ),\n          expectedPositions = ['start', 'middle', 'end'],\n          expectedDxs = [4, 0, -4]\n        lines.each(function(d, i) {\n          var text = d3.select(this).select('text'),\n            textAnchor = text.attr('text-anchor'),\n            dx = text.attr('dx')\n          expect(textAnchor).toBe(expectedPositions[i])\n          expect(+dx).toBe(expectedDxs[i])\n        })\n      })\n\n      describe('three grid lines', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              columns: [['data1', 30, 200, 100, 400]]\n            },\n            axis: {\n              rotated: true\n            },\n            grid: {\n              x: {\n                lines: [\n                  {\n                    value: 1,\n                    text: 'Label 1',\n                    position: 'start'\n                  },\n                  {\n                    value: 2,\n                    text: 'Label 2',\n                    position: 'middle'\n                  },\n                  { value: 3, text: 'Label 3' }\n                ]\n              }\n            }\n          }\n        })\n\n        it('should show 3 grid lines', function() {\n          expect(\n            chart.internal.main\n              .selectAll('.c3-xgrid-lines .c3-xgrid-line')\n              .size()\n          ).toBe(3)\n        })\n\n        it('should locate grid lines properly', function() {\n          var lines = chart.internal.main.selectAll(\n              '.c3-xgrid-lines .c3-xgrid-line'\n            ),\n            expectedY1s = [144, 283, 421]\n          lines.each(function(d, i) {\n            var y1 = d3\n              .select(this)\n              .select('line')\n              .attr('y1')\n            expect(y1).toBeCloseTo(expectedY1s[i], -2)\n          })\n        })\n\n        it('should locate grid texts properly', function() {\n          var lines = chart.internal.main.selectAll(\n              '.c3-xgrid-lines .c3-xgrid-line'\n            ),\n            expectedPositions = ['start', 'middle', 'end'],\n            expectedDxs = [4, 0, -4]\n          lines.each(function(d, i) {\n            var text = d3.select(this).select('text'),\n              textAnchor = text.attr('text-anchor'),\n              dx = text.attr('dx')\n            expect(textAnchor).toBe(expectedPositions[i])\n            expect(+dx).toBe(expectedDxs[i])\n          })\n        })\n      })\n    })\n\n    describe('with padding.top', function() {\n      describe('should have correct height', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              columns: [['data1', 30, 200, 100, 400]]\n            },\n            grid: {\n              x: {\n                lines: [{ value: 3, text: 'Label 3' }]\n              }\n            },\n            padding: {\n              top: 50\n            }\n          }\n        })\n\n        it('should show x grid lines', function() {\n          var lines = chart.internal.main.select(\n              '.c3-xgrid-lines .c3-xgrid-line'\n            ),\n            expectedX1 = 593,\n            expectedText = ['Label 3']\n          lines.each(function(id, i) {\n            var line = d3.select(this),\n              l = line.select('line'),\n              t = line.select('text')\n            expect(+l.attr('x1')).toBeCloseTo(expectedX1, -2)\n            expect(t.text()).toBe(expectedText[i])\n          })\n        })\n      })\n    })\n\n    describe('on category axis', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            x: 'x',\n            columns: [\n              ['x', 'a', 'b', 'c', 'd'],\n              ['data1', 30, 200, 100, 400]\n            ]\n          },\n          axis: {\n            x: {\n              type: 'category'\n            }\n          },\n          grid: {\n            x: {\n              lines: [\n                { value: 3, text: 'Label 3' },\n                { value: 'a', text: 'Label a' }\n              ]\n            }\n          }\n        }\n      })\n\n      it('should show x grid lines', function() {\n        var lines = chart.internal.main.selectAll(\n            '.c3-xgrid-lines .c3-xgrid-line'\n          ),\n          expectedX1 = [515, 74],\n          expectedText = ['Label 3', 'Label a']\n        lines.each(function(id, i) {\n          var line = d3.select(this),\n            l = line.select('line'),\n            t = line.select('text')\n          expect(+l.attr('x1')).toBeCloseTo(expectedX1[i], -2)\n          expect(t.text()).toBe(expectedText[i])\n        })\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/interaction-spec.ts",
    "content": "import { d3, setMouseEvent, initChart } from './c3-helper'\n\ndescribe('c3 chart interaction', function() {\n  'use strict'\n\n  var chart, args\n\n  const moveMouseOut = () =>\n    setMouseEvent(chart, 'mouseout', 0, 0, d3.select('.c3-event-rect').node())\n\n  const moveMouse = (x = 0, y = 0) =>\n    setMouseEvent(chart, 'mousemove', x, y, d3.select('.c3-event-rect').node())\n\n  const clickMouse = (x = 0, y = 0) =>\n    setMouseEvent(chart, 'click', x, y, d3.select('.c3-event-rect').node())\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('generate event rects', function() {\n    describe('custom x', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            x: 'x',\n            columns: [\n              ['x', 0, 1000, 3000, 10000],\n              ['data', 10, 10, 10, 10]\n            ],\n            type: 'bar'\n          }\n        }\n      })\n\n      it('should have only 1 event rect properly', function() {\n        var eventRects = d3.selectAll('.c3-event-rect')\n        expect(eventRects.size()).toBe(1)\n        eventRects.each(function() {\n          var box = (d3.select(this).node() as any).getBoundingClientRect()\n          expect(box.left).toBeCloseTo(40.5, -2)\n          expect(box.width).toBeCloseTo(598, -2)\n        })\n      })\n\n      describe('mouseover', function() {\n        let mouseoutCounter = 0\n        let mouseoverCounter = 0\n\n        beforeAll(function() {\n          args = {\n            data: {\n              columns: [\n                ['data1', 30, 200, 100, 400, -150, 250],\n                ['data2', 50, 20, 10, 40, 15, 25],\n                ['data3', -150, 120, 110, 140, 115, 125]\n              ],\n              type: 'bar',\n              onmouseout: function() {\n                mouseoutCounter += 1\n              },\n              onmouseover: function() {\n                mouseoverCounter += 1\n              }\n            },\n            axis: {\n              rotated: false\n            }\n          }\n        })\n\n        beforeEach(function() {\n          mouseoverCounter = 0\n          mouseoutCounter = 0\n        })\n\n        it('should be undefined when not within bar', function() {\n          moveMouseOut()\n\n          expect(mouseoutCounter).toEqual(0)\n          expect(mouseoverCounter).toEqual(0)\n          expect(chart.internal.mouseover).toBeUndefined()\n        })\n\n        it('should be data value when within bar', function() {\n          moveMouse(31, 280)\n\n          expect(mouseoutCounter).toEqual(0)\n          expect(mouseoverCounter).toEqual(1)\n          expect(chart.internal.mouseover).toEqual({\n            x: 0,\n            value: 30,\n            index: 0,\n            id: 'data1',\n            name: 'data1'\n          })\n        })\n\n        it('should be undefined after leaving chart', function() {\n          moveMouse(31, 280)\n          moveMouseOut()\n\n          expect(mouseoutCounter).toEqual(1)\n          expect(mouseoverCounter).toEqual(1)\n          expect(chart.internal.mouseover).toBeUndefined()\n        })\n\n        it('should retrigger mouseover event when returning to same value', function() {\n          moveMouse(31, 280)\n          moveMouseOut()\n          moveMouse(31, 280)\n\n          expect(mouseoutCounter).toEqual(1)\n          expect(mouseoverCounter).toEqual(2)\n          expect(chart.internal.mouseover).toEqual({\n            x: 0,\n            value: 30,\n            index: 0,\n            id: 'data1',\n            name: 'data1'\n          })\n        })\n      })\n\n      describe('should generate bar chart with only one data', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              x: 'x',\n              columns: [\n                ['x', 0],\n                ['data', 10]\n              ],\n              type: 'bar'\n            }\n          }\n        })\n\n        it('should have 1 event rects properly', function() {\n          var eventRects = d3.selectAll('.c3-event-rect')\n          expect(eventRects.size()).toBe(1)\n          eventRects.each(function() {\n            var box = (d3.select(this).node() as any).getBoundingClientRect()\n            expect(box.left).toBeCloseTo(40.5, -2)\n            expect(box.width).toBeCloseTo(598, -2)\n          })\n        })\n      })\n    })\n\n    describe('timeseries', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            x: 'x',\n            columns: [\n              ['x', '20140101', '20140201', '20140210', '20140301'],\n              ['data', 10, 10, 10, 10]\n            ]\n          }\n        }\n      })\n\n      it('should have only 1 event rect properly', function() {\n        var eventRects = d3.selectAll('.c3-event-rect')\n        expect(eventRects.size()).toBe(1)\n        eventRects.each(function() {\n          var box = (d3.select(this).node() as any).getBoundingClientRect()\n          expect(box.left).toBeCloseTo(40.5, -2)\n          expect(box.width).toBeCloseTo(598, -2)\n        })\n      })\n\n      describe('should generate line chart with only 1 data timeseries', function() {\n        beforeAll(function() {\n          args = {\n            data: {\n              x: 'x',\n              columns: [\n                ['x', '20140101'],\n                ['data', 10]\n              ]\n            }\n          }\n        })\n\n        it('should have 1 event rects properly', function() {\n          var eventRects = d3.selectAll('.c3-event-rect')\n          expect(eventRects.size()).toBe(1)\n          eventRects.each(function() {\n            var box = (d3.select(this).node() as any).getBoundingClientRect()\n            expect(box.left).toBeCloseTo(40.5, -2)\n            expect(box.width).toBeCloseTo(598, -2)\n          })\n        })\n      })\n    })\n  })\n\n  describe('bar chart', function() {\n    describe('tooltip_grouped=true', function() {\n      beforeAll(() => {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, 200, 200, 400, 150, -250],\n              ['data2', 130, -100, 100, 200, 150, 50],\n              ['data3', 230, -200, 200, 0, 250, 250]\n            ],\n            type: 'bar',\n            groups: [['data1', 'data2']],\n            hide: ['data1']\n          },\n          tooltip: {\n            grouped: true\n          },\n          axis: {\n            x: {\n              type: 'category'\n            },\n            rotated: true\n          },\n          interaction: {\n            enabled: true\n          }\n        }\n      })\n\n      it('generate a single rect', () => {\n        const eventRectList = d3.selectAll('.c3-event-rect')\n\n        expect(eventRectList.size()).toBe(1)\n        expect(eventRectList.attr('x')).toEqual('0')\n        expect(eventRectList.attr('y')).toEqual('0')\n        expect(eventRectList.attr('height')).toEqual('' + chart.internal.height)\n        expect(eventRectList.attr('width')).toEqual('' + chart.internal.width)\n      })\n\n      it('shows tooltip with visible data of currently hovered category', () => {\n        moveMouse(20, 20)\n\n        expect(\n          (document.querySelector('.c3-tooltip-container') as any).style.display\n        ).toEqual('block')\n\n        const tooltipData = [\n          ...(document.querySelectorAll('.c3-tooltip tr') as any)\n        ]\n\n        expect(tooltipData.length).toBe(3) // header + data[123]\n\n        expect(tooltipData[1].querySelector('.name').textContent).toBe('data3')\n        expect(tooltipData[2].querySelector('.name').textContent).toBe('data2')\n      })\n\n      it('shows cursor:pointer only if hovering bar', () => {\n        const eventRect = d3.select('.c3-event-rect')\n\n        moveMouse(1, 1)\n\n        expect(eventRect.style('cursor')).toEqual('auto')\n\n        moveMouse(360, 48)\n\n        expect(eventRect.style('cursor')).toEqual('pointer')\n\n        moveMouse(1, 1)\n\n        expect(eventRect.style('cursor')).toEqual('auto')\n      })\n\n      it('expands all bars of currently hovered category', () => {\n        moveMouse(20, 20)\n\n        const barList = d3.selectAll('.c3-bar')\n\n        expect(barList.size()).toBeGreaterThan(0)\n\n        barList.each(function() {\n          if (\n            (this as any).classList.contains('c3-bar-0') &&\n            !(this as any).parentElement.classList.contains('c3-bars-data1')\n          ) {\n            expect((this as any).classList.contains('_expanded_')).toBeTruthy()\n          } else {\n            expect((this as any).classList.contains('_expanded_')).toBeFalsy()\n          }\n        })\n\n        moveMouse(20, 170)\n\n        barList.each(function() {\n          if (\n            (this as any).classList.contains('c3-bar-2') &&\n            !(this as any).parentElement.classList.contains('c3-bars-data1')\n          ) {\n            expect((this as any).classList.contains('_expanded_')).toBeTruthy()\n          } else {\n            expect((this as any).classList.contains('_expanded_')).toBeFalsy()\n          }\n        })\n      })\n    })\n\n    describe('tooltip_grouped=false', function() {\n      beforeAll(() => {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, 200, 200, 400, 150, -250],\n              ['data2', 130, -100, 100, 200, 150, 50],\n              ['data3', 230, -200, 200, 0, 250, 250]\n            ],\n            type: 'bar',\n            groups: [['data1', 'data2']]\n          },\n          tooltip: {\n            grouped: false\n          },\n          axis: {\n            x: {\n              type: 'category'\n            }\n          },\n          interaction: {\n            enabled: true\n          }\n        }\n      })\n\n      it('generate a single rect', () => {\n        const eventRectList = d3.selectAll('.c3-event-rect')\n\n        expect(eventRectList.size()).toBe(1)\n        expect(eventRectList.attr('x')).toEqual('0')\n        expect(eventRectList.attr('y')).toEqual('0')\n        expect(eventRectList.attr('height')).toEqual('' + chart.internal.height)\n        expect(eventRectList.attr('width')).toEqual('' + chart.internal.width)\n      })\n\n      it('shows tooltip with only hovered data', () => {\n        moveMouse(1, 1)\n\n        expect(\n          (document.querySelector('.c3-tooltip-container') as any).style.display\n        ).toEqual('none')\n\n        moveMouse(35, 268)\n\n        expect(\n          (document.querySelector('.c3-tooltip-container') as any).style.display\n        ).toEqual('block')\n\n        const tooltipData = [\n          ...(document.querySelectorAll('.c3-tooltip tr') as any)\n        ]\n\n        expect(tooltipData.length).toBe(2) // header + data2\n\n        expect(tooltipData[1].querySelector('.name').textContent).toBe('data2')\n        expect(tooltipData[1].querySelector('.value').textContent).toBe('130')\n      })\n\n      it('expands only hovered bar', () => {\n        moveMouse(20, 20)\n\n        const barList = d3.selectAll('.c3-bar')\n\n        expect(barList.size()).toBeGreaterThan(0)\n\n        // nothing expanded\n        barList.each(function() {\n          expect((this as any).classList.contains('_expanded_')).toBeFalsy()\n        })\n\n        moveMouse(38, 258)\n\n        barList.each(function() {\n          if (\n            (this as any).classList.contains('c3-bar-0') &&\n            (this as any).parentElement.classList.contains('c3-bars-data2')\n          ) {\n            expect((this as any).classList.contains('_expanded_')).toBeTruthy()\n          } else {\n            expect((this as any).classList.contains('_expanded_')).toBeFalsy()\n          }\n        })\n      })\n    })\n  })\n\n  describe('line chart', function() {\n    describe('tooltip_grouped=false', function() {\n      let clickedData = []\n\n      beforeAll(() => {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, 200, 200, 400, 150, -250],\n              ['data2', 130, -100, 100, 200, 150, 50],\n              ['data3', 230, -200, 200, 0, 250, 250]\n            ],\n            type: 'line',\n            groups: [['data1', 'data2']],\n            onclick: function(d) {\n              clickedData.push(d)\n            }\n          },\n          tooltip: {\n            grouped: false\n          },\n          axis: {\n            x: {\n              type: 'category'\n            }\n          },\n          interaction: {\n            enabled: true\n          },\n          point: {\n            r: 2,\n            sensitivity: 10,\n            focus: {\n              expand: {\n                enabled: true,\n                r: 8\n              }\n            }\n          }\n        }\n      })\n\n      beforeEach(function() {\n        clickedData = []\n      })\n\n      it('shows tooltip with only hovered data', () => {\n        moveMouse(1, 1)\n\n        expect(\n          (document.querySelector('.c3-tooltip-container') as any).style.display\n        ).toEqual('none')\n\n        moveMouse(48, 184)\n\n        expect(\n          (document.querySelector('.c3-tooltip-container') as any).style.display\n        ).toEqual('block')\n\n        const tooltipData = [\n          ...(document.querySelectorAll('.c3-tooltip tr') as any)\n        ]\n\n        expect(tooltipData.length).toBe(2) // header + data3\n\n        expect(tooltipData[1].querySelector('.name').textContent).toBe('data3')\n        expect(tooltipData[1].querySelector('.value').textContent).toBe('230')\n      })\n\n      it('expands only hovered point', () => {\n        moveMouse(1, 1)\n\n        const circleList = d3.selectAll('.c3-circle')\n\n        expect(circleList.size()).toBeGreaterThan(0)\n\n        // nothing expanded\n        circleList.each(function() {\n          expect((this as any).classList.contains('_expanded_')).toBeFalsy()\n        })\n\n        moveMouse(45, 233)\n\n        circleList.each(function() {\n          expect((this as any).classList.contains('_expanded_')).toEqual(\n            (this as any).classList.contains('c3-circle-0') &&\n              (this as any).parentElement.classList.contains('c3-circles-data2')\n          )\n        })\n      })\n\n      it('shows cursor:pointer only if hovering point', () => {\n        const eventRect = d3.select('.c3-event-rect')\n\n        moveMouse(1, 1)\n\n        expect(eventRect.style('cursor')).toEqual('auto')\n\n        moveMouse(49, 219)\n\n        expect(eventRect.style('cursor')).toEqual('pointer')\n\n        moveMouse(1, 1)\n\n        expect(eventRect.style('cursor')).toEqual('auto')\n      })\n\n      it('clicks only on hovered point', () => {\n        clickMouse(144, 201)\n\n        expect(clickedData).toEqual([\n          {\n            x: 1,\n            index: 1,\n            value: 200,\n            id: 'data1',\n            name: 'data1'\n          }\n        ])\n      })\n\n      describe('with selection enabled', () => {\n        beforeAll(() => {\n          args.data.selection = {\n            enabled: true,\n            isselectable: function(d) {\n              return d.id !== 'data3'\n            }\n          }\n        })\n\n        it('can toggle selection', () => {\n          expect(d3.selectAll('.c3-circle _selected_').size()).toEqual(0)\n\n          clickMouse(144, 201) // index 1 @ data1\n\n          expect(d3.selectAll('.c3-circle._selected_').size()).toEqual(1)\n          expect(\n            d3.select('.c3-circles-data1 .c3-circle-1._selected_').size()\n          ).toEqual(1)\n\n          // data3 is not selectable\n          clickMouse(391, 283) // index 3 @ data3\n\n          expect(d3.selectAll('.c3-circle._selected_').size()).toEqual(1)\n          expect(\n            d3.select('.c3-circles-data3 .c3-circle-3._selected_').size()\n          ).toEqual(0)\n          expect(\n            d3.select('.c3-circles-data1 .c3-circle-1._selected_').size()\n          ).toEqual(1)\n\n          clickMouse(343, 204) // index 3 @ data2\n\n          expect(d3.selectAll('.c3-circle._selected_').size()).toEqual(2)\n          expect(\n            d3.select('.c3-circles-data2 .c3-circle-3._selected_').size()\n          ).toEqual(1)\n          expect(\n            d3.select('.c3-circles-data1 .c3-circle-1._selected_').size()\n          ).toEqual(1)\n\n          clickMouse(144, 201) // index 1 @ data1\n\n          expect(d3.selectAll('.c3-circle._selected_').size()).toEqual(1)\n          expect(\n            d3.select('.c3-circles-data2 .c3-circle-3._selected_').size()\n          ).toEqual(1)\n        })\n      })\n\n      describe('with tooltip_horizontal=true', () => {\n        beforeAll(() => {\n          args.tooltip.horizontal = true\n        })\n\n        it('can clicks on points', () => {\n          // out of point sensitivity\n          clickMouse(146, 46)\n          clickMouse(343, 263)\n\n          // click 3 data point\n          clickMouse(147, 370)\n          clickMouse(340, 203)\n          clickMouse(537, 386)\n\n          expect(clickedData).toEqual([\n            {\n              x: 1,\n              value: -200,\n              id: 'data3',\n              index: 1,\n              name: 'data3'\n            },\n            {\n              x: 3,\n              value: 200,\n              id: 'data2',\n              index: 3,\n              name: 'data2'\n            },\n            {\n              x: 5,\n              value: -250,\n              id: 'data1',\n              index: 5,\n              name: 'data1'\n            }\n          ])\n        })\n\n        it('shows tooltip with only closest data', () => {\n          moveMouse(1, 1)\n\n          expect(\n            (document.querySelector('.c3-tooltip-container') as any).style\n              .display\n          ).toEqual('none')\n\n          moveMouse(146, 46)\n\n          expect(\n            (document.querySelector('.c3-tooltip-container') as any).style\n              .display\n          ).toEqual('block')\n\n          let tooltipData = [\n            ...(document.querySelectorAll('.c3-tooltip tr') as any)\n          ]\n\n          expect(tooltipData.length).toBe(2) // header + data1\n\n          expect(tooltipData[1].querySelector('.name').textContent).toBe(\n            'data1'\n          )\n          expect(tooltipData[1].querySelector('.value').textContent).toBe('200')\n\n          moveMouse(343, 263)\n\n          expect(\n            (document.querySelector('.c3-tooltip-container') as any).style\n              .display\n          ).toEqual('block')\n\n          tooltipData = [\n            ...(document.querySelectorAll('.c3-tooltip tr') as any)\n          ]\n\n          expect(tooltipData.length).toBe(2) // header + data3\n\n          expect(tooltipData[1].querySelector('.name').textContent).toBe(\n            'data3'\n          )\n          expect(tooltipData[1].querySelector('.value').textContent).toBe('0')\n        })\n      })\n    })\n\n    describe('tooltip_grouped=true', function() {\n      let clickedData = []\n\n      beforeAll(() => {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, 200, 200, 400, 150, -250],\n              ['data2', 130, -100, 100, 200, 150, 50],\n              ['data3', 230, -200, 200, 0, 250, 250]\n            ],\n            type: 'line',\n            groups: [['data1', 'data2']],\n            onclick: function(d) {\n              clickedData.push(d)\n            }\n          },\n          tooltip: {\n            grouped: true\n          },\n          axis: {\n            x: {\n              type: 'category'\n            }\n          },\n          interaction: {\n            enabled: true\n          },\n          point: {\n            r: 2,\n            sensitivity: 10,\n            focus: {\n              expand: {\n                enabled: true,\n                r: 8\n              }\n            }\n          }\n        }\n      })\n\n      beforeEach(function() {\n        clickedData = []\n      })\n\n      describe('with tooltip_horizontal=true', () => {\n        beforeAll(() => {\n          args.tooltip.horizontal = true\n        })\n\n        it('can clicks on points', () => {\n          // out of point sensitivity\n          clickMouse(146, 46)\n          clickMouse(343, 263)\n\n          // click 3 data point\n          clickMouse(147, 370)\n          clickMouse(340, 203)\n          clickMouse(537, 386)\n\n          expect(clickedData).toEqual([\n            {\n              x: 1,\n              value: -200,\n              id: 'data3',\n              index: 1,\n              name: 'data3'\n            },\n            {\n              x: 3,\n              value: 200,\n              id: 'data2',\n              index: 3,\n              name: 'data2'\n            },\n            {\n              x: 5,\n              value: -250,\n              id: 'data1',\n              index: 5,\n              name: 'data1'\n            }\n          ])\n        })\n\n        it('shows tooltip with all data', () => {\n          moveMouse(1, 1)\n\n          expect(\n            (document.querySelector('.c3-tooltip-container') as any).style\n              .display\n          ).toEqual('block')\n\n          let tooltipData = [\n            ...(document.querySelectorAll('.c3-tooltip tr') as any)\n          ]\n\n          expect(tooltipData.length).toBe(4) // header + data[123]\n\n          expect(tooltipData[1].querySelector('.name').textContent).toBe(\n            'data1'\n          )\n          expect(tooltipData[1].querySelector('.value').textContent).toBe('30')\n\n          expect(tooltipData[2].querySelector('.name').textContent).toBe(\n            'data3'\n          )\n          expect(tooltipData[2].querySelector('.value').textContent).toBe('230')\n\n          expect(tooltipData[3].querySelector('.name').textContent).toBe(\n            'data2'\n          )\n          expect(tooltipData[3].querySelector('.value').textContent).toBe('130')\n\n          moveMouse(146, 46)\n\n          expect(\n            (document.querySelector('.c3-tooltip-container') as any).style\n              .display\n          ).toEqual('block')\n\n          tooltipData = [\n            ...(document.querySelectorAll('.c3-tooltip tr') as any)\n          ]\n\n          expect(tooltipData.length).toBe(4) // header + data[123]\n\n          expect(tooltipData[1].querySelector('.name').textContent).toBe(\n            'data1'\n          )\n          expect(tooltipData[1].querySelector('.value').textContent).toBe('200')\n\n          expect(tooltipData[2].querySelector('.name').textContent).toBe(\n            'data3'\n          )\n          expect(tooltipData[2].querySelector('.value').textContent).toBe(\n            '-200'\n          )\n\n          expect(tooltipData[3].querySelector('.name').textContent).toBe(\n            'data2'\n          )\n          expect(tooltipData[3].querySelector('.value').textContent).toBe(\n            '-100'\n          )\n        })\n      })\n    })\n  })\n\n  describe('line chart (multiple xs)', function() {\n    let clickedData = []\n\n    beforeAll(() => {\n      args = {\n        data: {\n          xs: {\n            data1: 'x1',\n            data2: 'x2'\n          },\n          columns: [\n            ['x1', 10, 30, 45, 50, 70, 100],\n            ['x2', 30, 50, 75, 100, 120],\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 20, 180, 240, 100, 190]\n          ],\n          type: 'line',\n          onclick: function(d) {\n            clickedData.push(d)\n          }\n        },\n        tooltip: {\n          grouped: true,\n          horizontal: true\n        },\n        interaction: {\n          enabled: true\n        }\n      }\n    })\n\n    beforeEach(function() {\n      clickedData = []\n    })\n\n    it('shows tooltip with all data', () => {\n      moveMouse(1, 1)\n\n      expect(\n        (document.querySelector('.c3-tooltip-container') as any).style.display\n      ).toEqual('block')\n\n      let tooltipData = [\n        ...(document.querySelectorAll('.c3-tooltip tr') as any)\n      ]\n\n      expect(tooltipData.length).toBe(2) // header + data[1]\n\n      expect(tooltipData[1].querySelector('.name').textContent).toBe('data1')\n      expect(tooltipData[1].querySelector('.value').textContent).toBe('30')\n\n      moveMouse(107, 95)\n\n      expect(\n        (document.querySelector('.c3-tooltip-container') as any).style.display\n      ).toEqual('block')\n\n      tooltipData = [...(document.querySelectorAll('.c3-tooltip tr') as any)]\n\n      expect(tooltipData.length).toBe(3) // header + data[12]\n\n      expect(tooltipData[1].querySelector('.name').textContent).toBe('data1')\n      expect(tooltipData[1].querySelector('.value').textContent).toBe('200')\n\n      expect(tooltipData[2].querySelector('.name').textContent).toBe('data2')\n      expect(tooltipData[2].querySelector('.value').textContent).toBe('20')\n\n      moveMouse(430, 140)\n\n      expect(\n        (document.querySelector('.c3-tooltip-container') as any).style.display\n      ).toEqual('block')\n\n      tooltipData = [...(document.querySelectorAll('.c3-tooltip tr') as any)]\n\n      expect(tooltipData.length).toBe(3) // header + data[12]\n\n      expect(tooltipData[1].querySelector('.name').textContent).toBe('data1')\n      expect(tooltipData[1].querySelector('.value').textContent).toBe('250')\n\n      expect(tooltipData[2].querySelector('.name').textContent).toBe('data2')\n      expect(tooltipData[2].querySelector('.value').textContent).toBe('100')\n    })\n  })\n\n  describe('scatter chart', function() {\n    describe('tooltip_grouped=true', function() {\n      beforeAll(() => {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, null, 100, 400, -150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25],\n              ['data3', -150, 120, 110, 140, 115, 125]\n            ],\n            type: 'scatter'\n          },\n          tooltip: {\n            grouped: true\n          },\n          interaction: {\n            enabled: true\n          }\n        }\n      })\n\n      it('shows tooltip with visible data of currently hovered category', () => {\n        moveMouse(20, 20)\n\n        let tooltipData = [\n          ...(document.querySelectorAll('.c3-tooltip tr') as any)\n        ]\n\n        expect(tooltipData.length).toBe(4) // header + data[123]\n\n        expect(tooltipData[1].querySelector('.name').textContent).toBe('data2')\n        expect(tooltipData[1].querySelector('.value').textContent).toBe('50')\n        expect(tooltipData[2].querySelector('.name').textContent).toBe('data1')\n        expect(tooltipData[2].querySelector('.value').textContent).toBe('30')\n        expect(tooltipData[3].querySelector('.name').textContent).toBe('data3')\n        expect(tooltipData[3].querySelector('.value').textContent).toBe('-150')\n\n        moveMouse(350, 354)\n\n        tooltipData = [...(document.querySelectorAll('.c3-tooltip tr') as any)]\n\n        expect(tooltipData.length).toBe(4) // header + data[123]\n\n        expect(tooltipData[1].querySelector('.name').textContent).toBe('data1')\n        expect(tooltipData[1].querySelector('.value').textContent).toBe('400')\n        expect(tooltipData[2].querySelector('.name').textContent).toBe('data3')\n        expect(tooltipData[2].querySelector('.value').textContent).toBe('140')\n        expect(tooltipData[3].querySelector('.name').textContent).toBe('data2')\n        expect(tooltipData[3].querySelector('.value').textContent).toBe('40')\n      })\n\n      it('shows x grid', () => {\n        moveMouse(20, 20)\n\n        expect(d3.select('.c3-xgrid-focus').style('visibility')).toBe('visible')\n      })\n    })\n  })\n\n  describe('area chart (timeseries)', function() {\n    describe('tooltip_grouped=true', function() {\n      beforeAll(() => {\n        args = {\n          data: {\n            x: 'x',\n            columns: [\n              [\n                'x',\n                '2018-01-01',\n                '2018-01-02',\n                '2018-01-03',\n                '2018-01-04',\n                '2018-01-05',\n                '2018-01-06'\n              ],\n              ['data1', 30, 200, 200, 400, 150, 250],\n              ['data2', 130, 100, 100, 200, 150, 50],\n              ['data3', 230, 200, 200, 0, 250, 250]\n            ],\n            type: 'area',\n            groups: [['data1', 'data2', 'data3']]\n          },\n          tooltip: {\n            grouped: true\n          },\n          axis: {\n            x: {\n              type: 'timeseries'\n            }\n          },\n          interaction: {\n            enabled: true\n          }\n        }\n      })\n\n      it('shows tooltip with visible data of currently hovered category', () => {\n        moveMouse(20, 20)\n\n        expect(\n          (document.querySelector('.c3-tooltip-container') as any).style.display\n        ).toEqual('block')\n\n        const tooltipData = [\n          ...(document.querySelectorAll('.c3-tooltip tr') as any)\n        ]\n\n        expect(tooltipData.length).toBe(4) // header + data[123]\n\n        expect(tooltipData[1].querySelector('.name').textContent).toBe('data1')\n        expect(tooltipData[2].querySelector('.name').textContent).toBe('data3')\n        expect(tooltipData[3].querySelector('.name').textContent).toBe('data2')\n      })\n\n      it('shows cursor:pointer only if hovering area', () => {\n        const eventRect = d3.select('.c3-event-rect')\n\n        moveMouse(1, 1)\n\n        expect(eventRect.style('cursor')).toEqual('auto')\n\n        moveMouse(360, 48)\n\n        expect(eventRect.style('cursor')).toEqual('pointer')\n\n        moveMouse(1, 1)\n\n        expect(eventRect.style('cursor')).toEqual('auto')\n      })\n    })\n\n    describe('tooltip_grouped=false', function() {\n      beforeAll(() => {\n        args = {\n          data: {\n            x: 'x',\n            columns: [\n              [\n                'x',\n                '2018-01-01',\n                '2018-01-02',\n                '2018-01-03',\n                '2018-01-04',\n                '2018-01-05',\n                '2018-01-06'\n              ],\n              ['data1', 30, 200, 200, 400, 150, 250],\n              ['data2', 130, 100, 100, 200, 150, 50],\n              ['data3', 230, 200, 200, 0, 250, 250]\n            ],\n            type: 'area',\n            groups: [['data1', 'data2', 'data3']]\n          },\n          tooltip: {\n            grouped: false\n          },\n          axis: {\n            x: {\n              type: 'timeseries'\n            },\n            rotated: false\n          },\n          interaction: {\n            enabled: true\n          }\n        }\n      })\n\n      it('shows tooltip with only hovered data', () => {\n        moveMouse(1, 1)\n\n        expect(\n          (document.querySelector('.c3-tooltip-container') as any).style.display\n        ).toEqual('none')\n\n        moveMouse(5, 174)\n\n        expect(\n          (document.querySelector('.c3-tooltip-container') as any).style.display\n        ).toEqual('block')\n\n        const tooltipData = [\n          ...(document.querySelectorAll('.c3-tooltip tr') as any)\n        ]\n\n        expect(tooltipData.length).toBe(2) // header + data1\n\n        expect(tooltipData[1].querySelector('.name').textContent).toBe('data1')\n        expect(tooltipData[1].querySelector('.value').textContent).toBe('30')\n      })\n    })\n  })\n\n  describe('disabled', function() {\n    beforeAll(() => {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 200, 400, 150, -250],\n            ['data2', 130, -100, 100, 200, 150, 50],\n            ['data3', 230, -200, 200, 0, 250, 250]\n          ],\n          type: 'bar',\n          groups: [['data1', 'data2']]\n        },\n        axis: {\n          x: {\n            type: 'category'\n          }\n        },\n        interaction: {\n          enabled: false\n        }\n      }\n    })\n\n    it('generate a single rect', () => {\n      const eventRectList = d3.selectAll('.c3-event-rect')\n\n      expect(eventRectList.size()).toBe(1)\n      expect(eventRectList.attr('x')).toEqual('0')\n      expect(eventRectList.attr('y')).toEqual('0')\n      expect(eventRectList.attr('height')).toEqual('' + chart.internal.height)\n      expect(eventRectList.attr('width')).toEqual('' + chart.internal.width)\n    })\n\n    it('does not show tooltip when hovering data', () => {\n      moveMouse(40, 260)\n\n      expect(\n        (document.querySelector('.c3-tooltip-container') as any).style.display\n      ).toEqual('none')\n    })\n\n    it('does not show cursor:pointer when hovering data', () => {\n      moveMouse(40, 260)\n\n      expect(d3.select('.c3-event-rect').style('cursor')).toEqual('auto')\n    })\n  })\n})\n"
  },
  {
    "path": "spec/legend-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('c3 chart legend', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('legend when multiple charts rendered', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30],\n            ['data2', 50],\n            ['data3', 100]\n          ]\n        }\n      }\n    })\n\n    describe('long data names', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['long data name 1', 30],\n              ['long data name 2', 50],\n              ['long data name 3', 50]\n            ]\n          }\n        }\n      })\n\n      it('should have properly computed legend width', function() {\n        var expectedLeft = [148, 226, 384],\n          expectedWidth = [118, 118, 108]\n        d3.selectAll('.c3-legend-item').each(function(d, i) {\n          var rect = (d3.select(this).node() as any).getBoundingClientRect()\n          expect(rect.left).toBeCloseTo(expectedLeft[i], -2)\n          expect(rect.width).toBeCloseTo(expectedWidth[i], -2)\n        })\n      })\n    })\n  })\n\n  describe('legend position', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25]\n          ]\n        }\n      }\n    })\n\n    it('should be located on the center of chart', function() {\n      var box = chart.internal.legend.node().getBoundingClientRect()\n      expect(box.left + box.right).toBe(638)\n    })\n  })\n\n  describe('legend as inset', function() {\n    describe('should change the legend to \"inset\" successfully', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, 200, 100, 400, 150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25]\n            ]\n          },\n          legend: {\n            position: 'inset',\n            inset: {\n              step: null\n            }\n          }\n        }\n      })\n\n      it('should be positioned properly', function() {\n        var box = (d3\n          .select('.c3-legend-background')\n          .node() as any).getBoundingClientRect()\n        expect(box.top).toBe(5.5)\n        expect(box.left).toBeGreaterThan(30)\n      })\n\n      it('should have automatically calculated height', function() {\n        var box = (d3\n          .select('.c3-legend-background')\n          .node() as any).getBoundingClientRect()\n        expect(box.height).toBe(48)\n      })\n    })\n\n    describe('should change the legend step to 1 successfully', function() {\n      beforeAll(function() {\n        args.legend.inset.step = 1\n      })\n\n      it('should have automatically calculated height', function() {\n        var box = (d3\n          .select('.c3-legend-background')\n          .node() as any).getBoundingClientRect()\n        expect(box.height).toBe(28)\n      })\n    })\n\n    describe('should change the legend step to 2 successfully', function() {\n      beforeAll(function() {\n        args.legend.inset.step = 2\n      })\n\n      it('should have automatically calculated height', function() {\n        var box = (d3\n          .select('.c3-legend-background')\n          .node() as any).getBoundingClientRect()\n        expect(box.height).toBe(48)\n      })\n    })\n\n    describe('with only one series', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [['data1', 30, 200, 100, 400, 150, 250]]\n          },\n          legend: {\n            position: 'inset'\n          }\n        }\n      })\n\n      it('should locate legend properly', function() {\n        var box = (d3\n          .select('.c3-legend-background')\n          .node() as any).getBoundingClientRect()\n        expect(box.height).toBe(28)\n        expect(box.width).toBeGreaterThan(64)\n      })\n    })\n  })\n\n  describe('legend.hide', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 200, 100, 250, 150]\n          ]\n        },\n        legend: {\n          hide: true\n        }\n      }\n    })\n\n    it('should not show legends', function() {\n      d3.selectAll('.c3-legend-item').each(function() {\n        expect(d3.select(this).style('visibility')).toBe('hidden')\n      })\n    })\n\n    describe('hidden legend', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, 200, 100, 400, 150, 250],\n              ['data2', 130, 100, 200, 100, 250, 150]\n            ]\n          },\n          legend: {\n            hide: 'data2'\n          }\n        }\n      })\n\n      it('should not show legends', function() {\n        expect(d3.select('.c3-legend-item-data1').style('visibility')).toBe(\n          'visible'\n        )\n        expect(d3.select('.c3-legend-item-data2').style('visibility')).toBe(\n          'hidden'\n        )\n      })\n    })\n  })\n\n  describe('legend.show', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 200, 100, 250, 150]\n          ]\n        },\n        legend: {\n          show: false\n        }\n      }\n    })\n\n    it('should not initially have rendered any legend items', function() {\n      expect(d3.selectAll('.c3-legend-item').empty()).toBe(true)\n    })\n\n    it('allows us to show the legend on showLegend call', function() {\n      chart.legend.show()\n      d3.selectAll('.c3-legend-item').each(function() {\n        expect(d3.select(this).style('visibility')).toBe('visible')\n        // This selects all the children, but we expect it to be empty\n        expect((d3.select(this).selectAll('*') as any).length).not.toEqual(0)\n      })\n    })\n  })\n\n  describe('with legend.show is true', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 200, 100, 250, 150]\n          ]\n        },\n        legend: {\n          show: true\n        }\n      }\n    })\n\n    it('should initially have rendered some legend items', function() {\n      expect(d3.selectAll('.c3-legend-item').empty()).toBe(false)\n    })\n\n    it('should remove rendered every legend items', function() {\n      chart.legend.hide()\n      d3.selectAll('.c3-legend-item').each(function() {\n        expect(d3.select(this).style('visibility')).toBe('hidden')\n        // This selects all the children, but we expect it to be empty\n        expect((d3.select(this).selectAll('*') as any).length).toEqual(\n          undefined\n        )\n      })\n    })\n  })\n\n  describe('custom legend size', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 130, 100, 200, 100, 250, 150]\n          ]\n        },\n        legend: {\n          item: {\n            tile: {\n              width: 15,\n              height: 2\n            }\n          }\n        }\n      }\n    })\n\n    it('renders the legend item with the correct width and height', function() {\n      d3.selectAll('.c3-legend-item-tile').each(function() {\n        expect(d3.select(this).style('stroke-width')).toBe(\n          args.legend.item.tile.height + 'px'\n        )\n        var tileWidth =\n          Number(d3.select(this).attr('x2')) -\n          Number(d3.select(this).attr('x1'))\n        expect(tileWidth).toBe(args.legend.item.tile.width)\n      })\n    })\n  })\n\n  describe('custom legend padding', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['padded1', 30, 200, 100, 400, 150, 250],\n            ['padded2', 130, 100, 200, 100, 250, 150]\n          ]\n        },\n        legend: {\n          padding: 10\n        }\n      }\n    })\n\n    it('renders the correct amount of padding on the legend element', function() {\n      d3.selectAll(\n        '.c3-legend-item-padded1 .c3-legend-item-tile, .c3-legend-item-padded2 .c3-legend-item-tile'\n      ).each(function(el, index) {\n        var itemWidth = (d3.select(this).node() as any).parentNode.getBBox()\n            .width,\n          textBoxWidth = (d3\n            .select((d3.select(this).node() as any).parentNode)\n            .select('text')\n            .node() as any).getBBox().width,\n          tileWidth = 17, // default value is 10, plus 7 more for padding @TODO verify this, seems PhantomJS@^2 adds another 1px to each side\n          expectedWidth =\n            textBoxWidth + tileWidth + (index ? 0 : 10) + args.legend.padding\n\n        expect(itemWidth).toBe(expectedWidth)\n      })\n    })\n  })\n\n  describe('legend item tile coloring with color_treshold', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['padded1', 100],\n            ['padded2', 90],\n            ['padded3', 50],\n            ['padded4', 20]\n          ]\n        },\n        type: 'gauge',\n        color: {\n          pattern: ['#FF0000', '#F97600', '#F6C600', '#60B044'],\n          threshold: {\n            values: [30, 80, 95]\n          }\n        }\n      }\n    })\n\n    // espacially for gauges with multiple arcs to have the same coloring between legend tiles, tooltip tiles and arc\n    it('selects the color from color_pattern if color_treshold is given', function() {\n      var tileColor = []\n      d3.selectAll('.c3-legend-item-tile').each(function() {\n        tileColor.push(d3.select(this).style('stroke'))\n      })\n      expect(tileColor[0]).toBe('rgb(96, 176, 68)')\n      expect(tileColor[1]).toBe('rgb(246, 198, 0)')\n      expect(tileColor[2]).toBe('rgb(249, 118, 0)')\n      expect(tileColor[3]).toBe('rgb(255, 0, 0)')\n    })\n  })\n\n  describe('legend item tile coloring with color_treshold (more than one data value)', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['padded1', 40, 60],\n            ['padded2', 100, -10],\n            ['padded3', 0, 50],\n            ['padded4', 20, 0]\n          ]\n        },\n        type: 'gauge',\n        color: {\n          pattern: ['#FF0000', '#F97600', '#F6C600', '#60B044'],\n          threshold: {\n            values: [30, 80, 95]\n          }\n        }\n      }\n    })\n\n    // espacially for gauges with multiple arcs to have the same coloring between legend tiles, tooltip tiles and arc\n    it('selects the color from color_pattern if color_treshold is given', function() {\n      var tileColor = []\n      d3.selectAll('.c3-legend-item-tile').each(function() {\n        tileColor.push(d3.select(this).style('stroke'))\n      })\n      expect(tileColor[0]).toBe('rgb(96, 176, 68)')\n      expect(tileColor[1]).toBe('rgb(246, 198, 0)')\n      expect(tileColor[2]).toBe('rgb(249, 118, 0)')\n      expect(tileColor[3]).toBe('rgb(255, 0, 0)')\n    })\n  })\n\n  describe('legend item tile coloring without color_treshold', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['padded1', 100],\n            ['padded2', 90],\n            ['padded3', 50],\n            ['padded4', 20]\n          ],\n          colors: {\n            padded1: '#60b044',\n            padded4: '#8b008b'\n          }\n        },\n        type: 'gauge'\n      }\n    })\n\n    it('selects the color from data_colors, data_color or default', function() {\n      var tileColor = []\n      d3.selectAll('.c3-legend-item-tile').each(function() {\n        tileColor.push(d3.select(this).style('stroke'))\n      })\n      expect(tileColor[0]).toBe('rgb(96, 176, 68)')\n      expect(tileColor[1]).toBe('rgb(31, 119, 180)')\n      expect(tileColor[2]).toBe('rgb(255, 127, 14)')\n      expect(tileColor[3]).toBe('rgb(139, 0, 139)')\n    })\n  })\n})\n"
  },
  {
    "path": "spec/shape.bar-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('c3 chart shape bar', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('Path boxes', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [['data1', 30]],\n          type: 'bar'\n        },\n        bar: {\n          width: {\n            max: 40\n          }\n        }\n      }\n    })\n\n    it('bars should have expected Path Box', function() {\n      var expected = {\n        x: 279,\n        y: 40,\n        width: 40,\n        height: 387\n      }\n\n      var shapes = chart.internal.main\n        .selectAll('.' + chart.internal.CLASS.shapes)\n        .selectAll('.' + chart.internal.CLASS.shape)\n      shapes.each(function() {\n        var pathBox = chart.internal.getPathBox(this)\n        expect(pathBox.x).toBeCloseTo(expected.x, -1)\n        expect(pathBox.y).toBeCloseTo(expected.y, -1)\n        expect(pathBox.width).toBeCloseTo(expected.width, -1)\n        expect(pathBox.height).toBeCloseTo(expected.height, -1)\n      })\n    })\n  })\n\n  describe('with groups', function() {\n    describe('with indexed data', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, 200, -100, 400, -150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25]\n            ],\n            groups: [['data1', 'data2']],\n            type: 'bar'\n          }\n        }\n      })\n      it('should be stacked', function() {\n        var expectedBottom = [275, 293, 365, 281, 395, 290]\n        chart.internal.main\n          .selectAll('.c3-bars-data1 .c3-bar')\n          .each(function(d, i) {\n            var rect = d3\n              .select(this)\n              .node()\n              .getBoundingClientRect()\n            expect(rect.bottom).toBeCloseTo(expectedBottom[i], -1)\n          })\n      })\n    })\n\n    describe('with timeseries data', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            x: 'date',\n            columns: [\n              [\n                'date',\n                '2012-12-24',\n                '2012-12-25',\n                '2012-12-26',\n                '2012-12-27',\n                '2012-12-28',\n                '2012-12-29'\n              ],\n              ['data1', 30, 200, -100, 400, -150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25]\n            ],\n            groups: [['data1', 'data2']],\n            type: 'bar'\n          },\n          axis: {\n            x: {\n              type: 'timeseries'\n            }\n          }\n        }\n      })\n      it('should be stacked', function() {\n        var expectedBottom = [275, 293, 365, 281, 395, 290]\n        chart.internal.main\n          .selectAll('.c3-bars-data1 .c3-bar')\n          .each(function(d, i) {\n            var rect = d3\n              .select(this)\n              .node()\n              .getBoundingClientRect()\n            expect(rect.bottom).toBeCloseTo(expectedBottom[i], -1)\n          })\n      })\n    })\n\n    describe('with category data', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            x: 'date',\n            columns: [\n              [\n                'date',\n                '2012-12-24',\n                '2012-12-25',\n                '2012-12-26',\n                '2012-12-27',\n                '2012-12-28',\n                '2012-12-29'\n              ],\n              ['data1', 30, 200, -100, 400, -150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25]\n            ],\n            groups: [['data1', 'data2']],\n            type: 'bar'\n          },\n          axis: {\n            x: {\n              type: 'category'\n            }\n          }\n        }\n      })\n\n      it('should be stacked', function() {\n        var expectedBottom = [275, 293, 365, 281, 395, 290]\n        chart.internal.main\n          .selectAll('.c3-bars-data1 .c3-bar')\n          .each(function(d, i) {\n            var rect = d3\n              .select(this)\n              .node()\n              .getBoundingClientRect()\n            expect(rect.bottom).toBeCloseTo(expectedBottom[i], -1)\n          })\n      })\n    })\n  })\n\n  describe('internal.isWithinBar', function() {\n    describe('with normal axis', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, 200, 100, 400, -150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25],\n              ['data3', -150, 120, 110, 140, 115, 125]\n            ],\n            type: 'bar'\n          },\n          axis: {\n            rotated: false\n          }\n        }\n      })\n\n      it('should not be within bar', function() {\n        var bar = d3.select('.c3-target-data1 .c3-bar-0').node()\n        expect(chart.internal.isWithinBar([0, 0], bar)).toBeFalsy()\n      })\n\n      it('should be within bar', function() {\n        var bar = d3.select('.c3-target-data1 .c3-bar-0').node()\n        expect(chart.internal.isWithinBar([31, 280], bar)).toBeTruthy()\n      })\n\n      it('should not be within bar of negative value', function() {\n        var bar = d3.select('.c3-target-data3 .c3-bar-0').node()\n        expect(chart.internal.isWithinBar([68, 280], bar)).toBeFalsy()\n      })\n\n      it('should be within bar of negative value', function() {\n        var bar = d3.select('.c3-target-data3 .c3-bar-0').node()\n        expect(chart.internal.isWithinBar([68, 350], bar)).toBeTruthy()\n      })\n    })\n\n    describe('with rotated axis', function() {\n      beforeAll(function() {\n        args.axis.rotated = true\n      })\n\n      it('should not be within bar', function() {\n        var bar = d3.select('.c3-target-data1 .c3-bar-0').node()\n        expect(chart.internal.isWithinBar([0, 0], bar)).toBeFalsy()\n      })\n\n      it('should be within bar', function() {\n        var bar = d3.select('.c3-target-data1 .c3-bar-0').node()\n        expect(chart.internal.isWithinBar([190, 20], bar)).toBeTruthy()\n      })\n\n      it('should be within bar of negative value', function() {\n        var bar = d3.select('.c3-target-data3 .c3-bar-0').node()\n        expect(chart.internal.isWithinBar([68, 50], bar)).toBeTruthy()\n      })\n    })\n  })\n\n  describe('bar spacing', function() {\n    var createArgs = function(spacing) {\n      return {\n        size: {\n          width: 500\n        },\n        data: {\n          columns: [\n            ['data1', 30, 200, 100],\n            ['data2', 50, 20, 10],\n            ['data3', 150, 120, 110],\n            ['data4', 12, 24, 20]\n          ],\n          type: 'bar',\n          groups: [['data1', 'data4']]\n        },\n        bar: {\n          space: spacing\n        }\n      }\n    }\n\n    var getBBox = function(selector) {\n      return d3\n        .select(selector)\n        .node()\n        .getBBox()\n    }\n\n    var getBarContainerWidth = function() {\n      return parseInt(getBBox('.c3-chart-bars').width)\n    }\n\n    var getBarContainerOffset = function() {\n      return parseInt(getBBox('.c3-chart-bars').x)\n    }\n\n    var getBarBBox = function(name, idx) {\n      return getBBox('.c3-target-' + name + ' .c3-bar-' + (idx || 0))\n    }\n\n    var getBarWidth = function(name, idx) {\n      return parseInt(getBarBBox(name, idx).width)\n    }\n\n    var getBarOffset = function(name1, name2, idx) {\n      var bbox1 = getBarBBox(name1, idx)\n      var bbox2 = getBarBBox(name2, idx)\n      return Math.floor(bbox2.x - (bbox1.x + bbox1.width))\n    }\n\n    it('should set bar spacing to 0', function() {\n      args = createArgs(0)\n      expect(true).toBeTruthy()\n    })\n\n    it('should display the bars without any spacing', function() {\n      // all bars should have the same width\n      expect(getBarWidth('data1', 0)).toEqual(30)\n      expect(getBarWidth('data2', 0)).toEqual(30)\n      expect(getBarWidth('data3', 0)).toEqual(30)\n      expect(getBarWidth('data1', 1)).toEqual(30)\n      expect(getBarWidth('data2', 1)).toEqual(30)\n      expect(getBarWidth('data3', 1)).toEqual(30)\n      expect(getBarWidth('data1', 2)).toEqual(30)\n      expect(getBarWidth('data2', 2)).toEqual(30)\n      expect(getBarWidth('data3', 2)).toEqual(30)\n\n      // all offsets should be the same\n      expect(getBarOffset('data1', 'data2', 0)).toEqual(0)\n      expect(getBarOffset('data2', 'data3', 0)).toEqual(0)\n      expect(getBarOffset('data1', 'data2', 1)).toEqual(0)\n      expect(getBarOffset('data2', 'data3', 1)).toEqual(0)\n      expect(getBarOffset('data1', 'data2', 2)).toEqual(0)\n      expect(getBarOffset('data2', 'data3', 2)).toEqual(0)\n\n      // default width/offset of the container for this chart\n      expect(getBarContainerWidth()).toEqual(396)\n      expect(getBarContainerOffset()).toEqual(31)\n    })\n\n    it('should set bar spacing to 0.25', function() {\n      args = createArgs(0.25)\n      expect(true).toBeTruthy()\n    })\n\n    it('should display the bars with a spacing ratio of 0.25', function() {\n      // with bar_space of 0.25, the space between bars is\n      // expected to be 25% of the original bar's width\n      // which is ~7\n\n      // expect all bars to be the same width\n      expect(getBarWidth('data1', 0)).toEqual(22)\n      expect(getBarWidth('data2', 0)).toEqual(22)\n      expect(getBarWidth('data3', 0)).toEqual(22)\n      expect(getBarWidth('data1', 1)).toEqual(22)\n      expect(getBarWidth('data2', 1)).toEqual(22)\n      expect(getBarWidth('data3', 1)).toEqual(22)\n      expect(getBarWidth('data1', 2)).toEqual(22)\n      expect(getBarWidth('data2', 2)).toEqual(22)\n      expect(getBarWidth('data3', 2)).toEqual(22)\n\n      // all offsets should be the same\n      expect(getBarOffset('data1', 'data2', 0)).toEqual(7)\n      expect(getBarOffset('data2', 'data3', 0)).toEqual(7)\n      expect(getBarOffset('data1', 'data2', 1)).toEqual(7)\n      expect(getBarOffset('data2', 'data3', 1)).toEqual(7)\n      expect(getBarOffset('data1', 'data2', 2)).toEqual(7)\n      expect(getBarOffset('data2', 'data3', 2)).toEqual(7)\n\n      // expect the container to shrink a little because of\n      // the offsets from the first/last chart\n      // we add/subtract 1 because of approximation due to rounded values\n      expect(getBarContainerWidth()).toEqual(396 - 7 - 1)\n      expect(getBarContainerOffset()).toEqual(31 + (Math.floor(7 / 2) + 1))\n    })\n\n    it('should set bar spacing to 0.5', function() {\n      args = createArgs(0.5)\n      expect(true).toBeTruthy()\n    })\n\n    it('should display the bars with a spacing ratio of 0.5', function() {\n      // with bar_space of 0.5, the space between bars is\n      // expected to be 50% of the original bar's width\n      // which is ~15\n\n      // expect all bars to be the same width\n      expect(getBarWidth('data1', 0)).toEqual(15)\n      expect(getBarWidth('data2', 0)).toEqual(15)\n      expect(getBarWidth('data3', 0)).toEqual(15)\n      expect(getBarWidth('data1', 1)).toEqual(15)\n      expect(getBarWidth('data2', 1)).toEqual(15)\n      expect(getBarWidth('data3', 1)).toEqual(15)\n      expect(getBarWidth('data1', 2)).toEqual(15)\n      expect(getBarWidth('data2', 2)).toEqual(15)\n      expect(getBarWidth('data3', 2)).toEqual(15)\n\n      // all offsets should be the same\n      expect(getBarOffset('data1', 'data2', 0)).toEqual(15)\n      expect(getBarOffset('data2', 'data3', 0)).toEqual(15)\n      expect(getBarOffset('data1', 'data2', 1)).toEqual(15)\n      expect(getBarOffset('data2', 'data3', 1)).toEqual(15)\n      expect(getBarOffset('data1', 'data2', 2)).toEqual(15)\n      expect(getBarOffset('data2', 'data3', 2)).toEqual(15)\n\n      // expect the container to shrink a little because of\n      // the offsets from the first/last chart\n      expect(getBarContainerWidth()).toEqual(396 - 15)\n      expect(getBarContainerOffset()).toEqual(31 + Math.floor(15 / 2))\n    })\n  })\n})\n"
  },
  {
    "path": "spec/shape.line-spec.ts",
    "content": "import { parseSvgPath } from './svg-helper'\nimport { d3, initChart } from './c3-helper'\n\ndescribe('c3 chart shape line', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('shape-rendering for line chart', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, -150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25],\n            ['data3', -150, 120, 110, 140, 115, 125]\n          ],\n          type: 'line'\n        },\n        line: {\n          step: {\n            type: 'step'\n          }\n        }\n      }\n    })\n\n    it('Should render the lines correctly', function(done) {\n      setTimeout(function() {\n        var target = chart.internal.main.select(\n          '.c3-chart-line.c3-target-data1'\n        )\n        var commands = parseSvgPath(target.select('.c3-line-data1').attr('d'))\n        expect(commands.length).toBe(6)\n        done()\n      }, 500)\n    })\n\n    it(\"should not have shape-rendering when it's line chart\", function() {\n      d3.selectAll('.c3-line').each(function() {\n        var style = d3.select(this).style('shape-rendering')\n        expect(style).toBe('auto')\n      })\n    })\n\n    describe('should change to step chart', function() {\n      beforeAll(function() {\n        args.data.type = 'step'\n      })\n\n      it(\"should have shape-rendering = crispedges when it's step chart\", function() {\n        d3.selectAll('.c3-line').each(function() {\n          var style = d3\n            .select(this)\n            .style('shape-rendering')\n            .toLowerCase()\n          expect(style).toBe('crispedges')\n        })\n      })\n    })\n\n    describe('should change to step chart with step-after', function() {\n      beforeAll(function() {\n        args.line.step.type = 'step-after'\n      })\n      it(\"should have shape-rendering = crispedges when it's step chart\", function() {\n        d3.selectAll('.c3-line').each(function() {\n          var style = d3\n            .select(this)\n            .style('shape-rendering')\n            .toLowerCase()\n          expect(style).toBe('crispedges')\n        })\n      })\n    })\n\n    describe('should change to step chart with step-before', function() {\n      beforeAll(function() {\n        args.line.step.type = 'step-before'\n      })\n      it(\"should have shape-rendering = crispedges when it's step chart\", function() {\n        d3.selectAll('.c3-line').each(function() {\n          var style = d3\n            .select(this)\n            .style('shape-rendering')\n            .toLowerCase()\n          expect(style).toBe('crispedges')\n        })\n      })\n    })\n\n    describe('should change to spline chart', function() {\n      beforeAll(function() {\n        args.data.type = 'spline'\n      })\n\n      it('should use cardinal interpolation by default', function() {\n        expect(chart.internal.config.spline_interpolation_type).toBe('cardinal')\n      })\n    })\n  })\n\n  describe('point.show option', function() {\n    describe('should change args to include null data', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, null, 100, 400, -150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25],\n              ['data3', -150, 120, 110, 140, 115, 125]\n            ],\n            type: 'line'\n          }\n        }\n      })\n\n      it('should not show the circle for null', function(done) {\n        setTimeout(function() {\n          var target = chart.internal.main.select(\n            '.c3-chart-line.c3-target-data1'\n          )\n          expect(+target.select('.c3-circle-0').style('opacity')).toBe(1)\n          expect(+target.select('.c3-circle-1').style('opacity')).toBe(0)\n          expect(+target.select('.c3-circle-2').style('opacity')).toBe(1)\n          done()\n        }, 500)\n      })\n\n      it('should not draw a line segment for null data', function(done) {\n        setTimeout(function() {\n          var target = chart.internal.main.select(\n            '.c3-chart-line.c3-target-data1'\n          )\n          var commands = parseSvgPath(target.select('.c3-line-data1').attr('d'))\n          var segments = 0\n          for (var i = 0; i < commands.length; i++) {\n            commands[i].command === 'L' ? segments++ : null\n          }\n          expect(segments).toBe(3)\n          done()\n        }, 500)\n      })\n\n      // it('should change args to include null data on scatter plot', function () {\n      //     args = {\n      //         data: {\n      //             columns: [\n      //                 ['data1', 30, null, 100, 400, -150, 250],\n      //                 ['data2', 50, 20, 10, 40, 15, 25],\n      //                 ['data3', -150, 120, 110, 140, 115, 125]\n      //             ],\n      //             type: 'scatter'\n      //         }\n      //     };\n      //     expect(true).toBeTruthy();\n      // });\n\n      // it('should not show the circle for null', function (done) {\n      //     setTimeout(function () {\n      //         var target = chart.internal.main.select('.c3-chart-line.c3-target-data1');\n      //         expect(+target.select('.c3-circle-0').style('opacity')).toBe(0.5);\n      //         expect(+target.select('.c3-circle-1').style('opacity')).toBe(0);\n      //         expect(+target.select('.c3-circle-2').style('opacity')).toBe(0.5);\n      //         done();\n      //     }, 500);\n      // });\n    })\n\n    describe('should allow passing a function', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [['data1', 30, 50, 100]],\n            type: 'line'\n          },\n          point: {\n            show: function(d) {\n              return d.value > 50\n            }\n          }\n        }\n      })\n\n      it('should show point if function returns true', function() {\n        var target = chart.internal.main.select(\n          '.c3-chart-line.c3-target-data1'\n        )\n        expect(+target.select('.c3-circle-0').style('opacity')).toBe(0)\n        expect(+target.select('.c3-circle-1').style('opacity')).toBe(0)\n        expect(+target.select('.c3-circle-2').style('opacity')).toBe(1)\n      })\n    })\n  })\n\n  describe('spline.interpolation option', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, -150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25],\n            ['data3', -150, 120, 110, 140, 115, 125]\n          ],\n          type: 'spline'\n        },\n        spline: {\n          interpolation: {\n            type: 'monotone'\n          }\n        }\n      }\n    })\n\n    it('updates interpolation function', function() {\n      expect(chart.internal.getInterpolate(chart.data()[0])).toBe(\n        d3.curveMonotoneX\n      )\n    })\n\n    describe('should not use a non-valid interpolation', function() {\n      beforeAll(function() {\n        args.spline.interpolation.type = 'foo'\n      })\n\n      it('should use cardinal interpolation when given option is not valid', function() {\n        expect(chart.internal.getInterpolate(chart.data()[0])).toBe(\n          d3.curveCardinal\n        )\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/stanford-spec.ts",
    "content": "import { initChart } from './c3-helper'\nimport { getRegionArea, compareEpochs, pointInRegion } from '../src/stanford'\n\ndescribe('c3 stanford tests', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('count epochs in region', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          x: 'x',\n          y: 'y',\n          epochs: 'epochs',\n          columns: [\n            ['x', 25, 35],\n            ['y', 25, 33],\n            ['epochs', 30, 35]\n          ],\n          type: 'stanford'\n        }\n      }\n    })\n\n    it('should return 0 if the region has no epochs', function() {\n      var region = [\n        { x: 0, y: 0 },\n        { x: 20, y: 0 },\n        { x: 20, y: 20 },\n        { x: 0, y: 20 }\n      ]\n\n      var result = chart.internal.countEpochsInRegion(region)\n\n      expect(result.percentage).toBe(0)\n      expect(result.value).toBe(0)\n    })\n\n    it('should return 100% if the region has all the epochs', function() {\n      var region = [\n        { x: 0, y: 0 },\n        { x: 60, y: 0 },\n        { x: 60, y: 60 },\n        { x: 0, y: 60 }\n      ]\n\n      var result = chart.internal.countEpochsInRegion(region)\n\n      expect(Number(result.percentage)).toBe(100)\n      expect(result.value).toBe(65)\n    })\n  })\n\n  describe('get centroid of region', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          x: 'x',\n          y: 'y',\n          epochs: 'epochs',\n          columns: [\n            ['x', 25, 35],\n            ['y', 25, 33],\n            ['epochs', 30, 35]\n          ],\n          type: 'stanford'\n        }\n      }\n    })\n\n    var region = [\n      // a 20 x 20 square\n      { x: 0, y: 0 },\n      { x: 20, y: 0 },\n      { x: 20, y: 20 },\n      { x: 0, y: 20 }\n    ]\n\n    it('should return the centroid of a polygon', function() {\n      var result = chart.internal.getCentroid(region)\n\n      expect(result.x).toBe(10)\n      expect(result.y).toBe(10)\n    })\n  })\n\n  describe('get region area', function() {\n    var square = [\n      // a 20 x 20 square\n      { x: 0, y: 0 },\n      { x: 20, y: 0 },\n      { x: 20, y: 20 },\n      { x: 0, y: 20 }\n    ]\n\n    var squareArea = 400\n\n    var triangle = [\n      // A = b * h / 2\n      { x: 0, y: 0 },\n      { x: 20, y: 20 },\n      { x: 0, y: 20 }\n    ]\n\n    var triangleArea = 200\n\n    it('should return the correct area for a square', function() {\n      expect(Math.abs(getRegionArea(square))).toBe(squareArea)\n    })\n\n    it('should return the correct area for a triangle', function() {\n      expect(Math.abs(getRegionArea(triangle))).toBe(triangleArea)\n    })\n  })\n\n  describe('compare epochs', function() {\n    var dataBigger = { epochs: 2 }\n    var dataLower = { epochs: 1 }\n\n    it('should return -1 if epochs are lower', function() {\n      expect(compareEpochs(dataLower, dataBigger)).toBe(-1)\n    })\n\n    it('should return 1 if epochs are bigger', function() {\n      expect(compareEpochs(dataBigger, dataLower)).toBe(1)\n    })\n\n    it('should return 0 if epochs are equal', function() {\n      expect(compareEpochs(dataLower, dataLower)).toBe(0)\n    })\n  })\n\n  describe('check if point is in region', function() {\n    var region = [\n      { x: 0, y: 0 },\n      { x: 20, y: 0 },\n      { x: 20, y: 20 },\n      { x: 20, y: 20 }\n    ]\n\n    var pointInside = { x: 0, value: 0 }\n    var pointOutInside = { x: 21, value: 0 }\n\n    it('should return true if point is inside region', function() {\n      expect(pointInRegion(pointInside, region)).toBeTruthy()\n    })\n\n    it('should return false if point is outside region', function() {\n      expect(pointInRegion(pointOutInside, region)).toBeFalsy()\n    })\n  })\n})\n"
  },
  {
    "path": "spec/subchart-spec.ts",
    "content": "import { initChart } from './c3-helper'\ndescribe('c3 subchart', function() {\n  'use strict'\n\n  let chart\n\n  let args = {\n    data: {\n      x: 'date',\n      columns: [\n        [\n          'date',\n          '2012-12-24',\n          '2012-12-25',\n          '2012-12-26',\n          '2012-12-27',\n          '2012-12-28',\n          '2012-12-29'\n        ],\n        ['data1', 30, 200, -100, 400, -150, 250],\n        ['data2', 50, 20, 10, 40, 15, 25]\n      ],\n      groups: [['data1', 'data2']],\n      type: 'bar'\n    },\n    axis: {\n      x: {\n        type: 'category'\n      }\n    },\n    subchart: {\n      show: true\n    }\n  }\n\n  beforeEach(done => {\n    chart = initChart(chart, args, done)\n  })\n\n  const getChartHeight = () =>\n    +chart.internal.svg.select('.c3-event-rect').attr('height') - 1\n\n  describe('api', () => {\n    it('can toggle subchart visibility', () => {\n      const chartHeightWithSubchart = getChartHeight()\n\n      expect(chart.subchart.isShown()).toBeTruthy()\n      expect(chart.internal.svg.selectAll('.c3-axis-x').size()).toEqual(2)\n      expect(chart.internal.svg.selectAll('.c3-brush').size()).toEqual(1)\n\n      chart.subchart.hide()\n\n      expect(chart.subchart.isShown()).toBeFalsy()\n      expect(chart.internal.svg.selectAll('.c3-axis-x').size()).toEqual(1)\n      expect(chart.internal.svg.selectAll('.c3-brush').size()).toEqual(0)\n      expect(getChartHeight()).toBeGreaterThan(chartHeightWithSubchart)\n\n      chart.subchart.show()\n\n      expect(chart.subchart.isShown()).toBeTruthy()\n      expect(chart.internal.svg.selectAll('.c3-axis-x').size()).toEqual(2)\n      expect(chart.internal.svg.selectAll('.c3-brush').size()).toEqual(1)\n      expect(getChartHeight()).toEqual(chartHeightWithSubchart)\n    })\n  })\n})\n"
  },
  {
    "path": "spec/svg-helper.ts",
    "content": "/**\n * Parse the d property of an SVG path into an array of drawing commands.\n * @param  {String} d SvgPath d attribute.]\n * @return {Array} an array of drawing commands.\n */\nexport function parseSvgPath(d) {\n  //jshint ignore:line\n  'use strict'\n\n  var commands = []\n  var commandTokens = ['M', 'L', 'I', 'H', 'V', 'C', 'S', 'Q', 'T', 'A']\n  var command\n  var in_x = false\n  var in_y = false\n  var x = ''\n  var y = ''\n  for (var i = 0; i <= d.length; i++) {\n    if (commandTokens.indexOf(d[i]) !== -1) {\n      if (in_x || in_y) {\n        commands.push({ command: command, x: x, y: y })\n        x = ''\n        y = ''\n      }\n      command = d[i]\n      in_x = true\n      in_y = false\n    } else {\n      if (d[i] === ',') {\n        if (in_y) {\n          commands.push({ command: command, x: x, y: y })\n          x = ''\n          y = ''\n        }\n        in_x = !in_x\n        in_y = !in_y\n      } else if (in_x) {\n        x += d[i]\n      } else if (in_y) {\n        y += d[i]\n      }\n    }\n  }\n  if (d[i] !== ',' && in_y) {\n    commands.push({ command: command, x: x, y: y })\n  }\n  return commands\n}\n"
  },
  {
    "path": "spec/title-spec.ts",
    "content": "import { d3, initChart } from './c3-helper'\n\ndescribe('c3 chart title', function() {\n  'use strict'\n\n  var chart, config\n\n  describe('when given a title too long', function() {\n    beforeEach(function(done) {\n      config = {\n        data: {\n          columns: [['data1', 30, 200, 100, 400, 150, 250]]\n        },\n        title: {\n          text: 'this is a very long title'.repeat(10),\n          position: 'top-center'\n        }\n      }\n\n      chart = initChart(chart, config, done)\n    })\n\n    it('should not use negative x offset', function() {\n      const titleEl = d3.select('.c3-title')\n      expect(+titleEl.attr('x')).toBe(0)\n    })\n  })\n\n  describe('when given a title config option', function() {\n    describe('with no padding and no position', function() {\n      beforeEach(function(done) {\n        config = {\n          data: {\n            columns: [['data1', 30, 200, 100, 400, 150, 250]]\n          },\n          title: {\n            text: 'new title'\n          }\n        }\n        chart = initChart(chart, config, done)\n      })\n\n      it('renders the title at the default config position', function() {\n        var titleEl = d3.select('.c3-title')\n        expect(+titleEl.attr('x')).toBeCloseTo(294, -2)\n        expect(+titleEl.attr('y')).toEqual(\n          (titleEl.node() as any).getBBox().height\n        )\n      })\n\n      it('renders the title text', function() {\n        var titleEl = d3.select('.c3-title')\n        expect((titleEl.node() as any).textContent).toEqual('new title')\n      })\n    })\n\n    describe('with padding', function() {\n      var config,\n        getConfig = function(titlePosition) {\n          return {\n            data: {\n              columns: [['data1', 30, 200, 100, 400, 150, 250]]\n            },\n            title: {\n              text: 'positioned title',\n              padding: {\n                top: 20,\n                right: 30,\n                bottom: 40,\n                left: 50\n              },\n              position: titlePosition\n            }\n          }\n        }\n\n      describe('and position center', function() {\n        beforeEach(function(done) {\n          config = getConfig('top-center')\n          chart = initChart(chart, config, done)\n        })\n        it('renders the title at the default config position', function() {\n          var titleEl = d3.select('.c3-title')\n          expect(+titleEl.attr('x')).toBeCloseTo(275, -2)\n          expect(+titleEl.attr('y')).toBeCloseTo(34, -1)\n        })\n        it('adds the correct amount of padding to fit the title', function() {\n          expect(chart.internal.getCurrentPaddingTop()).toEqual(\n            config.title.padding.top +\n              (d3.select('.c3-title').node() as any).getBBox().height +\n              config.title.padding.bottom\n          )\n        })\n      })\n\n      describe('and position left', function() {\n        beforeEach(function(done) {\n          config = getConfig('top-left')\n          chart = initChart(chart, config, done)\n        })\n        it('renders the title at the default config position', function() {\n          var titleEl = d3.select('.c3-title')\n          expect(+titleEl.attr('x')).toBeCloseTo(50, -1)\n          expect(+titleEl.attr('y')).toBeCloseTo(34, -1)\n        })\n      })\n\n      describe('and position right', function() {\n        beforeEach(function(done) {\n          config = getConfig('top-right')\n          chart = initChart(chart, config, done)\n        })\n        it('renders the title at the default config position', function() {\n          var titleEl = d3.select('.c3-title')\n          expect(+titleEl.attr('x')).toBeCloseTo(520, -2)\n          expect(+titleEl.attr('y')).toBeCloseTo(34, -1)\n        })\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/tooltip-spec.ts",
    "content": "import { d3, setMouseEvent, initChart } from './c3-helper'\n\ndescribe('c3 chart tooltip', function() {\n  'use strict'\n\n  var chart\n  var tooltipConfiguration = {}\n  var dataOrder: any = 'desc'\n  var dataGroups\n\n  var args = function() {\n    return {\n      data: {\n        columns: [\n          ['data1', 30, 200, 100, 400, 150, 250], // 1130\n          ['data2', 50, 20, 10, 40, 15, 25], // 160\n          ['data3', 150, 120, 110, 140, 115, 125] // 760\n        ],\n        order: dataOrder,\n        groups: dataGroups\n      },\n      tooltip: tooltipConfiguration\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args(), done)\n    dataOrder = 'desc'\n    dataGroups = undefined\n  })\n\n  describe('tooltip position', function() {\n    beforeAll(function() {\n      tooltipConfiguration = {}\n    })\n\n    describe('without left margin', function() {\n      it('should show tooltip on proper position', function() {\n        var eventRect = d3.select('.c3-event-rect').node(),\n          x = chart.internal.x(1),\n          y = chart.internal.y(200)\n        setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n        var tooltipContainer = d3.select('.c3-tooltip-container'),\n          top = Math.floor(+tooltipContainer.style('top').replace(/px/, '')),\n          left = Math.floor(+tooltipContainer.style('left').replace(/px/, ''))\n        expect(top).toBeGreaterThan(0)\n        expect(left).toBeGreaterThan(0)\n      })\n    })\n\n    describe('with left margin', function() {\n      beforeAll(function() {\n        d3.select('#chart').style('margin-left', '300px')\n      })\n\n      it('should show tooltip on proper position', function() {\n        var eventRect = d3.select('.c3-event-rect').node(),\n          x = chart.internal.x(1) + 300, // add margin-left\n          y = chart.internal.y(200)\n        setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n        var tooltipContainer = d3.select('.c3-tooltip-container'),\n          top = Math.floor(+tooltipContainer.style('top').replace(/px/, '')),\n          left = Math.floor(+tooltipContainer.style('left').replace(/px/, ''))\n        expect(top).toBeGreaterThan(0)\n        expect(left).toBeGreaterThan(0)\n      })\n\n      afterAll(function() {\n        d3.select('#chart').style('margin-left', null)\n      })\n    })\n  })\n\n  describe('tooltip positionFunction', function() {\n    var topExpected = 37,\n      leftExpected = 79\n\n    beforeAll(function() {\n      tooltipConfiguration = {\n        position: function(data, width, height, element) {\n          expect(data.length).toBe(args().data.columns.length)\n          expect(data[0]).toEqual(\n            jasmine.objectContaining({\n              index: 2,\n              value: 100,\n              id: 'data1'\n            })\n          )\n          expect(width).toBeGreaterThan(0)\n          expect(height).toBeGreaterThan(0)\n          expect(element).toBe(d3.select('.c3-event-rect').node())\n          return { top: topExpected, left: leftExpected }\n        }\n      }\n    })\n\n    it('should be set to the coordinate where the function returned', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(100)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var tooltipContainer = d3.select('.c3-tooltip-container'),\n        top = Math.floor(+tooltipContainer.style('top').replace(/px/, '')),\n        left = Math.floor(+tooltipContainer.style('left').replace(/px/, ''))\n      expect(top).toBeGreaterThan(0)\n      expect(left).toBeGreaterThan(0)\n    })\n  })\n\n  describe('tooltip getTooltipContent', function() {\n    beforeAll(function() {\n      tooltipConfiguration = {\n        data_order: 'desc'\n      }\n    })\n\n    it('should sort values desc', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(100)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data3')\n      expect(classes[2]).toBe('c3-tooltip-name--data1')\n      expect(classes[3]).toBe('c3-tooltip-name--data2')\n    })\n  })\n\n  describe('tooltip with data_order as desc with grouped data', function() {\n    beforeAll(function() {\n      dataOrder = 'desc'\n      dataGroups = [['data1', 'data2', 'data3']]\n    })\n\n    it('should display each data in descending order', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(220)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data1') // 1130\n      expect(classes[2]).toBe('c3-tooltip-name--data3') // 760\n      expect(classes[3]).toBe('c3-tooltip-name--data2') // 160\n    })\n  })\n\n  describe('tooltip with data_order as asc with grouped data', function() {\n    beforeAll(function() {\n      dataOrder = 'asc'\n      dataGroups = [['data1', 'data2', 'data3']]\n    })\n\n    it('should display each data in ascending order', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(220)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data2') // 160\n      expect(classes[2]).toBe('c3-tooltip-name--data3') // 760\n      expect(classes[3]).toBe('c3-tooltip-name--data1') // 1130\n    })\n  })\n\n  describe('tooltip with data_order as NULL with grouped data', function() {\n    beforeAll(function() {\n      dataOrder = null\n      dataGroups = [['data1', 'data2', 'data3']]\n    })\n\n    it('should display each data in given order', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(220)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data1')\n      expect(classes[2]).toBe('c3-tooltip-name--data2')\n      expect(classes[3]).toBe('c3-tooltip-name--data3')\n    })\n  })\n\n  describe('tooltip with data_order as Function with grouped data', function() {\n    beforeAll(function() {\n      var order = ['data2', 'data1', 'data3']\n      dataOrder = function(data1, data2) {\n        return order.indexOf(data1.id) - order.indexOf(data2.id)\n      }\n      dataGroups = [['data1', 'data2', 'data3']]\n    })\n\n    it('should display each data in order given by function', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(220)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data2')\n      expect(classes[2]).toBe('c3-tooltip-name--data1')\n      expect(classes[3]).toBe('c3-tooltip-name--data3')\n    })\n  })\n\n  describe('tooltip with data_order as Array with grouped data', function() {\n    beforeAll(function() {\n      dataOrder = ['data2', 'data1', 'data3']\n      dataGroups = [['data1', 'data2', 'data3']]\n    })\n\n    it('should display each data in order given by array', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(220)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data2')\n      expect(classes[2]).toBe('c3-tooltip-name--data1')\n      expect(classes[3]).toBe('c3-tooltip-name--data3')\n    })\n  })\n\n  describe('tooltip with data_order as desc with un-grouped data', function() {\n    beforeAll(function() {\n      dataOrder = 'desc'\n    })\n\n    it('should display each tooltip value descending order', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(100)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data3') // 110\n      expect(classes[2]).toBe('c3-tooltip-name--data1') // 100\n      expect(classes[3]).toBe('c3-tooltip-name--data2') // 10\n    })\n  })\n\n  describe('tooltip with data_order as asc with un-grouped data', function() {\n    beforeAll(function() {\n      dataOrder = 'asc'\n    })\n\n    it('should display each tooltip value in ascending order', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(100)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data2') // 10\n      expect(classes[2]).toBe('c3-tooltip-name--data1') // 100\n      expect(classes[3]).toBe('c3-tooltip-name--data3') // 110\n    })\n  })\n\n  describe('tooltip with data_order as NULL with un-grouped data', function() {\n    beforeAll(function() {\n      dataOrder = null\n    })\n\n    it('should display each tooltip value in given data order', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(100)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data1')\n      expect(classes[2]).toBe('c3-tooltip-name--data2')\n      expect(classes[3]).toBe('c3-tooltip-name--data3')\n    })\n  })\n\n  describe('tooltip with data_order as Function with un-grouped data', function() {\n    beforeAll(function() {\n      var order = ['data2', 'data1', 'data3']\n      dataOrder = function(data1, data2) {\n        return order.indexOf(data1.id) - order.indexOf(data2.id)\n      }\n    })\n\n    it('should display each tooltip value in data order given by function', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(100)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data2')\n      expect(classes[2]).toBe('c3-tooltip-name--data1')\n      expect(classes[3]).toBe('c3-tooltip-name--data3')\n    })\n  })\n\n  describe('tooltip with data_order as Array with un-grouped data', function() {\n    beforeAll(function() {\n      dataOrder = ['data2', 'data1', 'data3']\n    })\n\n    it('should display each tooltip value in data order given by array', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(100)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data2')\n      expect(classes[2]).toBe('c3-tooltip-name--data1')\n      expect(classes[3]).toBe('c3-tooltip-name--data3')\n    })\n  })\n\n  describe('tooltip with tooltip_order as desc', function() {\n    beforeAll(function() {\n      tooltipConfiguration = {\n        order: 'desc'\n      }\n\n      // this should be ignored\n      dataOrder = 'asc'\n      dataGroups = [['data1', 'data2', 'data3']]\n    })\n\n    it('should display each tooltip value descending order', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(100)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data3') // 110\n      expect(classes[2]).toBe('c3-tooltip-name--data1') // 100\n      expect(classes[3]).toBe('c3-tooltip-name--data2') // 10\n    })\n  })\n\n  describe('tooltip with tooltip_order as asc', function() {\n    beforeAll(function() {\n      tooltipConfiguration = {\n        order: 'asc'\n      }\n\n      // this should be ignored\n      dataOrder = 'desc'\n      dataGroups = [['data1', 'data2', 'data3']]\n    })\n\n    it('should display each tooltip value in ascending order', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(220)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data2') // 10\n      expect(classes[2]).toBe('c3-tooltip-name--data1') // 100\n      expect(classes[3]).toBe('c3-tooltip-name--data3') // 110\n    })\n  })\n\n  describe('tooltip with tooltip_order as NULL', function() {\n    beforeAll(function() {\n      tooltipConfiguration = {\n        order: null\n      }\n    })\n\n    it('should display each tooltip value in given order', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(100)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data1')\n      expect(classes[2]).toBe('c3-tooltip-name--data2')\n      expect(classes[3]).toBe('c3-tooltip-name--data3')\n    })\n  })\n\n  describe('tooltip with tooltip_order as Function', function() {\n    beforeAll(function() {\n      var order = ['data2', 'data1', 'data3']\n      tooltipConfiguration = {\n        order: function(data1, data2) {\n          return order.indexOf(data1.id) - order.indexOf(data2.id)\n        }\n      }\n    })\n\n    it('should display each tooltip value in data order given by function', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(100)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data2')\n      expect(classes[2]).toBe('c3-tooltip-name--data1')\n      expect(classes[3]).toBe('c3-tooltip-name--data3')\n    })\n  })\n\n  describe('tooltip with tooltip_order as Array', function() {\n    beforeAll(function() {\n      tooltipConfiguration = {\n        order: ['data2', 'data1', 'data3']\n      }\n    })\n\n    it('should display each tooltip value in data order given by array', function() {\n      var eventRect = d3.select('.c3-event-rect').node(),\n        x = chart.internal.x(2),\n        y = chart.internal.y(100)\n      setMouseEvent(chart, 'mousemove', x, y, eventRect)\n\n      var classes = d3\n        .selectAll('.c3-tooltip tr')\n        .nodes()\n        .map(function(node) {\n          return (node as any).className\n        })\n\n      expect(classes[0]).toBe('') // header\n      expect(classes[1]).toBe('c3-tooltip-name--data2')\n      expect(classes[2]).toBe('c3-tooltip-name--data1')\n      expect(classes[3]).toBe('c3-tooltip-name--data3')\n    })\n  })\n})\n"
  },
  {
    "path": "spec/type-spec.ts",
    "content": "import { initChart } from './c3-helper'\n\ndescribe('c3 chart types', function() {\n  'use strict'\n\n  var chart, args\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('internal.hasArcType', function() {\n    describe('with data', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [\n              ['data1', 30, 200, 100, 400, 150, 250],\n              ['data2', 50, 20, 10, 40, 15, 25],\n              ['data3', 150, 120, 110, 140, 115, 125]\n            ],\n            type: 'pie'\n          }\n        }\n      })\n\n      it('should return true', function() {\n        expect(chart.internal.hasArcType()).toBeTruthy()\n      })\n\n      describe('should change chart type to \"bar\"', function() {\n        beforeAll(function() {\n          args.data.type = 'bar'\n        })\n\n        it('should return false', function() {\n          expect(chart.internal.hasArcType()).toBeFalsy()\n        })\n      })\n    })\n\n    describe('with empty data', function() {\n      beforeAll(function() {\n        args = {\n          data: {\n            columns: [],\n            type: 'pie'\n          }\n        }\n      })\n\n      it('should return true', function() {\n        expect(chart.internal.hasArcType()).toBeTruthy()\n      })\n\n      describe('should change chart type to \"bar\"', function() {\n        beforeAll(function() {\n          args.data.type = 'bar'\n        })\n\n        it('should return false', function() {\n          expect(chart.internal.hasArcType()).toBeFalsy()\n        })\n      })\n    })\n  })\n\n  describe('internal.hasType', function() {\n    beforeAll(function() {\n      args = {\n        data: {\n          columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n            ['data2', 50, 20, 10, 40, 15, 25],\n            ['data3', 150, 120, 110, 140, 115, 125]\n          ],\n          type: 'pie'\n        }\n      }\n    })\n\n    it('should return true for \"pie\" type', function() {\n      expect(chart.internal.hasType('pie')).toBeTruthy()\n    })\n\n    it('should return false for \"line\" type', function() {\n      expect(chart.internal.hasType('line')).toBeFalsy()\n    })\n\n    it('should return false for \"bar\" type', function() {\n      expect(chart.internal.hasType('bar')).toBeFalsy()\n    })\n\n    describe('should unload successfully', function() {\n      beforeAll(function() {\n        chart.unload([])\n      })\n\n      it('should return true for \"pie\" type even if no data', function() {\n        expect(chart.internal.hasType('pie')).toBeTruthy()\n      })\n\n      it('should return false for \"line\" type even if no data', function() {\n        expect(chart.internal.hasType('line')).toBeFalsy()\n      })\n\n      it('should return false for \"bar\" type even if no data', function() {\n        expect(chart.internal.hasType('bar')).toBeFalsy()\n      })\n\n      describe('should change chart type to \"bar\" successfully', function() {\n        beforeAll(function() {\n          args.data.type = 'bar'\n        })\n\n        it('should return false for \"pie\" type even if no data', function() {\n          expect(chart.internal.hasType('pie')).toBeFalsy()\n        })\n\n        it('should return false for \"line\" type even if no data', function() {\n          expect(chart.internal.hasType('line')).toBeFalsy()\n        })\n\n        it('should return true for \"bar\" type even if no data', function() {\n          expect(chart.internal.hasType('bar')).toBeTruthy()\n        })\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "spec/util-spec.ts",
    "content": "import {\n  asHalfPixel,\n  ceil10,\n  diffDomain,\n  getOption,\n  hasValue,\n  isArray,\n  isDefined,\n  isEmpty,\n  isFunction,\n  isString,\n  isUndefined,\n  isValue,\n  notEmpty,\n  sanitise,\n  isNumber,\n  flattenArray,\n  getIEVersion,\n  isIE\n} from '../src/util'\n\ndescribe('util.js tests', function() {\n  'use strict'\n\n  var undefined_var\n  var html_str = '<div>Hello there</div>'\n  var html_entities_str = '&lt;div&gt;Hello there&lt;/div&gt;'\n  var empty_string = ''\n  var nonempty_string = 'hello there'\n  var nonempty_number = 1234.2\n  var zero_number = 0\n  var null_var = null\n  var empty_object = {}\n  var nonempty_object = {\n    a: 1\n  }\n  var empty_array = []\n  var nonempty_array = [1, 3]\n  var nonempty_function = function(a) {\n    return a\n  }\n\n  describe('asHalfPixel, ceil10 and diffDomain functions', function() {\n    it('asHalfPixel should return correct value', function() {\n      expect(asHalfPixel(nonempty_number)).toBe(1235.5)\n    })\n    it('ceil10 should return correct value', function() {\n      expect(ceil10(nonempty_number)).toBe(1240)\n    })\n    it('diffDomain should return correct value', function() {\n      expect(diffDomain(nonempty_array)).toBe(2)\n    })\n  })\n\n  describe('getOption and hasValue functions', function() {\n    it('getOption should return value if options dict has specified key', function() {\n      expect(getOption(nonempty_object, 'a', 'b')).toBe(1)\n    })\n    it('getOption should return default value if options dict lacks specified key', function() {\n      expect(getOption(empty_object, 'a', 'b')).toBe('b')\n    })\n\n    it('hasValue should return true if dict has requested value', function() {\n      expect(hasValue(nonempty_object, 1)).toBe(true)\n    })\n    it('hasValue should return false if dict lacks requested value', function() {\n      expect(hasValue(nonempty_object, 2)).toBe(false)\n    })\n  })\n\n  describe('sanitise function', function() {\n    it('should replace < and > tags', function() {\n      expect(sanitise(html_str)).toBe(html_entities_str)\n    })\n\n    it('should not modify a string not containing  < and > tags', function() {\n      expect(sanitise(html_entities_str)).toBe(html_entities_str)\n    })\n\n    it('should not modify an imput whose type is not string', function() {\n      expect(sanitise(nonempty_number)).toBe(nonempty_number)\n    })\n  })\n\n  describe('flattenArray', function() {\n    it('returns empty array for undefined value', function() {\n      expect(flattenArray(undefined_var)).toEqual([])\n    })\n\n    it('returns flattened arrays (1 array)', function() {\n      expect(flattenArray([[1]])).toEqual([1])\n    })\n\n    it('returns flatten arrays (n arrays)', function() {\n      expect(flattenArray([[1], ['2']])).toEqual([1, '2'])\n    })\n  })\n\n  describe('isArray, isDefined, isEmpty, isFunction, isNumber, isString, isUndefined, isValue and notEmpty functions', function() {\n    it('isArray should return true for array var', function() {\n      expect(isArray(nonempty_array)).toBe(true)\n    })\n    it('isDefined should return true for defined var', function() {\n      expect(isDefined(nonempty_string)).toBe(true)\n    })\n    it('isFunction should return true for function var', function() {\n      expect(isFunction(nonempty_function)).toBe(true)\n    })\n    it('isString should return true for string var', function() {\n      expect(isString(nonempty_string)).toBe(true)\n    })\n    it('isUndefined should return true for undefined var', function() {\n      expect(isUndefined(undefined_var)).toBe(true)\n    })\n    it('isValue should return true for value var', function() {\n      expect(isValue(nonempty_number)).toBe(1234.2)\n    })\n\n    it('isArray should return false for non array var', function() {\n      expect(isArray(nonempty_string)).toBe(false)\n    })\n    it('isDefined should return false for non defined var', function() {\n      expect(isDefined(undefined_var)).toBe(false)\n    })\n    it('isFunction should return false for non function var', function() {\n      expect(isFunction(nonempty_string)).toBe(false)\n    })\n    it('isString should return false for non string var', function() {\n      expect(isString(undefined_var)).toBe(false)\n    })\n    it('isUndefined should return false for non undefined var', function() {\n      expect(isUndefined(nonempty_string)).toBe(false)\n    })\n    it('isValue should return false for null var', function() {\n      expect(isValue(null_var)).toBe(false)\n    })\n\n    it('isNumber should return false for undefined var', function() {\n      expect(isNumber(undefined_var)).toBe(false)\n    })\n    it('isNumber should return false for null var', function() {\n      expect(isNumber(null_var)).toBe(false)\n    })\n    it('isNumber should return false for string var', function() {\n      expect(isNumber(nonempty_string)).toBe(false)\n    })\n    it('isNumber should return true for nonempty_number', function() {\n      expect(isNumber(nonempty_number)).toBe(true)\n    })\n    it('isNumber should return true for zero_number', function() {\n      expect(isNumber(zero_number)).toBe(true)\n    })\n\n    it('isEmpty should return false for nonempty_array', function() {\n      expect(isEmpty(nonempty_array)).toBe(false)\n    })\n    it('isEmpty should return false for nonempty_number', function() {\n      expect(isEmpty(nonempty_number)).toBe(false)\n    })\n    it('isEmpty should return false for nonempty_object', function() {\n      expect(isEmpty(nonempty_object)).toBe(false)\n    })\n    it('isEmpty should return false for nonempty_string', function() {\n      expect(isEmpty(nonempty_string)).toBe(false)\n    })\n\n    it('isEmpty should return true for empty_array', function() {\n      expect(isEmpty(empty_array)).toBe(true)\n    })\n    it('isEmpty should return true for empty_object', function() {\n      expect(isEmpty(empty_object)).toBe(true)\n    })\n    it('isEmpty should return true for empty_string', function() {\n      expect(isEmpty(empty_string)).toBe(true)\n    })\n    it('isEmpty should return true for null_var', function() {\n      expect(isEmpty(null_var)).toBe(true)\n    })\n    it('isEmpty should return true for undefined_var', function() {\n      expect(isEmpty(undefined_var)).toBe(true)\n    })\n\n    it('notEmpty should return false for empty_array', function() {\n      expect(notEmpty(empty_array)).toBe(false)\n    })\n    it('notEmpty should return false for empty_object', function() {\n      expect(notEmpty(empty_object)).toBe(false)\n    })\n    it('notEmpty should return false for empty_string', function() {\n      expect(notEmpty(empty_string)).toBe(false)\n    })\n    it('notEmpty should return false for null_var', function() {\n      expect(notEmpty(null_var)).toBe(false)\n    })\n    it('notEmpty should return false for undefined_var', function() {\n      expect(notEmpty(undefined_var)).toBe(false)\n    })\n\n    it('notEmpty should return true for nonempty_array', function() {\n      expect(notEmpty(nonempty_array)).toBe(true)\n    })\n    it('notEmpty should return true for nonempty_number', function() {\n      expect(notEmpty(nonempty_number)).toBe(true)\n    })\n    it('notEmpty should return true for nonempty_object', function() {\n      expect(notEmpty(nonempty_object)).toBe(true)\n    })\n    it('notEmpty should return true for nonempty_string', function() {\n      expect(notEmpty(nonempty_string)).toBe(true)\n    })\n  })\n\n  describe('getIEVersion and isIE', function() {\n    it('getIEVersion should return 10 for user agent string \"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)\"', function() {\n      expect(\n        getIEVersion(\n          'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)'\n        )\n      ).toBe(10)\n    })\n    it('getIEVersion should return 11 for user agent string \"Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko\"', function() {\n      expect(\n        getIEVersion(\n          'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko'\n        )\n      ).toBe(11)\n    })\n    it('getIEVersion should return false for user agent string \"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0\"', function() {\n      expect(\n        getIEVersion(\n          'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0'\n        )\n      ).toBe(false)\n    })\n    it('getIEVersion should return a number or false if parameter \"agent\" is not used', function() {\n      expect(getIEVersion()).toMatch(/(\\d+|false)/)\n    })\n\n    it('isIE should return false for version number 6', function() {\n      expect(isIE(6)).toBe(false)\n    })\n    it('isIE should return true or false if parameter \"version\" is not used', function() {\n      expect(isIE()).toMatch(/(true|false)/)\n    })\n  })\n})\n"
  },
  {
    "path": "spec/zoom-spec.ts",
    "content": "import { initChart } from './c3-helper'\n\ndescribe('c3 chart zoom', function() {\n  'use strict'\n\n  var chart\n\n  var args = {\n    data: {\n      columns: [\n        ['data1', 30, 200, 100, 400, 3150, 250],\n        ['data2', 50, 20, 10, 40, 15, 6025]\n      ]\n    },\n    zoom: {\n      enabled: true,\n      initialRange: [1, 2]\n    },\n    subchart: {\n      show: true\n    }\n  }\n\n  beforeEach(function(done) {\n    chart = initChart(chart, args, done)\n  })\n\n  describe('default extent', function() {\n    describe('main chart domain', function() {\n      it('should have original y domain', function() {\n        var yDomain = chart.internal.y.domain(),\n          expectedYDomain = [-591.5, 6626.5]\n        expect(yDomain[0]).toBe(expectedYDomain[0])\n        expect(yDomain[1]).toBe(expectedYDomain[1])\n      })\n    })\n\n    describe('main chart domain', function() {\n      it('should have original y domain in subchart', function() {\n        var yDomain = chart.internal.y.domain(),\n          subYDomain = chart.internal.subY.domain()\n        expect(subYDomain[0]).toBe(yDomain[0])\n        expect(subYDomain[1]).toBe(yDomain[1])\n      })\n    })\n\n    describe('main chart domain', function() {\n      it('should have specified brush extent', function() {\n        var brushSelection = chart.internal.brush.selectionAsValue(),\n          expectedBrushSelection = [1, 2]\n        expect(brushSelection[0]).toBeCloseTo(expectedBrushSelection[0], 1)\n        expect(brushSelection[1]).toBeCloseTo(expectedBrushSelection[1], 1)\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "src/api.axis.ts",
    "content": "import { Chart } from './core'\nimport { isValue, isDefined } from './util'\n\nChart.prototype.axis = function() {}\nChart.prototype.axis.labels = function(labels) {\n  var $$ = this.internal\n  if (arguments.length) {\n    Object.keys(labels).forEach(function(axisId) {\n      $$.axis.setLabelText(axisId, labels[axisId])\n    })\n    $$.axis.updateLabels()\n  }\n  // TODO: return some values?\n}\nChart.prototype.axis.max = function(max) {\n  var $$ = this.internal,\n    config = $$.config\n  if (arguments.length) {\n    if (typeof max === 'object') {\n      if (isValue(max.x)) {\n        config.axis_x_max = max.x\n      }\n      if (isValue(max.y)) {\n        config.axis_y_max = max.y\n      }\n      if (isValue(max.y2)) {\n        config.axis_y2_max = max.y2\n      }\n    } else {\n      config.axis_y_max = config.axis_y2_max = max\n    }\n    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true })\n  } else {\n    return {\n      x: config.axis_x_max,\n      y: config.axis_y_max,\n      y2: config.axis_y2_max\n    }\n  }\n}\nChart.prototype.axis.min = function(min) {\n  var $$ = this.internal,\n    config = $$.config\n  if (arguments.length) {\n    if (typeof min === 'object') {\n      if (isValue(min.x)) {\n        config.axis_x_min = min.x\n      }\n      if (isValue(min.y)) {\n        config.axis_y_min = min.y\n      }\n      if (isValue(min.y2)) {\n        config.axis_y2_min = min.y2\n      }\n    } else {\n      config.axis_y_min = config.axis_y2_min = min\n    }\n    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true })\n  } else {\n    return {\n      x: config.axis_x_min,\n      y: config.axis_y_min,\n      y2: config.axis_y2_min\n    }\n  }\n}\nChart.prototype.axis.range = function(range) {\n  if (arguments.length) {\n    if (isDefined(range.max)) {\n      this.axis.max(range.max)\n    }\n    if (isDefined(range.min)) {\n      this.axis.min(range.min)\n    }\n  } else {\n    return {\n      max: this.axis.max(),\n      min: this.axis.min()\n    }\n  }\n}\n\nChart.prototype.axis.types = function(types) {\n  const $$ = this.internal\n  if (types === undefined) {\n    return {\n      y: $$.config.axis_y_type,\n      y2: $$.config.axis_y2_type\n    }\n  } else {\n    if (isDefined(types.y)) {\n      $$.config.axis_y_type = types.y\n    }\n\n    if (isDefined(types.y2)) {\n      $$.config.axis_y2_type = types.y2\n    }\n\n    $$.updateScales()\n    $$.redraw()\n  }\n}\n"
  },
  {
    "path": "src/api.category.ts",
    "content": "import { Chart } from './core'\n\nChart.prototype.category = function(i, category) {\n  var $$ = this.internal,\n    config = $$.config\n  if (arguments.length > 1) {\n    config.axis_x_categories[i] = category\n    $$.redraw()\n  }\n  return config.axis_x_categories[i]\n}\nChart.prototype.categories = function(categories) {\n  var $$ = this.internal,\n    config = $$.config\n  if (!arguments.length) {\n    return config.axis_x_categories\n  }\n  config.axis_x_categories = categories\n  $$.redraw()\n  return config.axis_x_categories\n}\n"
  },
  {
    "path": "src/api.chart.ts",
    "content": "import { Chart } from './core'\n\nChart.prototype.resize = function(size) {\n  var $$ = this.internal,\n    config = $$.config\n  config.size_width = size ? size.width : null\n  config.size_height = size ? size.height : null\n  this.flush()\n}\n\nChart.prototype.flush = function() {\n  var $$ = this.internal\n  $$.updateAndRedraw({\n    withLegend: true,\n    withTransition: false,\n    withTransitionForTransform: false\n  })\n}\n\nChart.prototype.destroy = function() {\n  var $$ = this.internal\n\n  window.clearInterval($$.intervalForObserveInserted)\n\n  if ($$.resizeTimeout !== undefined) {\n    window.clearTimeout($$.resizeTimeout)\n  }\n\n  window.removeEventListener('resize', $$.resizeIfElementDisplayed)\n\n  // Removes the inner resize functions\n  $$.resizeFunction.remove()\n\n  // Unbinds from the window focus event\n  $$.unbindWindowFocus()\n\n  $$.selectChart.classed('c3', false).html('')\n\n  // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen.\n  Object.keys($$).forEach(function(key) {\n    $$[key] = null\n  })\n\n  return null\n}\n"
  },
  {
    "path": "src/api.color.ts",
    "content": "import { Chart } from './core'\n\n// TODO: fix\nChart.prototype.color = function(id) {\n  var $$ = this.internal\n  return $$.color(id) // more patterns\n}\n"
  },
  {
    "path": "src/api.data.ts",
    "content": "import { Chart } from './core'\nimport { isArray } from './util'\n\nChart.prototype.data = function(targetIds) {\n  var targets = this.internal.data.targets\n  return typeof targetIds === 'undefined'\n    ? targets\n    : targets.filter(function(t) {\n        return [].concat(targetIds).indexOf(t.id) >= 0\n      })\n}\nChart.prototype.data.shown = function(targetIds) {\n  return this.internal.filterTargetsToShow(this.data(targetIds))\n}\n\n/**\n * Get values of the data loaded in the chart.\n *\n * @param {String|Array} targetId This API returns the value of specified target.\n * @param flat\n * @return {Array} Data values\n */\nChart.prototype.data.values = function(targetId, flat = true) {\n  let values = null\n\n  if (targetId) {\n    const targets = this.data(targetId)\n    if (targets && isArray(targets)) {\n      values = targets.reduce((ret, v) => {\n        const dataValue = v.values.map(d => d.value)\n        if (flat) {\n          ret = ret.concat(dataValue)\n        } else {\n          ret.push(dataValue)\n        }\n        return ret\n      }, [])\n    }\n  }\n\n  return values\n}\nChart.prototype.data.names = function(names) {\n  this.internal.clearLegendItemTextBoxCache()\n  return this.internal.updateDataAttributes('names', names)\n}\nChart.prototype.data.colors = function(colors) {\n  return this.internal.updateDataAttributes('colors', colors)\n}\nChart.prototype.data.axes = function(axes) {\n  return this.internal.updateDataAttributes('axes', axes)\n}\n\nChart.prototype.data.stackNormalized = function(normalized) {\n  if (normalized === undefined) {\n    return this.internal.isStackNormalized()\n  }\n\n  this.internal.config.data_stack_normalize = !!normalized\n  this.internal.redraw()\n}\n"
  },
  {
    "path": "src/api.donut.ts",
    "content": "import { Chart } from './core'\n\nChart.prototype.donut = function() {}\n\nChart.prototype.donut.padAngle = function(padAngle) {\n  if (padAngle === undefined) {\n    return this.internal.config.donut_padAngle\n  }\n  this.internal.config.donut_padAngle = padAngle\n  this.flush()\n}\n"
  },
  {
    "path": "src/api.flow.ts",
    "content": "import CLASS from './class'\nimport { Chart, ChartInternal } from './core'\nimport { isValue, isDefined, diffDomain } from './util'\n\nChart.prototype.flow = function(args) {\n  var $$ = this.internal,\n    targets,\n    data,\n    notfoundIds = [],\n    orgDataCount = $$.getMaxDataCount(),\n    dataCount,\n    domain,\n    baseTarget,\n    baseValue,\n    length = 0,\n    tail = 0,\n    diff,\n    to\n\n  if (args.json) {\n    data = $$.convertJsonToData(args.json, args.keys)\n  } else if (args.rows) {\n    data = $$.convertRowsToData(args.rows)\n  } else if (args.columns) {\n    data = $$.convertColumnsToData(args.columns)\n  } else {\n    return\n  }\n  targets = $$.convertDataToTargets(data, true)\n\n  // Update/Add data\n  $$.data.targets.forEach(function(t) {\n    var found = false,\n      i,\n      j\n    for (i = 0; i < targets.length; i++) {\n      if (t.id === targets[i].id) {\n        found = true\n\n        if (t.values[t.values.length - 1]) {\n          tail = t.values[t.values.length - 1].index + 1\n        }\n        length = targets[i].values.length\n\n        for (j = 0; j < length; j++) {\n          targets[i].values[j].index = tail + j\n          if (!$$.isTimeSeries()) {\n            targets[i].values[j].x = tail + j\n          }\n        }\n        t.values = t.values.concat(targets[i].values)\n\n        targets.splice(i, 1)\n        break\n      }\n    }\n    if (!found) {\n      notfoundIds.push(t.id)\n    }\n  })\n\n  // Append null for not found targets\n  $$.data.targets.forEach(function(t) {\n    var i, j\n    for (i = 0; i < notfoundIds.length; i++) {\n      if (t.id === notfoundIds[i]) {\n        tail = t.values[t.values.length - 1].index + 1\n        for (j = 0; j < length; j++) {\n          t.values.push({\n            id: t.id,\n            index: tail + j,\n            x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,\n            value: null\n          })\n        }\n      }\n    }\n  })\n\n  // Generate null values for new target\n  if ($$.data.targets.length) {\n    targets.forEach(function(t) {\n      var i,\n        missing = []\n      for (i = $$.data.targets[0].values[0].index; i < tail; i++) {\n        missing.push({\n          id: t.id,\n          index: i,\n          x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,\n          value: null\n        })\n      }\n      t.values.forEach(function(v) {\n        v.index += tail\n        if (!$$.isTimeSeries()) {\n          v.x += tail\n        }\n      })\n      t.values = missing.concat(t.values)\n    })\n  }\n  $$.data.targets = $$.data.targets.concat(targets) // add remained\n\n  // check data count because behavior needs to change when it's only one\n  dataCount = $$.getMaxDataCount()\n  baseTarget = $$.data.targets[0]\n  baseValue = baseTarget.values[0]\n\n  // Update length to flow if needed\n  if (isDefined(args.to)) {\n    length = 0\n    to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to\n    baseTarget.values.forEach(function(v) {\n      if (v.x < to) {\n        length++\n      }\n    })\n  } else if (isDefined(args.length)) {\n    length = args.length\n  }\n\n  // If only one data, update the domain to flow from left edge of the chart\n  if (!orgDataCount) {\n    if ($$.isTimeSeries()) {\n      if (baseTarget.values.length > 1) {\n        diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x\n      } else {\n        diff = baseValue.x - $$.getXDomain($$.data.targets)[0]\n      }\n    } else {\n      diff = 1\n    }\n    domain = [baseValue.x - diff, baseValue.x]\n    $$.updateXDomain(null, true, true, false, domain)\n  } else if (orgDataCount === 1) {\n    if ($$.isTimeSeries()) {\n      diff =\n        (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2\n      domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)]\n      $$.updateXDomain(null, true, true, false, domain)\n    }\n  }\n\n  // Set targets\n  $$.updateTargets($$.data.targets)\n\n  // Redraw with new targets\n  $$.redraw({\n    flow: {\n      index: baseValue.index,\n      length: length,\n      duration: isValue(args.duration)\n        ? args.duration\n        : $$.config.transition_duration,\n      done: args.done,\n      orgDataCount: orgDataCount\n    },\n    withLegend: true,\n    withTransition: orgDataCount > 1,\n    withTrimXDomain: false,\n    withUpdateXAxis: true\n  })\n}\n\nChartInternal.prototype.generateFlow = function(args) {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3\n\n  return function() {\n    var targets = args.targets,\n      flow = args.flow,\n      drawBar = args.drawBar,\n      drawLine = args.drawLine,\n      drawArea = args.drawArea,\n      cx = args.cx,\n      cy = args.cy,\n      xv = args.xv,\n      xForText = args.xForText,\n      yForText = args.yForText,\n      duration = args.duration\n\n    var translateX,\n      scaleX = 1,\n      transform,\n      flowIndex = flow.index,\n      flowLength = flow.length,\n      flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex),\n      flowEnd = $$.getValueOnIndex(\n        $$.data.targets[0].values,\n        flowIndex + flowLength\n      ),\n      orgDomain = $$.x.domain(),\n      domain,\n      durationForFlow = flow.duration || duration,\n      done = flow.done || function() {},\n      wait = $$.generateWait()\n\n    var xgrid,\n      xgridLines,\n      mainRegion,\n      mainText,\n      mainBar,\n      mainLine,\n      mainArea,\n      mainCircle\n\n    // set flag\n    $$.flowing = true\n\n    // remove head data after rendered\n    $$.data.targets.forEach(function(d) {\n      d.values.splice(0, flowLength)\n    })\n\n    // update x domain to generate axis elements for flow\n    domain = $$.updateXDomain(targets, true, true)\n    // update elements related to x scale\n    if ($$.updateXGrid) {\n      $$.updateXGrid(true)\n    }\n\n    xgrid = $$.xgrid || d3.selectAll([]) // xgrid needs to be obtained after updateXGrid\n    xgridLines = $$.xgridLines || d3.selectAll([])\n    mainRegion = $$.mainRegion || d3.selectAll([])\n    mainText = $$.mainText || d3.selectAll([])\n    mainBar = $$.mainBar || d3.selectAll([])\n    mainLine = $$.mainLine || d3.selectAll([])\n    mainArea = $$.mainArea || d3.selectAll([])\n    mainCircle = $$.mainCircle || d3.selectAll([])\n\n    // generate transform to flow\n    if (!flow.orgDataCount) {\n      // if empty\n      if ($$.data.targets[0].values.length !== 1) {\n        translateX = $$.x(orgDomain[0]) - $$.x(domain[0])\n      } else {\n        if ($$.isTimeSeries()) {\n          flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0)\n          flowEnd = $$.getValueOnIndex(\n            $$.data.targets[0].values,\n            $$.data.targets[0].values.length - 1\n          )\n          translateX = $$.x(flowStart.x) - $$.x(flowEnd.x)\n        } else {\n          translateX = diffDomain(domain) / 2\n        }\n      }\n    } else if (\n      flow.orgDataCount === 1 ||\n      (flowStart && flowStart.x) === (flowEnd && flowEnd.x)\n    ) {\n      translateX = $$.x(orgDomain[0]) - $$.x(domain[0])\n    } else {\n      if ($$.isTimeSeries()) {\n        translateX = $$.x(orgDomain[0]) - $$.x(domain[0])\n      } else {\n        translateX = $$.x(flowStart.x) - $$.x(flowEnd.x)\n      }\n    }\n    scaleX = diffDomain(orgDomain) / diffDomain(domain)\n    transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)'\n\n    $$.hideXGridFocus()\n\n    var flowTransition = d3\n      .transition()\n      .ease(d3.easeLinear)\n      .duration(durationForFlow)\n    wait.add($$.xAxis($$.axes.x, flowTransition))\n    wait.add(mainBar.transition(flowTransition).attr('transform', transform))\n    wait.add(mainLine.transition(flowTransition).attr('transform', transform))\n    wait.add(mainArea.transition(flowTransition).attr('transform', transform))\n    wait.add(mainCircle.transition(flowTransition).attr('transform', transform))\n    wait.add(mainText.transition(flowTransition).attr('transform', transform))\n    wait.add(\n      mainRegion\n        .filter($$.isRegionOnX)\n        .transition(flowTransition)\n        .attr('transform', transform)\n    )\n    wait.add(xgrid.transition(flowTransition).attr('transform', transform))\n    wait.add(xgridLines.transition(flowTransition).attr('transform', transform))\n    wait(function() {\n      var i,\n        shapes = [],\n        texts = []\n\n      // remove flowed elements\n      if (flowLength) {\n        for (i = 0; i < flowLength; i++) {\n          shapes.push('.' + CLASS.shape + '-' + (flowIndex + i))\n          texts.push('.' + CLASS.text + '-' + (flowIndex + i))\n        }\n        $$.svg\n          .selectAll('.' + CLASS.shapes)\n          .selectAll(shapes)\n          .remove()\n        $$.svg\n          .selectAll('.' + CLASS.texts)\n          .selectAll(texts)\n          .remove()\n        $$.svg.select('.' + CLASS.xgrid).remove()\n      }\n\n      // draw again for removing flowed elements and reverting attr\n      xgrid\n        .attr('transform', null)\n        .attr('x1', $$.xgridAttr.x1)\n        .attr('x2', $$.xgridAttr.x2)\n        .attr('y1', $$.xgridAttr.y1)\n        .attr('y2', $$.xgridAttr.y2)\n        .style('opacity', $$.xgridAttr.opacity)\n      xgridLines.attr('transform', null)\n      xgridLines\n        .select('line')\n        .attr('x1', config.axis_rotated ? 0 : xv)\n        .attr('x2', config.axis_rotated ? $$.width : xv)\n      xgridLines\n        .select('text')\n        .attr('x', config.axis_rotated ? $$.width : 0)\n        .attr('y', xv)\n      mainBar.attr('transform', null).attr('d', drawBar)\n      mainLine.attr('transform', null).attr('d', drawLine)\n      mainArea.attr('transform', null).attr('d', drawArea)\n      mainCircle\n        .attr('transform', null)\n        .attr('cx', cx)\n        .attr('cy', cy)\n      mainText\n        .attr('transform', null)\n        .attr('x', xForText)\n        .attr('y', yForText)\n        .style('fill-opacity', $$.opacityForText.bind($$))\n      mainRegion.attr('transform', null)\n      mainRegion\n        .filter($$.isRegionOnX)\n        .attr('x', $$.regionX.bind($$))\n        .attr('width', $$.regionWidth.bind($$))\n\n      // callback for end of flow\n      done()\n\n      $$.flowing = false\n    })\n  }\n}\n"
  },
  {
    "path": "src/api.focus.ts",
    "content": "import CLASS from './class'\nimport { Chart } from './core'\n\nChart.prototype.focus = function(targetIds) {\n  var $$ = this.internal,\n    candidates\n\n  targetIds = $$.mapToTargetIds(targetIds)\n  ;(candidates = $$.svg.selectAll(\n    $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))\n  )),\n    this.revert()\n  this.defocus()\n  candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false)\n  if ($$.hasArcType()) {\n    $$.expandArc(targetIds)\n  }\n  $$.toggleFocusLegend(targetIds, true)\n\n  $$.focusedTargetIds = targetIds\n  $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function(id) {\n    return targetIds.indexOf(id) < 0\n  })\n}\n\nChart.prototype.defocus = function(targetIds) {\n  var $$ = this.internal,\n    candidates\n\n  targetIds = $$.mapToTargetIds(targetIds)\n  ;(candidates = $$.svg.selectAll(\n    $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))\n  )),\n    candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true)\n  if ($$.hasArcType()) {\n    $$.unexpandArc(targetIds)\n  }\n  $$.toggleFocusLegend(targetIds, false)\n\n  $$.focusedTargetIds = $$.focusedTargetIds.filter(function(id) {\n    return targetIds.indexOf(id) < 0\n  })\n  $$.defocusedTargetIds = targetIds\n}\n\nChart.prototype.revert = function(targetIds) {\n  var $$ = this.internal,\n    candidates\n\n  targetIds = $$.mapToTargetIds(targetIds)\n  candidates = $$.svg.selectAll($$.selectorTargets(targetIds)) // should be for all targets\n\n  candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false)\n  if ($$.hasArcType()) {\n    $$.unexpandArc(targetIds)\n  }\n  if ($$.config.legend_show) {\n    $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$)))\n    $$.legend\n      .selectAll($$.selectorLegends(targetIds))\n      .filter(function() {\n        return $$.d3.select(this).classed(CLASS.legendItemFocused)\n      })\n      .classed(CLASS.legendItemFocused, false)\n  }\n\n  $$.focusedTargetIds = []\n  $$.defocusedTargetIds = []\n}\n"
  },
  {
    "path": "src/api.grid.ts",
    "content": "import { Chart } from './core'\n\nChart.prototype.xgrids = function(grids) {\n  var $$ = this.internal,\n    config = $$.config\n  if (!grids) {\n    return config.grid_x_lines\n  }\n  config.grid_x_lines = grids\n  $$.redrawWithoutRescale()\n  return config.grid_x_lines\n}\nChart.prototype.xgrids.add = function(grids) {\n  var $$ = this.internal\n  return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : []))\n}\nChart.prototype.xgrids.remove = function(params) {\n  // TODO: multiple\n  var $$ = this.internal\n  $$.removeGridLines(params, true)\n}\n\nChart.prototype.ygrids = function(grids) {\n  var $$ = this.internal,\n    config = $$.config\n  if (!grids) {\n    return config.grid_y_lines\n  }\n  config.grid_y_lines = grids\n  $$.redrawWithoutRescale()\n  return config.grid_y_lines\n}\nChart.prototype.ygrids.add = function(grids) {\n  var $$ = this.internal\n  return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : []))\n}\nChart.prototype.ygrids.remove = function(params) {\n  // TODO: multiple\n  var $$ = this.internal\n  $$.removeGridLines(params, false)\n}\n"
  },
  {
    "path": "src/api.group.ts",
    "content": "import { Chart } from './core'\nimport { isUndefined } from './util'\n\nChart.prototype.groups = function(groups) {\n  var $$ = this.internal,\n    config = $$.config\n  if (isUndefined(groups)) {\n    return config.data_groups\n  }\n  config.data_groups = groups\n  $$.redraw()\n  return config.data_groups\n}\n"
  },
  {
    "path": "src/api.legend.ts",
    "content": "import { Chart } from './core'\n\nChart.prototype.legend = function() {}\nChart.prototype.legend.show = function(targetIds) {\n  var $$ = this.internal\n  $$.showLegend($$.mapToTargetIds(targetIds))\n  $$.updateAndRedraw({ withLegend: true })\n}\nChart.prototype.legend.hide = function(targetIds) {\n  var $$ = this.internal\n  $$.hideLegend($$.mapToTargetIds(targetIds))\n  $$.updateAndRedraw({ withLegend: false })\n}\n"
  },
  {
    "path": "src/api.load.ts",
    "content": "import { Chart } from './core'\n\nChart.prototype.load = function(args) {\n  var $$ = this.internal,\n    config = $$.config\n  // update xs if specified\n  if (args.xs) {\n    $$.addXs(args.xs)\n  }\n  // update names if exists\n  if ('names' in args) {\n    Chart.prototype.data.names.bind(this)(args.names)\n  }\n  // update classes if exists\n  if ('classes' in args) {\n    Object.keys(args.classes).forEach(function(id) {\n      config.data_classes[id] = args.classes[id]\n    })\n  }\n  // update categories if exists\n  if ('categories' in args && $$.isCategorized()) {\n    config.axis_x_categories = args.categories\n  }\n  // update axes if exists\n  if ('axes' in args) {\n    Object.keys(args.axes).forEach(function(id) {\n      config.data_axes[id] = args.axes[id]\n    })\n  }\n  // update colors if exists\n  if ('colors' in args) {\n    Object.keys(args.colors).forEach(function(id) {\n      config.data_colors[id] = args.colors[id]\n    })\n  }\n  // use cache if exists\n  if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) {\n    $$.load($$.getCaches(args.cacheIds), args.done)\n    return\n  }\n  // unload if needed\n  if (args.unload) {\n    // TODO: do not unload if target will load (included in url/rows/columns)\n    $$.unload(\n      $$.mapToTargetIds(args.unload === true ? null : args.unload),\n      function() {\n        $$.loadFromArgs(args)\n      }\n    )\n  } else {\n    $$.loadFromArgs(args)\n  }\n}\n\nChart.prototype.unload = function(args) {\n  var $$ = this.internal\n  args = args || {}\n  if (args instanceof Array) {\n    args = { ids: args }\n  } else if (typeof args === 'string') {\n    args = { ids: [args] }\n  }\n  $$.unload($$.mapToTargetIds(args.ids), function() {\n    $$.redraw({\n      withUpdateOrgXDomain: true,\n      withUpdateXDomain: true,\n      withLegend: true\n    })\n    if (args.done) {\n      args.done()\n    }\n  })\n}\n"
  },
  {
    "path": "src/api.pie.ts",
    "content": "import { Chart } from './core'\n\nChart.prototype.pie = function() {}\n\nChart.prototype.pie.padAngle = function(padAngle) {\n  if (padAngle === undefined) {\n    return this.internal.config.pie_padAngle\n  }\n  this.internal.config.pie_padAngle = padAngle\n  this.flush()\n}\n"
  },
  {
    "path": "src/api.region.ts",
    "content": "import CLASS from './class'\nimport { Chart } from './core'\nimport { getOption } from './util'\n\nChart.prototype.regions = function(regions) {\n  var $$ = this.internal,\n    config = $$.config\n  if (!regions) {\n    return config.regions\n  }\n  config.regions = regions\n  $$.redrawWithoutRescale()\n  return config.regions\n}\nChart.prototype.regions.add = function(regions) {\n  var $$ = this.internal,\n    config = $$.config\n  if (!regions) {\n    return config.regions\n  }\n  config.regions = config.regions.concat(regions)\n  $$.redrawWithoutRescale()\n  return config.regions\n}\nChart.prototype.regions.remove = function(options) {\n  var $$ = this.internal,\n    config = $$.config,\n    duration,\n    classes,\n    regions\n\n  options = options || {}\n  duration = getOption(options, 'duration', config.transition_duration)\n  classes = getOption(options, 'classes', [CLASS.region])\n\n  regions = $$.main.select('.' + CLASS.regions).selectAll(\n    classes.map(function(c) {\n      return '.' + c\n    })\n  )\n  ;(duration ? regions.transition().duration(duration) : regions)\n    .style('opacity', 0)\n    .remove()\n\n  config.regions = config.regions.filter(function(region) {\n    var found = false\n    if (!region['class']) {\n      return true\n    }\n    region['class'].split(' ').forEach(function(c) {\n      if (classes.indexOf(c) >= 0) {\n        found = true\n      }\n    })\n    return !found\n  })\n\n  return config.regions\n}\n"
  },
  {
    "path": "src/api.selection.ts",
    "content": "import CLASS from './class'\nimport { Chart } from './core'\nimport { isDefined } from './util'\n\nChart.prototype.selected = function(targetId) {\n  var $$ = this.internal,\n    d3 = $$.d3\n  return $$.main\n    .selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId))\n    .selectAll('.' + CLASS.shape)\n    .filter(function() {\n      return d3.select(this).classed(CLASS.SELECTED)\n    })\n    .nodes()\n    .map(function(d) {\n      var data = d.__data__\n      return data.data ? data.data : data\n    })\n}\nChart.prototype.select = function(ids, indices, resetOther) {\n  var $$ = this.internal,\n    d3 = $$.d3,\n    config = $$.config\n  if (!config.data_selection_enabled) {\n    return\n  }\n  $$.main\n    .selectAll('.' + CLASS.shapes)\n    .selectAll('.' + CLASS.shape)\n    .each(function(d, i) {\n      var shape = d3.select(this),\n        id = d.data ? d.data.id : d.id,\n        toggle = $$.getToggle(this, d).bind($$),\n        isTargetId =\n          config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,\n        isTargetIndex = !indices || indices.indexOf(i) >= 0,\n        isSelected = shape.classed(CLASS.SELECTED)\n      // line/area selection not supported yet\n      if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {\n        return\n      }\n      if (isTargetId && isTargetIndex) {\n        if (config.data_selection_isselectable(d) && !isSelected) {\n          toggle(true, shape.classed(CLASS.SELECTED, true), d, i)\n        }\n      } else if (isDefined(resetOther) && resetOther) {\n        if (isSelected) {\n          toggle(false, shape.classed(CLASS.SELECTED, false), d, i)\n        }\n      }\n    })\n}\nChart.prototype.unselect = function(ids, indices) {\n  var $$ = this.internal,\n    d3 = $$.d3,\n    config = $$.config\n  if (!config.data_selection_enabled) {\n    return\n  }\n  $$.main\n    .selectAll('.' + CLASS.shapes)\n    .selectAll('.' + CLASS.shape)\n    .each(function(d, i) {\n      var shape = d3.select(this),\n        id = d.data ? d.data.id : d.id,\n        toggle = $$.getToggle(this, d).bind($$),\n        isTargetId =\n          config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,\n        isTargetIndex = !indices || indices.indexOf(i) >= 0,\n        isSelected = shape.classed(CLASS.SELECTED)\n      // line/area selection not supported yet\n      if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {\n        return\n      }\n      if (isTargetId && isTargetIndex) {\n        if (config.data_selection_isselectable(d)) {\n          if (isSelected) {\n            toggle(false, shape.classed(CLASS.SELECTED, false), d, i)\n          }\n        }\n      }\n    })\n}\n"
  },
  {
    "path": "src/api.show.ts",
    "content": "import { Chart } from './core'\nimport { isIE } from './util'\n\nChart.prototype.show = function(targetIds, options) {\n  var $$ = this.internal,\n    targets\n\n  targetIds = $$.mapToTargetIds(targetIds)\n  options = options || {}\n\n  $$.removeHiddenTargetIds(targetIds)\n  targets = $$.svg.selectAll($$.selectorTargets(targetIds))\n\n  targets\n    .transition()\n    .style('display', isIE() ? 'block' : 'initial', 'important')\n    .style('opacity', 1, 'important')\n    .call($$.endall, function() {\n      targets.style('opacity', null).style('opacity', 1)\n    })\n\n  if (options.withLegend) {\n    $$.showLegend(targetIds)\n  }\n\n  $$.redraw({\n    withUpdateOrgXDomain: true,\n    withUpdateXDomain: true,\n    withLegend: true\n  })\n}\n\nChart.prototype.hide = function(targetIds, options) {\n  var $$ = this.internal,\n    targets\n\n  targetIds = $$.mapToTargetIds(targetIds)\n  options = options || {}\n\n  $$.addHiddenTargetIds(targetIds)\n  targets = $$.svg.selectAll($$.selectorTargets(targetIds))\n\n  targets\n    .transition()\n    .style('opacity', 0, 'important')\n    .call($$.endall, function() {\n      targets.style('opacity', null).style('opacity', 0)\n      targets.style('display', 'none')\n    })\n\n  if (options.withLegend) {\n    $$.hideLegend(targetIds)\n  }\n\n  $$.redraw({\n    withUpdateOrgXDomain: true,\n    withUpdateXDomain: true,\n    withLegend: true\n  })\n}\n\nChart.prototype.toggle = function(targetIds, options) {\n  var that = this,\n    $$ = this.internal\n  $$.mapToTargetIds(targetIds).forEach(function(targetId) {\n    $$.isTargetToShow(targetId)\n      ? that.hide(targetId, options)\n      : that.show(targetId, options)\n  })\n}\n"
  },
  {
    "path": "src/api.subchart.ts",
    "content": "import { Chart } from './core'\n\nChart.prototype.subchart = function() {}\n\nChart.prototype.subchart.isShown = function() {\n  const $$ = this.internal\n\n  return $$.config.subchart_show\n}\n\nChart.prototype.subchart.show = function() {\n  const $$ = this.internal\n\n  if ($$.config.subchart_show) {\n    return\n  }\n\n  $$.config.subchart_show = true\n\n  // insert DOM\n  $$.initSubchart()\n\n  // update dimensions with sub chart now visible\n  $$.updateDimension()\n\n  // insert brush (depends on sizes previously updated)\n  $$.initSubchartBrush()\n\n  // attach data\n  $$.updateTargetsForSubchart($$.getTargets())\n\n  // reset fade-in state\n  $$.mapToIds($$.data.targets).forEach(function(id) {\n    $$.withoutFadeIn[id] = false\n  })\n\n  // redraw chart !\n  $$.updateAndRedraw()\n\n  // update visible targets !\n  $$.showTargets()\n}\n\nChart.prototype.subchart.hide = function() {\n  const $$ = this.internal\n\n  if (!$$.config.subchart_show) {\n    return\n  }\n\n  $$.config.subchart_show = false\n\n  // remove DOM\n  $$.removeSubchart()\n\n  // re-render chart\n  $$.redraw()\n}\n"
  },
  {
    "path": "src/api.tooltip.ts",
    "content": "import { Chart } from './core'\n\nChart.prototype.tooltip = function() {}\nChart.prototype.tooltip.show = function(args) {\n  var $$ = this.internal,\n    targets,\n    data,\n    mouse = {}\n\n  // determine mouse position on the chart\n  if (args.mouse) {\n    mouse = args.mouse\n  } else {\n    // determine focus data\n    if (args.data) {\n      data = args.data\n    } else if (typeof args.x !== 'undefined') {\n      if (args.id) {\n        targets = $$.data.targets.filter(function(t) {\n          return t.id === args.id\n        })\n      } else {\n        targets = $$.data.targets\n      }\n      data = $$.filterByX(targets, args.x).slice(0, 1)[0]\n    }\n    mouse = data ? $$.getMousePosition(data) : null\n  }\n\n  // emulate mouse events to show\n  $$.dispatchEvent('mousemove', mouse)\n\n  $$.config.tooltip_onshow.call($$, data)\n}\nChart.prototype.tooltip.hide = function() {\n  // TODO: get target data by checking the state of focus\n  this.internal.dispatchEvent('mouseout', 0)\n\n  this.internal.config.tooltip_onhide.call(this)\n}\n"
  },
  {
    "path": "src/api.transform.ts",
    "content": "import { Chart, ChartInternal } from './core'\n\nChart.prototype.transform = function(type, targetIds) {\n  var $$ = this.internal,\n    options =\n      ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null\n  $$.transformTo(targetIds, type, options)\n}\n\nChartInternal.prototype.transformTo = function(\n  targetIds,\n  type,\n  optionsForRedraw\n) {\n  var $$ = this,\n    withTransitionForAxis = !$$.hasArcType(),\n    options = optionsForRedraw || {\n      withTransitionForAxis: withTransitionForAxis\n    }\n  options.withTransitionForTransform = false\n  $$.transiting = false\n  $$.setTargetType(targetIds, type)\n  $$.updateTargets($$.data.targets) // this is needed when transforming to arc\n  $$.updateAndRedraw(options)\n}\n"
  },
  {
    "path": "src/api.x.ts",
    "content": "import { Chart } from './core'\n\nChart.prototype.x = function(x) {\n  var $$ = this.internal\n  if (arguments.length) {\n    $$.updateTargetX($$.data.targets, x)\n    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true })\n  }\n  return $$.data.xs\n}\nChart.prototype.xs = function(xs) {\n  var $$ = this.internal\n  if (arguments.length) {\n    $$.updateTargetXs($$.data.targets, xs)\n    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true })\n  }\n  return $$.data.xs\n}\n"
  },
  {
    "path": "src/api.zoom.ts",
    "content": "import { Chart } from './core'\nimport { isDefined } from './util'\n\nChart.prototype.zoom = function(domain) {\n  var $$ = this.internal\n  if (domain) {\n    if ($$.isTimeSeries()) {\n      domain = domain.map(function(x) {\n        return $$.parseDate(x)\n      })\n    }\n    if ($$.config.subchart_show) {\n      $$.brush.selectionAsValue(domain, true)\n    } else {\n      $$.updateXDomain(null, true, false, false, domain)\n      $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false })\n    }\n    $$.config.zoom_onzoom.call(this, $$.x.orgDomain())\n    return domain\n  } else {\n    return $$.x.domain()\n  }\n}\nChart.prototype.zoom.enable = function(enabled) {\n  var $$ = this.internal\n  $$.config.zoom_enabled = enabled\n  $$.updateAndRedraw()\n}\nChart.prototype.unzoom = function() {\n  var $$ = this.internal\n  if ($$.config.subchart_show) {\n    $$.brush.clear()\n  } else {\n    $$.updateXDomain(null, true, false, false, $$.subX.domain())\n    $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false })\n  }\n}\n\nChart.prototype.zoom.max = function(max) {\n  var $$ = this.internal,\n    config = $$.config,\n    d3 = $$.d3\n  if (max === 0 || max) {\n    config.zoom_x_max = d3.max([$$.orgXDomain[1], max])\n  } else {\n    return config.zoom_x_max\n  }\n}\n\nChart.prototype.zoom.min = function(min) {\n  var $$ = this.internal,\n    config = $$.config,\n    d3 = $$.d3\n  if (min === 0 || min) {\n    config.zoom_x_min = d3.min([$$.orgXDomain[0], min])\n  } else {\n    return config.zoom_x_min\n  }\n}\n\nChart.prototype.zoom.range = function(range) {\n  if (arguments.length) {\n    if (isDefined(range.max)) {\n      this.domain.max(range.max)\n    }\n    if (isDefined(range.min)) {\n      this.domain.min(range.min)\n    }\n  } else {\n    return {\n      max: this.domain.max(),\n      min: this.domain.min()\n    }\n  }\n}\n"
  },
  {
    "path": "src/arc.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport { isFunction } from './util'\n\nChartInternal.prototype.initPie = function() {\n  var $$ = this,\n    d3 = $$.d3\n  $$.pie = d3\n    .pie()\n    .padAngle(this.getPadAngle.bind(this))\n    .value(function(d) {\n      return d.values.reduce(function(a, b) {\n        return a + b.value\n      }, 0)\n    })\n\n  let orderFct = $$.getOrderFunction()\n\n  // we need to reverse the returned order if asc or desc to have the slice in expected order.\n  if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) {\n    let defaultSort = orderFct\n    orderFct = (t1, t2) => defaultSort(t1, t2) * -1\n  }\n\n  $$.pie.sort(orderFct || null)\n}\n\nChartInternal.prototype.updateRadius = function() {\n  var $$ = this,\n    config = $$.config,\n    w = config.gauge_width || config.donut_width,\n    gaugeArcWidth =\n      $$.filterTargetsToShow($$.data.targets).length *\n      $$.config.gauge_arcs_minWidth\n  $$.radiusExpanded =\n    (Math.min($$.arcWidth, $$.arcHeight) / 2) * ($$.hasType('gauge') ? 0.85 : 1)\n  $$.radius = $$.radiusExpanded * 0.95\n  $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6\n  $$.innerRadius =\n    $$.hasType('donut') || $$.hasType('gauge')\n      ? $$.radius * $$.innerRadiusRatio\n      : 0\n  $$.gaugeArcWidth = w\n    ? w\n    : gaugeArcWidth <= $$.radius - $$.innerRadius\n    ? $$.radius - $$.innerRadius\n    : gaugeArcWidth <= $$.radius\n    ? gaugeArcWidth\n    : $$.radius\n}\n\nChartInternal.prototype.getPadAngle = function() {\n  if (this.hasType('pie')) {\n    return this.config.pie_padAngle || 0\n  } else if (this.hasType('donut')) {\n    return this.config.donut_padAngle || 0\n  } else {\n    return 0\n  }\n}\n\nChartInternal.prototype.updateArc = function() {\n  var $$ = this\n  $$.svgArc = $$.getSvgArc()\n  $$.svgArcExpanded = $$.getSvgArcExpanded()\n  $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98)\n}\n\nChartInternal.prototype.updateAngle = function(d) {\n  var $$ = this,\n    config = $$.config,\n    found = false,\n    index = 0,\n    gMin,\n    gMax,\n    gTic,\n    gValue\n\n  if (!config) {\n    return null\n  }\n\n  $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function(t) {\n    if (!found && t.data.id === d.data.id) {\n      found = true\n      d = t\n      d.index = index\n    }\n    index++\n  })\n  if (isNaN(d.startAngle)) {\n    d.startAngle = 0\n  }\n  if (isNaN(d.endAngle)) {\n    d.endAngle = d.startAngle\n  }\n  if ($$.isGaugeType(d.data)) {\n    gMin = config.gauge_min\n    gMax = config.gauge_max\n    gTic = (Math.PI * (config.gauge_fullCircle ? 2 : 1)) / (gMax - gMin)\n    gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin\n    d.startAngle = config.gauge_startingAngle\n    d.endAngle = d.startAngle + gTic * gValue\n  }\n  return found ? d : null\n}\n\nChartInternal.prototype.getSvgArc = function() {\n  var $$ = this,\n    hasGaugeType = $$.hasType('gauge'),\n    singleArcWidth =\n      $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,\n    arc = $$.d3\n      .arc()\n      .outerRadius(function(d) {\n        return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius\n      })\n      .innerRadius(function(d) {\n        return hasGaugeType\n          ? $$.radius - singleArcWidth * (d.index + 1)\n          : $$.innerRadius\n      }),\n    newArc = function(d, withoutUpdate) {\n      var updated\n      if (withoutUpdate) {\n        return arc(d)\n      } // for interpolate\n      updated = $$.updateAngle(d)\n      return updated ? arc(updated) : 'M 0 0'\n    }\n    // TODO: extends all function\n  ;(newArc as any).centroid = arc.centroid\n  return newArc\n}\n\nChartInternal.prototype.getSvgArcExpanded = function(rate) {\n  rate = rate || 1\n  var $$ = this,\n    hasGaugeType = $$.hasType('gauge'),\n    singleArcWidth =\n      $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,\n    expandWidth = Math.min(\n      $$.radiusExpanded * rate - $$.radius,\n      singleArcWidth * 0.8 - (1 - rate) * 100\n    ),\n    arc = $$.d3\n      .arc()\n      .outerRadius(function(d) {\n        return hasGaugeType\n          ? $$.radius - singleArcWidth * d.index + expandWidth\n          : $$.radiusExpanded * rate\n      })\n      .innerRadius(function(d) {\n        return hasGaugeType\n          ? $$.radius - singleArcWidth * (d.index + 1)\n          : $$.innerRadius\n      })\n  return function(d) {\n    var updated = $$.updateAngle(d)\n    return updated ? arc(updated) : 'M 0 0'\n  }\n}\n\nChartInternal.prototype.getArc = function(d, withoutUpdate, force) {\n  return force || this.isArcType(d.data)\n    ? this.svgArc(d, withoutUpdate)\n    : 'M 0 0'\n}\n\nChartInternal.prototype.transformForArcLabel = function(d) {\n  var $$ = this,\n    config = $$.config,\n    updated = $$.updateAngle(d),\n    c,\n    x,\n    y,\n    h,\n    ratio,\n    translate = '',\n    hasGauge = $$.hasType('gauge')\n  if (updated && !hasGauge) {\n    c = this.svgArc.centroid(updated)\n    x = isNaN(c[0]) ? 0 : c[0]\n    y = isNaN(c[1]) ? 0 : c[1]\n    h = Math.sqrt(x * x + y * y)\n    if ($$.hasType('donut') && config.donut_label_ratio) {\n      ratio = isFunction(config.donut_label_ratio)\n        ? config.donut_label_ratio(d, $$.radius, h)\n        : config.donut_label_ratio\n    } else if ($$.hasType('pie') && config.pie_label_ratio) {\n      ratio = isFunction(config.pie_label_ratio)\n        ? config.pie_label_ratio(d, $$.radius, h)\n        : config.pie_label_ratio\n    } else {\n      ratio =\n        $$.radius && h\n          ? ((36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) *\n              $$.radius) /\n            h\n          : 0\n    }\n    translate = 'translate(' + x * ratio + ',' + y * ratio + ')'\n  } else if (\n    updated &&\n    hasGauge &&\n    $$.filterTargetsToShow($$.data.targets).length > 1\n  ) {\n    var y1 = Math.sin(updated.endAngle - Math.PI / 2)\n    x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25)\n    y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3\n    translate = 'translate(' + x + ',' + y + ')'\n  }\n  return translate\n}\n\n/**\n * @deprecated Use `getRatio('arc', d)` instead.\n */\nChartInternal.prototype.getArcRatio = function(d) {\n  return this.getRatio('arc', d)\n}\n\nChartInternal.prototype.convertToArcData = function(d) {\n  return this.addName({\n    id: d.data.id,\n    value: d.value,\n    ratio: this.getRatio('arc', d),\n    index: d.index\n  })\n}\n\nChartInternal.prototype.textForArcLabel = function(d) {\n  var $$ = this,\n    updated,\n    value,\n    ratio,\n    id,\n    format\n  if (!$$.shouldShowArcLabel()) {\n    return ''\n  }\n  updated = $$.updateAngle(d)\n  value = updated ? updated.value : null\n  ratio = $$.getRatio('arc', updated)\n  id = d.data.id\n  if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) {\n    return ''\n  }\n  format = $$.getArcLabelFormat()\n  return format\n    ? format(value, ratio, id)\n    : $$.defaultArcValueFormat(value, ratio)\n}\n\nChartInternal.prototype.textForGaugeMinMax = function(value, isMax) {\n  var $$ = this,\n    format = $$.getGaugeLabelExtents()\n\n  return format ? format(value, isMax) : value\n}\n\nChartInternal.prototype.expandArc = function(targetIds) {\n  var $$ = this,\n    interval\n\n  // MEMO: avoid to cancel transition\n  if ($$.transiting) {\n    interval = window.setInterval(function() {\n      if (!$$.transiting) {\n        window.clearInterval(interval)\n        if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) {\n          $$.expandArc(targetIds)\n        }\n      }\n    }, 10)\n    return\n  }\n\n  targetIds = $$.mapToTargetIds(targetIds)\n\n  $$.svg\n    .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc))\n    .each(function(d) {\n      if (!$$.shouldExpand(d.data.id)) {\n        return\n      }\n      $$.d3\n        .select(this)\n        .selectAll('path')\n        .transition()\n        .duration($$.expandDuration(d.data.id))\n        .attr('d', $$.svgArcExpanded)\n        .transition()\n        .duration($$.expandDuration(d.data.id) * 2)\n        .attr('d', $$.svgArcExpandedSub)\n        .each(function(d) {\n          if ($$.isDonutType(d.data)) {\n            // callback here\n          }\n        })\n    })\n}\n\nChartInternal.prototype.unexpandArc = function(targetIds) {\n  var $$ = this\n\n  if ($$.transiting) {\n    return\n  }\n\n  targetIds = $$.mapToTargetIds(targetIds)\n\n  $$.svg\n    .selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc))\n    .selectAll('path')\n    .transition()\n    .duration(function(d) {\n      return $$.expandDuration(d.data.id)\n    })\n    .attr('d', $$.svgArc)\n  $$.svg.selectAll('.' + CLASS.arc)\n}\n\nChartInternal.prototype.expandDuration = function(id) {\n  var $$ = this,\n    config = $$.config\n\n  if ($$.isDonutType(id)) {\n    return config.donut_expand_duration\n  } else if ($$.isGaugeType(id)) {\n    return config.gauge_expand_duration\n  } else if ($$.isPieType(id)) {\n    return config.pie_expand_duration\n  } else {\n    return 50\n  }\n}\n\nChartInternal.prototype.shouldExpand = function(id) {\n  var $$ = this,\n    config = $$.config\n  return (\n    ($$.isDonutType(id) && config.donut_expand) ||\n    ($$.isGaugeType(id) && config.gauge_expand) ||\n    ($$.isPieType(id) && config.pie_expand)\n  )\n}\n\nChartInternal.prototype.shouldShowArcLabel = function() {\n  var $$ = this,\n    config = $$.config,\n    shouldShow = true\n  if ($$.hasType('donut')) {\n    shouldShow = config.donut_label_show\n  } else if ($$.hasType('pie')) {\n    shouldShow = config.pie_label_show\n  }\n  // when gauge, always true\n  return shouldShow\n}\n\nChartInternal.prototype.meetsArcLabelThreshold = function(ratio) {\n  var $$ = this,\n    config = $$.config,\n    threshold = $$.hasType('donut')\n      ? config.donut_label_threshold\n      : config.pie_label_threshold\n  return ratio >= threshold\n}\n\nChartInternal.prototype.getArcLabelFormat = function() {\n  var $$ = this,\n    config = $$.config,\n    format = config.pie_label_format\n  if ($$.hasType('gauge')) {\n    format = config.gauge_label_format\n  } else if ($$.hasType('donut')) {\n    format = config.donut_label_format\n  }\n  return format\n}\n\nChartInternal.prototype.getGaugeLabelExtents = function() {\n  var $$ = this,\n    config = $$.config\n  return config.gauge_label_extents\n}\n\nChartInternal.prototype.getArcTitle = function() {\n  var $$ = this\n  return $$.hasType('donut') ? $$.config.donut_title : ''\n}\n\nChartInternal.prototype.updateTargetsForArc = function(targets) {\n  var $$ = this,\n    main = $$.main,\n    mainPies,\n    mainPieEnter,\n    classChartArc = $$.classChartArc.bind($$),\n    classArcs = $$.classArcs.bind($$),\n    classFocus = $$.classFocus.bind($$)\n  mainPies = main\n    .select('.' + CLASS.chartArcs)\n    .selectAll('.' + CLASS.chartArc)\n    .data($$.pie(targets))\n    .attr('class', function(d) {\n      return classChartArc(d) + classFocus(d.data)\n    })\n  mainPieEnter = mainPies\n    .enter()\n    .append('g')\n    .attr('class', classChartArc)\n  mainPieEnter.append('g').attr('class', classArcs)\n  mainPieEnter\n    .append('text')\n    .attr('dy', $$.hasType('gauge') ? '-.1em' : '.35em')\n    .style('opacity', 0)\n    .style('text-anchor', 'middle')\n    .style('pointer-events', 'none')\n  // MEMO: can not keep same color..., but not bad to update color in redraw\n  //mainPieUpdate.exit().remove();\n}\n\nChartInternal.prototype.initArc = function() {\n  var $$ = this\n  $$.arcs = $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartArcs)\n    .attr('transform', $$.getTranslate('arc'))\n  $$.arcs\n    .append('text')\n    .attr('class', CLASS.chartArcsTitle)\n    .style('text-anchor', 'middle')\n    .text($$.getArcTitle())\n}\n\nChartInternal.prototype.redrawArc = function(\n  duration,\n  durationForExit,\n  withTransform\n) {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    main = $$.main,\n    arcs,\n    mainArc,\n    arcLabelLines,\n    mainArcLabelLine,\n    hasGaugeType = $$.hasType('gauge')\n  arcs = main\n    .selectAll('.' + CLASS.arcs)\n    .selectAll('.' + CLASS.arc)\n    .data($$.arcData.bind($$))\n  mainArc = arcs\n    .enter()\n    .append('path')\n    .attr('class', $$.classArc.bind($$))\n    .style('fill', function(d) {\n      return $$.color(d.data)\n    })\n    .style('cursor', function(d) {\n      return config.interaction_enabled && config.data_selection_isselectable(d)\n        ? 'pointer'\n        : null\n    })\n    .each(function(d) {\n      if ($$.isGaugeType(d.data)) {\n        d.startAngle = d.endAngle = config.gauge_startingAngle\n      }\n      this._current = d\n    })\n    .merge(arcs)\n  if (hasGaugeType) {\n    arcLabelLines = main\n      .selectAll('.' + CLASS.arcs)\n      .selectAll('.' + CLASS.arcLabelLine)\n      .data($$.arcData.bind($$))\n    mainArcLabelLine = arcLabelLines\n      .enter()\n      .append('rect')\n      .attr('class', function(d) {\n        return (\n          CLASS.arcLabelLine +\n          ' ' +\n          CLASS.target +\n          ' ' +\n          CLASS.target +\n          '-' +\n          d.data.id\n        )\n      })\n      .merge(arcLabelLines)\n\n    if ($$.filterTargetsToShow($$.data.targets).length === 1) {\n      mainArcLabelLine.style('display', 'none')\n    } else {\n      mainArcLabelLine\n        .style('fill', function(d) {\n          return $$.levelColor\n            ? $$.levelColor(\n                d.data.values.reduce(function(total, item) {\n                  return total + item.value\n                }, 0)\n              )\n            : $$.color(d.data)\n        })\n        .style('display', config.gauge_labelLine_show ? '' : 'none')\n        .each(function(d) {\n          var lineLength = 0,\n            lineThickness = 2,\n            x = 0,\n            y = 0,\n            transform = ''\n          if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) {\n            var updated = $$.updateAngle(d),\n              innerLineLength =\n                ($$.gaugeArcWidth /\n                  $$.filterTargetsToShow($$.data.targets).length) *\n                (updated.index + 1),\n              lineAngle = updated.endAngle - Math.PI / 2,\n              arcInnerRadius = $$.radius - innerLineLength,\n              linePositioningAngle =\n                lineAngle - (arcInnerRadius === 0 ? 0 : 1 / arcInnerRadius)\n            lineLength = $$.radiusExpanded - $$.radius + innerLineLength\n            x = Math.cos(linePositioningAngle) * arcInnerRadius\n            y = Math.sin(linePositioningAngle) * arcInnerRadius\n            transform =\n              'rotate(' +\n              (lineAngle * 180) / Math.PI +\n              ', ' +\n              x +\n              ', ' +\n              y +\n              ')'\n          }\n          d3.select(this)\n            .attr('x', x)\n            .attr('y', y)\n            .attr('width', lineLength)\n            .attr('height', lineThickness)\n            .attr('transform', transform)\n            .style(\n              'stroke-dasharray',\n              '0, ' + (lineLength + lineThickness) + ', 0'\n            )\n        })\n    }\n  }\n  mainArc\n    .attr('transform', function(d) {\n      return !$$.isGaugeType(d.data) && withTransform ? 'scale(0)' : ''\n    })\n    .on(\n      'mouseover',\n      config.interaction_enabled\n        ? function(d) {\n            var updated, arcData\n            if ($$.transiting) {\n              // skip while transiting\n              return\n            }\n            updated = $$.updateAngle(d)\n            if (updated) {\n              arcData = $$.convertToArcData(updated)\n              // transitions\n              $$.expandArc(updated.data.id)\n              $$.api.focus(updated.data.id)\n              $$.toggleFocusLegend(updated.data.id, true)\n              $$.config.data_onmouseover(arcData, this)\n            }\n          }\n        : null\n    )\n    .on(\n      'mousemove',\n      config.interaction_enabled\n        ? function(d) {\n            var updated = $$.updateAngle(d),\n              arcData,\n              selectedData\n            if (updated) {\n              ;(arcData = $$.convertToArcData(updated)),\n                (selectedData = [arcData])\n              $$.showTooltip(selectedData, this)\n            }\n          }\n        : null\n    )\n    .on(\n      'mouseout',\n      config.interaction_enabled\n        ? function(d) {\n            var updated, arcData\n            if ($$.transiting) {\n              // skip while transiting\n              return\n            }\n            updated = $$.updateAngle(d)\n            if (updated) {\n              arcData = $$.convertToArcData(updated)\n              // transitions\n              $$.unexpandArc(updated.data.id)\n              $$.api.revert()\n              $$.revertLegend()\n              $$.hideTooltip()\n              $$.config.data_onmouseout(arcData, this)\n            }\n          }\n        : null\n    )\n    .on(\n      'click',\n      config.interaction_enabled\n        ? function(d, i) {\n            var updated = $$.updateAngle(d),\n              arcData\n            if (updated) {\n              arcData = $$.convertToArcData(updated)\n              if ($$.toggleShape) {\n                $$.toggleShape(this, arcData, i)\n              }\n              $$.config.data_onclick.call($$.api, arcData, this)\n            }\n          }\n        : null\n    )\n    .each(function() {\n      $$.transiting = true\n    })\n    .transition()\n    .duration(duration)\n    .attrTween('d', function(d) {\n      var updated = $$.updateAngle(d),\n        interpolate\n      if (!updated) {\n        return function() {\n          return 'M 0 0'\n        }\n      }\n      //                if (this._current === d) {\n      //                    this._current = {\n      //                        startAngle: Math.PI*2,\n      //                        endAngle: Math.PI*2,\n      //                    };\n      //                }\n      if (isNaN(this._current.startAngle)) {\n        this._current.startAngle = 0\n      }\n      if (isNaN(this._current.endAngle)) {\n        this._current.endAngle = this._current.startAngle\n      }\n      interpolate = d3.interpolate(this._current, updated)\n      this._current = interpolate(0)\n      return function(t) {\n        // prevents crashing the charts once in transition and chart.destroy() has been called\n        if ($$.config === null) {\n          return 'M 0 0'\n        }\n        var interpolated = interpolate(t)\n        interpolated.data = d.data // data.id will be updated by interporator\n        return $$.getArc(interpolated, true)\n      }\n    })\n    .attr('transform', withTransform ? 'scale(1)' : '')\n    .style('fill', function(d) {\n      return $$.levelColor\n        ? $$.levelColor(\n            d.data.values.reduce(function(total, item) {\n              return total + item.value\n            }, 0)\n          )\n        : $$.color(d.data.id)\n    }) // Where gauge reading color would receive customization.\n    .call($$.endall, function() {\n      $$.transiting = false\n    })\n  arcs\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n    .remove()\n  main\n    .selectAll('.' + CLASS.chartArc)\n    .select('text')\n    .style('opacity', 0)\n    .attr('class', function(d) {\n      return $$.isGaugeType(d.data) ? CLASS.gaugeValue : ''\n    })\n    .text($$.textForArcLabel.bind($$))\n    .attr('transform', $$.transformForArcLabel.bind($$))\n    .style('font-size', function(d) {\n      return $$.isGaugeType(d.data) &&\n        $$.filterTargetsToShow($$.data.targets).length === 1\n        ? Math.round($$.radius / 5) + 'px'\n        : ''\n    })\n    .transition()\n    .duration(duration)\n    .style('opacity', function(d) {\n      return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0\n    })\n  main\n    .select('.' + CLASS.chartArcsTitle)\n    .style('opacity', $$.hasType('donut') || hasGaugeType ? 1 : 0)\n\n  if (hasGaugeType) {\n    let index = 0\n    const backgroundArc = $$.arcs\n      .select('g.' + CLASS.chartArcsBackground)\n      .selectAll('path.' + CLASS.chartArcsBackground)\n      .data($$.data.targets)\n\n    backgroundArc\n      .enter()\n      .append('path')\n      .attr(\n        'class',\n        (d, i) =>\n          CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i\n      )\n      .merge(backgroundArc)\n      .attr('d', d1 => {\n        if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) {\n          return 'M 0 0'\n        }\n\n        var d = {\n          data: [{ value: config.gauge_max }],\n          startAngle: config.gauge_startingAngle,\n          endAngle:\n            -1 *\n            config.gauge_startingAngle *\n            (config.gauge_fullCircle ? Math.PI : 1),\n          index: index++\n        }\n        return $$.getArc(d, true, true)\n      })\n\n    backgroundArc.exit().remove()\n\n    $$.arcs\n      .select('.' + CLASS.chartArcsGaugeUnit)\n      .attr('dy', '.75em')\n      .text(config.gauge_label_show ? config.gauge_units : '')\n    $$.arcs\n      .select('.' + CLASS.chartArcsGaugeMin)\n      .attr(\n        'dx',\n        -1 *\n          ($$.innerRadius +\n            ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) +\n          'px'\n      )\n      .attr('dy', '1.2em')\n      .text(\n        config.gauge_label_show\n          ? $$.textForGaugeMinMax(config.gauge_min, false)\n          : ''\n      )\n    $$.arcs\n      .select('.' + CLASS.chartArcsGaugeMax)\n      .attr(\n        'dx',\n        $$.innerRadius +\n          ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) +\n          'px'\n      )\n      .attr('dy', '1.2em')\n      .text(\n        config.gauge_label_show\n          ? $$.textForGaugeMinMax(config.gauge_max, true)\n          : ''\n      )\n  }\n}\nChartInternal.prototype.initGauge = function() {\n  var arcs = this.arcs\n  if (this.hasType('gauge')) {\n    arcs.append('g').attr('class', CLASS.chartArcsBackground)\n    arcs\n      .append('text')\n      .attr('class', CLASS.chartArcsGaugeUnit)\n      .style('text-anchor', 'middle')\n      .style('pointer-events', 'none')\n    arcs\n      .append('text')\n      .attr('class', CLASS.chartArcsGaugeMin)\n      .style('text-anchor', 'middle')\n      .style('pointer-events', 'none')\n    arcs\n      .append('text')\n      .attr('class', CLASS.chartArcsGaugeMax)\n      .style('text-anchor', 'middle')\n      .style('pointer-events', 'none')\n  }\n}\nChartInternal.prototype.getGaugeLabelHeight = function() {\n  return this.config.gauge_label_show ? 20 : 0\n}\n"
  },
  {
    "path": "src/axis-internal.ts",
    "content": "import { getBBox } from './util'\n\nfunction AxisInternal(component, params) {\n  var internal = this\n  internal.component = component\n  internal.params = params || {}\n\n  internal.d3 = component.d3\n  internal.scale = internal.d3.scaleLinear()\n  internal.range\n  internal.orient = 'bottom'\n  internal.innerTickSize = 6\n  internal.outerTickSize = this.params.withOuterTick ? 6 : 0\n  internal.tickPadding = 3\n  internal.tickValues = null\n  internal.tickFormat\n  internal.tickArguments\n\n  internal.tickOffset = 0\n  internal.tickCulling = true\n  internal.tickCentered\n  internal.tickTextCharSize\n  internal.tickTextRotate = internal.params.tickTextRotate\n  internal.tickLength\n\n  internal.axis = internal.generateAxis()\n}\n\nAxisInternal.prototype.axisX = function(selection, x, tickOffset) {\n  selection.attr('transform', function(d) {\n    return 'translate(' + Math.ceil(x(d) + tickOffset) + ', 0)'\n  })\n}\nAxisInternal.prototype.axisY = function(selection, y) {\n  selection.attr('transform', function(d) {\n    return 'translate(0,' + Math.ceil(y(d)) + ')'\n  })\n}\nAxisInternal.prototype.scaleExtent = function(domain) {\n  var start = domain[0],\n    stop = domain[domain.length - 1]\n  return start < stop ? [start, stop] : [stop, start]\n}\nAxisInternal.prototype.generateTicks = function(scale) {\n  var internal = this\n  var i,\n    domain,\n    ticks = []\n  if (scale.ticks) {\n    return scale.ticks.apply(scale, internal.tickArguments)\n  }\n  domain = scale.domain()\n  for (i = Math.ceil(domain[0]); i < domain[1]; i++) {\n    ticks.push(i)\n  }\n  if (ticks.length > 0 && ticks[0] > 0) {\n    ticks.unshift(ticks[0] - (ticks[1] - ticks[0]))\n  }\n  return ticks\n}\nAxisInternal.prototype.copyScale = function() {\n  var internal = this\n  var newScale = internal.scale.copy(),\n    domain\n  if (internal.params.isCategory) {\n    domain = internal.scale.domain()\n    newScale.domain([domain[0], domain[1] - 1])\n  }\n  return newScale\n}\nAxisInternal.prototype.textFormatted = function(v) {\n  var internal = this,\n    formatted = internal.tickFormat ? internal.tickFormat(v) : v\n  return typeof formatted !== 'undefined' ? formatted : ''\n}\nAxisInternal.prototype.updateRange = function() {\n  var internal = this\n  internal.range = internal.scale.rangeExtent\n    ? internal.scale.rangeExtent()\n    : internal.scaleExtent(internal.scale.range())\n  return internal.range\n}\nAxisInternal.prototype.updateTickTextCharSize = function(tick) {\n  var internal = this\n  if (internal.tickTextCharSize) {\n    return internal.tickTextCharSize\n  }\n  var size = {\n    h: 11.5,\n    w: 5.5\n  }\n  tick\n    .select('text')\n    .text(function(d) {\n      return internal.textFormatted(d)\n    })\n    .each(function(d) {\n      var box = getBBox(this),\n        text = internal.textFormatted(d),\n        h = box.height,\n        w = text ? box.width / text.length : undefined\n      if (h && w) {\n        size.h = h\n        size.w = w\n      }\n    })\n    .text('')\n  internal.tickTextCharSize = size\n  return size\n}\nAxisInternal.prototype.isVertical = function() {\n  return this.orient === 'left' || this.orient === 'right'\n}\nAxisInternal.prototype.tspanData = function(d, i, scale) {\n  var internal = this\n  var splitted = internal.params.tickMultiline\n    ? internal.splitTickText(d, scale)\n    : [].concat(internal.textFormatted(d))\n\n  if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) {\n    splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax)\n  }\n\n  return splitted.map(function(s) {\n    return { index: i, splitted: s, length: splitted.length }\n  })\n}\nAxisInternal.prototype.splitTickText = function(d, scale) {\n  var internal = this,\n    tickText = internal.textFormatted(d),\n    maxWidth = internal.params.tickWidth,\n    subtext,\n    spaceIndex,\n    textWidth,\n    splitted = []\n\n  if (Object.prototype.toString.call(tickText) === '[object Array]') {\n    return tickText\n  }\n\n  if (!maxWidth || maxWidth <= 0) {\n    maxWidth = internal.isVertical()\n      ? 95\n      : internal.params.isCategory\n      ? Math.ceil(scale(1) - scale(0)) - 12\n      : 110\n  }\n\n  function split(splitted, text) {\n    spaceIndex = undefined\n    for (var i = 1; i < text.length; i++) {\n      if (text.charAt(i) === ' ') {\n        spaceIndex = i\n      }\n      subtext = text.substr(0, i + 1)\n      textWidth = internal.tickTextCharSize.w * subtext.length\n      // if text width gets over tick width, split by space index or crrent index\n      if (maxWidth < textWidth) {\n        return split(\n          splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)),\n          text.slice(spaceIndex ? spaceIndex + 1 : i)\n        )\n      }\n    }\n    return splitted.concat(text)\n  }\n\n  return split(splitted, tickText + '')\n}\nAxisInternal.prototype.ellipsify = function(splitted, max) {\n  if (splitted.length <= max) {\n    return splitted\n  }\n\n  var ellipsified = splitted.slice(0, max)\n  var remaining = 3\n  for (var i = max - 1; i >= 0; i--) {\n    var available = ellipsified[i].length\n\n    ellipsified[i] = ellipsified[i]\n      .substr(0, available - remaining)\n      .padEnd(available, '.')\n\n    remaining -= available\n\n    if (remaining <= 0) {\n      break\n    }\n  }\n\n  return ellipsified\n}\nAxisInternal.prototype.updateTickLength = function() {\n  var internal = this\n  internal.tickLength =\n    Math.max(internal.innerTickSize, 0) + internal.tickPadding\n}\nAxisInternal.prototype.lineY2 = function(d) {\n  var internal = this,\n    tickPosition =\n      internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset)\n  return internal.range[0] < tickPosition && tickPosition < internal.range[1]\n    ? internal.innerTickSize\n    : 0\n}\nAxisInternal.prototype.textY = function() {\n  var internal = this,\n    rotate = internal.tickTextRotate\n  return rotate\n    ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1)\n    : internal.tickLength\n}\nAxisInternal.prototype.textTransform = function() {\n  var internal = this,\n    rotate = internal.tickTextRotate\n  return rotate ? 'rotate(' + rotate + ')' : ''\n}\nAxisInternal.prototype.textTextAnchor = function() {\n  var internal = this,\n    rotate = internal.tickTextRotate\n  return rotate ? (rotate > 0 ? 'start' : 'end') : 'middle'\n}\nAxisInternal.prototype.tspanDx = function() {\n  var internal = this,\n    rotate = internal.tickTextRotate\n  return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0\n}\nAxisInternal.prototype.tspanDy = function(d, i) {\n  var internal = this,\n    dy = internal.tickTextCharSize.h\n  if (i === 0) {\n    if (internal.isVertical()) {\n      dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3)\n    } else {\n      dy = '.71em'\n    }\n  }\n  return dy\n}\n\nAxisInternal.prototype.generateAxis = function() {\n  var internal = this,\n    d3 = internal.d3,\n    params = internal.params\n  function axis(g, transition) {\n    var self\n    g.each(function() {\n      var g = ((axis as any).g = d3.select(this))\n\n      var scale0 = this.__chart__ || internal.scale,\n        scale1 = (this.__chart__ = internal.copyScale())\n\n      var ticksValues = internal.tickValues\n          ? internal.tickValues\n          : internal.generateTicks(scale1),\n        ticks = g.selectAll('.tick').data(ticksValues, scale1),\n        tickEnter = ticks\n          .enter()\n          .insert('g', '.domain')\n          .attr('class', 'tick')\n          .style('opacity', 1e-6),\n        // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks.\n        tickExit = ticks.exit().remove(),\n        tickUpdate = ticks.merge(tickEnter),\n        tickTransform,\n        tickX,\n        tickY\n\n      if (params.isCategory) {\n        internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2)\n        tickX = internal.tickCentered ? 0 : internal.tickOffset\n        tickY = internal.tickCentered ? internal.tickOffset : 0\n      } else {\n        internal.tickOffset = tickX = 0\n      }\n\n      internal.updateRange()\n      internal.updateTickLength()\n      internal.updateTickTextCharSize(g.select('.tick'))\n\n      var lineUpdate = tickUpdate\n          .select('line')\n          .merge(tickEnter.append('line')),\n        textUpdate = tickUpdate.select('text').merge(tickEnter.append('text'))\n\n      var tspans = tickUpdate\n          .selectAll('text')\n          .selectAll('tspan')\n          .data(function(d, i) {\n            return internal.tspanData(d, i, scale1)\n          }),\n        tspanEnter = tspans.enter().append('tspan'),\n        tspanUpdate = tspanEnter.merge(tspans).text(function(d) {\n          return d.splitted\n        })\n      tspans.exit().remove()\n\n      var path = g.selectAll('.domain').data([0]),\n        pathUpdate = path\n          .enter()\n          .append('path')\n          .merge(path)\n          .attr('class', 'domain')\n\n      // TODO: each attr should be one function and change its behavior by internal.orient, probably\n      switch (internal.orient) {\n        case 'bottom': {\n          tickTransform = internal.axisX\n          lineUpdate\n            .attr('x1', tickX)\n            .attr('x2', tickX)\n            .attr('y2', function(d, i) {\n              return internal.lineY2(d, i)\n            })\n          textUpdate\n            .attr('x', 0)\n            .attr('y', function(d, i) {\n              return internal.textY(d, i)\n            })\n            .attr('transform', function(d, i) {\n              return internal.textTransform(d, i)\n            })\n            .style('text-anchor', function(d, i) {\n              return internal.textTextAnchor(d, i)\n            })\n          tspanUpdate\n            .attr('x', 0)\n            .attr('dy', function(d, i) {\n              return internal.tspanDy(d, i)\n            })\n            .attr('dx', function(d, i) {\n              return internal.tspanDx(d, i)\n            })\n          pathUpdate.attr(\n            'd',\n            'M' +\n              internal.range[0] +\n              ',' +\n              internal.outerTickSize +\n              'V0H' +\n              internal.range[1] +\n              'V' +\n              internal.outerTickSize\n          )\n          break\n        }\n        case 'top': {\n          // TODO: rotated tick text\n          tickTransform = internal.axisX\n          lineUpdate\n            .attr('x1', tickX)\n            .attr('x2', tickX)\n            .attr('y2', function(d, i) {\n              return -1 * internal.lineY2(d, i)\n            })\n          textUpdate\n            .attr('x', 0)\n            .attr('y', function(d, i) {\n              return (\n                -1 * internal.textY(d, i) -\n                (params.isCategory ? 2 : internal.tickLength - 2)\n              )\n            })\n            .attr('transform', function(d, i) {\n              return internal.textTransform(d, i)\n            })\n            .style('text-anchor', function(d, i) {\n              return internal.textTextAnchor(d, i)\n            })\n          tspanUpdate\n            .attr('x', 0)\n            .attr('dy', function(d, i) {\n              return internal.tspanDy(d, i)\n            })\n            .attr('dx', function(d, i) {\n              return internal.tspanDx(d, i)\n            })\n          pathUpdate.attr(\n            'd',\n            'M' +\n              internal.range[0] +\n              ',' +\n              -internal.outerTickSize +\n              'V0H' +\n              internal.range[1] +\n              'V' +\n              -internal.outerTickSize\n          )\n          break\n        }\n        case 'left': {\n          tickTransform = internal.axisY\n          lineUpdate\n            .attr('x2', -internal.innerTickSize)\n            .attr('y1', tickY)\n            .attr('y2', tickY)\n          textUpdate\n            .attr('x', -internal.tickLength)\n            .attr('y', internal.tickOffset)\n            .style('text-anchor', 'end')\n          tspanUpdate\n            .attr('x', -internal.tickLength)\n            .attr('dy', function(d, i) {\n              return internal.tspanDy(d, i)\n            })\n          pathUpdate.attr(\n            'd',\n            'M' +\n              -internal.outerTickSize +\n              ',' +\n              internal.range[0] +\n              'H0V' +\n              internal.range[1] +\n              'H' +\n              -internal.outerTickSize\n          )\n          break\n        }\n        case 'right': {\n          tickTransform = internal.axisY\n          lineUpdate\n            .attr('x2', internal.innerTickSize)\n            .attr('y1', tickY)\n            .attr('y2', tickY)\n          textUpdate\n            .attr('x', internal.tickLength)\n            .attr('y', internal.tickOffset)\n            .style('text-anchor', 'start')\n          tspanUpdate.attr('x', internal.tickLength).attr('dy', function(d, i) {\n            return internal.tspanDy(d, i)\n          })\n          pathUpdate.attr(\n            'd',\n            'M' +\n              internal.outerTickSize +\n              ',' +\n              internal.range[0] +\n              'H0V' +\n              internal.range[1] +\n              'H' +\n              internal.outerTickSize\n          )\n          break\n        }\n      }\n      if (scale1.rangeBand) {\n        var x = scale1,\n          dx = x.rangeBand() / 2\n        scale0 = scale1 = function(d) {\n          return x(d) + dx\n        }\n      } else if (scale0.rangeBand) {\n        scale0 = scale1\n      } else {\n        tickExit.call(tickTransform, scale1, internal.tickOffset)\n      }\n      tickEnter.call(tickTransform, scale0, internal.tickOffset)\n      self = (transition ? tickUpdate.transition(transition) : tickUpdate)\n        .style('opacity', 1)\n        .call(tickTransform, scale1, internal.tickOffset)\n    })\n    return self\n  }\n  axis.scale = function(x) {\n    if (!arguments.length) {\n      return internal.scale\n    }\n    internal.scale = x\n    return axis\n  }\n  axis.orient = function(x) {\n    if (!arguments.length) {\n      return internal.orient\n    }\n    internal.orient =\n      x in { top: 1, right: 1, bottom: 1, left: 1 } ? x + '' : 'bottom'\n    return axis\n  }\n  axis.tickFormat = function(format) {\n    if (!arguments.length) {\n      return internal.tickFormat\n    }\n    internal.tickFormat = format\n    return axis\n  }\n  axis.tickCentered = function(isCentered) {\n    if (!arguments.length) {\n      return internal.tickCentered\n    }\n    internal.tickCentered = isCentered\n    return axis\n  }\n  axis.tickOffset = function() {\n    return internal.tickOffset\n  }\n  axis.tickInterval = function() {\n    var interval, length\n    if (params.isCategory) {\n      interval = internal.tickOffset * 2\n    } else {\n      length =\n        (axis as any).g\n          .select('path.domain')\n          .node()\n          .getTotalLength() -\n        internal.outerTickSize * 2\n      interval = length / (axis as any).g.selectAll('line').size()\n    }\n    return interval === Infinity ? 0 : interval\n  }\n  axis.ticks = function() {\n    if (!arguments.length) {\n      return internal.tickArguments\n    }\n    internal.tickArguments = arguments\n    return axis\n  }\n  axis.tickCulling = function(culling) {\n    if (!arguments.length) {\n      return internal.tickCulling\n    }\n    internal.tickCulling = culling\n    return axis\n  }\n  axis.tickValues = function(x) {\n    if (typeof x === 'function') {\n      internal.tickValues = function() {\n        return x(internal.scale.domain())\n      }\n    } else {\n      if (!arguments.length) {\n        return internal.tickValues\n      }\n      internal.tickValues = x\n    }\n    return axis\n  }\n  return axis\n}\n\nexport { AxisInternal }\n"
  },
  {
    "path": "src/axis.ts",
    "content": "import CLASS from './class'\nimport { isValue, isFunction, isString, isEmpty, getBBox } from './util'\nimport { AxisInternal } from './axis-internal'\n\nexport default class AxisClass {\n  owner: any\n  d3: any\n  internal: typeof AxisInternal\n\n  constructor(owner) {\n    this.owner = owner\n    this.d3 = owner.d3\n    this.internal = AxisInternal\n  }\n}\n\nconst Axis = AxisClass as any\n\nAxis.prototype.init = function init() {\n  var $$ = this.owner,\n    config = $$.config,\n    main = $$.main\n  $$.axes.x = main\n    .append('g')\n    .attr('class', CLASS.axis + ' ' + CLASS.axisX)\n    .attr('clip-path', config.axis_x_inner ? '' : $$.clipPathForXAxis)\n    .attr('transform', $$.getTranslate('x'))\n    .style('visibility', config.axis_x_show ? 'visible' : 'hidden')\n  $$.axes.x\n    .append('text')\n    .attr('class', CLASS.axisXLabel)\n    .attr('transform', config.axis_rotated ? 'rotate(-90)' : '')\n    .style('text-anchor', this.textAnchorForXAxisLabel.bind(this))\n  $$.axes.y = main\n    .append('g')\n    .attr('class', CLASS.axis + ' ' + CLASS.axisY)\n    .attr('clip-path', config.axis_y_inner ? '' : $$.clipPathForYAxis)\n    .attr('transform', $$.getTranslate('y'))\n    .style('visibility', config.axis_y_show ? 'visible' : 'hidden')\n  $$.axes.y\n    .append('text')\n    .attr('class', CLASS.axisYLabel)\n    .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\n    .style('text-anchor', this.textAnchorForYAxisLabel.bind(this))\n\n  $$.axes.y2 = main\n    .append('g')\n    .attr('class', CLASS.axis + ' ' + CLASS.axisY2)\n    // clip-path?\n    .attr('transform', $$.getTranslate('y2'))\n    .style('visibility', config.axis_y2_show ? 'visible' : 'hidden')\n  $$.axes.y2\n    .append('text')\n    .attr('class', CLASS.axisY2Label)\n    .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\n    .style('text-anchor', this.textAnchorForY2AxisLabel.bind(this))\n}\nAxis.prototype.getXAxis = function getXAxis(\n  scale,\n  orient,\n  tickFormat,\n  tickValues,\n  withOuterTick,\n  withoutTransition,\n  withoutRotateTickText\n) {\n  var $$ = this.owner,\n    config = $$.config,\n    axisParams = {\n      isCategory: $$.isCategorized(),\n      withOuterTick: withOuterTick,\n      tickMultiline: config.axis_x_tick_multiline,\n      tickMultilineMax: config.axis_x_tick_multiline\n        ? Number(config.axis_x_tick_multilineMax)\n        : 0,\n      tickWidth: config.axis_x_tick_width,\n      tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate,\n      withoutTransition: withoutTransition\n    },\n    axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient)\n\n  if ($$.isTimeSeries() && tickValues && typeof tickValues !== 'function') {\n    tickValues = tickValues.map(function(v) {\n      return $$.parseDate(v)\n    })\n  }\n\n  // Set tick\n  axis.tickFormat(tickFormat).tickValues(tickValues)\n  if ($$.isCategorized()) {\n    axis.tickCentered(config.axis_x_tick_centered)\n    if (isEmpty(config.axis_x_tick_culling)) {\n      config.axis_x_tick_culling = false\n    }\n  }\n\n  return axis\n}\nAxis.prototype.updateXAxisTickValues = function updateXAxisTickValues(\n  targets,\n  axis\n) {\n  var $$ = this.owner,\n    config = $$.config,\n    tickValues\n  if (config.axis_x_tick_fit || config.axis_x_tick_count) {\n    tickValues = this.generateTickValues(\n      $$.mapTargetsToUniqueXs(targets),\n      config.axis_x_tick_count,\n      $$.isTimeSeries()\n    )\n  }\n  if (axis) {\n    axis.tickValues(tickValues)\n  } else {\n    $$.xAxis.tickValues(tickValues)\n    $$.subXAxis.tickValues(tickValues)\n  }\n  return tickValues\n}\nAxis.prototype.getYAxis = function getYAxis(\n  axisId,\n  scale,\n  orient,\n  tickValues,\n  withOuterTick,\n  withoutTransition,\n  withoutRotateTickText\n) {\n  const $$ = this.owner\n  const config = $$.config\n\n  let tickFormat = config[`axis_${axisId}_tick_format`]\n  if (!tickFormat && $$.isAxisNormalized(axisId)) {\n    tickFormat = x => `${x}%`\n  }\n\n  const axis = new this.internal(this, {\n    withOuterTick: withOuterTick,\n    withoutTransition: withoutTransition,\n    tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate\n  }).axis\n    .scale(scale)\n    .orient(orient)\n\n  if (tickFormat) {\n    axis.tickFormat(tickFormat)\n  }\n\n  if ($$.isTimeSeriesY()) {\n    axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval)\n  } else {\n    axis.tickValues(tickValues)\n  }\n  return axis\n}\nAxis.prototype.getId = function getId(id) {\n  var config = this.owner.config\n  return id in config.data_axes ? config.data_axes[id] : 'y'\n}\nAxis.prototype.getXAxisTickFormat = function getXAxisTickFormat() {\n  // #2251 previously set any negative values to a whole number,\n  // however both should be truncated according to the users format specification\n  var $$ = this.owner,\n    config = $$.config\n  let format = $$.isTimeSeries()\n    ? $$.defaultAxisTimeFormat\n    : $$.isCategorized()\n    ? $$.categoryName\n    : function(v) {\n        return v\n      }\n\n  if (config.axis_x_tick_format) {\n    if (isFunction(config.axis_x_tick_format)) {\n      format = config.axis_x_tick_format\n    } else if ($$.isTimeSeries()) {\n      format = function(date) {\n        return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : ''\n      }\n    }\n  }\n  return isFunction(format)\n    ? function(v) {\n        return format.call($$, v)\n      }\n    : format\n}\nAxis.prototype.getTickValues = function getTickValues(tickValues, axis) {\n  return tickValues ? tickValues : axis ? axis.tickValues() : undefined\n}\nAxis.prototype.getXAxisTickValues = function getXAxisTickValues() {\n  return this.getTickValues(\n    this.owner.config.axis_x_tick_values,\n    this.owner.xAxis\n  )\n}\nAxis.prototype.getYAxisTickValues = function getYAxisTickValues() {\n  return this.getTickValues(\n    this.owner.config.axis_y_tick_values,\n    this.owner.yAxis\n  )\n}\nAxis.prototype.getY2AxisTickValues = function getY2AxisTickValues() {\n  return this.getTickValues(\n    this.owner.config.axis_y2_tick_values,\n    this.owner.y2Axis\n  )\n}\nAxis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(\n  axisId\n) {\n  var $$ = this.owner,\n    config = $$.config,\n    option\n  if (axisId === 'y') {\n    option = config.axis_y_label\n  } else if (axisId === 'y2') {\n    option = config.axis_y2_label\n  } else if (axisId === 'x') {\n    option = config.axis_x_label\n  }\n  return option\n}\nAxis.prototype.getLabelText = function getLabelText(axisId) {\n  var option = this.getLabelOptionByAxisId(axisId)\n  return isString(option) ? option : option ? option.text : null\n}\nAxis.prototype.setLabelText = function setLabelText(axisId, text) {\n  var $$ = this.owner,\n    config = $$.config,\n    option = this.getLabelOptionByAxisId(axisId)\n  if (isString(option)) {\n    if (axisId === 'y') {\n      config.axis_y_label = text\n    } else if (axisId === 'y2') {\n      config.axis_y2_label = text\n    } else if (axisId === 'x') {\n      config.axis_x_label = text\n    }\n  } else if (option) {\n    option.text = text\n  }\n}\nAxis.prototype.getLabelPosition = function getLabelPosition(\n  axisId,\n  defaultPosition\n) {\n  var option = this.getLabelOptionByAxisId(axisId),\n    position =\n      option && typeof option === 'object' && option.position\n        ? option.position\n        : defaultPosition\n  return {\n    isInner: position.indexOf('inner') >= 0,\n    isOuter: position.indexOf('outer') >= 0,\n    isLeft: position.indexOf('left') >= 0,\n    isCenter: position.indexOf('center') >= 0,\n    isRight: position.indexOf('right') >= 0,\n    isTop: position.indexOf('top') >= 0,\n    isMiddle: position.indexOf('middle') >= 0,\n    isBottom: position.indexOf('bottom') >= 0\n  }\n}\nAxis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() {\n  return this.getLabelPosition(\n    'x',\n    this.owner.config.axis_rotated ? 'inner-top' : 'inner-right'\n  )\n}\nAxis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() {\n  return this.getLabelPosition(\n    'y',\n    this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'\n  )\n}\nAxis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() {\n  return this.getLabelPosition(\n    'y2',\n    this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'\n  )\n}\nAxis.prototype.getLabelPositionById = function getLabelPositionById(id) {\n  return id === 'y2'\n    ? this.getY2AxisLabelPosition()\n    : id === 'y'\n    ? this.getYAxisLabelPosition()\n    : this.getXAxisLabelPosition()\n}\nAxis.prototype.textForXAxisLabel = function textForXAxisLabel() {\n  return this.getLabelText('x')\n}\nAxis.prototype.textForYAxisLabel = function textForYAxisLabel() {\n  return this.getLabelText('y')\n}\nAxis.prototype.textForY2AxisLabel = function textForY2AxisLabel() {\n  return this.getLabelText('y2')\n}\nAxis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) {\n  var $$ = this.owner\n  if (forHorizontal) {\n    return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width\n  } else {\n    return position.isBottom\n      ? -$$.height\n      : position.isMiddle\n      ? -$$.height / 2\n      : 0\n  }\n}\nAxis.prototype.dxForAxisLabel = function dxForAxisLabel(\n  forHorizontal,\n  position\n) {\n  if (forHorizontal) {\n    return position.isLeft ? '0.5em' : position.isRight ? '-0.5em' : '0'\n  } else {\n    return position.isTop ? '-0.5em' : position.isBottom ? '0.5em' : '0'\n  }\n}\nAxis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(\n  forHorizontal,\n  position\n) {\n  if (forHorizontal) {\n    return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end'\n  } else {\n    return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end'\n  }\n}\nAxis.prototype.xForXAxisLabel = function xForXAxisLabel() {\n  return this.xForAxisLabel(\n    !this.owner.config.axis_rotated,\n    this.getXAxisLabelPosition()\n  )\n}\nAxis.prototype.xForYAxisLabel = function xForYAxisLabel() {\n  return this.xForAxisLabel(\n    this.owner.config.axis_rotated,\n    this.getYAxisLabelPosition()\n  )\n}\nAxis.prototype.xForY2AxisLabel = function xForY2AxisLabel() {\n  return this.xForAxisLabel(\n    this.owner.config.axis_rotated,\n    this.getY2AxisLabelPosition()\n  )\n}\nAxis.prototype.dxForXAxisLabel = function dxForXAxisLabel() {\n  return this.dxForAxisLabel(\n    !this.owner.config.axis_rotated,\n    this.getXAxisLabelPosition()\n  )\n}\nAxis.prototype.dxForYAxisLabel = function dxForYAxisLabel() {\n  return this.dxForAxisLabel(\n    this.owner.config.axis_rotated,\n    this.getYAxisLabelPosition()\n  )\n}\nAxis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() {\n  return this.dxForAxisLabel(\n    this.owner.config.axis_rotated,\n    this.getY2AxisLabelPosition()\n  )\n}\nAxis.prototype.dyForXAxisLabel = function dyForXAxisLabel() {\n  var $$ = this.owner,\n    config = $$.config,\n    position = this.getXAxisLabelPosition()\n  if (config.axis_rotated) {\n    return position.isInner\n      ? '1.2em'\n      : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x'))\n  } else {\n    return position.isInner ? '-0.5em' : $$.getHorizontalAxisHeight('x') - 10\n  }\n}\nAxis.prototype.dyForYAxisLabel = function dyForYAxisLabel() {\n  var $$ = this.owner,\n    position = this.getYAxisLabelPosition()\n  if ($$.config.axis_rotated) {\n    return position.isInner ? '-0.5em' : '3em'\n  } else {\n    return position.isInner\n      ? '1.2em'\n      : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10)\n  }\n}\nAxis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() {\n  var $$ = this.owner,\n    position = this.getY2AxisLabelPosition()\n  if ($$.config.axis_rotated) {\n    return position.isInner ? '1.2em' : '-2.2em'\n  } else {\n    return position.isInner\n      ? '-0.5em'\n      : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15)\n  }\n}\nAxis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() {\n  var $$ = this.owner\n  return this.textAnchorForAxisLabel(\n    !$$.config.axis_rotated,\n    this.getXAxisLabelPosition()\n  )\n}\nAxis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() {\n  var $$ = this.owner\n  return this.textAnchorForAxisLabel(\n    $$.config.axis_rotated,\n    this.getYAxisLabelPosition()\n  )\n}\nAxis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() {\n  var $$ = this.owner\n  return this.textAnchorForAxisLabel(\n    $$.config.axis_rotated,\n    this.getY2AxisLabelPosition()\n  )\n}\nAxis.prototype.getMaxTickWidth = function getMaxTickWidth(\n  id,\n  withoutRecompute\n) {\n  var $$ = this.owner,\n    maxWidth = 0,\n    targetsToShow,\n    scale,\n    axis,\n    dummy,\n    svg\n  if (withoutRecompute && $$.currentMaxTickWidths[id]) {\n    return $$.currentMaxTickWidths[id]\n  }\n  if ($$.svg) {\n    targetsToShow = $$.filterTargetsToShow($$.data.targets)\n    if (id === 'y') {\n      scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'))\n      axis = this.getYAxis(\n        id,\n        scale,\n        $$.yOrient,\n        $$.yAxisTickValues,\n        false,\n        true,\n        true\n      )\n    } else if (id === 'y2') {\n      scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'))\n      axis = this.getYAxis(\n        id,\n        scale,\n        $$.y2Orient,\n        $$.y2AxisTickValues,\n        false,\n        true,\n        true\n      )\n    } else {\n      scale = $$.x.copy().domain($$.getXDomain(targetsToShow))\n      axis = this.getXAxis(\n        scale,\n        $$.xOrient,\n        $$.xAxisTickFormat,\n        $$.xAxisTickValues,\n        false,\n        true,\n        true\n      )\n      this.updateXAxisTickValues(targetsToShow, axis)\n    }\n    dummy = $$.d3\n      .select('body')\n      .append('div')\n      .classed('c3', true)\n    ;(svg = dummy\n      .append('svg')\n      .style('visibility', 'hidden')\n      .style('position', 'fixed')\n      .style('top', 0)\n      .style('left', 0)),\n      svg\n        .append('g')\n        .call(axis)\n        .each(function() {\n          $$.d3\n            .select(this)\n            .selectAll('text')\n            .each(function() {\n              var box = getBBox(this)\n              if (maxWidth < box.width) {\n                maxWidth = box.width\n              }\n            })\n          dummy.remove()\n        })\n  }\n  $$.currentMaxTickWidths[id] =\n    maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth\n  return $$.currentMaxTickWidths[id]\n}\n\nAxis.prototype.updateLabels = function updateLabels(withTransition) {\n  var $$ = this.owner\n  var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel),\n    axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel),\n    axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label)\n  ;(withTransition ? axisXLabel.transition() : axisXLabel)\n    .attr('x', this.xForXAxisLabel.bind(this))\n    .attr('dx', this.dxForXAxisLabel.bind(this))\n    .attr('dy', this.dyForXAxisLabel.bind(this))\n    .text(this.textForXAxisLabel.bind(this))\n  ;(withTransition ? axisYLabel.transition() : axisYLabel)\n    .attr('x', this.xForYAxisLabel.bind(this))\n    .attr('dx', this.dxForYAxisLabel.bind(this))\n    .attr('dy', this.dyForYAxisLabel.bind(this))\n    .text(this.textForYAxisLabel.bind(this))\n  ;(withTransition ? axisY2Label.transition() : axisY2Label)\n    .attr('x', this.xForY2AxisLabel.bind(this))\n    .attr('dx', this.dxForY2AxisLabel.bind(this))\n    .attr('dy', this.dyForY2AxisLabel.bind(this))\n    .text(this.textForY2AxisLabel.bind(this))\n}\nAxis.prototype.getPadding = function getPadding(\n  padding,\n  key,\n  defaultValue,\n  domainLength\n) {\n  var p = typeof padding === 'number' ? padding : padding[key]\n  if (!isValue(p)) {\n    return defaultValue\n  }\n  if (padding.unit === 'ratio') {\n    return padding[key] * domainLength\n  }\n  // assume padding is pixels if unit is not specified\n  return this.convertPixelsToAxisPadding(p, domainLength)\n}\nAxis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(\n  pixels,\n  domainLength\n) {\n  var $$ = this.owner,\n    length = $$.config.axis_rotated ? $$.width : $$.height\n  return domainLength * (pixels / length)\n}\nAxis.prototype.generateTickValues = function generateTickValues(\n  values,\n  tickCount,\n  forTimeSeries\n) {\n  var tickValues = values,\n    targetCount,\n    start,\n    end,\n    count,\n    interval,\n    i,\n    tickValue\n  if (tickCount) {\n    targetCount = isFunction(tickCount) ? tickCount() : tickCount\n    // compute ticks according to tickCount\n    if (targetCount === 1) {\n      tickValues = [values[0]]\n    } else if (targetCount === 2) {\n      tickValues = [values[0], values[values.length - 1]]\n    } else if (targetCount > 2) {\n      count = targetCount - 2\n      start = values[0]\n      end = values[values.length - 1]\n      interval = (end - start) / (count + 1)\n      // re-construct unique values\n      tickValues = [start]\n      for (i = 0; i < count; i++) {\n        tickValue = +start + interval * (i + 1)\n        tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue)\n      }\n      tickValues.push(end)\n    }\n  }\n  if (!forTimeSeries) {\n    tickValues = tickValues.sort(function(a, b) {\n      return a - b\n    })\n  }\n  return tickValues\n}\nAxis.prototype.generateTransitions = function generateTransitions(duration) {\n  var $$ = this.owner,\n    axes = $$.axes\n  return {\n    axisX: duration ? axes.x.transition().duration(duration) : axes.x,\n    axisY: duration ? axes.y.transition().duration(duration) : axes.y,\n    axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2,\n    axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx\n  }\n}\nAxis.prototype.redraw = function redraw(duration, isHidden) {\n  var $$ = this.owner,\n    transition = duration ? $$.d3.transition().duration(duration) : null\n  $$.axes.x.style('opacity', isHidden ? 0 : 1).call($$.xAxis, transition)\n  $$.axes.y.style('opacity', isHidden ? 0 : 1).call($$.yAxis, transition)\n  $$.axes.y2.style('opacity', isHidden ? 0 : 1).call($$.y2Axis, transition)\n  $$.axes.subx.style('opacity', isHidden ? 0 : 1).call($$.subXAxis, transition)\n}\n"
  },
  {
    "path": "src/cache.ts",
    "content": "import { ChartInternal } from './core'\n\n/**\n * Store value into cache\n *\n * @param key\n * @param value\n */\nChartInternal.prototype.addToCache = function(key, value) {\n  this.cache[`$${key}`] = value\n}\n\n/**\n * Returns a cached value or undefined\n *\n * @param key\n * @return {*}\n */\nChartInternal.prototype.getFromCache = function(key) {\n  return this.cache[`$${key}`]\n}\n\n/**\n * Reset cached data\n */\nChartInternal.prototype.resetCache = function() {\n  Object.keys(this.cache)\n    .filter(key => /^\\$/.test(key))\n    .forEach(key => {\n      delete this.cache[key]\n    })\n}\n\n// Old API that stores Targets\n\nChartInternal.prototype.hasCaches = function(ids) {\n  for (var i = 0; i < ids.length; i++) {\n    if (!(ids[i] in this.cache)) {\n      return false\n    }\n  }\n  return true\n}\nChartInternal.prototype.addCache = function(id, target) {\n  this.cache[id] = this.cloneTarget(target)\n}\nChartInternal.prototype.getCaches = function(ids) {\n  var targets = [],\n    i\n  for (i = 0; i < ids.length; i++) {\n    if (ids[i] in this.cache) {\n      targets.push(this.cloneTarget(this.cache[ids[i]]))\n    }\n  }\n  return targets\n}\n"
  },
  {
    "path": "src/category.ts",
    "content": "import { ChartInternal } from './core'\n\nChartInternal.prototype.categoryName = function(i) {\n  var config = this.config\n  return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i\n}\n"
  },
  {
    "path": "src/chart-internal.ts",
    "content": "export function ChartInternal(api) {\n  var $$ = this\n  // Note: This part will be replaced by rollup-plugin-modify\n  // When bundling esm output. Beware of changing this line.\n  // TODO: Maybe we should check that the modification by rollup-plugin-modify\n  // is valid during unit tests.\n  $$.d3 = (window as any).d3\n    ? (window as any).d3\n    : typeof require !== 'undefined'\n    ? require('d3')\n    : undefined\n  $$.api = api\n  $$.config = $$.getDefaultConfig()\n  $$.data = {}\n  $$.cache = {}\n  $$.axes = {}\n}\n"
  },
  {
    "path": "src/chart.ts",
    "content": "import { ChartInternal } from './chart-internal'\n\n/**\n * The Chart class\n *\n * The methods of this class is the public APIs of the chart object.\n */\nexport function Chart(config) {\n  this.internal = new ChartInternal(this)\n  this.internal.loadConfig(config)\n\n  this.internal.beforeInit(config)\n  this.internal.init()\n  this.internal.afterInit(config)\n\n  // bind \"this\" to nested API\n  ;(function bindThis(fn, target, argThis) {\n    Object.keys(fn).forEach(function(key) {\n      target[key] = fn[key].bind(argThis)\n      if (Object.keys(fn[key]).length > 0) {\n        bindThis(fn[key], target[key], argThis)\n      }\n    })\n  })(Chart.prototype, this, this)\n}\n"
  },
  {
    "path": "src/class-utils.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\n\nChartInternal.prototype.generateTargetClass = function(targetId) {\n  return targetId || targetId === 0 ? ('-' + targetId).replace(/\\s/g, '-') : ''\n}\nChartInternal.prototype.generateClass = function(prefix, targetId) {\n  return ' ' + prefix + ' ' + prefix + this.generateTargetClass(targetId)\n}\nChartInternal.prototype.classText = function(d) {\n  return this.generateClass(CLASS.text, d.index)\n}\nChartInternal.prototype.classTexts = function(d) {\n  return this.generateClass(CLASS.texts, d.id)\n}\nChartInternal.prototype.classShape = function(d) {\n  return this.generateClass(CLASS.shape, d.index)\n}\nChartInternal.prototype.classShapes = function(d) {\n  return this.generateClass(CLASS.shapes, d.id)\n}\nChartInternal.prototype.classLine = function(d) {\n  return this.classShape(d) + this.generateClass(CLASS.line, d.id)\n}\nChartInternal.prototype.classLines = function(d) {\n  return this.classShapes(d) + this.generateClass(CLASS.lines, d.id)\n}\nChartInternal.prototype.classCircle = function(d) {\n  return this.classShape(d) + this.generateClass(CLASS.circle, d.index)\n}\nChartInternal.prototype.classCircles = function(d) {\n  return this.classShapes(d) + this.generateClass(CLASS.circles, d.id)\n}\nChartInternal.prototype.classBar = function(d) {\n  return this.classShape(d) + this.generateClass(CLASS.bar, d.index)\n}\nChartInternal.prototype.classBars = function(d) {\n  return this.classShapes(d) + this.generateClass(CLASS.bars, d.id)\n}\nChartInternal.prototype.classArc = function(d) {\n  return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id)\n}\nChartInternal.prototype.classArcs = function(d) {\n  return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id)\n}\nChartInternal.prototype.classArea = function(d) {\n  return this.classShape(d) + this.generateClass(CLASS.area, d.id)\n}\nChartInternal.prototype.classAreas = function(d) {\n  return this.classShapes(d) + this.generateClass(CLASS.areas, d.id)\n}\nChartInternal.prototype.classRegion = function(d, i) {\n  return (\n    this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : '')\n  )\n}\nChartInternal.prototype.classEvent = function(d) {\n  return this.generateClass(CLASS.eventRect, d.index)\n}\nChartInternal.prototype.classTarget = function(id) {\n  var $$ = this\n  var additionalClassSuffix = $$.config.data_classes[id],\n    additionalClass = ''\n  if (additionalClassSuffix) {\n    additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix\n  }\n  return $$.generateClass(CLASS.target, id) + additionalClass\n}\nChartInternal.prototype.classFocus = function(d) {\n  return this.classFocused(d) + this.classDefocused(d)\n}\nChartInternal.prototype.classFocused = function(d) {\n  return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '')\n}\nChartInternal.prototype.classDefocused = function(d) {\n  return (\n    ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : '')\n  )\n}\nChartInternal.prototype.classChartText = function(d) {\n  return CLASS.chartText + this.classTarget(d.id)\n}\nChartInternal.prototype.classChartLine = function(d) {\n  return CLASS.chartLine + this.classTarget(d.id)\n}\nChartInternal.prototype.classChartBar = function(d) {\n  return CLASS.chartBar + this.classTarget(d.id)\n}\nChartInternal.prototype.classChartArc = function(d) {\n  return CLASS.chartArc + this.classTarget(d.data.id)\n}\nChartInternal.prototype.getTargetSelectorSuffix = function(targetId) {\n  const targetClass = this.generateTargetClass(targetId)\n  if (window.CSS && window.CSS.escape) {\n    return window.CSS.escape(targetClass)\n  }\n\n  // fallback on imperfect method for old browsers (does not handles unicode)\n  return targetClass.replace(/([?!@#$%^&*()=+,.<>'\":;\\[\\]\\/|~`{}\\\\])/g, '\\\\$1')\n}\nChartInternal.prototype.selectorTarget = function(id, prefix) {\n  return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id)\n}\nChartInternal.prototype.selectorTargets = function(ids, prefix) {\n  var $$ = this\n  ids = ids || []\n  return ids.length\n    ? ids.map(function(id) {\n        return $$.selectorTarget(id, prefix)\n      })\n    : null\n}\nChartInternal.prototype.selectorLegend = function(id) {\n  return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id)\n}\nChartInternal.prototype.selectorLegends = function(ids) {\n  var $$ = this\n  return ids && ids.length\n    ? ids.map(function(id) {\n        return $$.selectorLegend(id)\n      })\n    : null\n}\n"
  },
  {
    "path": "src/class.ts",
    "content": "export default {\n  target: 'c3-target',\n  chart: 'c3-chart',\n  chartLine: 'c3-chart-line',\n  chartLines: 'c3-chart-lines',\n  chartBar: 'c3-chart-bar',\n  chartBars: 'c3-chart-bars',\n  chartText: 'c3-chart-text',\n  chartTexts: 'c3-chart-texts',\n  chartArc: 'c3-chart-arc',\n  chartArcs: 'c3-chart-arcs',\n  chartArcsTitle: 'c3-chart-arcs-title',\n  chartArcsBackground: 'c3-chart-arcs-background',\n  chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit',\n  chartArcsGaugeMax: 'c3-chart-arcs-gauge-max',\n  chartArcsGaugeMin: 'c3-chart-arcs-gauge-min',\n  selectedCircle: 'c3-selected-circle',\n  selectedCircles: 'c3-selected-circles',\n  eventRect: 'c3-event-rect',\n  eventRects: 'c3-event-rects',\n  eventRectsSingle: 'c3-event-rects-single',\n  eventRectsMultiple: 'c3-event-rects-multiple',\n  zoomRect: 'c3-zoom-rect',\n  brush: 'c3-brush',\n  dragZoom: 'c3-drag-zoom',\n  focused: 'c3-focused',\n  defocused: 'c3-defocused',\n  region: 'c3-region',\n  regions: 'c3-regions',\n  title: 'c3-title',\n  tooltipContainer: 'c3-tooltip-container',\n  tooltip: 'c3-tooltip',\n  tooltipName: 'c3-tooltip-name',\n  shape: 'c3-shape',\n  shapes: 'c3-shapes',\n  line: 'c3-line',\n  lines: 'c3-lines',\n  bar: 'c3-bar',\n  bars: 'c3-bars',\n  circle: 'c3-circle',\n  circles: 'c3-circles',\n  arc: 'c3-arc',\n  arcLabelLine: 'c3-arc-label-line',\n  arcs: 'c3-arcs',\n  area: 'c3-area',\n  areas: 'c3-areas',\n  empty: 'c3-empty',\n  text: 'c3-text',\n  texts: 'c3-texts',\n  gaugeValue: 'c3-gauge-value',\n  grid: 'c3-grid',\n  gridLines: 'c3-grid-lines',\n  xgrid: 'c3-xgrid',\n  xgrids: 'c3-xgrids',\n  xgridLine: 'c3-xgrid-line',\n  xgridLines: 'c3-xgrid-lines',\n  xgridFocus: 'c3-xgrid-focus',\n  ygrid: 'c3-ygrid',\n  ygrids: 'c3-ygrids',\n  ygridLine: 'c3-ygrid-line',\n  ygridLines: 'c3-ygrid-lines',\n  colorScale: 'c3-colorscale',\n  stanfordElements: 'c3-stanford-elements',\n  stanfordLine: 'c3-stanford-line',\n  stanfordLines: 'c3-stanford-lines',\n  stanfordRegion: 'c3-stanford-region',\n  stanfordRegions: 'c3-stanford-regions',\n  stanfordText: 'c3-stanford-text',\n  stanfordTexts: 'c3-stanford-texts',\n  axis: 'c3-axis',\n  axisX: 'c3-axis-x',\n  axisXLabel: 'c3-axis-x-label',\n  axisY: 'c3-axis-y',\n  axisYLabel: 'c3-axis-y-label',\n  axisY2: 'c3-axis-y2',\n  axisY2Label: 'c3-axis-y2-label',\n  legendBackground: 'c3-legend-background',\n  legendItem: 'c3-legend-item',\n  legendItemEvent: 'c3-legend-item-event',\n  legendItemTile: 'c3-legend-item-tile',\n  legendItemHidden: 'c3-legend-item-hidden',\n  legendItemFocused: 'c3-legend-item-focused',\n  dragarea: 'c3-dragarea',\n  EXPANDED: '_expanded_',\n  SELECTED: '_selected_',\n  INCLUDED: '_included_'\n}\n"
  },
  {
    "path": "src/clip.ts",
    "content": "import { ChartInternal } from './core'\nimport { isIE } from './util'\n\nChartInternal.prototype.getClipPath = function(id) {\n  return 'url(' + (isIE(9) ? '' : document.URL.split('#')[0]) + '#' + id + ')'\n}\nChartInternal.prototype.appendClip = function(parent, id) {\n  return parent\n    .append('clipPath')\n    .attr('id', id)\n    .append('rect')\n}\nChartInternal.prototype.getAxisClipX = function(forHorizontal) {\n  // axis line width + padding for left\n  var left = Math.max(30, this.margin.left)\n  return forHorizontal ? -(1 + left) : -(left - 1)\n}\nChartInternal.prototype.getAxisClipY = function(forHorizontal) {\n  return forHorizontal ? -20 : -this.margin.top\n}\nChartInternal.prototype.getXAxisClipX = function() {\n  var $$ = this\n  return $$.getAxisClipX(!$$.config.axis_rotated)\n}\nChartInternal.prototype.getXAxisClipY = function() {\n  var $$ = this\n  return $$.getAxisClipY(!$$.config.axis_rotated)\n}\nChartInternal.prototype.getYAxisClipX = function() {\n  var $$ = this\n  return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated)\n}\nChartInternal.prototype.getYAxisClipY = function() {\n  var $$ = this\n  return $$.getAxisClipY($$.config.axis_rotated)\n}\nChartInternal.prototype.getAxisClipWidth = function(forHorizontal) {\n  var $$ = this,\n    left = Math.max(30, $$.margin.left),\n    right = Math.max(30, $$.margin.right)\n  // width + axis line width + padding for left/right\n  return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20\n}\nChartInternal.prototype.getAxisClipHeight = function(forHorizontal) {\n  // less than 20 is not enough to show the axis label 'outer' without legend\n  return (\n    (forHorizontal ? this.margin.bottom : this.margin.top + this.height) + 20\n  )\n}\nChartInternal.prototype.getXAxisClipWidth = function() {\n  var $$ = this\n  return $$.getAxisClipWidth(!$$.config.axis_rotated)\n}\nChartInternal.prototype.getXAxisClipHeight = function() {\n  var $$ = this\n  return $$.getAxisClipHeight(!$$.config.axis_rotated)\n}\nChartInternal.prototype.getYAxisClipWidth = function() {\n  var $$ = this\n  return (\n    $$.getAxisClipWidth($$.config.axis_rotated) +\n    ($$.config.axis_y_inner ? 20 : 0)\n  )\n}\nChartInternal.prototype.getYAxisClipHeight = function() {\n  var $$ = this\n  return $$.getAxisClipHeight($$.config.axis_rotated)\n}\n"
  },
  {
    "path": "src/color.ts",
    "content": "import { ChartInternal } from './core'\nimport { notEmpty } from './util'\n\nChartInternal.prototype.generateColor = function() {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3,\n    colors = config.data_colors,\n    pattern = notEmpty(config.color_pattern)\n      ? config.color_pattern\n      : d3.schemeCategory10,\n    callback = config.data_color,\n    ids = []\n\n  return function(d) {\n    var id = d.id || (d.data && d.data.id) || d,\n      color\n\n    // if callback function is provided\n    if (colors[id] instanceof Function) {\n      color = colors[id](d)\n    }\n    // if specified, choose that color\n    else if (colors[id]) {\n      color = colors[id]\n    }\n    // if not specified, choose from pattern\n    else {\n      if (ids.indexOf(id) < 0) {\n        ids.push(id)\n      }\n      color = pattern[ids.indexOf(id) % pattern.length]\n      colors[id] = color\n    }\n    return callback instanceof Function ? callback(color, d) : color\n  }\n}\nChartInternal.prototype.generateLevelColor = function() {\n  var $$ = this,\n    config = $$.config,\n    colors = config.color_pattern,\n    threshold = config.color_threshold,\n    asValue = threshold.unit === 'value',\n    values =\n      threshold.values && threshold.values.length ? threshold.values : [],\n    max = threshold.max || 100\n  return notEmpty(threshold) && notEmpty(colors)\n    ? function(value) {\n        var i,\n          v,\n          color = colors[colors.length - 1]\n        for (i = 0; i < values.length; i++) {\n          v = asValue ? value : (value * 100) / max\n          if (v < values[i]) {\n            color = colors[i]\n            break\n          }\n        }\n        return color\n      }\n    : null\n}\n"
  },
  {
    "path": "src/colorscale.ts",
    "content": "import { ChartInternal } from './core'\nimport CLASS from './class'\nimport { isFunction, getBBox } from './util'\n\nfunction powerOfTen(d) {\n  return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1\n}\n\nChartInternal.prototype.drawColorScale = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    target = $$.data.targets[0],\n    barWidth,\n    barHeight,\n    axis,\n    points,\n    legendAxis,\n    axisScale,\n    inverseScale,\n    height\n\n  barWidth = !isNaN(config.stanford_scaleWidth)\n    ? config.stanford_scaleWidth\n    : 20\n  barHeight = 5\n\n  if (barHeight < 0 || barWidth < 0) {\n    throw Error(\"Colorscale's barheight and barwidth must be greater than 0.\")\n  }\n\n  height =\n    $$.height - config.stanford_padding.bottom - config.stanford_padding.top\n\n  points = d3.range(config.stanford_padding.bottom, height, barHeight)\n\n  inverseScale = d3\n    .scaleSequential(target.colors)\n    .domain([points[points.length - 1], points[0]])\n\n  if ($$.colorScale) {\n    $$.colorScale.remove()\n  }\n\n  $$.colorScale = $$.svg\n    .append('g')\n    .attr('width', 50)\n    .attr('height', height)\n    .attr('class', CLASS.colorScale)\n\n  $$.colorScale\n    .append('g')\n    .attr('transform', `translate(0, ${config.stanford_padding.top})`)\n    .selectAll('bars')\n    .data(points)\n    .enter()\n    .append('rect')\n    .attr('y', (d, i) => i * barHeight)\n    .attr('x', 0)\n    .attr('width', barWidth)\n    .attr('height', barHeight)\n    .attr('fill', function(d) {\n      return inverseScale(d)\n    })\n\n  // Legend Axis\n  axisScale = d3\n    .scaleLog()\n    .domain([target.minEpochs, target.maxEpochs])\n    .range([\n      points[0] +\n        config.stanford_padding.top +\n        points[points.length - 1] +\n        barHeight -\n        1,\n      points[0] + config.stanford_padding.top\n    ])\n\n  legendAxis = d3.axisRight(axisScale)\n\n  if (config.stanford_scaleFormat === 'pow10') {\n    legendAxis.tickValues([1, 10, 100, 1000, 10000, 100000, 1000000, 10000000])\n  } else if (isFunction(config.stanford_scaleFormat)) {\n    legendAxis.tickFormat(config.stanford_scaleFormat)\n  } else {\n    legendAxis.tickFormat(d3.format('d'))\n  }\n\n  if (isFunction(config.stanford_scaleValues)) {\n    legendAxis.tickValues(\n      config.stanford_scaleValues(target.minEpochs, target.maxEpochs)\n    )\n  }\n\n  // Draw Axis\n  axis = $$.colorScale\n    .append('g')\n    .attr('class', 'legend axis')\n    .attr('transform', `translate(${barWidth},0)`)\n    .call(legendAxis)\n\n  if (config.stanford_scaleFormat === 'pow10') {\n    axis\n      .selectAll('.tick text')\n      .text(null)\n      .filter(powerOfTen)\n      .text(10)\n      .append('tspan')\n      .attr('dy', '-.7em') // https://bl.ocks.org/mbostock/6738229\n      .text(function(d) {\n        return Math.round(Math.log(d) / Math.LN10)\n      })\n  }\n\n  $$.colorScale.attr(\n    'transform',\n    `translate(${$$.currentWidth - $$.xForColorScale()}, 0)`\n  )\n}\n\nChartInternal.prototype.xForColorScale = function() {\n  var $$ = this\n\n  return $$.config.stanford_padding.right + getBBox($$.colorScale.node()).width\n}\n\nChartInternal.prototype.getColorScalePadding = function() {\n  var $$ = this\n  return $$.xForColorScale() + $$.config.stanford_padding.left + 20\n}\n"
  },
  {
    "path": "src/config.ts",
    "content": "import { ChartInternal } from './core'\nimport { isDefined } from './util'\n\nChartInternal.prototype.getDefaultConfig = function() {\n  var config = {\n    bindto: '#chart',\n    svg_classname: undefined,\n    size_width: undefined,\n    size_height: undefined,\n    padding_left: undefined,\n    padding_right: undefined,\n    padding_top: undefined,\n    padding_bottom: undefined,\n    resize_auto: true,\n    zoom_enabled: false,\n    zoom_initialRange: undefined,\n    zoom_type: 'scroll',\n    zoom_disableDefaultBehavior: false,\n    zoom_privileged: false,\n    zoom_rescale: false,\n    zoom_onzoom: function() {},\n    zoom_onzoomstart: function() {},\n    zoom_onzoomend: function() {},\n    zoom_x_min: undefined,\n    zoom_x_max: undefined,\n    interaction_brighten: true,\n    interaction_enabled: true,\n    onmouseover: function() {},\n    onmouseout: function() {},\n    onresize: function() {},\n    onresized: function() {},\n    oninit: function() {},\n    onrendered: function() {},\n    transition_duration: 350,\n    data_epochs: 'epochs',\n    data_x: undefined,\n    data_xs: {},\n    data_xFormat: '%Y-%m-%d',\n    data_xLocaltime: true,\n    data_xSort: true,\n    data_idConverter: function(id) {\n      return id\n    },\n    data_names: {},\n    data_classes: {},\n    data_groups: [],\n    data_axes: {},\n    data_type: undefined,\n    data_types: {},\n    data_labels: {},\n    data_order: 'desc',\n    data_regions: {},\n    data_color: undefined,\n    data_colors: {},\n    data_hide: false,\n    data_filter: undefined,\n    data_selection_enabled: false,\n    data_selection_grouped: false,\n    data_selection_isselectable: function() {\n      return true\n    },\n    data_selection_multiple: true,\n    data_selection_draggable: false,\n    data_stack_normalize: false,\n    data_onclick: function() {},\n    data_onmouseover: function() {},\n    data_onmouseout: function() {},\n    data_onselected: function() {},\n    data_onunselected: function() {},\n    data_url: undefined,\n    data_headers: undefined,\n    data_json: undefined,\n    data_rows: undefined,\n    data_columns: undefined,\n    data_mimeType: undefined,\n    data_keys: undefined,\n    // configuration for no plot-able data supplied.\n    data_empty_label_text: '',\n    // subchart\n    subchart_show: false,\n    subchart_size_height: 60,\n    subchart_axis_x_show: true,\n    subchart_onbrush: function() {},\n    // color\n    color_pattern: [],\n    color_threshold: {},\n    // legend\n    legend_show: true,\n    legend_hide: false,\n    legend_position: 'bottom',\n    legend_inset_anchor: 'top-left',\n    legend_inset_x: 10,\n    legend_inset_y: 0,\n    legend_inset_step: undefined,\n    legend_item_onclick: undefined,\n    legend_item_onmouseover: undefined,\n    legend_item_onmouseout: undefined,\n    legend_equally: false,\n    legend_padding: 0,\n    legend_item_tile_width: 10,\n    legend_item_tile_height: 10,\n    // axis\n    axis_rotated: false,\n    axis_x_show: true,\n    axis_x_type: 'indexed',\n    axis_x_localtime: true,\n    axis_x_categories: [],\n    axis_x_tick_centered: false,\n    axis_x_tick_format: undefined,\n    axis_x_tick_culling: {},\n    axis_x_tick_culling_max: 10,\n    axis_x_tick_count: undefined,\n    axis_x_tick_fit: true,\n    axis_x_tick_values: null,\n    axis_x_tick_rotate: 0,\n    axis_x_tick_outer: true,\n    axis_x_tick_multiline: true,\n    axis_x_tick_multilineMax: 0,\n    axis_x_tick_width: null,\n    axis_x_max: undefined,\n    axis_x_min: undefined,\n    axis_x_padding: {},\n    axis_x_height: undefined,\n    axis_x_selection: undefined,\n    axis_x_label: {},\n    axis_x_inner: undefined,\n    axis_y_show: true,\n    axis_y_type: 'linear',\n    axis_y_max: undefined,\n    axis_y_min: undefined,\n    axis_y_inverted: false,\n    axis_y_center: undefined,\n    axis_y_inner: undefined,\n    axis_y_label: {},\n    axis_y_tick_format: undefined,\n    axis_y_tick_outer: true,\n    axis_y_tick_values: null,\n    axis_y_tick_rotate: 0,\n    axis_y_tick_count: undefined,\n    axis_y_tick_time_type: undefined,\n    axis_y_tick_time_interval: undefined,\n    axis_y_padding: {},\n    axis_y_default: undefined,\n    axis_y2_show: false,\n    axis_y2_type: 'linear',\n    axis_y2_max: undefined,\n    axis_y2_min: undefined,\n    axis_y2_inverted: false,\n    axis_y2_center: undefined,\n    axis_y2_inner: undefined,\n    axis_y2_label: {},\n    axis_y2_tick_format: undefined,\n    axis_y2_tick_outer: true,\n    axis_y2_tick_values: null,\n    axis_y2_tick_count: undefined,\n    axis_y2_padding: {},\n    axis_y2_default: undefined,\n    // grid\n    grid_x_show: false,\n    grid_x_type: 'tick',\n    grid_x_lines: [],\n    grid_y_show: false,\n    // not used\n    // grid_y_type: 'tick',\n    grid_y_lines: [],\n    grid_y_ticks: 10,\n    grid_focus_show: true,\n    grid_lines_front: true,\n    // point - point of each data\n    point_show: true,\n    point_r: 2.5,\n    point_sensitivity: 10,\n    point_focus_expand_enabled: true,\n    point_focus_expand_r: undefined,\n    point_select_r: undefined,\n    // line\n    line_connectNull: false,\n    line_step_type: 'step',\n    // bar\n    bar_width: undefined,\n    bar_width_ratio: 0.6,\n    bar_width_max: undefined,\n    bar_zerobased: true,\n    bar_space: 0,\n    // area\n    area_zerobased: true,\n    area_above: false,\n    // pie\n    pie_label_show: true,\n    pie_label_format: undefined,\n    pie_label_threshold: 0.05,\n    pie_label_ratio: undefined,\n    pie_expand: {},\n    pie_expand_duration: 50,\n    pie_padAngle: 0,\n    // gauge\n    gauge_fullCircle: false,\n    gauge_label_show: true,\n    gauge_labelLine_show: true,\n    gauge_label_format: undefined,\n    gauge_min: 0,\n    gauge_max: 100,\n    gauge_startingAngle: (-1 * Math.PI) / 2,\n    gauge_label_extents: undefined,\n    gauge_units: undefined,\n    gauge_width: undefined,\n    gauge_arcs_minWidth: 5,\n    gauge_expand: {},\n    gauge_expand_duration: 50,\n    // donut\n    donut_label_show: true,\n    donut_label_format: undefined,\n    donut_label_threshold: 0.05,\n    donut_label_ratio: undefined,\n    donut_width: undefined,\n    donut_title: '',\n    donut_expand: {},\n    donut_expand_duration: 50,\n    donut_padAngle: 0,\n    // spline\n    spline_interpolation_type: 'cardinal',\n    // stanford\n    stanford_lines: [],\n    stanford_regions: [],\n    stanford_texts: [],\n    stanford_scaleMin: undefined,\n    stanford_scaleMax: undefined,\n    stanford_scaleWidth: undefined,\n    stanford_scaleFormat: undefined,\n    stanford_scaleValues: undefined,\n    stanford_colors: undefined,\n    stanford_padding: {\n      top: 0,\n      right: 0,\n      bottom: 0,\n      left: 0\n    },\n    // region - region to change style\n    regions: [],\n    // tooltip - show when mouseover on each data\n    tooltip_show: true,\n    tooltip_grouped: true,\n    tooltip_order: undefined,\n    tooltip_format_title: undefined,\n    tooltip_format_name: undefined,\n    tooltip_format_value: undefined,\n    tooltip_horizontal: undefined,\n    tooltip_position: undefined,\n    tooltip_contents: function(\n      d,\n      defaultTitleFormat,\n      defaultValueFormat,\n      color\n    ) {\n      return this.getTooltipContent\n        ? this.getTooltipContent(\n            d,\n            defaultTitleFormat,\n            defaultValueFormat,\n            color\n          )\n        : ''\n    },\n    tooltip_init_show: false,\n    tooltip_init_x: 0,\n    tooltip_init_position: { top: '0px', left: '50px' },\n    tooltip_onshow: function() {},\n    tooltip_onhide: function() {},\n    // title\n    title_text: undefined,\n    title_padding: {\n      top: 0,\n      right: 0,\n      bottom: 0,\n      left: 0\n    },\n    title_position: 'top-center'\n  }\n\n  Object.keys(this.additionalConfig).forEach(function(key) {\n    config[key] = this.additionalConfig[key]\n  }, this)\n\n  return config\n}\nChartInternal.prototype.additionalConfig = {}\n\nChartInternal.prototype.loadConfig = function(config) {\n  var this_config = this.config,\n    target,\n    keys,\n    read\n  function find() {\n    var key = keys.shift()\n    //        console.log(\"key =>\", key, \", target =>\", target);\n    if (key && target && typeof target === 'object' && key in target) {\n      target = target[key]\n      return find()\n    } else if (!key) {\n      return target\n    } else {\n      return undefined\n    }\n  }\n  Object.keys(this_config).forEach(function(key) {\n    target = config\n    keys = key.split('_')\n    read = find()\n    //        console.log(\"CONFIG : \", key, read);\n    if (isDefined(read)) {\n      this_config[key] = read\n    }\n  })\n}\n"
  },
  {
    "path": "src/core.ts",
    "content": "import { ChartInternal } from './chart-internal'\nimport { Chart } from './chart'\nimport { AxisInternal } from './axis-internal'\nimport Axis from './axis'\nimport CLASS from './class'\n\nimport {\n  asHalfPixel,\n  getOption,\n  getPathBox,\n  isFunction,\n  isValue,\n  notEmpty\n} from './util'\n\nvar c3 = {\n  version: '0.7.20',\n  chart: {\n    fn: Chart.prototype,\n    internal: {\n      fn: ChartInternal.prototype,\n      axis: {\n        fn: Axis.prototype,\n        internal: {\n          fn: AxisInternal.prototype\n        }\n      }\n    }\n  },\n  generate: function(config) {\n    return new Chart(config)\n  }\n}\n\nexport { c3 }\n\nChartInternal.prototype.beforeInit = function() {\n  // can do something\n}\nChartInternal.prototype.afterInit = function() {\n  // can do something\n}\nChartInternal.prototype.init = function() {\n  var $$ = this,\n    config = $$.config\n\n  $$.initParams()\n\n  if (config.data_url) {\n    $$.convertUrlToData(\n      config.data_url,\n      config.data_mimeType,\n      config.data_headers,\n      config.data_keys,\n      $$.initWithData\n    )\n  } else if (config.data_json) {\n    $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys))\n  } else if (config.data_rows) {\n    $$.initWithData($$.convertRowsToData(config.data_rows))\n  } else if (config.data_columns) {\n    $$.initWithData($$.convertColumnsToData(config.data_columns))\n  } else {\n    throw Error('url or json or rows or columns is required.')\n  }\n}\n\nChartInternal.prototype.initParams = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config\n\n  // MEMO: clipId needs to be unique because it conflicts when multiple charts exist\n  $$.clipId = 'c3-' + new Date().valueOf() + '-clip'\n  $$.clipIdForXAxis = $$.clipId + '-xaxis'\n  $$.clipIdForYAxis = $$.clipId + '-yaxis'\n  $$.clipIdForGrid = $$.clipId + '-grid'\n  $$.clipIdForSubchart = $$.clipId + '-subchart'\n  $$.clipPath = $$.getClipPath($$.clipId)\n  $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis)\n  $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis)\n  $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid)\n  $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart)\n\n  $$.dragStart = null\n  $$.dragging = false\n  $$.flowing = false\n  $$.cancelClick = false\n  $$.mouseover = undefined\n  $$.transiting = false\n\n  $$.color = $$.generateColor()\n  $$.levelColor = $$.generateLevelColor()\n\n  $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)(\n    $$.config.data_xFormat\n  )\n  $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat\n  $$.defaultAxisTimeFormat = function(date) {\n    if (date.getMilliseconds()) {\n      return d3.timeFormat('.%L')(date)\n    }\n    if (date.getSeconds()) {\n      return d3.timeFormat(':%S')(date)\n    }\n    if (date.getMinutes()) {\n      return d3.timeFormat('%I:%M')(date)\n    }\n    if (date.getHours()) {\n      return d3.timeFormat('%I %p')(date)\n    }\n    if (date.getDay() && date.getDate() !== 1) {\n      return d3.timeFormat('%-m/%-d')(date)\n    }\n    if (date.getDate() !== 1) {\n      return d3.timeFormat('%-m/%-d')(date)\n    }\n    if (date.getMonth()) {\n      return d3.timeFormat('%-m/%-d')(date)\n    }\n    return d3.timeFormat('%Y/%-m/%-d')(date)\n  }\n  $$.hiddenTargetIds = []\n  $$.hiddenLegendIds = []\n  $$.focusedTargetIds = []\n  $$.defocusedTargetIds = []\n\n  $$.xOrient = config.axis_rotated\n    ? config.axis_x_inner\n      ? 'right'\n      : 'left'\n    : config.axis_x_inner\n    ? 'top'\n    : 'bottom'\n  $$.yOrient = config.axis_rotated\n    ? config.axis_y_inner\n      ? 'top'\n      : 'bottom'\n    : config.axis_y_inner\n    ? 'right'\n    : 'left'\n  $$.y2Orient = config.axis_rotated\n    ? config.axis_y2_inner\n      ? 'bottom'\n      : 'top'\n    : config.axis_y2_inner\n    ? 'left'\n    : 'right'\n  $$.subXOrient = config.axis_rotated ? 'left' : 'bottom'\n\n  $$.isLegendRight = config.legend_position === 'right'\n  $$.isLegendInset = config.legend_position === 'inset'\n  $$.isLegendTop =\n    config.legend_inset_anchor === 'top-left' ||\n    config.legend_inset_anchor === 'top-right'\n  $$.isLegendLeft =\n    config.legend_inset_anchor === 'top-left' ||\n    config.legend_inset_anchor === 'bottom-left'\n  $$.legendStep = 0\n  $$.legendItemWidth = 0\n  $$.legendItemHeight = 0\n\n  $$.currentMaxTickWidths = {\n    x: 0,\n    y: 0,\n    y2: 0\n  }\n\n  $$.rotated_padding_left = 30\n  $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30\n  $$.rotated_padding_top = 5\n\n  $$.withoutFadeIn = {}\n\n  $$.intervalForObserveInserted = undefined\n\n  $$.axes.subx = d3.selectAll([]) // needs when excluding subchart.js\n}\n\nChartInternal.prototype.initChartElements = function() {\n  if (this.initBar) {\n    this.initBar()\n  }\n  if (this.initLine) {\n    this.initLine()\n  }\n  if (this.initArc) {\n    this.initArc()\n  }\n  if (this.initGauge) {\n    this.initGauge()\n  }\n  if (this.initText) {\n    this.initText()\n  }\n}\n\nChartInternal.prototype.initWithData = function(data) {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config\n  var defs,\n    main,\n    binding = true\n\n  $$.axis = new Axis($$)\n\n  if (!config.bindto) {\n    $$.selectChart = d3.selectAll([])\n  } else if (typeof config.bindto.node === 'function') {\n    $$.selectChart = config.bindto\n  } else {\n    $$.selectChart = d3.select(config.bindto)\n  }\n  if ($$.selectChart.empty()) {\n    $$.selectChart = d3\n      .select(document.createElement('div'))\n      .style('opacity', 0)\n    $$.observeInserted($$.selectChart)\n    binding = false\n  }\n  $$.selectChart.html('').classed('c3', true)\n\n  // Init data as targets\n  $$.data.xs = {}\n  $$.data.targets = $$.convertDataToTargets(data)\n\n  if (config.data_filter) {\n    $$.data.targets = $$.data.targets.filter(config.data_filter)\n  }\n\n  // Set targets to hide if needed\n  if (config.data_hide) {\n    $$.addHiddenTargetIds(\n      config.data_hide === true\n        ? $$.mapToIds($$.data.targets)\n        : config.data_hide\n    )\n  }\n  if (config.legend_hide) {\n    $$.addHiddenLegendIds(\n      config.legend_hide === true\n        ? $$.mapToIds($$.data.targets)\n        : config.legend_hide\n    )\n  }\n\n  if ($$.isStanfordGraphType()) {\n    $$.initStanfordData()\n  }\n\n  // Init sizes and scales\n  $$.updateSizes()\n  $$.updateScales()\n\n  // Set domains for each scale\n  $$.x.domain(d3.extent($$.getXDomain($$.data.targets)))\n  $$.y.domain($$.getYDomain($$.data.targets, 'y'))\n  $$.y2.domain($$.getYDomain($$.data.targets, 'y2'))\n  $$.subX.domain($$.x.domain())\n  $$.subY.domain($$.y.domain())\n  $$.subY2.domain($$.y2.domain())\n\n  // Save original x domain for zoom update\n  $$.orgXDomain = $$.x.domain()\n\n  /*-- Basic Elements --*/\n\n  // Define svgs\n  $$.svg = $$.selectChart\n    .append('svg')\n    .style('overflow', 'hidden')\n    .on('mouseenter', function() {\n      return config.onmouseover.call($$)\n    })\n    .on('mouseleave', function() {\n      return config.onmouseout.call($$)\n    })\n\n  if ($$.config.svg_classname) {\n    $$.svg.attr('class', $$.config.svg_classname)\n  }\n\n  // Define defs\n  defs = $$.svg.append('defs')\n  $$.clipChart = $$.appendClip(defs, $$.clipId)\n  $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis)\n  $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis)\n  $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid)\n  $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart)\n  $$.updateSvgSize()\n\n  // Define regions\n  main = $$.main = $$.svg.append('g').attr('transform', $$.getTranslate('main'))\n\n  if ($$.initPie) {\n    $$.initPie()\n  }\n  if ($$.initDragZoom) {\n    $$.initDragZoom()\n  }\n  if (config.subchart_show && $$.initSubchart) {\n    $$.initSubchart()\n  }\n  if ($$.initTooltip) {\n    $$.initTooltip()\n  }\n  if ($$.initLegend) {\n    $$.initLegend()\n  }\n  if ($$.initTitle) {\n    $$.initTitle()\n  }\n  if ($$.initZoom) {\n    $$.initZoom()\n  }\n  if ($$.isStanfordGraphType()) {\n    $$.drawColorScale()\n  }\n\n  // Update selection based on size and scale\n  // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart.\n  if (config.subchart_show && $$.initSubchartBrush) {\n    $$.initSubchartBrush()\n  }\n\n  /*-- Main Region --*/\n\n  // text when empty\n  main\n    .append('text')\n    .attr('class', CLASS.text + ' ' + CLASS.empty)\n    .attr('text-anchor', 'middle') // horizontal centering of text at x position in all browsers.\n    .attr('dominant-baseline', 'middle') // vertical centering of text at y position in all browsers, except IE.\n\n  // Regions\n  $$.initRegion()\n\n  // Grids\n  $$.initGrid()\n\n  // Define g for chart area\n  main\n    .append('g')\n    .attr('clip-path', $$.clipPath)\n    .attr('class', CLASS.chart)\n\n  // Grid lines\n  if (config.grid_lines_front) {\n    $$.initGridLines()\n  }\n\n  $$.initStanfordElements()\n\n  // Cover whole with rects for events\n  $$.initEventRect()\n\n  // Define g for chart\n  $$.initChartElements()\n\n  // Add Axis\n  $$.axis.init()\n\n  // Set targets\n  $$.updateTargets($$.data.targets)\n\n  // Set default extent if defined\n  if (config.axis_x_selection) {\n    $$.brush.selectionAsValue($$.getDefaultSelection())\n  }\n\n  // Draw with targets\n  if (binding) {\n    $$.updateDimension()\n    $$.config.oninit.call($$)\n    $$.redraw({\n      withTransition: false,\n      withTransform: true,\n      withUpdateXDomain: true,\n      withUpdateOrgXDomain: true,\n      withTransitionForAxis: false\n    })\n  }\n\n  // Bind to resize event\n  $$.bindResize()\n\n  // Bind to window focus event\n  $$.bindWindowFocus()\n\n  // export element of the chart\n  $$.api.element = $$.selectChart.node()\n}\n\nChartInternal.prototype.smoothLines = function(el, type) {\n  var $$ = this\n  if (type === 'grid') {\n    el.each(function() {\n      var g = $$.d3.select(this),\n        x1 = g.attr('x1'),\n        x2 = g.attr('x2'),\n        y1 = g.attr('y1'),\n        y2 = g.attr('y2')\n      g.attr({\n        x1: Math.ceil(x1),\n        x2: Math.ceil(x2),\n        y1: Math.ceil(y1),\n        y2: Math.ceil(y2)\n      })\n    })\n  }\n}\n\nChartInternal.prototype.updateSizes = function() {\n  var $$ = this,\n    config = $$.config\n  var legendHeight = $$.legend ? $$.getLegendHeight() : 0,\n    legendWidth = $$.legend ? $$.getLegendWidth() : 0,\n    legendHeightForBottom =\n      $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight,\n    hasArc = $$.hasArcType(),\n    xAxisHeight =\n      config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'),\n    subchartXAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x',true),\n    subchartHeight =\n      config.subchart_show && !hasArc\n        ? config.subchart_size_height + subchartXAxisHeight\n        : 0\n\n  $$.currentWidth = $$.getCurrentWidth()\n  $$.currentHeight = $$.getCurrentHeight()\n\n  // for main\n  $$.margin = config.axis_rotated\n    ? {\n        top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(),\n        right: hasArc ? 0 : $$.getCurrentPaddingRight(),\n        bottom:\n          $$.getHorizontalAxisHeight('y') +\n          legendHeightForBottom +\n          $$.getCurrentPaddingBottom(),\n        left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft())\n      }\n    : {\n        top: 4 + $$.getCurrentPaddingTop(), // for top tick text\n        right: hasArc ? 0 : $$.getCurrentPaddingRight(),\n        bottom:\n          xAxisHeight +\n          subchartHeight +\n          legendHeightForBottom +\n          $$.getCurrentPaddingBottom(),\n        left: hasArc ? 0 : $$.getCurrentPaddingLeft()\n      }\n\n  // for subchart\n  $$.margin2 = config.axis_rotated\n    ? {\n        top: $$.margin.top,\n        right: NaN,\n        bottom: 20 + legendHeightForBottom,\n        left: $$.rotated_padding_left\n      }\n    : {\n        top: $$.currentHeight - subchartHeight - legendHeightForBottom,\n        right: NaN,\n        bottom: subchartXAxisHeight + legendHeightForBottom,\n        left: $$.margin.left\n      }\n\n  // for legend\n  $$.margin3 = {\n    top: 0,\n    right: NaN,\n    bottom: 0,\n    left: 0\n  }\n  if ($$.updateSizeForLegend) {\n    $$.updateSizeForLegend(legendHeight, legendWidth)\n  }\n\n  $$.width = $$.currentWidth - $$.margin.left - $$.margin.right\n  $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom\n  if ($$.width < 0) {\n    $$.width = 0\n  }\n  if ($$.height < 0) {\n    $$.height = 0\n  }\n\n  $$.width2 = config.axis_rotated\n    ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right\n    : $$.width\n  $$.height2 = config.axis_rotated\n    ? $$.height\n    : $$.currentHeight - $$.margin2.top - $$.margin2.bottom\n  if ($$.width2 < 0) {\n    $$.width2 = 0\n  }\n  if ($$.height2 < 0) {\n    $$.height2 = 0\n  }\n\n  // for arc\n  $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0)\n  $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10)\n  if ($$.hasType('gauge') && !config.gauge_fullCircle) {\n    $$.arcHeight += $$.height - $$.getGaugeLabelHeight()\n  }\n  if ($$.updateRadius) {\n    $$.updateRadius()\n  }\n\n  if ($$.isLegendRight && hasArc) {\n    $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1\n  }\n}\n\nChartInternal.prototype.updateTargets = function(targets) {\n  var $$ = this,\n    config = $$.config\n\n  /*-- Main --*/\n\n  //-- Text --//\n  $$.updateTargetsForText(targets)\n\n  //-- Bar --//\n  $$.updateTargetsForBar(targets)\n\n  //-- Line --//\n  $$.updateTargetsForLine(targets)\n\n  //-- Arc --//\n  if ($$.hasArcType() && $$.updateTargetsForArc) {\n    $$.updateTargetsForArc(targets)\n  }\n\n  /*-- Sub --*/\n\n  if (config.subchart_show && $$.updateTargetsForSubchart) {\n    $$.updateTargetsForSubchart(targets)\n  }\n\n  // Fade-in each chart\n  $$.showTargets()\n}\nChartInternal.prototype.showTargets = function() {\n  var $$ = this\n  $$.svg\n    .selectAll('.' + CLASS.target)\n    .filter(function(d) {\n      return $$.isTargetToShow(d.id)\n    })\n    .transition()\n    .duration($$.config.transition_duration)\n    .style('opacity', 1)\n}\n\nChartInternal.prototype.redraw = function(options, transitions) {\n  var $$ = this,\n    main = $$.main,\n    d3 = $$.d3,\n    config = $$.config\n  var areaIndices = $$.getShapeIndices($$.isAreaType),\n    barIndices = $$.getShapeIndices($$.isBarType),\n    lineIndices = $$.getShapeIndices($$.isLineType)\n  var withY,\n    withSubchart,\n    withTransition,\n    withTransitionForExit,\n    withTransitionForAxis,\n    withTransform,\n    withUpdateXDomain,\n    withUpdateOrgXDomain,\n    withTrimXDomain,\n    withLegend,\n    withEventRect,\n    withDimension,\n    withUpdateXAxis\n  var hideAxis = $$.hasArcType()\n  var drawArea, drawBar, drawLine, xForText, yForText\n  var duration, durationForExit, durationForAxis\n  var transitionsToWait, waitForDraw, flow, transition\n  var targetsToShow = $$.filterTargetsToShow($$.data.targets),\n    tickValues,\n    i,\n    intervalForCulling,\n    xDomainForZoom\n  var xv = $$.xv.bind($$),\n    cx,\n    cy\n\n  options = options || {}\n  withY = getOption(options, 'withY', true)\n  withSubchart = getOption(options, 'withSubchart', true)\n  withTransition = getOption(options, 'withTransition', true)\n  withTransform = getOption(options, 'withTransform', false)\n  withUpdateXDomain = getOption(options, 'withUpdateXDomain', false)\n  withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', false)\n  withTrimXDomain = getOption(options, 'withTrimXDomain', true)\n  withUpdateXAxis = getOption(options, 'withUpdateXAxis', withUpdateXDomain)\n  withLegend = getOption(options, 'withLegend', false)\n  withEventRect = getOption(options, 'withEventRect', true)\n  withDimension = getOption(options, 'withDimension', true)\n  withTransitionForExit = getOption(\n    options,\n    'withTransitionForExit',\n    withTransition\n  )\n  withTransitionForAxis = getOption(\n    options,\n    'withTransitionForAxis',\n    withTransition\n  )\n\n  duration = withTransition ? config.transition_duration : 0\n  durationForExit = withTransitionForExit ? duration : 0\n  durationForAxis = withTransitionForAxis ? duration : 0\n\n  transitions = transitions || $$.axis.generateTransitions(durationForAxis)\n\n  // update legend and transform each g\n  if (withLegend && config.legend_show) {\n    $$.updateLegend($$.mapToIds($$.data.targets), options, transitions)\n  } else if (withDimension) {\n    // need to update dimension (e.g. axis.y.tick.values) because y tick values should change\n    // no need to update axis in it because they will be updated in redraw()\n    $$.updateDimension(true)\n  }\n\n  // MEMO: needed for grids calculation\n  if ($$.isCategorized() && targetsToShow.length === 0) {\n    $$.x.domain([0, $$.axes.x.selectAll('.tick').size()])\n  }\n\n  if (targetsToShow.length) {\n    $$.updateXDomain(\n      targetsToShow,\n      withUpdateXDomain,\n      withUpdateOrgXDomain,\n      withTrimXDomain\n    )\n    if (!config.axis_x_tick_values) {\n      tickValues = $$.axis.updateXAxisTickValues(targetsToShow)\n    }\n  } else {\n    $$.xAxis.tickValues([])\n    $$.subXAxis.tickValues([])\n  }\n\n  if (config.zoom_rescale && !options.flow) {\n    xDomainForZoom = $$.x.orgDomain()\n  }\n\n  $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom))\n  $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom))\n\n  if (!config.axis_y_tick_values && config.axis_y_tick_count) {\n    $$.yAxis.tickValues(\n      $$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count)\n    )\n  }\n  if (!config.axis_y2_tick_values && config.axis_y2_tick_count) {\n    $$.y2Axis.tickValues(\n      $$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count)\n    )\n  }\n\n  // axes\n  $$.axis.redraw(durationForAxis, hideAxis)\n\n  // Update axis label\n  $$.axis.updateLabels(withTransition)\n\n  // show/hide if manual culling needed\n  if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) {\n    if (config.axis_x_tick_culling && tickValues) {\n      for (i = 1; i < tickValues.length; i++) {\n        if (tickValues.length / i < config.axis_x_tick_culling_max) {\n          intervalForCulling = i\n          break\n        }\n      }\n      $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function(e) {\n        var index = tickValues.indexOf(e)\n        if (index >= 0) {\n          d3.select(this).style(\n            'display',\n            index % intervalForCulling ? 'none' : 'block'\n          )\n        }\n      })\n    } else {\n      $$.svg\n        .selectAll('.' + CLASS.axisX + ' .tick text')\n        .style('display', 'block')\n    }\n  }\n\n  // setup drawer - MEMO: these must be called after axis updated\n  drawArea = $$.generateDrawArea\n    ? $$.generateDrawArea(areaIndices, false)\n    : undefined\n  drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined\n  drawLine = $$.generateDrawLine\n    ? $$.generateDrawLine(lineIndices, false)\n    : undefined\n  xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true)\n  yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false)\n\n  // update circleY based on updated parameters\n  $$.updateCircleY()\n  // generate circle x/y functions depending on updated params\n  cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$)\n  cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$)\n\n  // Update sub domain\n  if (withY) {\n    $$.subY.domain($$.getYDomain(targetsToShow, 'y'))\n    $$.subY2.domain($$.getYDomain(targetsToShow, 'y2'))\n  }\n\n  // xgrid focus\n  $$.updateXgridFocus()\n\n  // Data empty label positioning and text.\n  main\n    .select('text.' + CLASS.text + '.' + CLASS.empty)\n    .attr('x', $$.width / 2)\n    .attr('y', $$.height / 2)\n    .text(config.data_empty_label_text)\n    .transition()\n    .style('opacity', targetsToShow.length ? 0 : 1)\n\n  // event rect\n  if (withEventRect) {\n    $$.redrawEventRect()\n  }\n\n  // grid\n  $$.updateGrid(duration)\n\n  $$.updateStanfordElements(duration)\n\n  // rect for regions\n  $$.updateRegion(duration)\n\n  // bars\n  $$.updateBar(durationForExit)\n\n  // lines, areas and circles\n  $$.updateLine(durationForExit)\n  $$.updateArea(durationForExit)\n  $$.updateCircle(cx, cy)\n\n  // text\n  if ($$.hasDataLabel()) {\n    $$.updateText(xForText, yForText, durationForExit)\n  }\n\n  // title\n  if ($$.redrawTitle) {\n    $$.redrawTitle()\n  }\n\n  // arc\n  if ($$.redrawArc) {\n    $$.redrawArc(duration, durationForExit, withTransform)\n  }\n\n  // subchart\n  if (config.subchart_show && $$.redrawSubchart) {\n    $$.redrawSubchart(\n      withSubchart,\n      transitions,\n      duration,\n      durationForExit,\n      areaIndices,\n      barIndices,\n      lineIndices\n    )\n  }\n\n  if ($$.isStanfordGraphType()) {\n    $$.drawColorScale()\n  }\n\n  // circles for select\n  main\n    .selectAll('.' + CLASS.selectedCircles)\n    .filter($$.isBarType.bind($$))\n    .selectAll('circle')\n    .remove()\n\n  if (options.flow) {\n    flow = $$.generateFlow({\n      targets: targetsToShow,\n      flow: options.flow,\n      duration: options.flow.duration,\n      drawBar: drawBar,\n      drawLine: drawLine,\n      drawArea: drawArea,\n      cx: cx,\n      cy: cy,\n      xv: xv,\n      xForText: xForText,\n      yForText: yForText\n    })\n  }\n\n  if (duration && $$.isTabVisible()) {\n    // Only use transition if tab visible. See #938.\n    // transition should be derived from one transition\n    transition = d3.transition().duration(duration)\n    transitionsToWait = []\n    ;[\n      $$.redrawBar(drawBar, true, transition),\n      $$.redrawLine(drawLine, true, transition),\n      $$.redrawArea(drawArea, true, transition),\n      $$.redrawCircle(cx, cy, true, transition),\n      $$.redrawText(xForText, yForText, options.flow, true, transition),\n      $$.redrawRegion(true, transition),\n      $$.redrawGrid(true, transition)\n    ].forEach(function(transitions) {\n      transitions.forEach(function(transition) {\n        transitionsToWait.push(transition)\n      })\n    })\n    // Wait for end of transitions to call flow and onrendered callback\n    waitForDraw = $$.generateWait()\n    transitionsToWait.forEach(function(t) {\n      waitForDraw.add(t)\n    })\n    waitForDraw(function() {\n      if (flow) {\n        flow()\n      }\n      if (config.onrendered) {\n        config.onrendered.call($$)\n      }\n    })\n  } else {\n    $$.redrawBar(drawBar)\n    $$.redrawLine(drawLine)\n    $$.redrawArea(drawArea)\n    $$.redrawCircle(cx, cy)\n    $$.redrawText(xForText, yForText, options.flow)\n    $$.redrawRegion()\n    $$.redrawGrid()\n    if (flow) {\n      flow()\n    }\n    if (config.onrendered) {\n      config.onrendered.call($$)\n    }\n  }\n\n  // update fadein condition\n  $$.mapToIds($$.data.targets).forEach(function(id) {\n    $$.withoutFadeIn[id] = true\n  })\n}\n\nChartInternal.prototype.updateAndRedraw = function(options) {\n  var $$ = this,\n    config = $$.config,\n    transitions\n  options = options || {}\n  // same with redraw\n  options.withTransition = getOption(options, 'withTransition', true)\n  options.withTransform = getOption(options, 'withTransform', false)\n  options.withLegend = getOption(options, 'withLegend', false)\n  // NOT same with redraw\n  options.withUpdateXDomain = getOption(options, 'withUpdateXDomain', true)\n  options.withUpdateOrgXDomain = getOption(\n    options,\n    'withUpdateOrgXDomain',\n    true\n  )\n  options.withTransitionForExit = false\n  options.withTransitionForTransform = getOption(\n    options,\n    'withTransitionForTransform',\n    options.withTransition\n  )\n  // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called)\n  $$.updateSizes()\n  // MEMO: called in updateLegend in redraw if withLegend\n  if (!(options.withLegend && config.legend_show)) {\n    transitions = $$.axis.generateTransitions(\n      options.withTransitionForAxis ? config.transition_duration : 0\n    )\n    // Update scales\n    $$.updateScales()\n    $$.updateSvgSize()\n    // Update g positions\n    $$.transformAll(options.withTransitionForTransform, transitions)\n  }\n  // Draw with new sizes & scales\n  $$.redraw(options, transitions)\n}\nChartInternal.prototype.redrawWithoutRescale = function() {\n  this.redraw({\n    withY: false,\n    withSubchart: false,\n    withEventRect: false,\n    withTransitionForAxis: false\n  })\n}\n\nChartInternal.prototype.isTimeSeries = function() {\n  return this.config.axis_x_type === 'timeseries'\n}\nChartInternal.prototype.isCategorized = function() {\n  return this.config.axis_x_type.indexOf('categor') >= 0\n}\nChartInternal.prototype.isCustomX = function() {\n  var $$ = this,\n    config = $$.config\n  return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs))\n}\n\nChartInternal.prototype.isTimeSeriesY = function() {\n  return this.config.axis_y_type === 'timeseries'\n}\n\nChartInternal.prototype.getTranslate = function(target) {\n  var $$ = this,\n    config = $$.config,\n    x,\n    y\n  if (target === 'main') {\n    x = asHalfPixel($$.margin.left)\n    y = asHalfPixel($$.margin.top)\n  } else if (target === 'context') {\n    x = asHalfPixel($$.margin2.left)\n    y = asHalfPixel($$.margin2.top)\n  } else if (target === 'legend') {\n    x = $$.margin3.left\n    y = $$.margin3.top\n  } else if (target === 'x') {\n    x = 0\n    y = config.axis_rotated ? 0 : $$.height\n  } else if (target === 'y') {\n    x = 0\n    y = config.axis_rotated ? $$.height : 0\n  } else if (target === 'y2') {\n    x = config.axis_rotated ? 0 : $$.width\n    y = config.axis_rotated ? 1 : 0\n  } else if (target === 'subx') {\n    x = 0\n    y = config.axis_rotated ? 0 : $$.height2\n  } else if (target === 'arc') {\n    x = $$.arcWidth / 2\n    y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0) // to prevent wrong display of min and max label\n  }\n  return 'translate(' + x + ',' + y + ')'\n}\nChartInternal.prototype.initialOpacity = function(d) {\n  return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0\n}\nChartInternal.prototype.initialOpacityForCircle = function(d) {\n  return d.value !== null && this.withoutFadeIn[d.id]\n    ? this.opacityForCircle(d)\n    : 0\n}\nChartInternal.prototype.opacityForCircle = function(d) {\n  var isPointShouldBeShown = isFunction(this.config.point_show)\n    ? this.config.point_show(d)\n    : this.config.point_show\n  var opacity = isPointShouldBeShown || this.isStanfordType(d) ? 1 : 0\n  return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0\n}\nChartInternal.prototype.opacityForText = function() {\n  return this.hasDataLabel() ? 1 : 0\n}\nChartInternal.prototype.xx = function(d) {\n  return d ? this.x(d.x) : null\n}\nChartInternal.prototype.xvCustom = function(d, xyValue) {\n  var $$ = this,\n    value = xyValue ? d[xyValue] : d.value\n  if ($$.isTimeSeries()) {\n    value = $$.parseDate(d.value)\n  } else if ($$.isCategorized() && typeof d.value === 'string') {\n    value = $$.config.axis_x_categories.indexOf(d.value)\n  }\n  return Math.ceil($$.x(value))\n}\nChartInternal.prototype.yvCustom = function(d, xyValue) {\n  var $$ = this,\n    yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y,\n    value = xyValue ? d[xyValue] : d.value\n  return Math.ceil(yScale(value))\n}\nChartInternal.prototype.xv = function(d) {\n  var $$ = this,\n    value = d.value\n  if ($$.isTimeSeries()) {\n    value = $$.parseDate(d.value)\n  } else if ($$.isCategorized() && typeof d.value === 'string') {\n    value = $$.config.axis_x_categories.indexOf(d.value)\n  }\n  return Math.ceil($$.x(value))\n}\nChartInternal.prototype.yv = function(d) {\n  var $$ = this,\n    yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y\n  return Math.ceil(yScale(d.value))\n}\nChartInternal.prototype.subxx = function(d) {\n  return d ? this.subX(d.x) : null\n}\n\nChartInternal.prototype.transformMain = function(withTransition, transitions) {\n  var $$ = this,\n    xAxis,\n    yAxis,\n    y2Axis\n  if (transitions && transitions.axisX) {\n    xAxis = transitions.axisX\n  } else {\n    xAxis = $$.main.select('.' + CLASS.axisX)\n    if (withTransition) {\n      xAxis = xAxis.transition()\n    }\n  }\n  if (transitions && transitions.axisY) {\n    yAxis = transitions.axisY\n  } else {\n    yAxis = $$.main.select('.' + CLASS.axisY)\n    if (withTransition) {\n      yAxis = yAxis.transition()\n    }\n  }\n  if (transitions && transitions.axisY2) {\n    y2Axis = transitions.axisY2\n  } else {\n    y2Axis = $$.main.select('.' + CLASS.axisY2)\n    if (withTransition) {\n      y2Axis = y2Axis.transition()\n    }\n  }\n  ;(withTransition ? $$.main.transition() : $$.main).attr(\n    'transform',\n    $$.getTranslate('main')\n  )\n  xAxis.attr('transform', $$.getTranslate('x'))\n  yAxis.attr('transform', $$.getTranslate('y'))\n  y2Axis.attr('transform', $$.getTranslate('y2'))\n  $$.main\n    .select('.' + CLASS.chartArcs)\n    .attr('transform', $$.getTranslate('arc'))\n}\nChartInternal.prototype.transformAll = function(withTransition, transitions) {\n  var $$ = this\n  $$.transformMain(withTransition, transitions)\n  if ($$.config.subchart_show) {\n    $$.transformContext(withTransition, transitions)\n  }\n  if ($$.legend) {\n    $$.transformLegend(withTransition)\n  }\n}\n\nChartInternal.prototype.updateSvgSize = function() {\n  var $$ = this,\n    brush = $$.svg.select(`.${CLASS.brush} .overlay`)\n  $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight)\n  $$.svg\n    .selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid])\n    .select('rect')\n    .attr('width', $$.width)\n    .attr('height', $$.height)\n  $$.svg\n    .select('#' + $$.clipIdForXAxis)\n    .select('rect')\n    .attr('x', $$.getXAxisClipX.bind($$))\n    .attr('y', $$.getXAxisClipY.bind($$))\n    .attr('width', $$.getXAxisClipWidth.bind($$))\n    .attr('height', $$.getXAxisClipHeight.bind($$))\n  $$.svg\n    .select('#' + $$.clipIdForYAxis)\n    .select('rect')\n    .attr('x', $$.getYAxisClipX.bind($$))\n    .attr('y', $$.getYAxisClipY.bind($$))\n    .attr('width', $$.getYAxisClipWidth.bind($$))\n    .attr('height', $$.getYAxisClipHeight.bind($$))\n  $$.svg\n    .select('#' + $$.clipIdForSubchart)\n    .select('rect')\n    .attr('width', $$.width)\n    .attr('height', (brush.size() && brush.attr('height')) || 0)\n  // MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>\n  $$.selectChart.style('max-height', $$.currentHeight + 'px')\n}\n\nChartInternal.prototype.updateDimension = function(withoutAxis) {\n  var $$ = this\n  if (!withoutAxis) {\n    if ($$.config.axis_rotated) {\n      $$.axes.x.call($$.xAxis)\n      $$.axes.subx.call($$.subXAxis)\n    } else {\n      $$.axes.y.call($$.yAxis)\n      $$.axes.y2.call($$.y2Axis)\n    }\n  }\n  $$.updateSizes()\n  $$.updateScales()\n  $$.updateSvgSize()\n  $$.transformAll(false)\n}\n\nChartInternal.prototype.observeInserted = function(selection) {\n  var $$ = this,\n    observer\n  if (typeof MutationObserver === 'undefined') {\n    window.console.error('MutationObserver not defined.')\n    return\n  }\n  observer = new MutationObserver(function(mutations) {\n    mutations.forEach(function(mutation) {\n      if (mutation.type === 'childList' && mutation.previousSibling) {\n        observer.disconnect()\n        // need to wait for completion of load because size calculation requires the actual sizes determined after that completion\n        $$.intervalForObserveInserted = window.setInterval(function() {\n          // parentNode will NOT be null when completed\n          if (selection.node().parentNode) {\n            window.clearInterval($$.intervalForObserveInserted)\n            $$.updateDimension()\n            if ($$.brush) {\n              $$.brush.update()\n            }\n            $$.config.oninit.call($$)\n            $$.redraw({\n              withTransform: true,\n              withUpdateXDomain: true,\n              withUpdateOrgXDomain: true,\n              withTransition: false,\n              withTransitionForTransform: false,\n              withLegend: true\n            })\n            selection.transition().style('opacity', 1)\n          }\n        }, 10)\n      }\n    })\n  })\n  observer.observe(selection.node(), {\n    attributes: true,\n    childList: true,\n    characterData: true\n  })\n}\n\n/**\n * Binds handlers to the window resize event.\n */\nChartInternal.prototype.bindResize = function() {\n  var $$ = this,\n    config = $$.config\n\n  $$.resizeFunction = $$.generateResize() // need to call .remove\n\n  $$.resizeFunction.add(function() {\n    config.onresize.call($$)\n  })\n  if (config.resize_auto) {\n    $$.resizeFunction.add(function() {\n      if ($$.resizeTimeout !== undefined) {\n        window.clearTimeout($$.resizeTimeout)\n      }\n      $$.resizeTimeout = window.setTimeout(function() {\n        delete $$.resizeTimeout\n        $$.updateAndRedraw({\n          withUpdateXDomain: false,\n          withUpdateOrgXDomain: false,\n          withTransition: false,\n          withTransitionForTransform: false,\n          withLegend: true\n        })\n        if ($$.brush) {\n          $$.brush.update()\n        }\n      }, 100)\n    })\n  }\n  $$.resizeFunction.add(function() {\n    config.onresized.call($$)\n  })\n\n  $$.resizeIfElementDisplayed = function() {\n    // if element not displayed skip it\n    if ($$.api == null || !$$.api.element.offsetParent) {\n      return\n    }\n\n    $$.resizeFunction()\n  }\n\n  window.addEventListener('resize', $$.resizeIfElementDisplayed, false)\n}\n\n/**\n * Binds handlers to the window focus event.\n */\nChartInternal.prototype.bindWindowFocus = function() {\n  if (this.windowFocusHandler) {\n    // The handler is already set\n    return\n  }\n\n  this.windowFocusHandler = () => {\n    this.redraw()\n  }\n\n  window.addEventListener('focus', this.windowFocusHandler)\n}\n\n/**\n * Unbinds from the window focus event.\n */\nChartInternal.prototype.unbindWindowFocus = function() {\n  window.removeEventListener('focus', this.windowFocusHandler)\n  delete this.windowFocusHandler\n}\n\nChartInternal.prototype.generateResize = function() {\n  var resizeFunctions = []\n\n  function callResizeFunctions() {\n    resizeFunctions.forEach(function(f) {\n      f()\n    })\n  }\n  callResizeFunctions.add = function(f) {\n    resizeFunctions.push(f)\n  }\n  callResizeFunctions.remove = function(f) {\n    for (var i = 0; i < resizeFunctions.length; i++) {\n      if (resizeFunctions[i] === f) {\n        resizeFunctions.splice(i, 1)\n        break\n      }\n    }\n  }\n  return callResizeFunctions\n}\n\nChartInternal.prototype.endall = function(transition, callback) {\n  var n = 0\n  transition\n    .each(function() {\n      ++n\n    })\n    .on('end', function() {\n      if (!--n) {\n        callback.apply(this, arguments)\n      }\n    })\n}\nChartInternal.prototype.generateWait = function() {\n  var $$ = this\n  var transitionsToWait = [],\n    f = function(callback) {\n      var timer = setInterval(function() {\n        if (!$$.isTabVisible()) {\n          return\n        }\n\n        var done = 0\n        transitionsToWait.forEach(function(t) {\n          if (t.empty()) {\n            done += 1\n            return\n          }\n          try {\n            t.transition()\n          } catch (e) {\n            done += 1\n          }\n        })\n        if (done === transitionsToWait.length) {\n          clearInterval(timer)\n          if (callback) {\n            callback()\n          }\n        }\n      }, 50)\n    }\n  ;(f as any).add = function(transition) {\n    transitionsToWait.push(transition)\n  }\n  return f\n}\n\nChartInternal.prototype.parseDate = function(date) {\n  var $$ = this,\n    parsedDate\n  if (date instanceof Date) {\n    parsedDate = date\n  } else if (typeof date === 'string') {\n    parsedDate = $$.dataTimeParse(date)\n  } else if (typeof date === 'object') {\n    parsedDate = new Date(+date)\n  } else if (typeof date === 'number' && !isNaN(date)) {\n    parsedDate = new Date(+date)\n  }\n  if (!parsedDate || isNaN(+parsedDate)) {\n    window.console.error(\"Failed to parse x '\" + date + \"' to Date object\")\n  }\n  return parsedDate\n}\n\nChartInternal.prototype.isTabVisible = function() {\n  return !document.hidden\n}\n\nChartInternal.prototype.getPathBox = getPathBox\nChartInternal.prototype.CLASS = CLASS\n\nexport { Chart }\nexport { ChartInternal }\n"
  },
  {
    "path": "src/data.convert.ts",
    "content": "import { ChartInternal } from './core'\nimport { isValue, isUndefined, isDefined, notEmpty, isArray } from './util'\n\nChartInternal.prototype.convertUrlToData = function(\n  url,\n  mimeType,\n  headers,\n  keys,\n  done\n) {\n  var $$ = this,\n    type = mimeType ? mimeType : 'csv',\n    f,\n    converter\n\n  if (type === 'json') {\n    f = $$.d3.json\n    converter = $$.convertJsonToData\n  } else if (type === 'tsv') {\n    f = $$.d3.tsv\n    converter = $$.convertXsvToData\n  } else {\n    f = $$.d3.csv\n    converter = $$.convertXsvToData\n  }\n\n  f(url, headers)\n    .then(function(data) {\n      done.call($$, converter.call($$, data, keys))\n    })\n    .catch(function(error) {\n      throw error\n    })\n}\nChartInternal.prototype.convertXsvToData = function(xsv) {\n  var keys = xsv.columns,\n    rows = xsv\n  if (rows.length === 0) {\n    return {\n      keys,\n      rows: [keys.reduce((row, key) => Object.assign(row, { [key]: null }), {})]\n    }\n  } else {\n    // [].concat() is to convert result into a plain array otherwise\n    // test is not happy because rows have properties.\n    return { keys, rows: [].concat(xsv) }\n  }\n}\nChartInternal.prototype.convertJsonToData = function(json, keys) {\n  var $$ = this,\n    new_rows = [],\n    targetKeys,\n    data\n  if (keys) {\n    // when keys specified, json would be an array that includes objects\n    if (keys.x) {\n      targetKeys = keys.value.concat(keys.x)\n      $$.config.data_x = keys.x\n    } else {\n      targetKeys = keys.value\n    }\n    new_rows.push(targetKeys)\n    json.forEach(function(o) {\n      var new_row = []\n      targetKeys.forEach(function(key) {\n        // convert undefined to null because undefined data will be removed in convertDataToTargets()\n        var v = $$.findValueInJson(o, key)\n        if (isUndefined(v)) {\n          v = null\n        }\n        new_row.push(v)\n      })\n      new_rows.push(new_row)\n    })\n    data = $$.convertRowsToData(new_rows)\n  } else {\n    Object.keys(json).forEach(function(key) {\n      new_rows.push([key].concat(json[key]))\n    })\n    data = $$.convertColumnsToData(new_rows)\n  }\n  return data\n}\n/**\n * Finds value from the given nested object by the given path.\n * If it's not found, then this returns undefined.\n * @param {Object} object the object\n * @param {string} path the path\n */\nChartInternal.prototype.findValueInJson = function(object, path) {\n  if (path in object) {\n    // If object has a key that contains . or [], return the key's value\n    // instead of searching for an inner object.\n    // See https://github.com/c3js/c3/issues/1691 for details.\n    return object[path]\n  }\n\n  path = path.replace(/\\[(\\w+)\\]/g, '.$1') // convert indexes to properties (replace [] with .)\n  path = path.replace(/^\\./, '') // strip a leading dot\n  var pathArray = path.split('.')\n  for (var i = 0; i < pathArray.length; ++i) {\n    var k = pathArray[i]\n    if (k in object) {\n      object = object[k]\n    } else {\n      return\n    }\n  }\n  return object\n}\n\n/**\n * Converts the rows to normalized data.\n * @param {any[][]} rows The row data\n * @return {Object}\n */\nChartInternal.prototype.convertRowsToData = rows => {\n  const newRows = []\n  const keys = rows[0]\n\n  for (let i = 1; i < rows.length; i++) {\n    const newRow = {}\n    for (let j = 0; j < rows[i].length; j++) {\n      if (isUndefined(rows[i][j])) {\n        throw new Error(\n          'Source data is missing a component at (' + i + ',' + j + ')!'\n        )\n      }\n      newRow[keys[j]] = rows[i][j]\n    }\n    newRows.push(newRow)\n  }\n  return { keys, rows: newRows }\n}\n\n/**\n * Converts the columns to normalized data.\n * @param {any[][]} columns The column data\n * @return {Object}\n */\nChartInternal.prototype.convertColumnsToData = columns => {\n  const newRows = []\n  const keys = []\n\n  for (let i = 0; i < columns.length; i++) {\n    const key = columns[i][0]\n    for (let j = 1; j < columns[i].length; j++) {\n      if (isUndefined(newRows[j - 1])) {\n        newRows[j - 1] = {}\n      }\n      if (isUndefined(columns[i][j])) {\n        throw new Error(\n          'Source data is missing a component at (' + i + ',' + j + ')!'\n        )\n      }\n      newRows[j - 1][key] = columns[i][j]\n    }\n    keys.push(key)\n  }\n\n  return { keys, rows: newRows }\n}\n\n/**\n * Converts the data format into the target format.\n * @param {!Object} data\n * @param {!Array} data.keys Ordered list of target IDs.\n * @param {!Array} data.rows Rows of data to convert.\n * @param {boolean} appendXs True to append to $$.data.xs, False to replace.\n * @return {!Array}\n */\nChartInternal.prototype.convertDataToTargets = function(data, appendXs) {\n  var $$ = this,\n    config = $$.config,\n    targets,\n    ids,\n    xs,\n    keys,\n    epochs\n\n  // handles format where keys are not orderly provided\n  if (isArray(data)) {\n    keys = Object.keys(data[0])\n  } else {\n    keys = data.keys\n    data = data.rows\n  }\n\n  xs = keys.filter($$.isX, $$)\n\n  if (!$$.isStanfordGraphType()) {\n    ids = keys.filter($$.isNotX, $$)\n  } else {\n    epochs = keys.filter($$.isEpochs, $$)\n    ids = keys.filter($$.isNotXAndNotEpochs, $$)\n\n    if (xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) {\n      throw new Error(\n        \"You must define the 'x' key name and the 'epochs' for Stanford Diagrams\"\n      )\n    }\n  }\n\n  // save x for update data by load when custom x and c3.x API\n  ids.forEach(function(id) {\n    var xKey = $$.getXKey(id)\n\n    if ($$.isCustomX() || $$.isTimeSeries()) {\n      // if included in input data\n      if (xs.indexOf(xKey) >= 0) {\n        $$.data.xs[id] = (appendXs && $$.data.xs[id]\n          ? $$.data.xs[id]\n          : []\n        ).concat(\n          data\n            .map(function(d) {\n              return d[xKey]\n            })\n            .filter(isValue)\n            .map(function(rawX, i) {\n              return $$.generateTargetX(rawX, id, i)\n            })\n        )\n      }\n      // if not included in input data, find from preloaded data of other id's x\n      else if (config.data_x) {\n        $$.data.xs[id] = $$.getOtherTargetXs()\n      }\n      // if not included in input data, find from preloaded data\n      else if (notEmpty(config.data_xs)) {\n        $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets)\n      }\n      // MEMO: if no x included, use same x of current will be used\n    } else {\n      $$.data.xs[id] = data.map(function(d, i) {\n        return i\n      })\n    }\n  })\n\n  // check x is defined\n  ids.forEach(function(id) {\n    if (!$$.data.xs[id]) {\n      throw new Error('x is not defined for id = \"' + id + '\".')\n    }\n  })\n\n  // convert to target\n  targets = ids.map(function(id, index) {\n    var convertedId = config.data_idConverter(id)\n    return {\n      id: convertedId,\n      id_org: id,\n      values: data\n        .map(function(d, i) {\n          var xKey = $$.getXKey(id),\n            rawX = d[xKey],\n            value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null,\n            x,\n            returnData\n          // use x as categories if custom x and categorized\n          if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) {\n            if (index === 0 && i === 0) {\n              config.axis_x_categories = []\n            }\n            x = config.axis_x_categories.indexOf(rawX)\n            if (x === -1) {\n              x = config.axis_x_categories.length\n              config.axis_x_categories.push(rawX)\n            }\n          } else {\n            x = $$.generateTargetX(rawX, id, i)\n          }\n          // mark as x = undefined if value is undefined and filter to remove after mapped\n          if (isUndefined(d[id]) || $$.data.xs[id].length <= i) {\n            x = undefined\n          }\n\n          returnData = { x: x, value: value, id: convertedId }\n\n          if ($$.isStanfordGraphType()) {\n            returnData.epochs = d[epochs]\n          }\n\n          return returnData\n        })\n        .filter(function(v) {\n          return isDefined(v.x)\n        })\n    }\n  })\n\n  // finish targets\n  targets.forEach(function(t) {\n    var i\n    // sort values by its x\n    if (config.data_xSort) {\n      t.values = t.values.sort(function(v1, v2) {\n        var x1 = v1.x || v1.x === 0 ? v1.x : Infinity,\n          x2 = v2.x || v2.x === 0 ? v2.x : Infinity\n        return x1 - x2\n      })\n    }\n    // indexing each value\n    i = 0\n    t.values.forEach(function(v) {\n      v.index = i++\n    })\n    // this needs to be sorted because its index and value.index is identical\n    $$.data.xs[t.id].sort(function(v1, v2) {\n      return v1 - v2\n    })\n  })\n\n  // cache information about values\n  $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets)\n  $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets)\n\n  // set target types\n  if (config.data_type) {\n    $$.setTargetType(\n      $$.mapToIds(targets).filter(function(id) {\n        return !(id in config.data_types)\n      }),\n      config.data_type\n    )\n  }\n\n  // cache as original id keyed\n  targets.forEach(function(d) {\n    $$.addCache(d.id_org, d)\n  })\n\n  return targets\n}\n"
  },
  {
    "path": "src/data.load.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\n\nChartInternal.prototype.load = function(targets, args) {\n  var $$ = this\n  if (targets) {\n    // filter loading targets if needed\n    if (args.filter) {\n      targets = targets.filter(args.filter)\n    }\n    // set type if args.types || args.type specified\n    if (args.type || args.types) {\n      targets.forEach(function(t) {\n        var type = args.types && args.types[t.id] ? args.types[t.id] : args.type\n        $$.setTargetType(t.id, type)\n      })\n    }\n    // Update/Add data\n    $$.data.targets.forEach(function(d) {\n      for (var i = 0; i < targets.length; i++) {\n        if (d.id === targets[i].id) {\n          d.values = targets[i].values\n          targets.splice(i, 1)\n          break\n        }\n      }\n    })\n    $$.data.targets = $$.data.targets.concat(targets) // add remained\n  }\n\n  // Set targets\n  $$.updateTargets($$.data.targets)\n\n  // Redraw with new targets\n  $$.redraw({\n    withUpdateOrgXDomain: true,\n    withUpdateXDomain: true,\n    withLegend: true\n  })\n\n  if (args.done) {\n    args.done()\n  }\n}\nChartInternal.prototype.loadFromArgs = function(args) {\n  var $$ = this\n\n  $$.resetCache()\n\n  if (args.data) {\n    $$.load($$.convertDataToTargets(args.data), args)\n  } else if (args.url) {\n    $$.convertUrlToData(\n      args.url,\n      args.mimeType,\n      args.headers,\n      args.keys,\n      function(data) {\n        $$.load($$.convertDataToTargets(data), args)\n      }\n    )\n  } else if (args.json) {\n    $$.load(\n      $$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)),\n      args\n    )\n  } else if (args.rows) {\n    $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args)\n  } else if (args.columns) {\n    $$.load(\n      $$.convertDataToTargets($$.convertColumnsToData(args.columns)),\n      args\n    )\n  } else {\n    $$.load(null, args)\n  }\n}\nChartInternal.prototype.unload = function(targetIds, done) {\n  var $$ = this\n\n  $$.resetCache()\n\n  if (!done) {\n    done = function() {}\n  }\n  // filter existing target\n  targetIds = targetIds.filter(function(id) {\n    return $$.hasTarget($$.data.targets, id)\n  })\n  // If no target, call done and return\n  if (!targetIds || targetIds.length === 0) {\n    done()\n    return\n  }\n  $$.svg\n    .selectAll(\n      targetIds.map(function(id) {\n        return $$.selectorTarget(id)\n      })\n    )\n    .transition()\n    .style('opacity', 0)\n    .remove()\n    .call($$.endall, done)\n  targetIds.forEach(function(id) {\n    // Reset fadein for future load\n    $$.withoutFadeIn[id] = false\n    // Remove target's elements\n    if ($$.legend) {\n      $$.legend\n        .selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id))\n        .remove()\n    }\n    // Remove target\n    $$.data.targets = $$.data.targets.filter(function(t) {\n      return t.id !== id\n    })\n  })\n}\n"
  },
  {
    "path": "src/data.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport {\n  isValue,\n  isFunction,\n  isNumber,\n  isArray,\n  notEmpty,\n  hasValue,\n  flattenArray,\n  getBBox\n} from './util'\n\nChartInternal.prototype.isEpochs = function(key) {\n  var $$ = this,\n    config = $$.config\n  return config.data_epochs && key === config.data_epochs\n}\nChartInternal.prototype.isX = function(key) {\n  var $$ = this,\n    config = $$.config\n  return (\n    (config.data_x && key === config.data_x) ||\n    (notEmpty(config.data_xs) && hasValue(config.data_xs, key))\n  )\n}\nChartInternal.prototype.isNotX = function(key) {\n  return !this.isX(key)\n}\nChartInternal.prototype.isNotXAndNotEpochs = function(key) {\n  return !this.isX(key) && !this.isEpochs(key)\n}\n\n/**\n * Returns whether the normalized stack option is enabled or not.\n *\n * To be enabled it must also have data.groups defined.\n *\n * @return {boolean}\n */\nChartInternal.prototype.isStackNormalized = function() {\n  return this.config.data_stack_normalize && this.config.data_groups.length > 0\n}\n\n/**\n * Returns whether the axis is normalized or not.\n *\n * An axis is normalized as long as one of its associated target\n * is normalized.\n *\n * @param axisId Axis ID (y or y2)\n * @return {Boolean}\n */\nChartInternal.prototype.isAxisNormalized = function(axisId) {\n  const $$ = this\n\n  if (!$$.isStackNormalized()) {\n    // shortcut\n    return false\n  }\n\n  return $$.data.targets\n    .filter(target => $$.axis.getId(target.id) === axisId)\n    .some(target => $$.isTargetNormalized(target.id))\n}\n\n/**\n * Returns whether the values for this target ID is normalized or not.\n *\n * To be normalized the option needs to be enabled and target needs\n * to be defined in `data.groups`.\n *\n * @param targetId ID of the target\n * @return {Boolean} True if the target is normalized, false otherwise.\n */\nChartInternal.prototype.isTargetNormalized = function(targetId) {\n  const $$ = this\n\n  return (\n    $$.isStackNormalized() &&\n    $$.config.data_groups.some(group => group.includes(targetId))\n  )\n}\n\nChartInternal.prototype.getXKey = function(id) {\n  var $$ = this,\n    config = $$.config\n  return config.data_x\n    ? config.data_x\n    : notEmpty(config.data_xs)\n    ? config.data_xs[id]\n    : null\n}\n\n/**\n * Get sum of visible data per index for given axis.\n *\n * Expect axisId to be either 'y' or 'y2'.\n *\n * @private\n * @param axisId Compute sum for data associated to given axis.\n * @return {Array}\n */\nChartInternal.prototype.getTotalPerIndex = function(axisId) {\n  const $$ = this\n\n  if (!$$.isStackNormalized()) {\n    return null\n  }\n\n  const cached = $$.getFromCache('getTotalPerIndex')\n  if (cached !== undefined) {\n    return cached[axisId]\n  }\n\n  const sum = { y: [], y2: [] }\n\n  $$.data.targets\n    // keep only target that are normalized\n    .filter(target => $$.isTargetNormalized(target.id))\n\n    // keep only target that are visible\n    .filter(target => $$.isTargetToShow(target.id))\n\n    // compute sum per axis\n    .forEach(target => {\n      const sumByAxis = sum[$$.axis.getId(target.id)]\n\n      target.values.forEach((v, i) => {\n        if (!sumByAxis[i]) {\n          sumByAxis[i] = 0\n        }\n        sumByAxis[i] += isNumber(v.value) ? v.value : 0\n      })\n    })\n\n  $$.addToCache('getTotalPerIndex', sum)\n\n  return sum[axisId]\n}\n\n/**\n * Get sum of visible data.\n *\n * Should be used for normalised data only since all values\n * are expected to be positive.\n *\n * @private\n * @return {Number}\n */\nChartInternal.prototype.getTotalDataSum = function() {\n  const $$ = this\n\n  const cached = $$.getFromCache('getTotalDataSum')\n  if (cached !== undefined) {\n    return cached\n  }\n\n  const totalDataSum = flattenArray(\n    $$.data.targets\n      .filter(target => $$.isTargetToShow(target.id))\n      .map(target => target.values)\n  )\n    .map(d => d.value)\n    .reduce((p, c) => p + c, 0)\n\n  $$.addToCache('getTotalDataSum', totalDataSum)\n\n  return totalDataSum\n}\n\nChartInternal.prototype.getXValuesOfXKey = function(key, targets) {\n  var $$ = this,\n    xValues,\n    ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : []\n  ids.forEach(function(id) {\n    if ($$.getXKey(id) === key) {\n      xValues = $$.data.xs[id]\n    }\n  })\n  return xValues\n}\nChartInternal.prototype.getXValue = function(id, i) {\n  var $$ = this\n  return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i])\n    ? $$.data.xs[id][i]\n    : i\n}\nChartInternal.prototype.getOtherTargetXs = function() {\n  var $$ = this,\n    idsForX = Object.keys($$.data.xs)\n  return idsForX.length ? $$.data.xs[idsForX[0]] : null\n}\nChartInternal.prototype.getOtherTargetX = function(index) {\n  var xs = this.getOtherTargetXs()\n  return xs && index < xs.length ? xs[index] : null\n}\nChartInternal.prototype.addXs = function(xs) {\n  var $$ = this\n  Object.keys(xs).forEach(function(id) {\n    $$.config.data_xs[id] = xs[id]\n  })\n}\nChartInternal.prototype.addName = function(data) {\n  var $$ = this,\n    name\n  if (data) {\n    name = $$.config.data_names[data.id]\n    data.name = name !== undefined ? name : data.id\n  }\n  return data\n}\nChartInternal.prototype.getValueOnIndex = function(values, index) {\n  var valueOnIndex = values.filter(function(v) {\n    return v.index === index\n  })\n  return valueOnIndex.length ? valueOnIndex[0] : null\n}\nChartInternal.prototype.updateTargetX = function(targets, x) {\n  var $$ = this\n  targets.forEach(function(t) {\n    t.values.forEach(function(v, i) {\n      v.x = $$.generateTargetX(x[i], t.id, i)\n    })\n    $$.data.xs[t.id] = x\n  })\n}\nChartInternal.prototype.updateTargetXs = function(targets, xs) {\n  var $$ = this\n  targets.forEach(function(t) {\n    if (xs[t.id]) {\n      $$.updateTargetX([t], xs[t.id])\n    }\n  })\n}\nChartInternal.prototype.generateTargetX = function(rawX, id, index) {\n  var $$ = this,\n    x\n  if ($$.isTimeSeries()) {\n    x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index))\n  } else if ($$.isCustomX() && !$$.isCategorized()) {\n    x = isValue(rawX) ? +rawX : $$.getXValue(id, index)\n  } else {\n    x = index\n  }\n  return x\n}\nChartInternal.prototype.cloneTarget = function(target) {\n  return {\n    id: target.id,\n    id_org: target.id_org,\n    values: target.values.map(function(d) {\n      return {\n        x: d.x,\n        value: d.value,\n        id: d.id\n      }\n    })\n  }\n}\nChartInternal.prototype.getMaxDataCount = function() {\n  var $$ = this\n  return $$.d3.max($$.data.targets, function(t) {\n    return t.values.length\n  })\n}\nChartInternal.prototype.mapToIds = function(targets) {\n  return targets.map(function(d) {\n    return d.id\n  })\n}\nChartInternal.prototype.mapToTargetIds = function(ids) {\n  var $$ = this\n  return ids ? [].concat(ids) : $$.mapToIds($$.data.targets)\n}\nChartInternal.prototype.hasTarget = function(targets, id) {\n  var ids = this.mapToIds(targets),\n    i\n  for (i = 0; i < ids.length; i++) {\n    if (ids[i] === id) {\n      return true\n    }\n  }\n  return false\n}\nChartInternal.prototype.isTargetToShow = function(targetId) {\n  return this.hiddenTargetIds.indexOf(targetId) < 0\n}\nChartInternal.prototype.isLegendToShow = function(targetId) {\n  return this.hiddenLegendIds.indexOf(targetId) < 0\n}\n\n/**\n * Returns only visible targets.\n *\n * This is the same as calling {@link filterTargetsToShow} on $$.data.targets.\n *\n * @return {Array}\n */\nChartInternal.prototype.getTargetsToShow = function() {\n  const $$ = this\n  return $$.filterTargetsToShow($$.data.targets)\n}\n\nChartInternal.prototype.filterTargetsToShow = function(targets) {\n  var $$ = this\n  return targets.filter(function(t) {\n    return $$.isTargetToShow(t.id)\n  })\n}\n\n/**\n * @return {Array} Returns all the targets attached to the chart, visible or not\n */\nChartInternal.prototype.getTargets = function() {\n  const $$ = this\n  return $$.data.targets\n}\n\nChartInternal.prototype.mapTargetsToUniqueXs = function(targets) {\n  var $$ = this\n  var xs = $$.d3\n    .set(\n      $$.d3.merge(\n        targets.map(function(t) {\n          return t.values.map(function(v) {\n            return +v.x\n          })\n        })\n      )\n    )\n    .values()\n  xs = $$.isTimeSeries()\n    ? xs.map(function(x) {\n        return new Date(+x)\n      })\n    : xs.map(function(x) {\n        return +x\n      })\n  return xs.sort(function(a, b) {\n    return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN\n  })\n}\nChartInternal.prototype.addHiddenTargetIds = function(targetIds) {\n  targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds)\n  for (var i = 0; i < targetIds.length; i++) {\n    if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) {\n      this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i])\n    }\n  }\n  this.resetCache()\n}\nChartInternal.prototype.removeHiddenTargetIds = function(targetIds) {\n  this.hiddenTargetIds = this.hiddenTargetIds.filter(function(id) {\n    return targetIds.indexOf(id) < 0\n  })\n  this.resetCache()\n}\nChartInternal.prototype.addHiddenLegendIds = function(targetIds) {\n  targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds)\n  for (var i = 0; i < targetIds.length; i++) {\n    if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) {\n      this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i])\n    }\n  }\n}\nChartInternal.prototype.removeHiddenLegendIds = function(targetIds) {\n  this.hiddenLegendIds = this.hiddenLegendIds.filter(function(id) {\n    return targetIds.indexOf(id) < 0\n  })\n}\nChartInternal.prototype.getValuesAsIdKeyed = function(targets) {\n  var ys = {}\n  targets.forEach(function(t) {\n    ys[t.id] = []\n    t.values.forEach(function(v) {\n      ys[t.id].push(v.value)\n    })\n  })\n  return ys\n}\nChartInternal.prototype.checkValueInTargets = function(targets, checker) {\n  var ids = Object.keys(targets),\n    i,\n    j,\n    values\n  for (i = 0; i < ids.length; i++) {\n    values = targets[ids[i]].values\n    for (j = 0; j < values.length; j++) {\n      if (checker(values[j].value)) {\n        return true\n      }\n    }\n  }\n  return false\n}\nChartInternal.prototype.hasNegativeValueInTargets = function(targets) {\n  return this.checkValueInTargets(targets, function(v) {\n    return v < 0\n  })\n}\nChartInternal.prototype.hasPositiveValueInTargets = function(targets) {\n  return this.checkValueInTargets(targets, function(v) {\n    return v > 0\n  })\n}\nChartInternal.prototype.isOrderDesc = function() {\n  var config = this.config\n  return (\n    typeof config.data_order === 'string' &&\n    config.data_order.toLowerCase() === 'desc'\n  )\n}\nChartInternal.prototype.isOrderAsc = function() {\n  var config = this.config\n  return (\n    typeof config.data_order === 'string' &&\n    config.data_order.toLowerCase() === 'asc'\n  )\n}\nChartInternal.prototype.getOrderFunction = function() {\n  var $$ = this,\n    config = $$.config,\n    orderAsc = $$.isOrderAsc(),\n    orderDesc = $$.isOrderDesc()\n  if (orderAsc || orderDesc) {\n    var reducer = function(p, c) {\n      return p + Math.abs(c.value)\n    }\n    return function(t1, t2) {\n      var t1Sum = t1.values.reduce(reducer, 0),\n        t2Sum = t2.values.reduce(reducer, 0)\n      return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum\n    }\n  } else if (isFunction(config.data_order)) {\n    return config.data_order\n  } else if (isArray(config.data_order)) {\n    var order = config.data_order\n    return function(t1, t2) {\n      return order.indexOf(t1.id) - order.indexOf(t2.id)\n    }\n  }\n}\nChartInternal.prototype.orderTargets = function(targets) {\n  var fct = this.getOrderFunction()\n  if (fct) {\n    targets.sort(fct)\n  }\n  return targets\n}\n\n/**\n * Returns all the values from the given targets at the given index.\n *\n * @param {Array} targets\n * @param {Number} index\n * @return {Array}\n */\nChartInternal.prototype.filterByIndex = function(targets, index) {\n  return this.d3.merge(\n    targets.map(t => t.values.filter(v => v.index === index))\n  )\n}\n\nChartInternal.prototype.filterByX = function(targets, x) {\n  return this.d3\n    .merge(\n      targets.map(function(t) {\n        return t.values\n      })\n    )\n    .filter(function(v) {\n      return v.x - x === 0\n    })\n}\nChartInternal.prototype.filterRemoveNull = function(data) {\n  return data.filter(function(d) {\n    return isValue(d.value)\n  })\n}\nChartInternal.prototype.filterByXDomain = function(targets, xDomain) {\n  return targets.map(function(t) {\n    return {\n      id: t.id,\n      id_org: t.id_org,\n      values: t.values.filter(function(v) {\n        return xDomain[0] <= v.x && v.x <= xDomain[1]\n      })\n    }\n  })\n}\nChartInternal.prototype.hasDataLabel = function() {\n  var config = this.config\n  if (typeof config.data_labels === 'boolean' && config.data_labels) {\n    return true\n  } else if (\n    typeof config.data_labels === 'object' &&\n    notEmpty(config.data_labels)\n  ) {\n    return true\n  }\n  return false\n}\nChartInternal.prototype.getDataLabelLength = function(min, max, key) {\n  var $$ = this,\n    lengths = [0, 0],\n    paddingCoef = 1.3\n  $$.selectChart\n    .select('svg')\n    .selectAll('.dummy')\n    .data([min, max])\n    .enter()\n    .append('text')\n    .text(function(d) {\n      return $$.dataLabelFormat(d.id)(d)\n    })\n    .each(function(d, i) {\n      lengths[i] = getBBox(this)[key] * paddingCoef\n    })\n    .remove()\n  return lengths\n}\n/**\n * Returns true if the given data point is not arc type, otherwise false.\n * @param {Object} d The data point\n * @return {boolean}\n */\nChartInternal.prototype.isNoneArc = function(d) {\n  return this.hasTarget(this.data.targets, d.id)\n}\n\n/**\n * Returns true if the given data point is arc type, otherwise false.\n * @param {Object} d The data point\n * @return {boolean}\n */\nChartInternal.prototype.isArc = function(d) {\n  return 'data' in d && this.hasTarget(this.data.targets, d.data.id)\n}\n\n/**\n * Find the closest point from the given pos among the given targets or\n * undefined if none satisfies conditions.\n *\n * @param {Array} targets\n * @param {Array} pos An [x,y] coordinate\n * @return {Object|undefined}\n */\nChartInternal.prototype.findClosestFromTargets = function(targets, pos) {\n  const $$ = this\n\n  // for each target, find the closest point\n  const candidates = targets\n    .map(t =>\n      $$.findClosest(\n        t.values,\n        pos,\n        $$.config.tooltip_horizontal\n          ? $$.horizontalDistance.bind($$)\n          : $$.dist.bind($$),\n        $$.config.point_sensitivity\n      )\n    )\n    .filter(v => v)\n\n  // returns the closest of candidates\n  if (candidates.length === 0) {\n    return undefined\n  } else if (candidates.length === 1) {\n    return candidates[0]\n  } else {\n    return $$.findClosest(candidates, pos, $$.dist.bind($$))\n  }\n}\n\n/**\n * Find the closest point from the x value or undefined if none satisfies conditions.\n *\n * @param {Array} targets\n * @param {Array} x A value on X axis\n * @return {Object|undefined}\n */\nChartInternal.prototype.findClosestFromTargetsByX = function(targets, x) {\n  let closest\n  let diff\n\n  targets.forEach(t => {\n    t.values.forEach(d => {\n      let newDiff = Math.abs(x - d.x)\n\n      if (diff === undefined || newDiff < diff) {\n        closest = d\n        diff = newDiff\n      }\n    })\n  })\n\n  return closest\n}\n\n/**\n * Using given compute distance method, returns the closest data point from the\n * given position.\n *\n * Giving optionally a minimum distance to satisfy.\n *\n * @param {Array} dataPoints List of DataPoints\n * @param {Array} pos An [x,y] coordinate\n * @param {Function} computeDist Function to compute distance between 2 points\n * @param {Number} minDist Minimal distance to satisfy\n * @return {Object|undefined} Closest data point\n */\nChartInternal.prototype.findClosest = function(\n  dataPoints,\n  pos,\n  computeDist,\n  minDist = Infinity\n) {\n  const $$ = this\n\n  let closest\n\n  // find closest bar\n  dataPoints\n    .filter(v => v && $$.isBarType(v.id))\n    .forEach(function(v) {\n      if (!closest) {\n        const shape = $$.main\n          .select(\n            '.' +\n              CLASS.bars +\n              $$.getTargetSelectorSuffix(v.id) +\n              ' .' +\n              CLASS.bar +\n              '-' +\n              v.index\n          )\n          .node()\n        if ($$.isWithinBar(pos, shape)) {\n          closest = v\n        }\n      }\n    })\n\n  // find closest point from non-bar\n  dataPoints\n    .filter(v => v && !$$.isBarType(v.id))\n    .forEach(v => {\n      let d = computeDist(v, pos)\n      if (d < minDist) {\n        minDist = d\n        closest = v\n      }\n    })\n\n  return closest\n}\nChartInternal.prototype.dist = function(data, pos) {\n  var $$ = this,\n    config = $$.config,\n    xIndex = config.axis_rotated ? 1 : 0,\n    yIndex = config.axis_rotated ? 0 : 1,\n    y = $$.circleY(data, data.index),\n    x = $$.x(data.x)\n  return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2))\n}\nChartInternal.prototype.horizontalDistance = function(data, pos) {\n  var $$ = this,\n    config = $$.config,\n    xIndex = config.axis_rotated ? 1 : 0,\n    x = $$.x(data.x)\n\n  return Math.abs(x - pos[xIndex])\n}\nChartInternal.prototype.convertValuesToStep = function(values) {\n  var converted = [].concat(values),\n    i\n\n  if (!this.isCategorized()) {\n    return values\n  }\n\n  for (i = values.length + 1; 0 < i; i--) {\n    converted[i] = converted[i - 1]\n  }\n\n  converted[0] = {\n    x: converted[0].x - 1,\n    value: converted[0].value,\n    id: converted[0].id\n  }\n  converted[values.length + 1] = {\n    x: converted[values.length].x + 1,\n    value: converted[values.length].value,\n    id: converted[values.length].id\n  }\n\n  return converted\n}\n\n/**\n * Get ratio value\n *\n * @param {String} type Ratio for given type\n * @param {Object} d Data value object\n * @param {Boolean} asPercent Convert the return as percent or not\n * @return {Number} Ratio value\n * @private\n */\nChartInternal.prototype.getRatio = function(type, d, asPercent = false) {\n  const $$ = this\n  const api = $$.api\n  let ratio = 0\n\n  if (d && api.data.shown.call(api).length) {\n    ratio = d.ratio || d.value\n\n    if (type === 'arc') {\n      if ($$.hasType('gauge')) {\n        ratio =\n          (d.endAngle - d.startAngle) /\n          (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1))\n      } else {\n        const total = $$.getTotalDataSum()\n\n        ratio = d.value / total\n      }\n    } else if (type === 'index') {\n      const total = $$.getTotalPerIndex($$.axis.getId(d.id))\n\n      d.ratio =\n        isNumber(d.value) && total && total[d.index] > 0\n          ? d.value / total[d.index]\n          : 0\n\n      ratio = d.ratio\n    }\n  }\n\n  return asPercent && ratio ? ratio * 100 : ratio\n}\n\nChartInternal.prototype.updateDataAttributes = function(name, attrs) {\n  var $$ = this,\n    config = $$.config,\n    current = config['data_' + name]\n  if (typeof attrs === 'undefined') {\n    return current\n  }\n  Object.keys(attrs).forEach(function(id) {\n    current[id] = attrs[id]\n  })\n  $$.redraw({\n    withLegend: true\n  })\n  return current\n}\n"
  },
  {
    "path": "src/domain.ts",
    "content": "import { ChartInternal } from './core'\nimport { isValue, isDefined, diffDomain, notEmpty } from './util'\n\nChartInternal.prototype.getYDomainMin = function(targets) {\n  var $$ = this,\n    config = $$.config,\n    ids = $$.mapToIds(targets),\n    ys = $$.getValuesAsIdKeyed(targets),\n    j,\n    k,\n    baseId,\n    idsInGroup,\n    id,\n    hasNegativeValue\n  if (config.data_groups.length > 0) {\n    hasNegativeValue = $$.hasNegativeValueInTargets(targets)\n    for (j = 0; j < config.data_groups.length; j++) {\n      // Determine baseId\n      idsInGroup = config.data_groups[j].filter(function(id) {\n        return ids.indexOf(id) >= 0\n      })\n      if (idsInGroup.length === 0) {\n        continue\n      }\n      baseId = idsInGroup[0]\n      // Consider negative values\n      if (hasNegativeValue && ys[baseId]) {\n        ys[baseId].forEach(function(v, i) {\n          ys[baseId][i] = v < 0 ? v : 0\n        })\n      }\n      // Compute min\n      for (k = 1; k < idsInGroup.length; k++) {\n        id = idsInGroup[k]\n        if (!ys[id]) {\n          continue\n        }\n        ys[id].forEach(function(v, i) {\n          if (\n            $$.axis.getId(id) === $$.axis.getId(baseId) &&\n            ys[baseId] &&\n            !(hasNegativeValue && +v > 0)\n          ) {\n            ys[baseId][i] += +v\n          }\n        })\n      }\n    }\n  }\n  return $$.d3.min(\n    Object.keys(ys).map(function(key) {\n      return $$.d3.min(ys[key])\n    })\n  )\n}\nChartInternal.prototype.getYDomainMax = function(targets) {\n  var $$ = this,\n    config = $$.config,\n    ids = $$.mapToIds(targets),\n    ys = $$.getValuesAsIdKeyed(targets),\n    j,\n    k,\n    baseId,\n    idsInGroup,\n    id,\n    hasPositiveValue\n  if (config.data_groups.length > 0) {\n    hasPositiveValue = $$.hasPositiveValueInTargets(targets)\n    for (j = 0; j < config.data_groups.length; j++) {\n      // Determine baseId\n      idsInGroup = config.data_groups[j].filter(function(id) {\n        return ids.indexOf(id) >= 0\n      })\n      if (idsInGroup.length === 0) {\n        continue\n      }\n      baseId = idsInGroup[0]\n      // Consider positive values\n      if (hasPositiveValue && ys[baseId]) {\n        ys[baseId].forEach(function(v, i) {\n          ys[baseId][i] = v > 0 ? v : 0\n        })\n      }\n      // Compute max\n      for (k = 1; k < idsInGroup.length; k++) {\n        id = idsInGroup[k]\n        if (!ys[id]) {\n          continue\n        }\n        ys[id].forEach(function(v, i) {\n          if (\n            $$.axis.getId(id) === $$.axis.getId(baseId) &&\n            ys[baseId] &&\n            !(hasPositiveValue && +v < 0)\n          ) {\n            ys[baseId][i] += +v\n          }\n        })\n      }\n    }\n  }\n  return $$.d3.max(\n    Object.keys(ys).map(function(key) {\n      return $$.d3.max(ys[key])\n    })\n  )\n}\nChartInternal.prototype.getYDomain = function(targets, axisId, xDomain) {\n  var $$ = this,\n    config = $$.config\n\n  if ($$.isAxisNormalized(axisId)) {\n    return [0, 100]\n  }\n\n  var targetsByAxisId = targets.filter(function(t) {\n      return $$.axis.getId(t.id) === axisId\n    }),\n    yTargets = xDomain\n      ? $$.filterByXDomain(targetsByAxisId, xDomain)\n      : targetsByAxisId,\n    yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min,\n    yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max,\n    yDomainMin = $$.getYDomainMin(yTargets),\n    yDomainMax = $$.getYDomainMax(yTargets),\n    domain,\n    domainLength,\n    padding_top,\n    padding_bottom,\n    center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center,\n    yDomainAbs,\n    lengths,\n    diff,\n    ratio,\n    isAllPositive,\n    isAllNegative,\n    isZeroBased =\n      ($$.hasType('bar', yTargets) && config.bar_zerobased) ||\n      ($$.hasType('area', yTargets) && config.area_zerobased),\n    isInverted =\n      axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted,\n    showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated,\n    showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated\n\n  // MEMO: avoid inverting domain unexpectedly\n  yDomainMin = isValue(yMin)\n    ? yMin\n    : isValue(yMax)\n    ? yDomainMin < yMax\n      ? yDomainMin\n      : yMax - 10\n    : yDomainMin\n  yDomainMax = isValue(yMax)\n    ? yMax\n    : isValue(yMin)\n    ? yMin < yDomainMax\n      ? yDomainMax\n      : yMin + 10\n    : yDomainMax\n\n  if (yTargets.length === 0) {\n    // use current domain if target of axisId is none\n    return axisId === 'y2' ? $$.y2.domain() : $$.y.domain()\n  }\n  if (isNaN(yDomainMin)) {\n    // set minimum to zero when not number\n    yDomainMin = 0\n  }\n  if (isNaN(yDomainMax)) {\n    // set maximum to have same value as yDomainMin\n    yDomainMax = yDomainMin\n  }\n  if (yDomainMin === yDomainMax) {\n    yDomainMin < 0 ? (yDomainMax = 0) : (yDomainMin = 0)\n  }\n  isAllPositive = yDomainMin >= 0 && yDomainMax >= 0\n  isAllNegative = yDomainMin <= 0 && yDomainMax <= 0\n\n  // Cancel zerobased if axis_*_min / axis_*_max specified\n  if ((isValue(yMin) && isAllPositive) || (isValue(yMax) && isAllNegative)) {\n    isZeroBased = false\n  }\n\n  // Bar/Area chart should be 0-based if all positive|negative\n  if (isZeroBased) {\n    if (isAllPositive) {\n      yDomainMin = 0\n    }\n    if (isAllNegative) {\n      yDomainMax = 0\n    }\n  }\n\n  domainLength = Math.abs(yDomainMax - yDomainMin)\n  padding_top = padding_bottom = domainLength * 0.1\n\n  if (typeof center !== 'undefined') {\n    yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax))\n    yDomainMax = center + yDomainAbs\n    yDomainMin = center - yDomainAbs\n  }\n  // add padding for data label\n  if (showHorizontalDataLabel) {\n    lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width')\n    diff = diffDomain($$.y.range())\n    ratio = [lengths[0] / diff, lengths[1] / diff]\n    padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1]))\n    padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1]))\n  } else if (showVerticalDataLabel) {\n    lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height')\n\n    const pixelsToAxisPadding = $$.getY(\n      config[`axis_${axisId}_type`],\n      // input domain as pixels\n      [0, config.axis_rotated ? $$.width : $$.height],\n      // output range as axis padding\n      [0, domainLength]\n    )\n\n    padding_top += pixelsToAxisPadding(lengths[1])\n    padding_bottom += pixelsToAxisPadding(lengths[0])\n  }\n  if (axisId === 'y' && notEmpty(config.axis_y_padding)) {\n    padding_top = $$.axis.getPadding(\n      config.axis_y_padding,\n      'top',\n      padding_top,\n      domainLength\n    )\n    padding_bottom = $$.axis.getPadding(\n      config.axis_y_padding,\n      'bottom',\n      padding_bottom,\n      domainLength\n    )\n  }\n  if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) {\n    padding_top = $$.axis.getPadding(\n      config.axis_y2_padding,\n      'top',\n      padding_top,\n      domainLength\n    )\n    padding_bottom = $$.axis.getPadding(\n      config.axis_y2_padding,\n      'bottom',\n      padding_bottom,\n      domainLength\n    )\n  }\n  // Bar/Area chart should be 0-based if all positive|negative\n  if (isZeroBased) {\n    if (isAllPositive) {\n      padding_bottom = yDomainMin\n    }\n    if (isAllNegative) {\n      padding_top = -yDomainMax\n    }\n  }\n  domain = [yDomainMin - padding_bottom, yDomainMax + padding_top]\n  return isInverted ? domain.reverse() : domain\n}\nChartInternal.prototype.getXDomainMin = function(targets) {\n  var $$ = this,\n    config = $$.config\n  return isDefined(config.axis_x_min)\n    ? $$.isTimeSeries()\n      ? this.parseDate(config.axis_x_min)\n      : config.axis_x_min\n    : $$.d3.min(targets, function(t) {\n        return $$.d3.min(t.values, function(v) {\n          return v.x\n        })\n      })\n}\nChartInternal.prototype.getXDomainMax = function(targets) {\n  var $$ = this,\n    config = $$.config\n  return isDefined(config.axis_x_max)\n    ? $$.isTimeSeries()\n      ? this.parseDate(config.axis_x_max)\n      : config.axis_x_max\n    : $$.d3.max(targets, function(t) {\n        return $$.d3.max(t.values, function(v) {\n          return v.x\n        })\n      })\n}\nChartInternal.prototype.getXDomainPadding = function(domain) {\n  var $$ = this,\n    config = $$.config,\n    diff = domain[1] - domain[0],\n    maxDataCount,\n    padding,\n    paddingLeft,\n    paddingRight\n  if ($$.isCategorized()) {\n    padding = 0\n  } else if ($$.hasType('bar')) {\n    maxDataCount = $$.getMaxDataCount()\n    padding = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : 0.5\n  } else {\n    padding = diff * 0.01\n  }\n  if (\n    typeof config.axis_x_padding === 'object' &&\n    notEmpty(config.axis_x_padding)\n  ) {\n    paddingLeft = isValue(config.axis_x_padding.left)\n      ? config.axis_x_padding.left\n      : padding\n    paddingRight = isValue(config.axis_x_padding.right)\n      ? config.axis_x_padding.right\n      : padding\n  } else if (typeof config.axis_x_padding === 'number') {\n    paddingLeft = paddingRight = config.axis_x_padding\n  } else {\n    paddingLeft = paddingRight = padding\n  }\n  return { left: paddingLeft, right: paddingRight }\n}\nChartInternal.prototype.getXDomain = function(targets) {\n  var $$ = this,\n    xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)],\n    firstX = xDomain[0],\n    lastX = xDomain[1],\n    padding = $$.getXDomainPadding(xDomain),\n    min: Date | number = 0,\n    max: Date | number = 0\n  // show center of x domain if min and max are the same\n  if (firstX - lastX === 0 && !$$.isCategorized()) {\n    if ($$.isTimeSeries()) {\n      firstX = new Date(firstX.getTime() * 0.5)\n      lastX = new Date(lastX.getTime() * 1.5)\n    } else {\n      firstX = firstX === 0 ? 1 : firstX * 0.5\n      lastX = lastX === 0 ? -1 : lastX * 1.5\n    }\n  }\n  if (firstX || firstX === 0) {\n    min = $$.isTimeSeries()\n      ? new Date(firstX.getTime() - padding.left)\n      : firstX - padding.left\n  }\n  if (lastX || lastX === 0) {\n    max = $$.isTimeSeries()\n      ? new Date(lastX.getTime() + padding.right)\n      : lastX + padding.right\n  }\n  return [min, max]\n}\nChartInternal.prototype.updateXDomain = function(\n  targets,\n  withUpdateXDomain,\n  withUpdateOrgXDomain,\n  withTrim,\n  domain\n) {\n  var $$ = this,\n    config = $$.config\n\n  if (withUpdateOrgXDomain) {\n    $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets)))\n    $$.orgXDomain = $$.x.domain()\n    if (config.zoom_enabled) {\n      $$.zoom.update()\n    }\n    $$.subX.domain($$.x.domain())\n    if ($$.brush) {\n      $$.brush.updateScale($$.subX)\n    }\n  }\n  if (withUpdateXDomain) {\n    $$.x.domain(\n      domain\n        ? domain\n        : !$$.brush || $$.brush.empty()\n        ? $$.orgXDomain\n        : $$.brush.selectionAsValue()\n    )\n  }\n\n  // Trim domain when too big by zoom mousemove event\n  if (withTrim) {\n    $$.x.domain($$.trimXDomain($$.x.orgDomain()))\n  }\n\n  return $$.x.domain()\n}\nChartInternal.prototype.trimXDomain = function(domain) {\n  var zoomDomain = this.getZoomDomain(),\n    min = zoomDomain[0],\n    max = zoomDomain[1]\n  if (domain[0] <= min) {\n    domain[1] = +domain[1] + (min - domain[0])\n    domain[0] = min\n  }\n  if (max <= domain[1]) {\n    domain[0] = +domain[0] - (domain[1] - max)\n    domain[1] = max\n  }\n  return domain\n}\n"
  },
  {
    "path": "src/drag.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport { getPathBox } from './util'\n\nChartInternal.prototype.drag = function(mouse) {\n  var $$ = this,\n    config = $$.config,\n    main = $$.main,\n    d3 = $$.d3\n  var sx, sy, mx, my, minX, maxX, minY, maxY\n\n  if ($$.hasArcType()) {\n    return\n  }\n  if (!config.data_selection_enabled) {\n    return\n  } // do nothing if not selectable\n  if (!config.data_selection_multiple) {\n    return\n  } // skip when single selection because drag is used for multiple selection\n\n  sx = $$.dragStart[0]\n  sy = $$.dragStart[1]\n  mx = mouse[0]\n  my = mouse[1]\n  minX = Math.min(sx, mx)\n  maxX = Math.max(sx, mx)\n  minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my)\n  maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my)\n\n  main\n    .select('.' + CLASS.dragarea)\n    .attr('x', minX)\n    .attr('y', minY)\n    .attr('width', maxX - minX)\n    .attr('height', maxY - minY)\n  // TODO: binary search when multiple xs\n  main\n    .selectAll('.' + CLASS.shapes)\n    .selectAll('.' + CLASS.shape)\n    .each(function(d, i) {\n      if (!config.data_selection_isselectable(d)) {\n        return\n      }\n      var shape = d3.select(this),\n        isSelected = shape.classed(CLASS.SELECTED),\n        isIncluded = shape.classed(CLASS.INCLUDED),\n        _x,\n        _y,\n        _w,\n        _h,\n        toggle,\n        isWithin = false,\n        box\n      if (shape.classed(CLASS.circle)) {\n        _x = shape.attr('cx') * 1\n        _y = shape.attr('cy') * 1\n        toggle = $$.togglePoint\n        isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY\n      } else if (shape.classed(CLASS.bar)) {\n        box = getPathBox(this)\n        _x = box.x\n        _y = box.y\n        _w = box.width\n        _h = box.height\n        toggle = $$.togglePath\n        isWithin =\n          !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY)\n      } else {\n        // line/area selection not supported yet\n        return\n      }\n      if ((isWithin as any) ^ isIncluded) {\n        shape.classed(CLASS.INCLUDED, !isIncluded)\n        // TODO: included/unincluded callback here\n        shape.classed(CLASS.SELECTED, !isSelected)\n        toggle.call($$, !isSelected, shape, d, i)\n      }\n    })\n}\n\nChartInternal.prototype.dragstart = function(mouse) {\n  var $$ = this,\n    config = $$.config\n  if ($$.hasArcType()) {\n    return\n  }\n  if (!config.data_selection_enabled) {\n    return\n  } // do nothing if not selectable\n  $$.dragStart = mouse\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('rect')\n    .attr('class', CLASS.dragarea)\n    .style('opacity', 0.1)\n  $$.dragging = true\n}\n\nChartInternal.prototype.dragend = function() {\n  var $$ = this,\n    config = $$.config\n  if ($$.hasArcType()) {\n    return\n  }\n  if (!config.data_selection_enabled) {\n    return\n  } // do nothing if not selectable\n  $$.main\n    .select('.' + CLASS.dragarea)\n    .transition()\n    .duration(100)\n    .style('opacity', 0)\n    .remove()\n  $$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false)\n  $$.dragging = false\n}\n"
  },
  {
    "path": "src/format.ts",
    "content": "import { ChartInternal } from './core'\nimport { isValue } from './util'\n\nChartInternal.prototype.getYFormat = function(forArc) {\n  var $$ = this,\n    formatForY =\n      forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat,\n    formatForY2 =\n      forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format\n  return function(v, ratio, id) {\n    var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY\n    return format.call($$, v, ratio)\n  }\n}\nChartInternal.prototype.yFormat = function(v) {\n  var $$ = this,\n    config = $$.config,\n    format = config.axis_y_tick_format\n      ? config.axis_y_tick_format\n      : $$.defaultValueFormat\n  return format(v)\n}\nChartInternal.prototype.y2Format = function(v) {\n  var $$ = this,\n    config = $$.config,\n    format = config.axis_y2_tick_format\n      ? config.axis_y2_tick_format\n      : $$.defaultValueFormat\n  return format(v)\n}\nChartInternal.prototype.defaultValueFormat = function(v) {\n  return isValue(v) ? +v : ''\n}\nChartInternal.prototype.defaultArcValueFormat = function(v, ratio) {\n  return (ratio * 100).toFixed(1) + '%'\n}\nChartInternal.prototype.dataLabelFormat = function(targetId) {\n  var $$ = this,\n    data_labels = $$.config.data_labels,\n    format,\n    defaultFormat = function(v) {\n      return isValue(v) ? +v : ''\n    }\n  // find format according to axis id\n  if (typeof data_labels.format === 'function') {\n    format = data_labels.format\n  } else if (typeof data_labels.format === 'object') {\n    if (data_labels.format[targetId]) {\n      format =\n        data_labels.format[targetId] === true\n          ? defaultFormat\n          : data_labels.format[targetId]\n    } else {\n      format = function() {\n        return ''\n      }\n    }\n  } else {\n    format = defaultFormat\n  }\n  return format\n}\n"
  },
  {
    "path": "src/grid.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport { isValue } from './util'\n\nChartInternal.prototype.initGrid = function() {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3\n  $$.grid = $$.main\n    .append('g')\n    .attr('clip-path', $$.clipPathForGrid)\n    .attr('class', CLASS.grid)\n  if (config.grid_x_show) {\n    $$.grid.append('g').attr('class', CLASS.xgrids)\n  }\n  if (config.grid_y_show) {\n    $$.grid.append('g').attr('class', CLASS.ygrids)\n  }\n  if (config.grid_focus_show) {\n    $$.grid\n      .append('g')\n      .attr('class', CLASS.xgridFocus)\n      .append('line')\n      .attr('class', CLASS.xgridFocus)\n  }\n  $$.xgrid = d3.selectAll([])\n  if (!config.grid_lines_front) {\n    $$.initGridLines()\n  }\n}\nChartInternal.prototype.initGridLines = function() {\n  var $$ = this,\n    d3 = $$.d3\n  $$.gridLines = $$.main\n    .append('g')\n    .attr('clip-path', $$.clipPathForGrid)\n    .attr('class', CLASS.grid + ' ' + CLASS.gridLines)\n  $$.gridLines.append('g').attr('class', CLASS.xgridLines)\n  $$.gridLines.append('g').attr('class', CLASS.ygridLines)\n  $$.xgridLines = d3.selectAll([])\n}\nChartInternal.prototype.updateXGrid = function(withoutUpdate) {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3,\n    xgridData = $$.generateGridData(config.grid_x_type, $$.x),\n    tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0\n\n  $$.xgridAttr = config.axis_rotated\n    ? {\n        x1: 0,\n        x2: $$.width,\n        y1: function(d) {\n          return $$.x(d) - tickOffset\n        },\n        y2: function(d) {\n          return $$.x(d) - tickOffset\n        }\n      }\n    : {\n        x1: function(d) {\n          return $$.x(d) + tickOffset\n        },\n        x2: function(d) {\n          return $$.x(d) + tickOffset\n        },\n        y1: 0,\n        y2: $$.height\n      }\n  $$.xgridAttr.opacity = function() {\n    var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1')\n    return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1\n  }\n\n  var xgrid = $$.main\n    .select('.' + CLASS.xgrids)\n    .selectAll('.' + CLASS.xgrid)\n    .data(xgridData)\n  var xgridEnter = xgrid\n    .enter()\n    .append('line')\n    .attr('class', CLASS.xgrid)\n    .attr('x1', $$.xgridAttr.x1)\n    .attr('x2', $$.xgridAttr.x2)\n    .attr('y1', $$.xgridAttr.y1)\n    .attr('y2', $$.xgridAttr.y2)\n    .style('opacity', 0)\n  $$.xgrid = xgridEnter.merge(xgrid)\n  if (!withoutUpdate) {\n    $$.xgrid\n      .attr('x1', $$.xgridAttr.x1)\n      .attr('x2', $$.xgridAttr.x2)\n      .attr('y1', $$.xgridAttr.y1)\n      .attr('y2', $$.xgridAttr.y2)\n      .style('opacity', $$.xgridAttr.opacity)\n  }\n  xgrid.exit().remove()\n}\n\nChartInternal.prototype.updateYGrid = function() {\n  var $$ = this,\n    config = $$.config,\n    gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks)\n  var ygrid = $$.main\n    .select('.' + CLASS.ygrids)\n    .selectAll('.' + CLASS.ygrid)\n    .data(gridValues)\n  var ygridEnter = ygrid\n    .enter()\n    .append('line')\n    // TODO: x1, x2, y1, y2, opacity need to be set here maybe\n    .attr('class', CLASS.ygrid)\n  $$.ygrid = ygridEnter.merge(ygrid)\n  $$.ygrid\n    .attr('x1', config.axis_rotated ? $$.y : 0)\n    .attr('x2', config.axis_rotated ? $$.y : $$.width)\n    .attr('y1', config.axis_rotated ? 0 : $$.y)\n    .attr('y2', config.axis_rotated ? $$.height : $$.y)\n  ygrid.exit().remove()\n  $$.smoothLines($$.ygrid, 'grid')\n}\n\nChartInternal.prototype.gridTextAnchor = function(d) {\n  return d.position ? d.position : 'end'\n}\nChartInternal.prototype.gridTextDx = function(d) {\n  return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4\n}\nChartInternal.prototype.xGridTextX = function(d) {\n  return d.position === 'start'\n    ? -this.height\n    : d.position === 'middle'\n    ? -this.height / 2\n    : 0\n}\nChartInternal.prototype.yGridTextX = function(d) {\n  return d.position === 'start'\n    ? 0\n    : d.position === 'middle'\n    ? this.width / 2\n    : this.width\n}\nChartInternal.prototype.updateGrid = function(duration) {\n  var $$ = this,\n    main = $$.main,\n    config = $$.config,\n    xgridLine,\n    xgridLineEnter,\n    ygridLine,\n    ygridLineEnter,\n    xv = $$.xv.bind($$),\n    yv = $$.yv.bind($$),\n    xGridTextX = $$.xGridTextX.bind($$),\n    yGridTextX = $$.yGridTextX.bind($$)\n\n  // hide if arc type\n  $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible')\n\n  main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden')\n  if (config.grid_x_show) {\n    $$.updateXGrid()\n  }\n  xgridLine = main\n    .select('.' + CLASS.xgridLines)\n    .selectAll('.' + CLASS.xgridLine)\n    .data(config.grid_x_lines)\n  // enter\n  xgridLineEnter = xgridLine\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : '')\n    })\n  xgridLineEnter\n    .append('line')\n    .attr('x1', config.axis_rotated ? 0 : xv)\n    .attr('x2', config.axis_rotated ? $$.width : xv)\n    .attr('y1', config.axis_rotated ? xv : 0)\n    .attr('y2', config.axis_rotated ? xv : $$.height)\n    .style('opacity', 0)\n  xgridLineEnter\n    .append('text')\n    .attr('text-anchor', $$.gridTextAnchor)\n    .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')\n    .attr('x', config.axis_rotated ? yGridTextX : xGridTextX)\n    .attr('y', xv)\n    .attr('dx', $$.gridTextDx)\n    .attr('dy', -5)\n    .style('opacity', 0)\n  // udpate\n  $$.xgridLines = xgridLineEnter.merge(xgridLine)\n  // done in d3.transition() of the end of this function\n  // exit\n  xgridLine\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove()\n\n  // Y-Grid\n  if (config.grid_y_show) {\n    $$.updateYGrid()\n  }\n  ygridLine = main\n    .select('.' + CLASS.ygridLines)\n    .selectAll('.' + CLASS.ygridLine)\n    .data(config.grid_y_lines)\n  // enter\n  ygridLineEnter = ygridLine\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : '')\n    })\n  ygridLineEnter\n    .append('line')\n    .attr('x1', config.axis_rotated ? yv : 0)\n    .attr('x2', config.axis_rotated ? yv : $$.width)\n    .attr('y1', config.axis_rotated ? 0 : yv)\n    .attr('y2', config.axis_rotated ? $$.height : yv)\n    .style('opacity', 0)\n  ygridLineEnter\n    .append('text')\n    .attr('text-anchor', $$.gridTextAnchor)\n    .attr('transform', config.axis_rotated ? 'rotate(-90)' : '')\n    .attr('x', config.axis_rotated ? xGridTextX : yGridTextX)\n    .attr('y', yv)\n    .attr('dx', $$.gridTextDx)\n    .attr('dy', -5)\n    .style('opacity', 0)\n  // update\n  $$.ygridLines = ygridLineEnter.merge(ygridLine)\n  $$.ygridLines\n    .select('line')\n    .transition()\n    .duration(duration)\n    .attr('x1', config.axis_rotated ? yv : 0)\n    .attr('x2', config.axis_rotated ? yv : $$.width)\n    .attr('y1', config.axis_rotated ? 0 : yv)\n    .attr('y2', config.axis_rotated ? $$.height : yv)\n    .style('opacity', 1)\n  $$.ygridLines\n    .select('text')\n    .transition()\n    .duration(duration)\n    .attr(\n      'x',\n      config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)\n    )\n    .attr('y', yv)\n    .text(function(d) {\n      return d.text\n    })\n    .style('opacity', 1)\n  // exit\n  ygridLine\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove()\n}\nChartInternal.prototype.redrawGrid = function(withTransition, transition) {\n  var $$ = this,\n    config = $$.config,\n    xv = $$.xv.bind($$),\n    lines = $$.xgridLines.select('line'),\n    texts = $$.xgridLines.select('text')\n  return [\n    (withTransition ? lines.transition(transition) : lines)\n      .attr('x1', config.axis_rotated ? 0 : xv)\n      .attr('x2', config.axis_rotated ? $$.width : xv)\n      .attr('y1', config.axis_rotated ? xv : 0)\n      .attr('y2', config.axis_rotated ? xv : $$.height)\n      .style('opacity', 1),\n    (withTransition ? texts.transition(transition) : texts)\n      .attr(\n        'x',\n        config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)\n      )\n      .attr('y', xv)\n      .text(function(d) {\n        return d.text\n      })\n      .style('opacity', 1)\n  ]\n}\nChartInternal.prototype.showXGridFocus = function(selectedData) {\n  var $$ = this,\n    config = $$.config,\n    dataToShow = selectedData.filter(function(d) {\n      return d && isValue(d.value)\n    }),\n    focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus),\n    xx = $$.xx.bind($$)\n  if (!config.tooltip_show) {\n    return\n  }\n  // Hide when stanford plot exists\n  if ($$.hasType('stanford') || $$.hasArcType()) {\n    return\n  }\n  focusEl\n    .style('visibility', 'visible')\n    .data([dataToShow[0]])\n    .attr(config.axis_rotated ? 'y1' : 'x1', xx)\n    .attr(config.axis_rotated ? 'y2' : 'x2', xx)\n  $$.smoothLines(focusEl, 'grid')\n}\nChartInternal.prototype.hideXGridFocus = function() {\n  this.main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden')\n}\nChartInternal.prototype.updateXgridFocus = function() {\n  var $$ = this,\n    config = $$.config\n  $$.main\n    .select('line.' + CLASS.xgridFocus)\n    .attr('x1', config.axis_rotated ? 0 : -10)\n    .attr('x2', config.axis_rotated ? $$.width : -10)\n    .attr('y1', config.axis_rotated ? -10 : 0)\n    .attr('y2', config.axis_rotated ? -10 : $$.height)\n}\nChartInternal.prototype.generateGridData = function(type, scale) {\n  var $$ = this,\n    gridData = [],\n    xDomain,\n    firstYear,\n    lastYear,\n    i,\n    tickNum = $$.main\n      .select('.' + CLASS.axisX)\n      .selectAll('.tick')\n      .size()\n  if (type === 'year') {\n    xDomain = $$.getXDomain()\n    firstYear = xDomain[0].getFullYear()\n    lastYear = xDomain[1].getFullYear()\n    for (i = firstYear; i <= lastYear; i++) {\n      gridData.push(new Date(i + '-01-01 00:00:00'))\n    }\n  } else {\n    gridData = scale.ticks(10)\n    if (gridData.length > tickNum) {\n      // use only int\n      gridData = gridData.filter(function(d) {\n        return ('' + d).indexOf('.') < 0\n      })\n    }\n  }\n  return gridData\n}\nChartInternal.prototype.getGridFilterToRemove = function(params) {\n  return params\n    ? function(line) {\n        var found = false\n        ;[].concat(params).forEach(function(param) {\n          if (\n            ('value' in param && line.value === param.value) ||\n            ('class' in param && line['class'] === param['class'])\n          ) {\n            found = true\n          }\n        })\n        return found\n      }\n    : function() {\n        return true\n      }\n}\nChartInternal.prototype.removeGridLines = function(params, forX) {\n  var $$ = this,\n    config = $$.config,\n    toRemove = $$.getGridFilterToRemove(params),\n    toShow = function(line) {\n      return !toRemove(line)\n    },\n    classLines = forX ? CLASS.xgridLines : CLASS.ygridLines,\n    classLine = forX ? CLASS.xgridLine : CLASS.ygridLine\n  $$.main\n    .select('.' + classLines)\n    .selectAll('.' + classLine)\n    .filter(toRemove)\n    .transition()\n    .duration(config.transition_duration)\n    .style('opacity', 0)\n    .remove()\n  if (forX) {\n    config.grid_x_lines = config.grid_x_lines.filter(toShow)\n  } else {\n    config.grid_y_lines = config.grid_y_lines.filter(toShow)\n  }\n}\n"
  },
  {
    "path": "src/index.ts",
    "content": "import { c3 } from './core'\n\nimport './polyfill'\nimport './api.axis'\nimport './api.category'\nimport './api.chart'\nimport './api.color'\nimport './api.data'\nimport './api.donut'\nimport './api.flow'\nimport './api.focus'\nimport './api.grid'\nimport './api.group'\nimport './api.legend'\nimport './api.load'\nimport './api.pie'\nimport './api.region'\nimport './api.selection'\nimport './api.show'\nimport './api.subchart'\nimport './api.tooltip'\nimport './api.transform'\nimport './api.x'\nimport './api.zoom'\nimport './arc'\nimport './axis'\nimport './cache'\nimport './category'\nimport './class'\nimport './class-utils'\nimport './clip'\nimport './color'\nimport './config'\nimport './data.convert'\nimport './data'\nimport './data.load'\nimport './domain'\nimport './drag'\nimport './format'\nimport './grid'\nimport './interaction'\nimport './legend'\nimport './region'\nimport './scale'\nimport './selection'\nimport './shape.bar'\nimport './shape'\nimport './shape.line'\nimport './size'\nimport './subchart'\nimport './text'\nimport './title'\nimport './colorscale'\nimport './stanford'\nimport './stanfordelements'\nimport './tooltip'\nimport './type'\nimport './ua'\nimport './util'\nimport './zoom'\n\nexport default c3\n"
  },
  {
    "path": "src/interaction.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\n\nChartInternal.prototype.initEventRect = function() {\n  var $$ = this,\n    config = $$.config\n\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.eventRects)\n    .style('fill-opacity', 0)\n  $$.eventRect = $$.main\n    .select('.' + CLASS.eventRects)\n    .append('rect')\n    .attr('class', CLASS.eventRect)\n\n  // event rect handle zoom event as well\n  if (config.zoom_enabled && $$.zoom) {\n    $$.eventRect.call($$.zoom).on('dblclick.zoom', null)\n    if (config.zoom_initialRange) {\n      // WORKAROUND: Add transition to apply transform immediately when no subchart\n      $$.eventRect\n        .transition()\n        .duration(0)\n        .call($$.zoom.transform, $$.zoomTransform(config.zoom_initialRange))\n    }\n  }\n}\nChartInternal.prototype.redrawEventRect = function() {\n  const $$ = this,\n    d3 = $$.d3,\n    config = $$.config\n\n  function mouseout() {\n    $$.svg.select('.' + CLASS.eventRect).style('cursor', null)\n    $$.hideXGridFocus()\n    $$.hideTooltip()\n    $$.unexpandCircles()\n    $$.unexpandBars()\n  }\n\n  const isHoveringDataPoint = (mouse, closest) =>\n    closest &&\n    ($$.isBarType(closest.id) ||\n      $$.dist(closest, mouse) < config.point_sensitivity)\n\n  const withName = d => (d ? $$.addName(Object.assign({}, d)) : null)\n\n  // rects for mouseover\n  $$.main\n    .select('.' + CLASS.eventRects)\n    .style(\n      'cursor',\n      config.zoom_enabled\n        ? config.axis_rotated\n          ? 'ns-resize'\n          : 'ew-resize'\n        : null\n    )\n\n  $$.eventRect\n    .attr('x', 0)\n    .attr('y', 0)\n    .attr('width', $$.width)\n    .attr('height', $$.height)\n    .on(\n      'mouseout',\n      config.interaction_enabled\n        ? function() {\n            if (!config) {\n              return\n            } // chart is destroyed\n            if ($$.hasArcType()) {\n              return\n            }\n            if ($$.mouseover) {\n              config.data_onmouseout.call($$.api, $$.mouseover)\n              $$.mouseover = undefined\n            }\n            mouseout()\n          }\n        : null\n    )\n    .on(\n      'mousemove',\n      config.interaction_enabled\n        ? function() {\n            // do nothing when dragging\n            if ($$.dragging) {\n              return\n            }\n\n            const targetsToShow = $$.getTargetsToShow()\n\n            // do nothing if arc type\n            if ($$.hasArcType(targetsToShow)) {\n              return\n            }\n\n            const mouse = d3.mouse(this)\n            const closest = withName(\n              $$.findClosestFromTargets(targetsToShow, mouse)\n            )\n            const isMouseCloseToDataPoint = isHoveringDataPoint(mouse, closest)\n\n            // ensure onmouseout is always called if mousemove switch between 2 targets\n            if (\n              $$.mouseover &&\n              (!closest ||\n                closest.id !== $$.mouseover.id ||\n                closest.index !== $$.mouseover.index)\n            ) {\n              config.data_onmouseout.call($$.api, $$.mouseover)\n              $$.mouseover = undefined\n            }\n            if (closest && !$$.mouseover) {\n              config.data_onmouseover.call($$.api, closest)\n              $$.mouseover = closest\n            }\n\n            // show cursor as pointer if we're hovering a data point close enough\n            $$.svg\n              .select('.' + CLASS.eventRect)\n              .style('cursor', isMouseCloseToDataPoint ? 'pointer' : null)\n\n            // if tooltip not grouped, we want to display only data from closest data point\n            const showSingleDataPoint =\n              !config.tooltip_grouped || $$.hasType('stanford', targetsToShow)\n\n            // find data to highlight\n            let selectedData\n            if (showSingleDataPoint) {\n              if (closest) {\n                selectedData = [closest]\n              }\n            } else {\n              let closestByX\n              if (closest) {\n                // reuse closest value\n                closestByX = closest\n              } else {\n                // try to find the closest value by X values from the mouse position\n                const mouseX = config.axis_rotated ? mouse[1] : mouse[0]\n                closestByX = $$.findClosestFromTargetsByX(\n                  targetsToShow,\n                  $$.x.invert(mouseX)\n                )\n              }\n\n              // highlight all data for this 'x' value\n              if (closestByX) {\n                selectedData = $$.filterByX(targetsToShow, closestByX.x)\n              }\n            }\n\n            // ensure we have data to show\n            if (!selectedData || selectedData.length === 0) {\n              return mouseout()\n            }\n\n            // inject names for each point\n            selectedData = selectedData.map(withName)\n\n            // show tooltip\n            $$.showTooltip(selectedData, this)\n\n            // expand points\n            if (config.point_focus_expand_enabled) {\n              $$.unexpandCircles()\n              selectedData.forEach(function(d) {\n                $$.expandCircles(d.index, d.id, false)\n              })\n            }\n\n            // expand bars\n            $$.unexpandBars()\n            selectedData.forEach(function(d) {\n              $$.expandBars(d.index, d.id, false)\n            })\n\n            // Show xgrid focus line\n            $$.showXGridFocus(selectedData)\n          }\n        : null\n    )\n    .on(\n      'click',\n      config.interaction_enabled\n        ? function() {\n            const targetsToShow = $$.getTargetsToShow()\n\n            if ($$.hasArcType(targetsToShow)) {\n              return\n            }\n\n            const mouse = d3.mouse(this)\n            const closest = withName(\n              $$.findClosestFromTargets(targetsToShow, mouse)\n            )\n\n            if (!isHoveringDataPoint(mouse, closest)) {\n              return\n            }\n\n            // select if selection enabled\n            let sameXData\n            if (!config.data_selection_grouped || $$.isStanfordType(closest)) {\n              sameXData = [closest]\n            } else {\n              sameXData = $$.filterByX(targetsToShow, closest.x)\n            }\n\n            // toggle selected state\n            sameXData.forEach(function(d) {\n              $$.main\n                .selectAll(\n                  '.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id)\n                )\n                .selectAll('.' + CLASS.shape + '-' + d.index)\n                .each(function() {\n                  if (\n                    config.data_selection_grouped ||\n                    $$.isWithinShape(this, d)\n                  ) {\n                    $$.toggleShape(this, d, d.index)\n                  }\n                })\n            })\n\n            // call data_onclick on the closest data point\n            if (closest) {\n              const shape = $$.main\n                .selectAll(\n                  '.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id)\n                )\n                .select('.' + CLASS.shape + '-' + closest.index)\n              config.data_onclick.call($$.api, closest, shape.node())\n            }\n          }\n        : null\n    )\n    .call(\n      config.interaction_enabled && config.data_selection_draggable && $$.drag\n        ? d3\n            .drag()\n            .on('drag', function() {\n              $$.drag(d3.mouse(this))\n            })\n            .on('start', function() {\n              $$.dragstart(d3.mouse(this))\n            })\n            .on('end', function() {\n              $$.dragend()\n            })\n        : function() {}\n    )\n}\nChartInternal.prototype.getMousePosition = function(data) {\n  var $$ = this\n  return [$$.x(data.x), $$.getYScale(data.id)(data.value)]\n}\nChartInternal.prototype.dispatchEvent = function(type, mouse) {\n  var $$ = this,\n    selector = '.' + CLASS.eventRect,\n    eventRect = $$.main.select(selector).node(),\n    box = eventRect.getBoundingClientRect(),\n    x = box.left + (mouse ? mouse[0] : 0),\n    y = box.top + (mouse ? mouse[1] : 0),\n    event = document.createEvent('MouseEvents')\n\n  event.initMouseEvent(\n    type,\n    true,\n    true,\n    window,\n    0,\n    x,\n    y,\n    x,\n    y,\n    false,\n    false,\n    false,\n    false,\n    0,\n    null\n  )\n  eventRect.dispatchEvent(event)\n}\n"
  },
  {
    "path": "src/legend.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport { isDefined, isEmpty, getOption } from './util'\n\nChartInternal.prototype.initLegend = function() {\n  var $$ = this\n  $$.legendItemTextBox = {}\n  $$.legendHasRendered = false\n  $$.legend = $$.svg.append('g').attr('transform', $$.getTranslate('legend'))\n  if (!$$.config.legend_show) {\n    $$.legend.style('visibility', 'hidden')\n    $$.hiddenLegendIds = $$.mapToIds($$.data.targets)\n    return\n  }\n  // MEMO: call here to update legend box and tranlate for all\n  // MEMO: translate will be updated by this, so transform not needed in updateLegend()\n  $$.updateLegendWithDefaults()\n}\nChartInternal.prototype.updateLegendWithDefaults = function() {\n  var $$ = this\n  $$.updateLegend($$.mapToIds($$.data.targets), {\n    withTransform: false,\n    withTransitionForTransform: false,\n    withTransition: false\n  })\n}\nChartInternal.prototype.updateSizeForLegend = function(\n  legendHeight,\n  legendWidth\n) {\n  var $$ = this,\n    config = $$.config,\n    insetLegendPosition = {\n      top: $$.isLegendTop\n        ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5\n        : $$.currentHeight -\n          legendHeight -\n          $$.getCurrentPaddingBottom() -\n          config.legend_inset_y,\n      left: $$.isLegendLeft\n        ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5\n        : $$.currentWidth -\n          legendWidth -\n          $$.getCurrentPaddingRight() -\n          config.legend_inset_x +\n          0.5\n    }\n\n  $$.margin3 = {\n    top: $$.isLegendRight\n      ? 0\n      : $$.isLegendInset\n      ? insetLegendPosition.top\n      : $$.currentHeight - legendHeight,\n    right: NaN,\n    bottom: 0,\n    left: $$.isLegendRight\n      ? $$.currentWidth - legendWidth\n      : $$.isLegendInset\n      ? insetLegendPosition.left\n      : 0\n  }\n}\nChartInternal.prototype.transformLegend = function(withTransition) {\n  var $$ = this\n  ;(withTransition ? $$.legend.transition() : $$.legend).attr(\n    'transform',\n    $$.getTranslate('legend')\n  )\n}\nChartInternal.prototype.updateLegendStep = function(step) {\n  this.legendStep = step\n}\nChartInternal.prototype.updateLegendItemWidth = function(w) {\n  this.legendItemWidth = w\n}\nChartInternal.prototype.updateLegendItemHeight = function(h) {\n  this.legendItemHeight = h\n}\nChartInternal.prototype.getLegendWidth = function() {\n  var $$ = this\n  return $$.config.legend_show\n    ? $$.isLegendRight || $$.isLegendInset\n      ? $$.legendItemWidth * ($$.legendStep + 1)\n      : $$.currentWidth\n    : 0\n}\nChartInternal.prototype.getLegendHeight = function() {\n  var $$ = this,\n    h = 0\n  if ($$.config.legend_show) {\n    if ($$.isLegendRight) {\n      h = $$.currentHeight\n    } else {\n      h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1)\n    }\n  }\n  return h\n}\nChartInternal.prototype.opacityForLegend = function(legendItem) {\n  return legendItem.classed(CLASS.legendItemHidden) ? null : 1\n}\nChartInternal.prototype.opacityForUnfocusedLegend = function(legendItem) {\n  return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3\n}\nChartInternal.prototype.toggleFocusLegend = function(targetIds, focus) {\n  var $$ = this\n  targetIds = $$.mapToTargetIds(targetIds)\n  $$.legend\n    .selectAll('.' + CLASS.legendItem)\n    .filter(function(id) {\n      return targetIds.indexOf(id) >= 0\n    })\n    .classed(CLASS.legendItemFocused, focus)\n    .transition()\n    .duration(100)\n    .style('opacity', function() {\n      var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend\n      return opacity.call($$, $$.d3.select(this))\n    })\n}\nChartInternal.prototype.revertLegend = function() {\n  var $$ = this,\n    d3 = $$.d3\n  $$.legend\n    .selectAll('.' + CLASS.legendItem)\n    .classed(CLASS.legendItemFocused, false)\n    .transition()\n    .duration(100)\n    .style('opacity', function() {\n      return $$.opacityForLegend(d3.select(this))\n    })\n}\nChartInternal.prototype.showLegend = function(targetIds) {\n  var $$ = this,\n    config = $$.config\n  if (!config.legend_show) {\n    config.legend_show = true\n    $$.legend.style('visibility', 'visible')\n    if (!$$.legendHasRendered) {\n      $$.updateLegendWithDefaults()\n    }\n  }\n  $$.removeHiddenLegendIds(targetIds)\n  $$.legend\n    .selectAll($$.selectorLegends(targetIds))\n    .style('visibility', 'visible')\n    .transition()\n    .style('opacity', function() {\n      return $$.opacityForLegend($$.d3.select(this))\n    })\n}\nChartInternal.prototype.hideLegend = function(targetIds) {\n  var $$ = this,\n    config = $$.config\n  if (config.legend_show && isEmpty(targetIds)) {\n    config.legend_show = false\n    $$.legend.style('visibility', 'hidden')\n  }\n  $$.addHiddenLegendIds(targetIds)\n  $$.legend\n    .selectAll($$.selectorLegends(targetIds))\n    .style('opacity', 0)\n    .style('visibility', 'hidden')\n}\nChartInternal.prototype.clearLegendItemTextBoxCache = function() {\n  this.legendItemTextBox = {}\n}\nChartInternal.prototype.updateLegend = function(\n  targetIds,\n  options,\n  transitions\n) {\n  var $$ = this,\n    config = $$.config\n  var xForLegend,\n    xForLegendText,\n    xForLegendRect,\n    yForLegend,\n    yForLegendText,\n    yForLegendRect,\n    x1ForLegendTile,\n    x2ForLegendTile,\n    yForLegendTile\n  var paddingTop = 4,\n    paddingRight = 10,\n    maxWidth = 0,\n    maxHeight = 0,\n    posMin = 10,\n    tileWidth = config.legend_item_tile_width + 5\n  var l,\n    totalLength = 0,\n    offsets = {},\n    widths = {},\n    heights = {},\n    margins = [0],\n    steps = {},\n    step = 0\n  var withTransition, withTransitionForTransform\n  var texts, rects, tiles, background\n\n  // Skip elements when their name is set to null\n  targetIds = targetIds.filter(function(id) {\n    return !isDefined(config.data_names[id]) || config.data_names[id] !== null\n  })\n\n  options = options || {}\n  withTransition = getOption(options, 'withTransition', true)\n  withTransitionForTransform = getOption(\n    options,\n    'withTransitionForTransform',\n    true\n  )\n\n  function getTextBox(textElement, id) {\n    if (!$$.legendItemTextBox[id]) {\n      $$.legendItemTextBox[id] = $$.getTextRect(\n        textElement.textContent,\n        CLASS.legendItem,\n        textElement\n      )\n    }\n    return $$.legendItemTextBox[id]\n  }\n\n  function updatePositions(textElement, id, index) {\n    var reset = index === 0,\n      isLast = index === targetIds.length - 1,\n      box = getTextBox(textElement, id),\n      itemWidth =\n        box.width +\n        tileWidth +\n        (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) +\n        config.legend_padding,\n      itemHeight = box.height + paddingTop,\n      itemLength =\n        $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth,\n      areaLength =\n        $$.isLegendRight || $$.isLegendInset\n          ? $$.getLegendHeight()\n          : $$.getLegendWidth(),\n      margin,\n      maxLength\n\n    // MEMO: care about condifion of step, totalLength\n    function updateValues(id, withoutStep?: boolean) {\n      if (!withoutStep) {\n        margin = (areaLength - totalLength - itemLength) / 2\n        if (margin < posMin) {\n          margin = (areaLength - itemLength) / 2\n          totalLength = 0\n          step++\n        }\n      }\n      steps[id] = step\n      margins[step] = $$.isLegendInset ? 10 : margin\n      offsets[id] = totalLength\n      totalLength += itemLength\n    }\n\n    if (reset) {\n      totalLength = 0\n      step = 0\n      maxWidth = 0\n      maxHeight = 0\n    }\n\n    if (config.legend_show && !$$.isLegendToShow(id)) {\n      widths[id] = heights[id] = steps[id] = offsets[id] = 0\n      return\n    }\n\n    widths[id] = itemWidth\n    heights[id] = itemHeight\n\n    if (!maxWidth || itemWidth >= maxWidth) {\n      maxWidth = itemWidth\n    }\n    if (!maxHeight || itemHeight >= maxHeight) {\n      maxHeight = itemHeight\n    }\n    maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth\n\n    if (config.legend_equally) {\n      Object.keys(widths).forEach(function(id) {\n        widths[id] = maxWidth\n      })\n      Object.keys(heights).forEach(function(id) {\n        heights[id] = maxHeight\n      })\n      margin = (areaLength - maxLength * targetIds.length) / 2\n      if (margin < posMin) {\n        totalLength = 0\n        step = 0\n        targetIds.forEach(function(id) {\n          updateValues(id)\n        })\n      } else {\n        updateValues(id, true)\n      }\n    } else {\n      updateValues(id)\n    }\n  }\n\n  if ($$.isLegendInset) {\n    step = config.legend_inset_step\n      ? config.legend_inset_step\n      : targetIds.length\n    $$.updateLegendStep(step)\n  }\n\n  if ($$.isLegendRight) {\n    xForLegend = function(id) {\n      return maxWidth * steps[id]\n    }\n    yForLegend = function(id) {\n      return margins[steps[id]] + offsets[id]\n    }\n  } else if ($$.isLegendInset) {\n    xForLegend = function(id) {\n      return maxWidth * steps[id] + 10\n    }\n    yForLegend = function(id) {\n      return margins[steps[id]] + offsets[id]\n    }\n  } else {\n    xForLegend = function(id) {\n      return margins[steps[id]] + offsets[id]\n    }\n    yForLegend = function(id) {\n      return maxHeight * steps[id]\n    }\n  }\n  xForLegendText = function(id, i) {\n    return xForLegend(id, i) + 4 + config.legend_item_tile_width\n  }\n  yForLegendText = function(id, i) {\n    return yForLegend(id, i) + 9\n  }\n  xForLegendRect = function(id, i) {\n    return xForLegend(id, i)\n  }\n  yForLegendRect = function(id, i) {\n    return yForLegend(id, i) - 5\n  }\n  x1ForLegendTile = function(id, i) {\n    return xForLegend(id, i) - 2\n  }\n  x2ForLegendTile = function(id, i) {\n    return xForLegend(id, i) - 2 + config.legend_item_tile_width\n  }\n  yForLegendTile = function(id, i) {\n    return yForLegend(id, i) + 4\n  }\n\n  // Define g for legend area\n  l = $$.legend\n    .selectAll('.' + CLASS.legendItem)\n    .data(targetIds)\n    .enter()\n    .append('g')\n    .attr('class', function(id) {\n      return $$.generateClass(CLASS.legendItem, id)\n    })\n    .style('visibility', function(id) {\n      return $$.isLegendToShow(id) ? 'visible' : 'hidden'\n    })\n    .style('cursor', function() {\n      return config.interaction_enabled ? 'pointer' : 'auto'\n    })\n    .on(\n      'click',\n      config.interaction_enabled\n        ? function(id) {\n            if (config.legend_item_onclick) {\n              config.legend_item_onclick.call($$, id)\n            } else {\n              if ($$.d3.event.altKey) {\n                $$.api.hide()\n                $$.api.show(id)\n              } else {\n                $$.api.toggle(id)\n                $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert()\n              }\n            }\n          }\n        : null\n    )\n    .on(\n      'mouseover',\n      config.interaction_enabled\n        ? function(id) {\n            if (config.legend_item_onmouseover) {\n              config.legend_item_onmouseover.call($$, id)\n            } else {\n              $$.d3.select(this).classed(CLASS.legendItemFocused, true)\n              if (!$$.transiting && $$.isTargetToShow(id)) {\n                $$.api.focus(id)\n              }\n            }\n          }\n        : null\n    )\n    .on(\n      'mouseout',\n      config.interaction_enabled\n        ? function(id) {\n            if (config.legend_item_onmouseout) {\n              config.legend_item_onmouseout.call($$, id)\n            } else {\n              $$.d3.select(this).classed(CLASS.legendItemFocused, false)\n              $$.api.revert()\n            }\n          }\n        : null\n    )\n\n  l.append('text')\n    .text(function(id) {\n      return isDefined(config.data_names[id]) ? config.data_names[id] : id\n    })\n    .each(function(id, i) {\n      updatePositions(this, id, i)\n    })\n    .style('pointer-events', 'none')\n    .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200)\n    .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText)\n\n  l.append('rect')\n    .attr('class', CLASS.legendItemEvent)\n    .style('fill-opacity', 0)\n    .attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200)\n    .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect)\n\n  l.append('line')\n    .attr('class', CLASS.legendItemTile)\n    .style('stroke', $$.color)\n    .style('pointer-events', 'none')\n    .attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200)\n    .attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile)\n    .attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200)\n    .attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile)\n    .attr('stroke-width', config.legend_item_tile_height)\n\n  // Set background for inset legend\n  background = $$.legend.select('.' + CLASS.legendBackground + ' rect')\n  if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) {\n    background = $$.legend\n      .insert('g', '.' + CLASS.legendItem)\n      .attr('class', CLASS.legendBackground)\n      .append('rect')\n  }\n\n  texts = $$.legend\n    .selectAll('text')\n    .data(targetIds)\n    .text(function(id) {\n      return isDefined(config.data_names[id]) ? config.data_names[id] : id\n    }) // MEMO: needed for update\n    .each(function(id, i) {\n      updatePositions(this, id, i)\n    })\n  ;(withTransition ? texts.transition() : texts)\n    .attr('x', xForLegendText)\n    .attr('y', yForLegendText)\n\n  rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent).data(targetIds)\n  ;(withTransition ? rects.transition() : rects)\n    .attr('width', function(id) {\n      return widths[id]\n    })\n    .attr('height', function(id) {\n      return heights[id]\n    })\n    .attr('x', xForLegendRect)\n    .attr('y', yForLegendRect)\n\n  tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile).data(targetIds)\n  ;(withTransition ? tiles.transition() : tiles)\n    .style(\n      'stroke',\n      $$.levelColor\n        ? function(id) {\n            return $$.levelColor(\n              $$.cache[id].values.reduce(function(total, item) {\n                return total + item.value\n              }, 0)\n            )\n          }\n        : $$.color\n    )\n    .attr('x1', x1ForLegendTile)\n    .attr('y1', yForLegendTile)\n    .attr('x2', x2ForLegendTile)\n    .attr('y2', yForLegendTile)\n\n  if (background) {\n    ;(withTransition ? background.transition() : background)\n      .attr('height', $$.getLegendHeight() - 12)\n      .attr('width', maxWidth * (step + 1) + 10)\n  }\n\n  // toggle legend state\n  $$.legend\n    .selectAll('.' + CLASS.legendItem)\n    .classed(CLASS.legendItemHidden, function(id) {\n      return !$$.isTargetToShow(id)\n    })\n\n  // Update all to reflect change of legend\n  $$.updateLegendItemWidth(maxWidth)\n  $$.updateLegendItemHeight(maxHeight)\n  $$.updateLegendStep(step)\n  // Update size and scale\n  $$.updateSizes()\n  $$.updateScales()\n  $$.updateSvgSize()\n  // Update g positions\n  $$.transformAll(withTransitionForTransform, transitions)\n  $$.legendHasRendered = true\n}\n"
  },
  {
    "path": "src/polyfill.ts",
    "content": "/* jshint ignore:start */\n// @ts-nocheck\n\n// SVGPathSeg API polyfill\n// https://github.com/progers/pathseg\n//\n// This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from\n// SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec\n// changes which were implemented in Firefox 43 and Chrome 46.\n\n;(function() {\n  'use strict'\n  if (!('SVGPathSeg' in window)) {\n    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg\n    window.SVGPathSeg = function(type, typeAsLetter, owningPathSegList) {\n      this.pathSegType = type\n      this.pathSegTypeAsLetter = typeAsLetter\n      this._owningPathSegList = owningPathSegList\n    }\n\n    window.SVGPathSeg.prototype.classname = 'SVGPathSeg'\n\n    window.SVGPathSeg.PATHSEG_UNKNOWN = 0\n    window.SVGPathSeg.PATHSEG_CLOSEPATH = 1\n    window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2\n    window.SVGPathSeg.PATHSEG_MOVETO_REL = 3\n    window.SVGPathSeg.PATHSEG_LINETO_ABS = 4\n    window.SVGPathSeg.PATHSEG_LINETO_REL = 5\n    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6\n    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7\n    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8\n    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9\n    window.SVGPathSeg.PATHSEG_ARC_ABS = 10\n    window.SVGPathSeg.PATHSEG_ARC_REL = 11\n    window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12\n    window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13\n    window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14\n    window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15\n    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16\n    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17\n    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18\n    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19\n\n    // Notify owning PathSegList on any changes so they can be synchronized back to the path element.\n    window.SVGPathSeg.prototype._segmentChanged = function() {\n      if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this)\n    }\n\n    window.SVGPathSegClosePath = function(owningPathSegList) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CLOSEPATH,\n        'z',\n        owningPathSegList\n      )\n    }\n    window.SVGPathSegClosePath.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegClosePath.prototype.toString = function() {\n      return '[object SVGPathSegClosePath]'\n    }\n    window.SVGPathSegClosePath.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter\n    }\n    window.SVGPathSegClosePath.prototype.clone = function() {\n      return new window.SVGPathSegClosePath(undefined)\n    }\n\n    window.SVGPathSegMovetoAbs = function(owningPathSegList, x, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_MOVETO_ABS,\n        'M',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n    }\n    window.SVGPathSegMovetoAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegMovetoAbs.prototype.toString = function() {\n      return '[object SVGPathSegMovetoAbs]'\n    }\n    window.SVGPathSegMovetoAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    }\n    window.SVGPathSegMovetoAbs.prototype.clone = function() {\n      return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y)\n    }\n    Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n\n    window.SVGPathSegMovetoRel = function(owningPathSegList, x, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_MOVETO_REL,\n        'm',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n    }\n    window.SVGPathSegMovetoRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegMovetoRel.prototype.toString = function() {\n      return '[object SVGPathSegMovetoRel]'\n    }\n    window.SVGPathSegMovetoRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    }\n    window.SVGPathSegMovetoRel.prototype.clone = function() {\n      return new window.SVGPathSegMovetoRel(undefined, this._x, this._y)\n    }\n    Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n\n    window.SVGPathSegLinetoAbs = function(owningPathSegList, x, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_ABS,\n        'L',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n    }\n    window.SVGPathSegLinetoAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegLinetoAbs.prototype.toString = function() {\n      return '[object SVGPathSegLinetoAbs]'\n    }\n    window.SVGPathSegLinetoAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    }\n    window.SVGPathSegLinetoAbs.prototype.clone = function() {\n      return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y)\n    }\n    Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n\n    window.SVGPathSegLinetoRel = function(owningPathSegList, x, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_REL,\n        'l',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n    }\n    window.SVGPathSegLinetoRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegLinetoRel.prototype.toString = function() {\n      return '[object SVGPathSegLinetoRel]'\n    }\n    window.SVGPathSegLinetoRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    }\n    window.SVGPathSegLinetoRel.prototype.clone = function() {\n      return new window.SVGPathSegLinetoRel(undefined, this._x, this._y)\n    }\n    Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n\n    window.SVGPathSegCurvetoCubicAbs = function(\n      owningPathSegList,\n      x,\n      y,\n      x1,\n      y1,\n      x2,\n      y2\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS,\n        'C',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n      this._x1 = x1\n      this._y1 = y1\n      this._x2 = x2\n      this._y2 = y2\n    }\n    window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegCurvetoCubicAbs.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoCubicAbs]'\n    }\n    window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x1 +\n        ' ' +\n        this._y1 +\n        ' ' +\n        this._x2 +\n        ' ' +\n        this._y2 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    }\n    window.SVGPathSegCurvetoCubicAbs.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoCubicAbs(\n        undefined,\n        this._x,\n        this._y,\n        this._x1,\n        this._y1,\n        this._x2,\n        this._y2\n      )\n    }\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x1', {\n      get: function() {\n        return this._x1\n      },\n      set: function(x1) {\n        this._x1 = x1\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y1', {\n      get: function() {\n        return this._y1\n      },\n      set: function(y1) {\n        this._y1 = y1\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x2', {\n      get: function() {\n        return this._x2\n      },\n      set: function(x2) {\n        this._x2 = x2\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y2', {\n      get: function() {\n        return this._y2\n      },\n      set: function(y2) {\n        this._y2 = y2\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n\n    window.SVGPathSegCurvetoCubicRel = function(\n      owningPathSegList,\n      x,\n      y,\n      x1,\n      y1,\n      x2,\n      y2\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL,\n        'c',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n      this._x1 = x1\n      this._y1 = y1\n      this._x2 = x2\n      this._y2 = y2\n    }\n    window.SVGPathSegCurvetoCubicRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegCurvetoCubicRel.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoCubicRel]'\n    }\n    window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x1 +\n        ' ' +\n        this._y1 +\n        ' ' +\n        this._x2 +\n        ' ' +\n        this._y2 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    }\n    window.SVGPathSegCurvetoCubicRel.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoCubicRel(\n        undefined,\n        this._x,\n        this._y,\n        this._x1,\n        this._y1,\n        this._x2,\n        this._y2\n      )\n    }\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x1', {\n      get: function() {\n        return this._x1\n      },\n      set: function(x1) {\n        this._x1 = x1\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y1', {\n      get: function() {\n        return this._y1\n      },\n      set: function(y1) {\n        this._y1 = y1\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x2', {\n      get: function() {\n        return this._x2\n      },\n      set: function(x2) {\n        this._x2 = x2\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y2', {\n      get: function() {\n        return this._y2\n      },\n      set: function(y2) {\n        this._y2 = y2\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n\n    window.SVGPathSegCurvetoQuadraticAbs = function(\n      owningPathSegList,\n      x,\n      y,\n      x1,\n      y1\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS,\n        'Q',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n      this._x1 = x1\n      this._y1 = y1\n    }\n    window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoQuadraticAbs]'\n    }\n    window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x1 +\n        ' ' +\n        this._y1 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    }\n    window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoQuadraticAbs(\n        undefined,\n        this._x,\n        this._y,\n        this._x1,\n        this._y1\n      )\n    }\n    Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticAbs.prototype,\n      'x1',\n      {\n        get: function() {\n          return this._x1\n        },\n        set: function(x1) {\n          this._x1 = x1\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticAbs.prototype,\n      'y1',\n      {\n        get: function() {\n          return this._y1\n        },\n        set: function(y1) {\n          this._y1 = y1\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n\n    window.SVGPathSegCurvetoQuadraticRel = function(\n      owningPathSegList,\n      x,\n      y,\n      x1,\n      y1\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL,\n        'q',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n      this._x1 = x1\n      this._y1 = y1\n    }\n    window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoQuadraticRel]'\n    }\n    window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x1 +\n        ' ' +\n        this._y1 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    }\n    window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoQuadraticRel(\n        undefined,\n        this._x,\n        this._y,\n        this._x1,\n        this._y1\n      )\n    }\n    Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticRel.prototype,\n      'x1',\n      {\n        get: function() {\n          return this._x1\n        },\n        set: function(x1) {\n          this._x1 = x1\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticRel.prototype,\n      'y1',\n      {\n        get: function() {\n          return this._y1\n        },\n        set: function(y1) {\n          this._y1 = y1\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n\n    window.SVGPathSegArcAbs = function(\n      owningPathSegList,\n      x,\n      y,\n      r1,\n      r2,\n      angle,\n      largeArcFlag,\n      sweepFlag\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_ARC_ABS,\n        'A',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n      this._r1 = r1\n      this._r2 = r2\n      this._angle = angle\n      this._largeArcFlag = largeArcFlag\n      this._sweepFlag = sweepFlag\n    }\n    window.SVGPathSegArcAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegArcAbs.prototype.toString = function() {\n      return '[object SVGPathSegArcAbs]'\n    }\n    window.SVGPathSegArcAbs.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._r1 +\n        ' ' +\n        this._r2 +\n        ' ' +\n        this._angle +\n        ' ' +\n        (this._largeArcFlag ? '1' : '0') +\n        ' ' +\n        (this._sweepFlag ? '1' : '0') +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    }\n    window.SVGPathSegArcAbs.prototype.clone = function() {\n      return new window.SVGPathSegArcAbs(\n        undefined,\n        this._x,\n        this._y,\n        this._r1,\n        this._r2,\n        this._angle,\n        this._largeArcFlag,\n        this._sweepFlag\n      )\n    }\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r1', {\n      get: function() {\n        return this._r1\n      },\n      set: function(r1) {\n        this._r1 = r1\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r2', {\n      get: function() {\n        return this._r2\n      },\n      set: function(r2) {\n        this._r2 = r2\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'angle', {\n      get: function() {\n        return this._angle\n      },\n      set: function(angle) {\n        this._angle = angle\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'largeArcFlag', {\n      get: function() {\n        return this._largeArcFlag\n      },\n      set: function(largeArcFlag) {\n        this._largeArcFlag = largeArcFlag\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'sweepFlag', {\n      get: function() {\n        return this._sweepFlag\n      },\n      set: function(sweepFlag) {\n        this._sweepFlag = sweepFlag\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n\n    window.SVGPathSegArcRel = function(\n      owningPathSegList,\n      x,\n      y,\n      r1,\n      r2,\n      angle,\n      largeArcFlag,\n      sweepFlag\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_ARC_REL,\n        'a',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n      this._r1 = r1\n      this._r2 = r2\n      this._angle = angle\n      this._largeArcFlag = largeArcFlag\n      this._sweepFlag = sweepFlag\n    }\n    window.SVGPathSegArcRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegArcRel.prototype.toString = function() {\n      return '[object SVGPathSegArcRel]'\n    }\n    window.SVGPathSegArcRel.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._r1 +\n        ' ' +\n        this._r2 +\n        ' ' +\n        this._angle +\n        ' ' +\n        (this._largeArcFlag ? '1' : '0') +\n        ' ' +\n        (this._sweepFlag ? '1' : '0') +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    }\n    window.SVGPathSegArcRel.prototype.clone = function() {\n      return new window.SVGPathSegArcRel(\n        undefined,\n        this._x,\n        this._y,\n        this._r1,\n        this._r2,\n        this._angle,\n        this._largeArcFlag,\n        this._sweepFlag\n      )\n    }\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r1', {\n      get: function() {\n        return this._r1\n      },\n      set: function(r1) {\n        this._r1 = r1\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r2', {\n      get: function() {\n        return this._r2\n      },\n      set: function(r2) {\n        this._r2 = r2\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'angle', {\n      get: function() {\n        return this._angle\n      },\n      set: function(angle) {\n        this._angle = angle\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'largeArcFlag', {\n      get: function() {\n        return this._largeArcFlag\n      },\n      set: function(largeArcFlag) {\n        this._largeArcFlag = largeArcFlag\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'sweepFlag', {\n      get: function() {\n        return this._sweepFlag\n      },\n      set: function(sweepFlag) {\n        this._sweepFlag = sweepFlag\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n\n    window.SVGPathSegLinetoHorizontalAbs = function(owningPathSegList, x) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS,\n        'H',\n        owningPathSegList\n      )\n      this._x = x\n    }\n    window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function() {\n      return '[object SVGPathSegLinetoHorizontalAbs]'\n    }\n    window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x\n    }\n    window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function() {\n      return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x)\n    }\n    Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n\n    window.SVGPathSegLinetoHorizontalRel = function(owningPathSegList, x) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL,\n        'h',\n        owningPathSegList\n      )\n      this._x = x\n    }\n    window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegLinetoHorizontalRel.prototype.toString = function() {\n      return '[object SVGPathSegLinetoHorizontalRel]'\n    }\n    window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x\n    }\n    window.SVGPathSegLinetoHorizontalRel.prototype.clone = function() {\n      return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x)\n    }\n    Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, 'x', {\n      get: function() {\n        return this._x\n      },\n      set: function(x) {\n        this._x = x\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n\n    window.SVGPathSegLinetoVerticalAbs = function(owningPathSegList, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS,\n        'V',\n        owningPathSegList\n      )\n      this._y = y\n    }\n    window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegLinetoVerticalAbs.prototype.toString = function() {\n      return '[object SVGPathSegLinetoVerticalAbs]'\n    }\n    window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._y\n    }\n    window.SVGPathSegLinetoVerticalAbs.prototype.clone = function() {\n      return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y)\n    }\n    Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n\n    window.SVGPathSegLinetoVerticalRel = function(owningPathSegList, y) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL,\n        'v',\n        owningPathSegList\n      )\n      this._y = y\n    }\n    window.SVGPathSegLinetoVerticalRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegLinetoVerticalRel.prototype.toString = function() {\n      return '[object SVGPathSegLinetoVerticalRel]'\n    }\n    window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._y\n    }\n    window.SVGPathSegLinetoVerticalRel.prototype.clone = function() {\n      return new window.SVGPathSegLinetoVerticalRel(undefined, this._y)\n    }\n    Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, 'y', {\n      get: function() {\n        return this._y\n      },\n      set: function(y) {\n        this._y = y\n        this._segmentChanged()\n      },\n      enumerable: true\n    })\n\n    window.SVGPathSegCurvetoCubicSmoothAbs = function(\n      owningPathSegList,\n      x,\n      y,\n      x2,\n      y2\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS,\n        'S',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n      this._x2 = x2\n      this._y2 = y2\n    }\n    window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoCubicSmoothAbs]'\n    }\n    window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x2 +\n        ' ' +\n        this._y2 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    }\n    window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoCubicSmoothAbs(\n        undefined,\n        this._x,\n        this._y,\n        this._x2,\n        this._y2\n      )\n    }\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,\n      'x',\n      {\n        get: function() {\n          return this._x\n        },\n        set: function(x) {\n          this._x = x\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,\n      'y',\n      {\n        get: function() {\n          return this._y\n        },\n        set: function(y) {\n          this._y = y\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,\n      'x2',\n      {\n        get: function() {\n          return this._x2\n        },\n        set: function(x2) {\n          this._x2 = x2\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,\n      'y2',\n      {\n        get: function() {\n          return this._y2\n        },\n        set: function(y2) {\n          this._y2 = y2\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n\n    window.SVGPathSegCurvetoCubicSmoothRel = function(\n      owningPathSegList,\n      x,\n      y,\n      x2,\n      y2\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL,\n        's',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n      this._x2 = x2\n      this._y2 = y2\n    }\n    window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoCubicSmoothRel]'\n    }\n    window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function() {\n      return (\n        this.pathSegTypeAsLetter +\n        ' ' +\n        this._x2 +\n        ' ' +\n        this._y2 +\n        ' ' +\n        this._x +\n        ' ' +\n        this._y\n      )\n    }\n    window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoCubicSmoothRel(\n        undefined,\n        this._x,\n        this._y,\n        this._x2,\n        this._y2\n      )\n    }\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothRel.prototype,\n      'x',\n      {\n        get: function() {\n          return this._x\n        },\n        set: function(x) {\n          this._x = x\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothRel.prototype,\n      'y',\n      {\n        get: function() {\n          return this._y\n        },\n        set: function(y) {\n          this._y = y\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothRel.prototype,\n      'x2',\n      {\n        get: function() {\n          return this._x2\n        },\n        set: function(x2) {\n          this._x2 = x2\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n    Object.defineProperty(\n      window.SVGPathSegCurvetoCubicSmoothRel.prototype,\n      'y2',\n      {\n        get: function() {\n          return this._y2\n        },\n        set: function(y2) {\n          this._y2 = y2\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n\n    window.SVGPathSegCurvetoQuadraticSmoothAbs = function(\n      owningPathSegList,\n      x,\n      y\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS,\n        'T',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n    }\n    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoQuadraticSmoothAbs]'\n    }\n    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    }\n    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoQuadraticSmoothAbs(\n        undefined,\n        this._x,\n        this._y\n      )\n    }\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype,\n      'x',\n      {\n        get: function() {\n          return this._x\n        },\n        set: function(x) {\n          this._x = x\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype,\n      'y',\n      {\n        get: function() {\n          return this._y\n        },\n        set: function(y) {\n          this._y = y\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n\n    window.SVGPathSegCurvetoQuadraticSmoothRel = function(\n      owningPathSegList,\n      x,\n      y\n    ) {\n      window.SVGPathSeg.call(\n        this,\n        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL,\n        't',\n        owningPathSegList\n      )\n      this._x = x\n      this._y = y\n    }\n    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(\n      window.SVGPathSeg.prototype\n    )\n    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function() {\n      return '[object SVGPathSegCurvetoQuadraticSmoothRel]'\n    }\n    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function() {\n      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y\n    }\n    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function() {\n      return new window.SVGPathSegCurvetoQuadraticSmoothRel(\n        undefined,\n        this._x,\n        this._y\n      )\n    }\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticSmoothRel.prototype,\n      'x',\n      {\n        get: function() {\n          return this._x\n        },\n        set: function(x) {\n          this._x = x\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n    Object.defineProperty(\n      window.SVGPathSegCurvetoQuadraticSmoothRel.prototype,\n      'y',\n      {\n        get: function() {\n          return this._y\n        },\n        set: function(y) {\n          this._y = y\n          this._segmentChanged()\n        },\n        enumerable: true\n      }\n    )\n\n    // Add createSVGPathSeg* functions to window.SVGPathElement.\n    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.\n    window.SVGPathElement.prototype.createSVGPathSegClosePath = function() {\n      return new window.SVGPathSegClosePath(undefined)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function(x, y) {\n      return new window.SVGPathSegMovetoAbs(undefined, x, y)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function(x, y) {\n      return new window.SVGPathSegMovetoRel(undefined, x, y)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function(x, y) {\n      return new window.SVGPathSegLinetoAbs(undefined, x, y)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function(x, y) {\n      return new window.SVGPathSegLinetoRel(undefined, x, y)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function(\n      x,\n      y,\n      x1,\n      y1,\n      x2,\n      y2\n    ) {\n      return new window.SVGPathSegCurvetoCubicAbs(\n        undefined,\n        x,\n        y,\n        x1,\n        y1,\n        x2,\n        y2\n      )\n    }\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function(\n      x,\n      y,\n      x1,\n      y1,\n      x2,\n      y2\n    ) {\n      return new window.SVGPathSegCurvetoCubicRel(\n        undefined,\n        x,\n        y,\n        x1,\n        y1,\n        x2,\n        y2\n      )\n    }\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function(\n      x,\n      y,\n      x1,\n      y1\n    ) {\n      return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function(\n      x,\n      y,\n      x1,\n      y1\n    ) {\n      return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegArcAbs = function(\n      x,\n      y,\n      r1,\n      r2,\n      angle,\n      largeArcFlag,\n      sweepFlag\n    ) {\n      return new window.SVGPathSegArcAbs(\n        undefined,\n        x,\n        y,\n        r1,\n        r2,\n        angle,\n        largeArcFlag,\n        sweepFlag\n      )\n    }\n    window.SVGPathElement.prototype.createSVGPathSegArcRel = function(\n      x,\n      y,\n      r1,\n      r2,\n      angle,\n      largeArcFlag,\n      sweepFlag\n    ) {\n      return new window.SVGPathSegArcRel(\n        undefined,\n        x,\n        y,\n        r1,\n        r2,\n        angle,\n        largeArcFlag,\n        sweepFlag\n      )\n    }\n    window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function(\n      x\n    ) {\n      return new window.SVGPathSegLinetoHorizontalAbs(undefined, x)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function(\n      x\n    ) {\n      return new window.SVGPathSegLinetoHorizontalRel(undefined, x)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function(\n      y\n    ) {\n      return new window.SVGPathSegLinetoVerticalAbs(undefined, y)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function(\n      y\n    ) {\n      return new window.SVGPathSegLinetoVerticalRel(undefined, y)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function(\n      x,\n      y,\n      x2,\n      y2\n    ) {\n      return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function(\n      x,\n      y,\n      x2,\n      y2\n    ) {\n      return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function(\n      x,\n      y\n    ) {\n      return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y)\n    }\n    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function(\n      x,\n      y\n    ) {\n      return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y)\n    }\n\n    if (!('getPathSegAtLength' in window.SVGPathElement.prototype)) {\n      // Add getPathSegAtLength to SVGPathElement.\n      // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength\n      // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.\n      window.SVGPathElement.prototype.getPathSegAtLength = function(distance) {\n        if (distance === undefined || !isFinite(distance))\n          throw 'Invalid arguments.'\n\n        var measurementElement = document.createElementNS(\n          'http://www.w3.org/2000/svg',\n          'path'\n        )\n        measurementElement.setAttribute('d', this.getAttribute('d'))\n        var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1\n\n        // If the path is empty, return 0.\n        if (lastPathSegment <= 0) return 0\n\n        do {\n          measurementElement.pathSegList.removeItem(lastPathSegment)\n          if (distance > measurementElement.getTotalLength()) break\n          lastPathSegment--\n        } while (lastPathSegment > 0)\n        return lastPathSegment\n      }\n    }\n  }\n\n  if (!('SVGPathSegList' in window)) {\n    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList\n    window.SVGPathSegList = function(pathElement) {\n      this._pathElement = pathElement\n      this._list = this._parsePath(this._pathElement.getAttribute('d'))\n\n      // Use a MutationObserver to catch changes to the path's \"d\" attribute.\n      this._mutationObserverConfig = {\n        attributes: true,\n        attributeFilter: ['d']\n      }\n      this._pathElementMutationObserver = new MutationObserver(\n        this._updateListFromPathMutations.bind(this)\n      )\n      this._pathElementMutationObserver.observe(\n        this._pathElement,\n        this._mutationObserverConfig\n      )\n    }\n\n    window.SVGPathSegList.prototype.classname = 'SVGPathSegList'\n\n    Object.defineProperty(window.SVGPathSegList.prototype, 'numberOfItems', {\n      get: function() {\n        this._checkPathSynchronizedToList()\n        return this._list.length\n      },\n      enumerable: true\n    })\n\n    // Add the pathSegList accessors to window.SVGPathElement.\n    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData\n    Object.defineProperty(window.SVGPathElement.prototype, 'pathSegList', {\n      get: function() {\n        if (!this._pathSegList)\n          this._pathSegList = new window.SVGPathSegList(this)\n        return this._pathSegList\n      },\n      enumerable: true\n    })\n    // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.\n    Object.defineProperty(\n      window.SVGPathElement.prototype,\n      'normalizedPathSegList',\n      {\n        get: function() {\n          return this.pathSegList\n        },\n        enumerable: true\n      }\n    )\n    Object.defineProperty(\n      window.SVGPathElement.prototype,\n      'animatedPathSegList',\n      {\n        get: function() {\n          return this.pathSegList\n        },\n        enumerable: true\n      }\n    )\n    Object.defineProperty(\n      window.SVGPathElement.prototype,\n      'animatedNormalizedPathSegList',\n      {\n        get: function() {\n          return this.pathSegList\n        },\n        enumerable: true\n      }\n    )\n\n    // Process any pending mutations to the path element and update the list as needed.\n    // This should be the first call of all public functions and is needed because\n    // MutationObservers are not synchronous so we can have pending asynchronous mutations.\n    window.SVGPathSegList.prototype._checkPathSynchronizedToList = function() {\n      this._updateListFromPathMutations(\n        this._pathElementMutationObserver.takeRecords()\n      )\n    }\n\n    window.SVGPathSegList.prototype._updateListFromPathMutations = function(\n      mutationRecords\n    ) {\n      if (!this._pathElement) return\n      var hasPathMutations = false\n      mutationRecords.forEach(function(record) {\n        if (record.attributeName == 'd') hasPathMutations = true\n      })\n      if (hasPathMutations)\n        this._list = this._parsePath(this._pathElement.getAttribute('d'))\n    }\n\n    // Serialize the list and update the path's 'd' attribute.\n    window.SVGPathSegList.prototype._writeListToPath = function() {\n      this._pathElementMutationObserver.disconnect()\n      this._pathElement.setAttribute(\n        'd',\n        window.SVGPathSegList._pathSegArrayAsString(this._list)\n      )\n      this._pathElementMutationObserver.observe(\n        this._pathElement,\n        this._mutationObserverConfig\n      )\n    }\n\n    // When a path segment changes the list needs to be synchronized back to the path element.\n    window.SVGPathSegList.prototype.segmentChanged = function(pathSeg) {\n      this._writeListToPath()\n    }\n\n    window.SVGPathSegList.prototype.clear = function() {\n      this._checkPathSynchronizedToList()\n\n      this._list.forEach(function(pathSeg) {\n        pathSeg._owningPathSegList = null\n      })\n      this._list = []\n      this._writeListToPath()\n    }\n\n    window.SVGPathSegList.prototype.initialize = function(newItem) {\n      this._checkPathSynchronizedToList()\n\n      this._list = [newItem]\n      newItem._owningPathSegList = this\n      this._writeListToPath()\n      return newItem\n    }\n\n    window.SVGPathSegList.prototype._checkValidIndex = function(index) {\n      if (isNaN(index) || index < 0 || index >= this.numberOfItems)\n        throw 'INDEX_SIZE_ERR'\n    }\n\n    window.SVGPathSegList.prototype.getItem = function(index) {\n      this._checkPathSynchronizedToList()\n\n      this._checkValidIndex(index)\n      return this._list[index]\n    }\n\n    window.SVGPathSegList.prototype.insertItemBefore = function(\n      newItem,\n      index\n    ) {\n      this._checkPathSynchronizedToList()\n\n      // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.\n      if (index > this.numberOfItems) index = this.numberOfItems\n      if (newItem._owningPathSegList) {\n        // SVG2 spec says to make a copy.\n        newItem = newItem.clone()\n      }\n      this._list.splice(index, 0, newItem)\n      newItem._owningPathSegList = this\n      this._writeListToPath()\n      return newItem\n    }\n\n    window.SVGPathSegList.prototype.replaceItem = function(newItem, index) {\n      this._checkPathSynchronizedToList()\n\n      if (newItem._owningPathSegList) {\n        // SVG2 spec says to make a copy.\n        newItem = newItem.clone()\n      }\n      this._checkValidIndex(index)\n      this._list[index] = newItem\n      newItem._owningPathSegList = this\n      this._writeListToPath()\n      return newItem\n    }\n\n    window.SVGPathSegList.prototype.removeItem = function(index) {\n      this._checkPathSynchronizedToList()\n\n      this._checkValidIndex(index)\n      var item = this._list[index]\n      this._list.splice(index, 1)\n      this._writeListToPath()\n      return item\n    }\n\n    window.SVGPathSegList.prototype.appendItem = function(newItem) {\n      this._checkPathSynchronizedToList()\n\n      if (newItem._owningPathSegList) {\n        // SVG2 spec says to make a copy.\n        newItem = newItem.clone()\n      }\n      this._list.push(newItem)\n      newItem._owningPathSegList = this\n      // TODO: Optimize this to just append to the existing attribute.\n      this._writeListToPath()\n      return newItem\n    }\n\n    window.SVGPathSegList._pathSegArrayAsString = function(pathSegArray) {\n      var string = ''\n      var first = true\n      pathSegArray.forEach(function(pathSeg) {\n        if (first) {\n          first = false\n          string += pathSeg._asPathString()\n        } else {\n          string += ' ' + pathSeg._asPathString()\n        }\n      })\n      return string\n    }\n\n    // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.\n    window.SVGPathSegList.prototype._parsePath = function(string) {\n      if (!string || string.length == 0) return []\n\n      var owningPathSegList = this\n\n      var Builder = function() {\n        this.pathSegList = []\n      }\n\n      Builder.prototype.appendSegment = function(pathSeg) {\n        this.pathSegList.push(pathSeg)\n      }\n\n      var Source = function(string) {\n        this._string = string\n        this._currentIndex = 0\n        this._endIndex = this._string.length\n        this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN\n\n        this._skipOptionalSpaces()\n      }\n\n      Source.prototype._isCurrentSpace = function() {\n        var character = this._string[this._currentIndex]\n        return (\n          character <= ' ' &&\n          (character == ' ' ||\n            character == '\\n' ||\n            character == '\\t' ||\n            character == '\\r' ||\n            character == '\\f')\n        )\n      }\n\n      Source.prototype._skipOptionalSpaces = function() {\n        while (this._currentIndex < this._endIndex && this._isCurrentSpace())\n          this._currentIndex++\n        return this._currentIndex < this._endIndex\n      }\n\n      Source.prototype._skipOptionalSpacesOrDelimiter = function() {\n        if (\n          this._currentIndex < this._endIndex &&\n          !this._isCurrentSpace() &&\n          this._string.charAt(this._currentIndex) != ','\n        )\n          return false\n        if (this._skipOptionalSpaces()) {\n          if (\n            this._currentIndex < this._endIndex &&\n            this._string.charAt(this._currentIndex) == ','\n          ) {\n            this._currentIndex++\n            this._skipOptionalSpaces()\n          }\n        }\n        return this._currentIndex < this._endIndex\n      }\n\n      Source.prototype.hasMoreData = function() {\n        return this._currentIndex < this._endIndex\n      }\n\n      Source.prototype.peekSegmentType = function() {\n        var lookahead = this._string[this._currentIndex]\n        return this._pathSegTypeFromChar(lookahead)\n      }\n\n      Source.prototype._pathSegTypeFromChar = function(lookahead) {\n        switch (lookahead) {\n          case 'Z':\n          case 'z':\n            return window.SVGPathSeg.PATHSEG_CLOSEPATH\n          case 'M':\n            return window.SVGPathSeg.PATHSEG_MOVETO_ABS\n          case 'm':\n            return window.SVGPathSeg.PATHSEG_MOVETO_REL\n          case 'L':\n            return window.SVGPathSeg.PATHSEG_LINETO_ABS\n          case 'l':\n            return window.SVGPathSeg.PATHSEG_LINETO_REL\n          case 'C':\n            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS\n          case 'c':\n            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL\n          case 'Q':\n            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS\n          case 'q':\n            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL\n          case 'A':\n            return window.SVGPathSeg.PATHSEG_ARC_ABS\n          case 'a':\n            return window.SVGPathSeg.PATHSEG_ARC_REL\n          case 'H':\n            return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS\n          case 'h':\n            return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL\n          case 'V':\n            return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS\n          case 'v':\n            return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL\n          case 'S':\n            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS\n          case 's':\n            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL\n          case 'T':\n            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS\n          case 't':\n            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL\n          default:\n            return window.SVGPathSeg.PATHSEG_UNKNOWN\n        }\n      }\n\n      Source.prototype._nextCommandHelper = function(\n        lookahead,\n        previousCommand\n      ) {\n        // Check for remaining coordinates in the current command.\n        if (\n          (lookahead == '+' ||\n            lookahead == '-' ||\n            lookahead == '.' ||\n            (lookahead >= '0' && lookahead <= '9')) &&\n          previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH\n        ) {\n          if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS)\n            return window.SVGPathSeg.PATHSEG_LINETO_ABS\n          if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL)\n            return window.SVGPathSeg.PATHSEG_LINETO_REL\n          return previousCommand\n        }\n        return window.SVGPathSeg.PATHSEG_UNKNOWN\n      }\n\n      Source.prototype.initialCommandIsMoveTo = function() {\n        // If the path is empty it is still valid, so return true.\n        if (!this.hasMoreData()) return true\n        var command = this.peekSegmentType()\n        // Path must start with moveTo.\n        return (\n          command == window.SVGPathSeg.PATHSEG_MOVETO_ABS ||\n          command == window.SVGPathSeg.PATHSEG_MOVETO_REL\n        )\n      }\n\n      // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.\n      // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF\n      Source.prototype._parseNumber = function() {\n        var exponent = 0\n        var integer = 0\n        var frac = 1\n        var decimal = 0\n        var sign = 1\n        var expsign = 1\n\n        var startIndex = this._currentIndex\n\n        this._skipOptionalSpaces()\n\n        // Read the sign.\n        if (\n          this._currentIndex < this._endIndex &&\n          this._string.charAt(this._currentIndex) == '+'\n        )\n          this._currentIndex++\n        else if (\n          this._currentIndex < this._endIndex &&\n          this._string.charAt(this._currentIndex) == '-'\n        ) {\n          this._currentIndex++\n          sign = -1\n        }\n\n        if (\n          this._currentIndex == this._endIndex ||\n          ((this._string.charAt(this._currentIndex) < '0' ||\n            this._string.charAt(this._currentIndex) > '9') &&\n            this._string.charAt(this._currentIndex) != '.')\n        )\n          // The first character of a number must be one of [0-9+-.].\n          return undefined\n\n        // Read the integer part, build right-to-left.\n        var startIntPartIndex = this._currentIndex\n        while (\n          this._currentIndex < this._endIndex &&\n          this._string.charAt(this._currentIndex) >= '0' &&\n          this._string.charAt(this._currentIndex) <= '9'\n        )\n          this._currentIndex++ // Advance to first non-digit.\n\n        if (this._currentIndex != startIntPartIndex) {\n          var scanIntPartIndex = this._currentIndex - 1\n          var multiplier = 1\n          while (scanIntPartIndex >= startIntPartIndex) {\n            integer +=\n              multiplier * (this._string.charAt(scanIntPartIndex--) - '0')\n            multiplier *= 10\n          }\n        }\n\n        // Read the decimals.\n        if (\n          this._currentIndex < this._endIndex &&\n          this._string.charAt(this._currentIndex) == '.'\n        ) {\n          this._currentIndex++\n\n          // There must be a least one digit following the .\n          if (\n            this._currentIndex >= this._endIndex ||\n            this._string.charAt(this._currentIndex) < '0' ||\n            this._string.charAt(this._currentIndex) > '9'\n          )\n            return undefined\n          while (\n            this._currentIndex < this._endIndex &&\n            this._string.charAt(this._currentIndex) >= '0' &&\n            this._string.charAt(this._currentIndex) <= '9'\n          ) {\n            frac *= 10\n            decimal += (this._string.charAt(this._currentIndex) - '0') / frac\n            this._currentIndex += 1\n          }\n        }\n\n        // Read the exponent part.\n        if (\n          this._currentIndex != startIndex &&\n          this._currentIndex + 1 < this._endIndex &&\n          (this._string.charAt(this._currentIndex) == 'e' ||\n            this._string.charAt(this._currentIndex) == 'E') &&\n          this._string.charAt(this._currentIndex + 1) != 'x' &&\n          this._string.charAt(this._currentIndex + 1) != 'm'\n        ) {\n          this._currentIndex++\n\n          // Read the sign of the exponent.\n          if (this._string.charAt(this._currentIndex) == '+') {\n            this._currentIndex++\n          } else if (this._string.charAt(this._currentIndex) == '-') {\n            this._currentIndex++\n            expsign = -1\n          }\n\n          // There must be an exponent.\n          if (\n            this._currentIndex >= this._endIndex ||\n            this._string.charAt(this._currentIndex) < '0' ||\n            this._string.charAt(this._currentIndex) > '9'\n          )\n            return undefined\n\n          while (\n            this._currentIndex < this._endIndex &&\n            this._string.charAt(this._currentIndex) >= '0' &&\n            this._string.charAt(this._currentIndex) <= '9'\n          ) {\n            exponent *= 10\n            exponent += this._string.charAt(this._currentIndex) - '0'\n            this._currentIndex++\n          }\n        }\n\n        var number = integer + decimal\n        number *= sign\n\n        if (exponent) number *= Math.pow(10, expsign * exponent)\n\n        if (startIndex == this._currentIndex) return undefined\n\n        this._skipOptionalSpacesOrDelimiter()\n\n        return number\n      }\n\n      Source.prototype._parseArcFlag = function() {\n        if (this._currentIndex >= this._endIndex) return undefined\n        var flag = false\n        var flagChar = this._string.charAt(this._currentIndex++)\n        if (flagChar == '0') flag = false\n        else if (flagChar == '1') flag = true\n        else return undefined\n\n        this._skipOptionalSpacesOrDelimiter()\n        return flag\n      }\n\n      Source.prototype.parseSegment = function() {\n        var lookahead = this._string[this._currentIndex]\n        var command = this._pathSegTypeFromChar(lookahead)\n        if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {\n          // Possibly an implicit command. Not allowed if this is the first command.\n          if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN)\n            return null\n          command = this._nextCommandHelper(lookahead, this._previousCommand)\n          if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null\n        } else {\n          this._currentIndex++\n        }\n\n        this._previousCommand = command\n\n        switch (command) {\n          case window.SVGPathSeg.PATHSEG_MOVETO_REL:\n            return new window.SVGPathSegMovetoRel(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_MOVETO_ABS:\n            return new window.SVGPathSegMovetoAbs(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_REL:\n            return new window.SVGPathSegLinetoRel(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_ABS:\n            return new window.SVGPathSegLinetoAbs(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:\n            return new window.SVGPathSegLinetoHorizontalRel(\n              owningPathSegList,\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:\n            return new window.SVGPathSegLinetoHorizontalAbs(\n              owningPathSegList,\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:\n            return new window.SVGPathSegLinetoVerticalRel(\n              owningPathSegList,\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:\n            return new window.SVGPathSegLinetoVerticalAbs(\n              owningPathSegList,\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_CLOSEPATH:\n            this._skipOptionalSpaces()\n            return new window.SVGPathSegClosePath(owningPathSegList)\n          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              x2: this._parseNumber(),\n              y2: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            }\n            return new window.SVGPathSegCurvetoCubicRel(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1,\n              points.x2,\n              points.y2\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              x2: this._parseNumber(),\n              y2: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            }\n            return new window.SVGPathSegCurvetoCubicAbs(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1,\n              points.x2,\n              points.y2\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:\n            var points = {\n              x2: this._parseNumber(),\n              y2: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            }\n            return new window.SVGPathSegCurvetoCubicSmoothRel(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x2,\n              points.y2\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:\n            var points = {\n              x2: this._parseNumber(),\n              y2: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            }\n            return new window.SVGPathSegCurvetoCubicSmoothAbs(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x2,\n              points.y2\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            }\n            return new window.SVGPathSegCurvetoQuadraticRel(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            }\n            return new window.SVGPathSegCurvetoQuadraticAbs(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:\n            return new window.SVGPathSegCurvetoQuadraticSmoothRel(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:\n            return new window.SVGPathSegCurvetoQuadraticSmoothAbs(\n              owningPathSegList,\n              this._parseNumber(),\n              this._parseNumber()\n            )\n          case window.SVGPathSeg.PATHSEG_ARC_REL:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              arcAngle: this._parseNumber(),\n              arcLarge: this._parseArcFlag(),\n              arcSweep: this._parseArcFlag(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            }\n            return new window.SVGPathSegArcRel(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1,\n              points.arcAngle,\n              points.arcLarge,\n              points.arcSweep\n            )\n          case window.SVGPathSeg.PATHSEG_ARC_ABS:\n            var points = {\n              x1: this._parseNumber(),\n              y1: this._parseNumber(),\n              arcAngle: this._parseNumber(),\n              arcLarge: this._parseArcFlag(),\n              arcSweep: this._parseArcFlag(),\n              x: this._parseNumber(),\n              y: this._parseNumber()\n            }\n            return new window.SVGPathSegArcAbs(\n              owningPathSegList,\n              points.x,\n              points.y,\n              points.x1,\n              points.y1,\n              points.arcAngle,\n              points.arcLarge,\n              points.arcSweep\n            )\n          default:\n            throw 'Unknown path seg type.'\n        }\n      }\n\n      var builder = new Builder()\n      var source = new Source(string)\n\n      if (!source.initialCommandIsMoveTo()) return []\n      while (source.hasMoreData()) {\n        var pathSeg = source.parseSegment()\n        if (!pathSeg) return []\n        builder.appendSegment(pathSeg)\n      }\n\n      return builder.pathSegList\n    }\n  }\n})()\n\n// String.padEnd polyfill for IE11\n//\n// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd\nif (!String.prototype.padEnd) {\n  String.prototype.padEnd = function padEnd(targetLength, padString) {\n    targetLength = targetLength >> 0 //floor if number or convert non-number to 0;\n    padString = String(typeof padString !== 'undefined' ? padString : ' ')\n    if (this.length > targetLength) {\n      return String(this)\n    } else {\n      targetLength = targetLength - this.length\n      if (targetLength > padString.length) {\n        padString += padString.repeat(targetLength / padString.length) //append to original to ensure we are longer than needed\n      }\n      return String(this) + padString.slice(0, targetLength)\n    }\n  }\n}\n\n// Object.assign polyfill for IE11\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill\nif (typeof Object.assign !== 'function') {\n  // Must be writable: true, enumerable: false, configurable: true\n  Object.defineProperty(Object, 'assign', {\n    value: function assign(target, varArgs) {\n      // .length of function is 2\n      'use strict'\n      if (target === null || target === undefined) {\n        throw new TypeError('Cannot convert undefined or null to object')\n      }\n\n      var to = Object(target)\n\n      for (var index = 1; index < arguments.length; index++) {\n        var nextSource = arguments[index]\n\n        if (nextSource !== null && nextSource !== undefined) {\n          for (var nextKey in nextSource) {\n            // Avoid bugs when hasOwnProperty is shadowed\n            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n              to[nextKey] = nextSource[nextKey]\n            }\n          }\n        }\n      }\n      return to\n    },\n    writable: true,\n    configurable: true\n  })\n}\n\n/* jshint ignore:end */\n"
  },
  {
    "path": "src/region.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport { isValue } from './util'\n\nChartInternal.prototype.initRegion = function() {\n  var $$ = this\n  $$.region = $$.main\n    .append('g')\n    .attr('clip-path', $$.clipPath)\n    .attr('class', CLASS.regions)\n}\nChartInternal.prototype.updateRegion = function(duration) {\n  var $$ = this,\n    config = $$.config\n\n  // hide if arc type\n  $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible')\n\n  var mainRegion = $$.main\n    .select('.' + CLASS.regions)\n    .selectAll('.' + CLASS.region)\n    .data(config.regions)\n  var g = mainRegion.enter().append('g')\n  g.append('rect')\n    .attr('x', $$.regionX.bind($$))\n    .attr('y', $$.regionY.bind($$))\n    .attr('width', $$.regionWidth.bind($$))\n    .attr('height', $$.regionHeight.bind($$))\n    .style('fill-opacity', function(d) {\n      return isValue(d.opacity) ? d.opacity : 0.1\n    })\n  g.append('text').text($$.labelRegion.bind($$))\n  $$.mainRegion = g.merge(mainRegion).attr('class', $$.classRegion.bind($$))\n  mainRegion\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove()\n}\nChartInternal.prototype.redrawRegion = function(withTransition, transition) {\n  var $$ = this,\n    regions = $$.mainRegion,\n    regionLabels = $$.mainRegion.selectAll('text')\n  return [\n    (withTransition ? regions.transition(transition) : regions)\n      .attr('x', $$.regionX.bind($$))\n      .attr('y', $$.regionY.bind($$))\n      .attr('width', $$.regionWidth.bind($$))\n      .attr('height', $$.regionHeight.bind($$))\n      .style('fill-opacity', function(d) {\n        return isValue(d.opacity) ? d.opacity : 0.1\n      }),\n    (withTransition ? regionLabels.transition(transition) : regionLabels)\n      .attr('x', $$.labelOffsetX.bind($$))\n      .attr('y', $$.labelOffsetY.bind($$))\n      .attr('transform', $$.labelTransform.bind($$))\n      .attr('style', 'text-anchor: left;')\n  ]\n}\nChartInternal.prototype.regionX = function(d) {\n  var $$ = this,\n    config = $$.config,\n    xPos,\n    yScale = d.axis === 'y' ? $$.y : $$.y2\n  if (d.axis === 'y' || d.axis === 'y2') {\n    xPos = config.axis_rotated ? ('start' in d ? yScale(d.start) : 0) : 0\n  } else {\n    xPos = config.axis_rotated\n      ? 0\n      : 'start' in d\n      ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start)\n      : 0\n  }\n  return xPos\n}\nChartInternal.prototype.regionY = function(d) {\n  var $$ = this,\n    config = $$.config,\n    yPos,\n    yScale = d.axis === 'y' ? $$.y : $$.y2\n  if (d.axis === 'y' || d.axis === 'y2') {\n    yPos = config.axis_rotated ? 0 : 'end' in d ? yScale(d.end) : 0\n  } else {\n    yPos = config.axis_rotated\n      ? 'start' in d\n        ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start)\n        : 0\n      : 0\n  }\n  return yPos\n}\nChartInternal.prototype.regionWidth = function(d) {\n  var $$ = this,\n    config = $$.config,\n    start = $$.regionX(d),\n    end,\n    yScale = d.axis === 'y' ? $$.y : $$.y2\n  if (d.axis === 'y' || d.axis === 'y2') {\n    end = config.axis_rotated\n      ? 'end' in d\n        ? yScale(d.end)\n        : $$.width\n      : $$.width\n  } else {\n    end = config.axis_rotated\n      ? $$.width\n      : 'end' in d\n      ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end)\n      : $$.width\n  }\n  return end < start ? 0 : end - start\n}\nChartInternal.prototype.regionHeight = function(d) {\n  var $$ = this,\n    config = $$.config,\n    start = this.regionY(d),\n    end,\n    yScale = d.axis === 'y' ? $$.y : $$.y2\n  if (d.axis === 'y' || d.axis === 'y2') {\n    end = config.axis_rotated\n      ? $$.height\n      : 'start' in d\n      ? yScale(d.start)\n      : $$.height\n  } else {\n    end = config.axis_rotated\n      ? 'end' in d\n        ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end)\n        : $$.height\n      : $$.height\n  }\n  return end < start ? 0 : end - start\n}\nChartInternal.prototype.isRegionOnX = function(d) {\n  return !d.axis || d.axis === 'x'\n}\nChartInternal.prototype.labelRegion = function(d) {\n  return 'label' in d ? d.label : ''\n}\nChartInternal.prototype.labelTransform = function(d) {\n  return 'vertical' in d && d.vertical ? 'rotate(90)' : ''\n}\nChartInternal.prototype.labelOffsetX = function(d) {\n  var paddingX = 'paddingX' in d ? d.paddingX : 3\n  var paddingY = 'paddingY' in d ? d.paddingY : 3\n  return 'vertical' in d && d.vertical\n    ? this.regionY(d) + paddingY\n    : this.regionX(d) + paddingX\n}\nChartInternal.prototype.labelOffsetY = function(d) {\n  var paddingX = 'paddingX' in d ? d.paddingX : 3\n  var paddingY = 'paddingY' in d ? d.paddingY : 3\n  return 'vertical' in d && d.vertical\n    ? -(this.regionX(d) + paddingX)\n    : this.regionY(d) + 10 + paddingY\n}\n"
  },
  {
    "path": "src/scale.ts",
    "content": "import { ChartInternal } from './core'\n\nfunction c3LogScale(d3, linearScale?, logScale?) {\n  var PROJECTION = [0.01, 10]\n\n  if (!linearScale) {\n    linearScale = d3.scaleLinear()\n    linearScale.range(PROJECTION)\n  }\n\n  if (!logScale) {\n    logScale = d3.scaleLog()\n    logScale.domain(PROJECTION)\n    logScale.nice()\n  }\n\n  // copied from https://github.com/compute-io/logspace\n  function logspace(a, b, len) {\n    var arr, end, tmp, d\n\n    if (arguments.length < 3) {\n      len = 10\n    } else {\n      if (len === 0) {\n        return []\n      }\n    }\n    // Calculate the increment:\n    end = len - 1\n    d = (b - a) / end\n\n    // Build the output array...\n    arr = new Array(len)\n    tmp = a\n    arr[0] = Math.pow(10, tmp)\n    for (var i = 1; i < end; i++) {\n      tmp += d\n      arr[i] = Math.pow(10, tmp)\n    }\n    arr[end] = Math.pow(10, b)\n    return arr\n  }\n\n  function scale(x) {\n    return logScale(linearScale(x))\n  }\n\n  scale.domain = function(x) {\n    if (!arguments.length) {\n      return linearScale.domain()\n    }\n    linearScale.domain(x)\n    return scale\n  }\n\n  scale.range = function(x) {\n    if (!arguments.length) {\n      return logScale.range()\n    }\n    logScale.range(x)\n    return scale\n  }\n\n  scale.ticks = function(m) {\n    return logspace(-2, 1, m || 10).map(function(v) {\n      return linearScale.invert(v)\n    })\n  }\n\n  scale.copy = function() {\n    return c3LogScale(d3, linearScale.copy(), logScale.copy())\n  }\n\n  return scale\n}\n\nChartInternal.prototype.getScale = function(min, max, forTimeseries) {\n  return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([\n    min,\n    max\n  ])\n}\nChartInternal.prototype.getX = function(min, max, domain, offset) {\n  var $$ = this,\n    scale = $$.getScale(min, max, $$.isTimeSeries()),\n    _scale = domain ? scale.domain(domain) : scale,\n    key\n  // Define customized scale if categorized axis\n  if ($$.isCategorized()) {\n    offset =\n      offset ||\n      function() {\n        return 0\n      }\n    scale = function(d, raw) {\n      var v = _scale(d) + offset(d)\n      return raw ? v : Math.ceil(v)\n    }\n  } else {\n    scale = function(d, raw) {\n      var v = _scale(d)\n      return raw ? v : Math.ceil(v)\n    }\n  }\n  // define functions\n  for (key in _scale) {\n    scale[key] = _scale[key]\n  }\n  scale.orgDomain = function() {\n    return _scale.domain()\n  }\n  // define custom domain() for categorized axis\n  if ($$.isCategorized()) {\n    scale.domain = function(domain) {\n      if (!arguments.length) {\n        domain = this.orgDomain()\n        return [domain[0], domain[1] + 1]\n      }\n      _scale.domain(domain)\n      return scale\n    }\n  }\n  return scale\n}\n\n/**\n * Creates and configures a D3 scale instance for the given type.\n *\n * By defaults it returns a Linear scale.\n *\n * @param {String} type Type of d3-scale to create. Type can be 'linear', 'time', 'timeseries' or 'log'.\n * @param {Array} domain The scale domain such as [from, to]\n * @param {Array} range The scale's range such as [from, to]\n *\n * @return A d3-scale instance\n */\nChartInternal.prototype.getY = function(type, domain, range) {\n  let scale\n  if (type === 'timeseries' || type === 'time') {\n    scale = this.d3.scaleTime()\n  } else if (type === 'log') {\n    scale = c3LogScale(this.d3)\n  } else if (type === 'linear' || type === undefined) {\n    scale = this.d3.scaleLinear()\n  } else {\n    throw new Error(`Invalid Y axis type: \"${type}\"`)\n  }\n\n  if (domain) {\n    scale.domain(domain)\n  }\n\n  if (range) {\n    scale.range(range)\n  }\n\n  return scale\n}\nChartInternal.prototype.getYScale = function(id) {\n  return this.axis.getId(id) === 'y2' ? this.y2 : this.y\n}\nChartInternal.prototype.getSubYScale = function(id) {\n  return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY\n}\nChartInternal.prototype.updateScales = function() {\n  var $$ = this,\n    config = $$.config,\n    forInit = !$$.x\n  // update edges\n  $$.xMin = config.axis_rotated ? 1 : 0\n  $$.xMax = config.axis_rotated ? $$.height : $$.width\n  $$.yMin = config.axis_rotated ? 0 : $$.height\n  $$.yMax = config.axis_rotated ? $$.width : 1\n  $$.subXMin = $$.xMin\n  $$.subXMax = $$.xMax\n  $$.subYMin = config.axis_rotated ? 0 : $$.height2\n  $$.subYMax = config.axis_rotated ? $$.width2 : 1\n  // update scales\n  $$.x = $$.getX(\n    $$.xMin,\n    $$.xMax,\n    forInit ? undefined : $$.x.orgDomain(),\n    function() {\n      return $$.xAxis.tickOffset()\n    }\n  )\n  $$.y = $$.getY(\n    config.axis_y_type,\n    forInit ? config.axis_y_default : $$.y.domain(),\n    [$$.yMin, $$.yMax]\n  )\n  $$.y2 = $$.getY(\n    config.axis_y2_type,\n    forInit ? config.axis_y2_default : $$.y2.domain(),\n    [$$.yMin, $$.yMax]\n  )\n  $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function(d) {\n    return d % 1 ? 0 : $$.subXAxis.tickOffset()\n  })\n  $$.subY = $$.getY(\n    config.axis_y_type,\n    forInit ? config.axis_y_default : $$.subY.domain(),\n    [$$.subYMin, $$.subYMax]\n  )\n  $$.subY2 = $$.getY(\n    config.axis_y2_type,\n    forInit ? config.axis_y2_default : $$.subY2.domain(),\n    [$$.subYMin, $$.subYMax]\n  )\n  // update axes\n  $$.xAxisTickFormat = $$.axis.getXAxisTickFormat()\n  $$.xAxisTickValues = $$.axis.getXAxisTickValues()\n  $$.yAxisTickValues = $$.axis.getYAxisTickValues()\n  $$.y2AxisTickValues = $$.axis.getY2AxisTickValues()\n\n  $$.xAxis = $$.axis.getXAxis(\n    $$.x,\n    $$.xOrient,\n    $$.xAxisTickFormat,\n    $$.xAxisTickValues,\n    config.axis_x_tick_outer\n  )\n  $$.subXAxis = $$.axis.getXAxis(\n    $$.subX,\n    $$.subXOrient,\n    $$.xAxisTickFormat,\n    $$.xAxisTickValues,\n    config.axis_x_tick_outer\n  )\n  $$.yAxis = $$.axis.getYAxis(\n    'y',\n    $$.y,\n    $$.yOrient,\n    $$.yAxisTickValues,\n    config.axis_y_tick_outer\n  )\n  $$.y2Axis = $$.axis.getYAxis(\n    'y2',\n    $$.y2,\n    $$.y2Orient,\n    $$.y2AxisTickValues,\n    config.axis_y2_tick_outer\n  )\n\n  // Set initialized scales to brush and zoom\n  if (!forInit) {\n    if ($$.brush) {\n      $$.brush.updateScale($$.subX)\n    }\n  }\n  // update for arc\n  if ($$.updateArc) {\n    $$.updateArc()\n  }\n}\n"
  },
  {
    "path": "src/scss/arc.scss",
    "content": ".c3-chart-arcs-title {\n  dominant-baseline: middle;\n  font-size: 1.3em;\n}\n\n.c3-chart-arcs .c3-chart-arcs-background {\n  fill: #e0e0e0;\n  stroke: #FFF;\n}\n.c3-chart-arcs .c3-chart-arcs-gauge-unit {\n  fill: #000;\n  font-size: 16px;\n}\n.c3-chart-arcs .c3-chart-arcs-gauge-max {\n  fill: #777;\n}\n.c3-chart-arcs .c3-chart-arcs-gauge-min {\n  fill: #777;\n}\n\n.c3-chart-arc .c3-gauge-value {\n  fill: #000;\n/*  font-size: 28px !important;*/\n}\n\n.c3-chart-arc.c3-target g path {\n  opacity: 1;\n}\n\n.c3-chart-arc.c3-target.c3-focused g path {\n  opacity: 1;\n}\n"
  },
  {
    "path": "src/scss/area.scss",
    "content": ".c3-area {\n  stroke-width: 0;\n  opacity: 0.2;\n}\n"
  },
  {
    "path": "src/scss/axis.scss",
    "content": ".c3-axis-x .tick {\n}\n.c3-axis-x-label {\n}\n\n.c3-axis-y .tick {\n}\n.c3-axis-y-label {\n}\n\n.c3-axis-y2 .tick {\n}\n.c3-axis-y2-label {\n}\n"
  },
  {
    "path": "src/scss/bar.scss",
    "content": ".c3-bar {\n  stroke-width: 0;\n}\n.c3-bar._expanded_ {\n  fill-opacity: 1;\n  fill-opacity: 0.75;\n}\n"
  },
  {
    "path": "src/scss/brush.scss",
    "content": ".c3-brush .extent {\n  fill-opacity: .1;\n}\n"
  },
  {
    "path": "src/scss/chart.scss",
    "content": ".c3 svg {\n  font: 10px sans-serif;\n  -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n.c3 path, .c3 line {\n  fill: none;\n  stroke: #000;\n}\n.c3 text {\n  -webkit-user-select: none;\n     -moz-user-select: none;\n          user-select: none;\n}\n\n.c3-legend-item-tile,\n.c3-xgrid-focus,\n.c3-ygrid,\n.c3-event-rect,\n.c3-bars path {\n  shape-rendering: crispEdges;\n}\n\n.c3-chart-arc path {\n  stroke: #fff;\n}\n\n.c3-chart-arc rect {\n    stroke: white;\n    stroke-width: 1;\n}\n\n.c3-chart-arc text {\n  fill: #fff;\n  font-size: 13px;\n}\n"
  },
  {
    "path": "src/scss/focus.scss",
    "content": ".c3-target.c3-focused {\n  opacity: 1;\n}\n.c3-target.c3-focused path.c3-line, .c3-target.c3-focused path.c3-step {\n  stroke-width: 2px;\n}\n.c3-target.c3-defocused {\n  opacity: 0.3 !important;\n}\n"
  },
  {
    "path": "src/scss/grid.scss",
    "content": ".c3-grid line {\n  stroke: #aaa;\n}\n.c3-grid text {\n  fill: #aaa;\n}\n.c3-xgrid, .c3-ygrid {\n  stroke-dasharray: 3 3;\n}\n.c3-xgrid-focus {\n}\n"
  },
  {
    "path": "src/scss/legend.scss",
    "content": ".c3-legend-item {\n  font-size: 12px;\n}\n.c3-legend-item-hidden {\n  opacity: 0.15;\n}\n\n.c3-legend-background {\n  opacity: 0.75;\n  fill: white;\n  stroke: lightgray;\n  stroke-width: 1\n}\n"
  },
  {
    "path": "src/scss/line.scss",
    "content": ".c3-line {\n  stroke-width: 1px;\n}\n"
  },
  {
    "path": "src/scss/main.scss",
    "content": "/*-- Chart --*/\n\n@import 'chart';\n\n/*-- Axis --*/\n\n@import 'axis';\n\n/*-- Grid --*/\n\n@import 'grid';\n\n/*-- Text on Chart --*/\n\n@import 'text';\n\n/*-- Line --*/\n\n@import 'line';\n\n/*-- Point --*/\n\n@import 'point';\n\n/*-- Bar --*/\n\n@import 'bar';\n\n/*-- Focus --*/\n\n@import 'focus';\n\n/*-- Region --*/\n\n@import 'region';\n\n/*-- Brush --*/\n\n@import 'brush';\n\n/*-- Select - Drag --*/\n\n@import 'select_drag';\n\n/*-- Legend --*/\n\n@import 'legend';\n\n/*-- Title --*/\n\n@import 'title';\n\n/*-- Tooltip --*/\n\n@import 'tooltip';\n\n/*-- Area --*/\n\n@import 'area';\n\n/*-- Arc --*/\n\n@import 'arc';\n\n/*-- Zoom --*/\n\n@import 'zoom';\n"
  },
  {
    "path": "src/scss/point.scss",
    "content": ".c3-circle {\n  fill: currentColor;\n}\n.c3-circle._expanded_ {\n  stroke-width: 1px;\n  stroke: white;\n}\n.c3-selected-circle {\n  fill: white;\n  stroke-width: 2px;\n}\n"
  },
  {
    "path": "src/scss/region.scss",
    "content": ".c3-region {\n  fill: steelblue;\n  fill-opacity: .1;\n\n  text {\n    fill-opacity: 1;\n  }\n}\n"
  },
  {
    "path": "src/scss/select_drag.scss",
    "content": ".c3-dragarea {\n}\n"
  },
  {
    "path": "src/scss/text.scss",
    "content": ".c3-text {\n}\n\n.c3-text.c3-empty {\n  fill: #808080;\n  font-size: 2em;\n}\n"
  },
  {
    "path": "src/scss/title.scss",
    "content": ".c3-title {\n  font: 14px sans-serif;\n}\n"
  },
  {
    "path": "src/scss/tooltip.scss",
    "content": ".c3-tooltip-container {\n  z-index: 10;\n}\n.c3-tooltip {\n  border-collapse:collapse;\n  border-spacing:0;\n  background-color:#fff;\n  empty-cells:show;\n  -webkit-box-shadow: 7px 7px 12px -9px rgb(119,119,119);\n     -moz-box-shadow: 7px 7px 12px -9px rgb(119,119,119);\n          box-shadow: 7px 7px 12px -9px rgb(119,119,119);\n  opacity: 0.9;\n}\n.c3-tooltip tr {\n  border:1px solid #CCC;\n}\n.c3-tooltip th {\n  background-color: #aaa;\n  font-size:14px;\n  padding:2px 5px;\n  text-align:left;\n  color:#FFF;\n}\n.c3-tooltip td {\n  font-size:13px;\n  padding: 3px 6px;\n  background-color:#fff;\n  border-left:1px dotted #999;\n}\n.c3-tooltip td > span {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin-right: 6px;\n}\n.c3-tooltip .value {\n  text-align: right;\n}\n"
  },
  {
    "path": "src/scss/zoom.scss",
    "content": ".c3-drag-zoom.enabled{\n  pointer-events: all!important;\n  visibility: visible;\n}\n\n.c3-drag-zoom.disabled{\n    pointer-events: none!important;\n    visibility: hidden;\n}\n\n.c3-drag-zoom .extent {\n    fill-opacity: .1;\n}\n"
  },
  {
    "path": "src/selection.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\n\nChartInternal.prototype.selectPoint = function(target, d, i) {\n  var $$ = this,\n    config = $$.config,\n    cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$),\n    cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$),\n    r = $$.pointSelectR.bind($$)\n  config.data_onselected.call($$.api, d, target.node())\n  // add selected-circle on low layer g\n  $$.main\n    .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id))\n    .selectAll('.' + CLASS.selectedCircle + '-' + i)\n    .data([d])\n    .enter()\n    .append('circle')\n    .attr('class', function() {\n      return $$.generateClass(CLASS.selectedCircle, i)\n    })\n    .attr('cx', cx)\n    .attr('cy', cy)\n    .attr('stroke', function() {\n      return $$.color(d)\n    })\n    .attr('r', function(d) {\n      return $$.pointSelectR(d) * 1.4\n    })\n    .transition()\n    .duration(100)\n    .attr('r', r)\n}\nChartInternal.prototype.unselectPoint = function(target, d, i) {\n  var $$ = this\n  $$.config.data_onunselected.call($$.api, d, target.node())\n  // remove selected-circle from low layer g\n  $$.main\n    .select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id))\n    .selectAll('.' + CLASS.selectedCircle + '-' + i)\n    .transition()\n    .duration(100)\n    .attr('r', 0)\n    .remove()\n}\nChartInternal.prototype.togglePoint = function(selected, target, d, i) {\n  selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i)\n}\nChartInternal.prototype.selectPath = function(target, d) {\n  var $$ = this\n  $$.config.data_onselected.call($$, d, target.node())\n  if ($$.config.interaction_brighten) {\n    target\n      .transition()\n      .duration(100)\n      .style('fill', function() {\n        return $$.d3.rgb($$.color(d)).brighter(0.75)\n      })\n  }\n}\nChartInternal.prototype.unselectPath = function(target, d) {\n  var $$ = this\n  $$.config.data_onunselected.call($$, d, target.node())\n  if ($$.config.interaction_brighten) {\n    target\n      .transition()\n      .duration(100)\n      .style('fill', function() {\n        return $$.color(d)\n      })\n  }\n}\nChartInternal.prototype.togglePath = function(selected, target, d, i) {\n  selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i)\n}\nChartInternal.prototype.getToggle = function(that, d) {\n  var $$ = this,\n    toggle\n  if (that.nodeName === 'circle') {\n    if ($$.isStepType(d)) {\n      // circle is hidden in step chart, so treat as within the click area\n      toggle = function() {} // TODO: how to select step chart?\n    } else {\n      toggle = $$.togglePoint\n    }\n  } else if (that.nodeName === 'path') {\n    toggle = $$.togglePath\n  }\n  return toggle\n}\nChartInternal.prototype.toggleShape = function(that, d, i) {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    shape = d3.select(that),\n    isSelected = shape.classed(CLASS.SELECTED),\n    toggle = $$.getToggle(that, d).bind($$)\n\n  if (config.data_selection_enabled && config.data_selection_isselectable(d)) {\n    if (!config.data_selection_multiple) {\n      $$.main\n        .selectAll(\n          '.' +\n            CLASS.shapes +\n            (config.data_selection_grouped\n              ? $$.getTargetSelectorSuffix(d.id)\n              : '')\n        )\n        .selectAll('.' + CLASS.shape)\n        .each(function(d, i) {\n          var shape = d3.select(this)\n          if (shape.classed(CLASS.SELECTED)) {\n            toggle(false, shape.classed(CLASS.SELECTED, false), d, i)\n          }\n        })\n    }\n    shape.classed(CLASS.SELECTED, !isSelected)\n    toggle(!isSelected, shape, d, i)\n  }\n}\n"
  },
  {
    "path": "src/shape.bar.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport { getBBox, isValue, isWithinBox } from './util'\n\nChartInternal.prototype.initBar = function() {\n  var $$ = this\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartBars)\n}\nChartInternal.prototype.updateTargetsForBar = function(targets) {\n  var $$ = this,\n    config = $$.config,\n    mainBars,\n    mainBarEnter,\n    classChartBar = $$.classChartBar.bind($$),\n    classBars = $$.classBars.bind($$),\n    classFocus = $$.classFocus.bind($$)\n  mainBars = $$.main\n    .select('.' + CLASS.chartBars)\n    .selectAll('.' + CLASS.chartBar)\n    .data(targets)\n    .attr('class', function(d) {\n      return classChartBar(d) + classFocus(d)\n    })\n  mainBarEnter = mainBars\n    .enter()\n    .append('g')\n    .attr('class', classChartBar)\n    .style('pointer-events', 'none')\n  // Bars for each data\n  mainBarEnter\n    .append('g')\n    .attr('class', classBars)\n    .style('cursor', function(d) {\n      return config.data_selection_isselectable(d) ? 'pointer' : null\n    })\n}\nChartInternal.prototype.updateBar = function(durationForExit) {\n  var $$ = this,\n    barData = $$.barData.bind($$),\n    classBar = $$.classBar.bind($$),\n    initialOpacity = $$.initialOpacity.bind($$),\n    color = function(d) {\n      return $$.color(d.id)\n    }\n  var mainBar = $$.main\n    .selectAll('.' + CLASS.bars)\n    .selectAll('.' + CLASS.bar)\n    .data(barData)\n  var mainBarEnter = mainBar\n    .enter()\n    .append('path')\n    .attr('class', classBar)\n    .style('stroke', color)\n    .style('fill', color)\n  $$.mainBar = mainBarEnter.merge(mainBar).style('opacity', initialOpacity)\n  mainBar\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n}\nChartInternal.prototype.redrawBar = function(\n  drawBar,\n  withTransition,\n  transition\n) {\n  const $$ = this\n\n  return [\n    (withTransition ? this.mainBar.transition(transition) : this.mainBar)\n      .attr('d', drawBar)\n      .style('stroke', this.color)\n      .style('fill', this.color)\n      .style('opacity', d => ($$.isTargetToShow(d.id) ? 1 : 0))\n  ]\n}\nChartInternal.prototype.getBarW = function(axis, barTargetsNum) {\n  var $$ = this,\n    config = $$.config,\n    w =\n      typeof config.bar_width === 'number'\n        ? config.bar_width\n        : barTargetsNum\n        ? (axis.tickInterval() * config.bar_width_ratio) / barTargetsNum\n        : 0\n  return config.bar_width_max && w > config.bar_width_max\n    ? config.bar_width_max\n    : w\n}\nChartInternal.prototype.getBars = function(i, id) {\n  var $$ = this\n  return (id\n    ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id))\n    : $$.main\n  ).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''))\n}\nChartInternal.prototype.expandBars = function(i, id, reset) {\n  var $$ = this\n  if (reset) {\n    $$.unexpandBars()\n  }\n  $$.getBars(i, id).classed(CLASS.EXPANDED, true)\n}\nChartInternal.prototype.unexpandBars = function(i) {\n  var $$ = this\n  $$.getBars(i).classed(CLASS.EXPANDED, false)\n}\nChartInternal.prototype.generateDrawBar = function(barIndices, isSub) {\n  var $$ = this,\n    config = $$.config,\n    getPoints = $$.generateGetBarPoints(barIndices, isSub)\n  return function(d, i) {\n    // 4 points that make a bar\n    var points = getPoints(d, i)\n\n    // switch points if axis is rotated, not applicable for sub chart\n    var indexX = config.axis_rotated ? 1 : 0\n    var indexY = config.axis_rotated ? 0 : 1\n\n    var path =\n      'M ' +\n      points[0][indexX] +\n      ',' +\n      points[0][indexY] +\n      ' ' +\n      'L' +\n      points[1][indexX] +\n      ',' +\n      points[1][indexY] +\n      ' ' +\n      'L' +\n      points[2][indexX] +\n      ',' +\n      points[2][indexY] +\n      ' ' +\n      'L' +\n      points[3][indexX] +\n      ',' +\n      points[3][indexY] +\n      ' ' +\n      'z'\n\n    return path\n  }\n}\nChartInternal.prototype.generateGetBarPoints = function(barIndices, isSub) {\n  var $$ = this,\n    axis = isSub ? $$.subXAxis : $$.xAxis,\n    barTargetsNum = barIndices.__max__ + 1,\n    barW = $$.getBarW(axis, barTargetsNum),\n    barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub),\n    barY = $$.getShapeY(!!isSub),\n    barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub),\n    barSpaceOffset = barW * ($$.config.bar_space / 2),\n    yScale = isSub ? $$.getSubYScale : $$.getYScale\n  return function(d, i) {\n    var y0 = yScale.call($$, d.id)(0),\n      offset = barOffset(d, i) || y0, // offset is for stacked bar chart\n      posX = barX(d),\n      posY = barY(d)\n    // fix posY not to overflow opposite quadrant\n    if ($$.config.axis_rotated) {\n      if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\n        posY = y0\n      }\n    }\n\n    posY -= y0 - offset\n\n    // 4 points that make a bar\n    return [\n      [posX + barSpaceOffset, offset],\n      [posX + barSpaceOffset, posY],\n      [posX + barW - barSpaceOffset, posY],\n      [posX + barW - barSpaceOffset, offset]\n    ]\n  }\n}\n\n/**\n * Returns whether the data point is within the given bar shape.\n *\n * @param mouse\n * @param barShape\n * @return {boolean}\n */\nChartInternal.prototype.isWithinBar = function(mouse, barShape) {\n  return isWithinBox(mouse, getBBox(barShape), 2)\n}\n"
  },
  {
    "path": "src/shape.line.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport { isValue, isFunction, isUndefined, isDefined } from './util'\n\nChartInternal.prototype.initLine = function() {\n  var $$ = this\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartLines)\n}\nChartInternal.prototype.updateTargetsForLine = function(targets) {\n  var $$ = this,\n    config = $$.config,\n    mainLines,\n    mainLineEnter,\n    classChartLine = $$.classChartLine.bind($$),\n    classLines = $$.classLines.bind($$),\n    classAreas = $$.classAreas.bind($$),\n    classCircles = $$.classCircles.bind($$),\n    classFocus = $$.classFocus.bind($$)\n  mainLines = $$.main\n    .select('.' + CLASS.chartLines)\n    .selectAll('.' + CLASS.chartLine)\n    .data(targets)\n    .attr('class', function(d) {\n      return classChartLine(d) + classFocus(d)\n    })\n  mainLineEnter = mainLines\n    .enter()\n    .append('g')\n    .attr('class', classChartLine)\n    .style('opacity', 0)\n    .style('pointer-events', 'none')\n  // Lines for each data\n  mainLineEnter.append('g').attr('class', classLines)\n  // Areas\n  mainLineEnter.append('g').attr('class', classAreas)\n  // Circles for each data point on lines\n  mainLineEnter.append('g').attr('class', function(d) {\n    return $$.generateClass(CLASS.selectedCircles, d.id)\n  })\n  mainLineEnter\n    .append('g')\n    .attr('class', classCircles)\n    .style('cursor', function(d) {\n      return config.data_selection_isselectable(d) ? 'pointer' : null\n    })\n  // Update date for selected circles\n  targets.forEach(function(t) {\n    $$.main\n      .selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id))\n      .selectAll('.' + CLASS.selectedCircle)\n      .each(function(d) {\n        d.value = t.values[d.index].value\n      })\n  })\n  // MEMO: can not keep same color...\n  //mainLineUpdate.exit().remove();\n}\nChartInternal.prototype.updateLine = function(durationForExit) {\n  var $$ = this\n  var mainLine = $$.main\n    .selectAll('.' + CLASS.lines)\n    .selectAll('.' + CLASS.line)\n    .data($$.lineData.bind($$))\n  var mainLineEnter = mainLine\n    .enter()\n    .append('path')\n    .attr('class', $$.classLine.bind($$))\n    .style('stroke', $$.color)\n  $$.mainLine = mainLineEnter\n    .merge(mainLine)\n    .style('opacity', $$.initialOpacity.bind($$))\n    .style('shape-rendering', function(d) {\n      return $$.isStepType(d) ? 'crispEdges' : ''\n    })\n    .attr('transform', null)\n  mainLine\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n}\nChartInternal.prototype.redrawLine = function(\n  drawLine,\n  withTransition,\n  transition\n) {\n  return [\n    (withTransition ? this.mainLine.transition(transition) : this.mainLine)\n      .attr('d', drawLine)\n      .style('stroke', this.color)\n      .style('opacity', 1)\n  ]\n}\nChartInternal.prototype.generateDrawLine = function(lineIndices, isSub) {\n  var $$ = this,\n    config = $$.config,\n    line = $$.d3.line(),\n    getPoints = $$.generateGetLinePoints(lineIndices, isSub),\n    yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,\n    xValue = function(d) {\n      return (isSub ? $$.subxx : $$.xx).call($$, d)\n    },\n    yValue = function(d, i) {\n      return config.data_groups.length > 0\n        ? getPoints(d, i)[0][1]\n        : yScaleGetter.call($$, d.id)(d.value)\n    }\n\n  line = config.axis_rotated\n    ? line.x(yValue).y(xValue)\n    : line.x(xValue).y(yValue)\n  if (!config.line_connectNull) {\n    line = line.defined(function(d) {\n      return d.value != null\n    })\n  }\n  return function(d) {\n    var values = config.line_connectNull\n        ? $$.filterRemoveNull(d.values)\n        : d.values,\n      x = isSub ? $$.subX : $$.x,\n      y = yScaleGetter.call($$, d.id),\n      x0 = 0,\n      y0 = 0,\n      path\n    if ($$.isLineType(d)) {\n      if (config.data_regions[d.id]) {\n        path = $$.lineWithRegions(values, x, y, config.data_regions[d.id])\n      } else {\n        if ($$.isStepType(d)) {\n          values = $$.convertValuesToStep(values)\n        }\n        path = line.curve($$.getInterpolate(d))(values)\n      }\n    } else {\n      if (values[0]) {\n        x0 = x(values[0].x)\n        y0 = y(values[0].value)\n      }\n      path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0\n    }\n    return path ? path : 'M 0 0'\n  }\n}\nChartInternal.prototype.generateGetLinePoints = function(lineIndices, isSub) {\n  // partial duplication of generateGetBarPoints\n  var $$ = this,\n    config = $$.config,\n    lineTargetsNum = lineIndices.__max__ + 1,\n    x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub),\n    y = $$.getShapeY(!!isSub),\n    lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub),\n    yScale = isSub ? $$.getSubYScale : $$.getYScale\n  return function(d, i) {\n    var y0 = yScale.call($$, d.id)(0),\n      offset = lineOffset(d, i) || y0, // offset is for stacked area chart\n      posX = x(d),\n      posY = y(d)\n    // fix posY not to overflow opposite quadrant\n    if (config.axis_rotated) {\n      if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\n        posY = y0\n      }\n    }\n    // 1 point that marks the line position\n    return [\n      [posX, posY - (y0 - offset)],\n      [posX, posY - (y0 - offset)], // needed for compatibility\n      [posX, posY - (y0 - offset)], // needed for compatibility\n      [posX, posY - (y0 - offset)] // needed for compatibility\n    ]\n  }\n}\n\nChartInternal.prototype.lineWithRegions = function(d, x, y, _regions) {\n  var $$ = this,\n    config = $$.config,\n    prev = -1,\n    i,\n    j,\n    s = 'M',\n    sWithRegion,\n    xp,\n    yp,\n    dx,\n    dy,\n    dd,\n    diff,\n    diffx2,\n    xOffset = $$.isCategorized() ? 0.5 : 0,\n    xValue,\n    yValue,\n    regions = []\n\n  function isWithinRegions(x, regions) {\n    var i\n    for (i = 0; i < regions.length; i++) {\n      if (regions[i].start < x && x <= regions[i].end) {\n        return true\n      }\n    }\n    return false\n  }\n\n  // Check start/end of regions\n  if (isDefined(_regions)) {\n    for (i = 0; i < _regions.length; i++) {\n      regions[i] = {}\n      if (isUndefined(_regions[i].start)) {\n        regions[i].start = d[0].x\n      } else {\n        regions[i].start = $$.isTimeSeries()\n          ? $$.parseDate(_regions[i].start)\n          : _regions[i].start\n      }\n      if (isUndefined(_regions[i].end)) {\n        regions[i].end = d[d.length - 1].x\n      } else {\n        regions[i].end = $$.isTimeSeries()\n          ? $$.parseDate(_regions[i].end)\n          : _regions[i].end\n      }\n    }\n  }\n\n  // Set scales\n  xValue = config.axis_rotated\n    ? function(d) {\n        return y(d.value)\n      }\n    : function(d) {\n        return x(d.x)\n      }\n  yValue = config.axis_rotated\n    ? function(d) {\n        return x(d.x)\n      }\n    : function(d) {\n        return y(d.value)\n      }\n\n  // Define svg generator function for region\n  function generateM(points) {\n    return (\n      'M' +\n      points[0][0] +\n      ' ' +\n      points[0][1] +\n      ' ' +\n      points[1][0] +\n      ' ' +\n      points[1][1]\n    )\n  }\n  if ($$.isTimeSeries()) {\n    sWithRegion = function(d0, d1, j, diff) {\n      var x0 = d0.x.getTime(),\n        x_diff = d1.x - d0.x,\n        xv0 = new Date(x0 + x_diff * j),\n        xv1 = new Date(x0 + x_diff * (j + diff)),\n        points\n      if (config.axis_rotated) {\n        points = [\n          [y(yp(j)), x(xv0)],\n          [y(yp(j + diff)), x(xv1)]\n        ]\n      } else {\n        points = [\n          [x(xv0), y(yp(j))],\n          [x(xv1), y(yp(j + diff))]\n        ]\n      }\n      return generateM(points)\n    }\n  } else {\n    sWithRegion = function(d0, d1, j, diff) {\n      var points\n      if (config.axis_rotated) {\n        points = [\n          [y(yp(j), true), x(xp(j))],\n          [y(yp(j + diff), true), x(xp(j + diff))]\n        ]\n      } else {\n        points = [\n          [x(xp(j), true), y(yp(j))],\n          [x(xp(j + diff), true), y(yp(j + diff))]\n        ]\n      }\n      return generateM(points)\n    }\n  }\n\n  // Generate\n  for (i = 0; i < d.length; i++) {\n    // Draw as normal\n    if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) {\n      s += ' ' + xValue(d[i]) + ' ' + yValue(d[i])\n    }\n    // Draw with region // TODO: Fix for horizotal charts\n    else {\n      xp = $$.getScale(\n        d[i - 1].x + xOffset,\n        d[i].x + xOffset,\n        $$.isTimeSeries()\n      )\n      yp = $$.getScale(d[i - 1].value, d[i].value)\n\n      dx = x(d[i].x) - x(d[i - 1].x)\n      dy = y(d[i].value) - y(d[i - 1].value)\n      dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2))\n      diff = 2 / dd\n      diffx2 = diff * 2\n\n      for (j = diff; j <= 1; j += diffx2) {\n        s += sWithRegion(d[i - 1], d[i], j, diff)\n      }\n    }\n    prev = d[i].x\n  }\n\n  return s\n}\n\nChartInternal.prototype.updateArea = function(durationForExit) {\n  var $$ = this,\n    d3 = $$.d3\n  var mainArea = $$.main\n    .selectAll('.' + CLASS.areas)\n    .selectAll('.' + CLASS.area)\n    .data($$.lineData.bind($$))\n  var mainAreaEnter = mainArea\n    .enter()\n    .append('path')\n    .attr('class', $$.classArea.bind($$))\n    .style('fill', $$.color)\n    .style('opacity', function() {\n      $$.orgAreaOpacity = +d3.select(this).style('opacity')\n      return 0\n    })\n  $$.mainArea = mainAreaEnter\n    .merge(mainArea)\n    .style('opacity', $$.orgAreaOpacity)\n  mainArea\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n}\nChartInternal.prototype.redrawArea = function(\n  drawArea,\n  withTransition,\n  transition\n) {\n  return [\n    (withTransition ? this.mainArea.transition(transition) : this.mainArea)\n      .attr('d', drawArea)\n      .style('fill', this.color)\n      .style('opacity', this.orgAreaOpacity)\n  ]\n}\nChartInternal.prototype.generateDrawArea = function(areaIndices, isSub) {\n  var $$ = this,\n    config = $$.config,\n    area = $$.d3.area(),\n    getPoints = $$.generateGetAreaPoints(areaIndices, isSub),\n    yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,\n    xValue = function(d) {\n      return (isSub ? $$.subxx : $$.xx).call($$, d)\n    },\n    value0 = function(d, i) {\n      return config.data_groups.length > 0\n        ? getPoints(d, i)[0][1]\n        : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id))\n    },\n    value1 = function(d, i) {\n      return config.data_groups.length > 0\n        ? getPoints(d, i)[1][1]\n        : yScaleGetter.call($$, d.id)(d.value)\n    }\n\n  area = config.axis_rotated\n    ? area\n        .x0(value0)\n        .x1(value1)\n        .y(xValue)\n    : area\n        .x(xValue)\n        .y0(config.area_above ? 0 : value0)\n        .y1(value1)\n  if (!config.line_connectNull) {\n    area = area.defined(function(d) {\n      return d.value !== null\n    })\n  }\n\n  return function(d) {\n    var values = config.line_connectNull\n        ? $$.filterRemoveNull(d.values)\n        : d.values,\n      x0 = 0,\n      y0 = 0,\n      path\n    if ($$.isAreaType(d)) {\n      if ($$.isStepType(d)) {\n        values = $$.convertValuesToStep(values)\n      }\n      path = area.curve($$.getInterpolate(d))(values)\n    } else {\n      if (values[0]) {\n        x0 = $$.x(values[0].x)\n        y0 = $$.getYScale(d.id)(values[0].value)\n      }\n      path = config.axis_rotated ? 'M ' + y0 + ' ' + x0 : 'M ' + x0 + ' ' + y0\n    }\n    return path ? path : 'M 0 0'\n  }\n}\nChartInternal.prototype.getAreaBaseValue = function() {\n  return 0\n}\nChartInternal.prototype.generateGetAreaPoints = function(areaIndices, isSub) {\n  // partial duplication of generateGetBarPoints\n  var $$ = this,\n    config = $$.config,\n    areaTargetsNum = areaIndices.__max__ + 1,\n    x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub),\n    y = $$.getShapeY(!!isSub),\n    areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub),\n    yScale = isSub ? $$.getSubYScale : $$.getYScale\n  return function(d, i) {\n    var y0 = yScale.call($$, d.id)(0),\n      offset = areaOffset(d, i) || y0, // offset is for stacked area chart\n      posX = x(d),\n      posY = y(d)\n    // fix posY not to overflow opposite quadrant\n    if (config.axis_rotated) {\n      if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) {\n        posY = y0\n      }\n    }\n    // 1 point that marks the area position\n    return [\n      [posX, offset],\n      [posX, posY - (y0 - offset)],\n      [posX, posY - (y0 - offset)], // needed for compatibility\n      [posX, offset] // needed for compatibility\n    ]\n  }\n}\n\nChartInternal.prototype.updateCircle = function(cx, cy) {\n  var $$ = this\n  var mainCircle = $$.main\n    .selectAll('.' + CLASS.circles)\n    .selectAll('.' + CLASS.circle)\n    .data($$.lineOrScatterOrStanfordData.bind($$))\n\n  var mainCircleEnter = mainCircle\n    .enter()\n    .append('circle')\n    .attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '')\n    .attr('class', $$.classCircle.bind($$))\n    .attr('cx', cx)\n    .attr('cy', cy)\n    .attr('r', $$.pointR.bind($$))\n    .style(\n      'color',\n      $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color\n    )\n\n  $$.mainCircle = mainCircleEnter\n    .merge(mainCircle)\n    .style(\n      'opacity',\n      $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$)\n    )\n\n  mainCircle.exit().style('opacity', 0)\n}\nChartInternal.prototype.redrawCircle = function(\n  cx,\n  cy,\n  withTransition,\n  transition\n) {\n  var $$ = this,\n    selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle)\n  return [\n    (withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle)\n      .style('opacity', this.opacityForCircle.bind($$))\n      .style(\n        'color',\n        $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color\n      )\n      .attr('cx', cx)\n      .attr('cy', cy),\n    (withTransition ? selectedCircles.transition(transition) : selectedCircles)\n      .attr('cx', cx)\n      .attr('cy', cy)\n  ]\n}\nChartInternal.prototype.circleX = function(d) {\n  return d.x || d.x === 0 ? this.x(d.x) : null\n}\nChartInternal.prototype.updateCircleY = function() {\n  var $$ = this,\n    lineIndices,\n    getPoints\n  if ($$.config.data_groups.length > 0) {\n    ;(lineIndices = $$.getShapeIndices($$.isLineType)),\n      (getPoints = $$.generateGetLinePoints(lineIndices))\n    $$.circleY = function(d, i) {\n      return getPoints(d, i)[0][1]\n    }\n  } else {\n    $$.circleY = function(d) {\n      return $$.getYScale(d.id)(d.value)\n    }\n  }\n}\nChartInternal.prototype.getCircles = function(i, id) {\n  var $$ = this\n  return (id\n    ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id))\n    : $$.main\n  ).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''))\n}\nChartInternal.prototype.expandCircles = function(i, id, reset) {\n  var $$ = this,\n    r = $$.pointExpandedR.bind($$)\n  if (reset) {\n    $$.unexpandCircles()\n  }\n  $$.getCircles(i, id)\n    .classed(CLASS.EXPANDED, true)\n    .attr('r', r)\n}\nChartInternal.prototype.unexpandCircles = function(i) {\n  var $$ = this,\n    r = $$.pointR.bind($$)\n  $$.getCircles(i)\n    .filter(function() {\n      return $$.d3.select(this).classed(CLASS.EXPANDED)\n    })\n    .classed(CLASS.EXPANDED, false)\n    .attr('r', r)\n}\nChartInternal.prototype.pointR = function(d) {\n  var $$ = this,\n    config = $$.config\n  return $$.isStepType(d)\n    ? 0\n    : isFunction(config.point_r)\n    ? config.point_r(d)\n    : config.point_r\n}\nChartInternal.prototype.pointExpandedR = function(d) {\n  var $$ = this,\n    config = $$.config\n  if (config.point_focus_expand_enabled) {\n    return isFunction(config.point_focus_expand_r)\n      ? config.point_focus_expand_r(d)\n      : config.point_focus_expand_r\n      ? config.point_focus_expand_r\n      : $$.pointR(d) * 1.75\n  } else {\n    return $$.pointR(d)\n  }\n}\nChartInternal.prototype.pointSelectR = function(d) {\n  var $$ = this,\n    config = $$.config\n  return isFunction(config.point_select_r)\n    ? config.point_select_r(d)\n    : config.point_select_r\n    ? config.point_select_r\n    : $$.pointR(d) * 4\n}\nChartInternal.prototype.isWithinCircle = function(that, r) {\n  var d3 = this.d3,\n    mouse = d3.mouse(that),\n    d3_this = d3.select(that),\n    cx = +d3_this.attr('cx'),\n    cy = +d3_this.attr('cy')\n  return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r\n}\nChartInternal.prototype.isWithinStep = function(that, y) {\n  return Math.abs(y - this.d3.mouse(that)[1]) < 30\n}\n"
  },
  {
    "path": "src/shape.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport { isUndefined } from './util'\n\nChartInternal.prototype.getShapeIndices = function(typeFilter) {\n  var $$ = this,\n    config = $$.config,\n    indices = {},\n    i = 0,\n    j,\n    k\n  $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(\n    function(d) {\n      for (j = 0; j < config.data_groups.length; j++) {\n        if (config.data_groups[j].indexOf(d.id) < 0) {\n          continue\n        }\n        for (k = 0; k < config.data_groups[j].length; k++) {\n          if (config.data_groups[j][k] in indices) {\n            indices[d.id] = indices[config.data_groups[j][k]]\n            break\n          }\n        }\n      }\n      if (isUndefined(indices[d.id])) {\n        indices[d.id] = i++\n      }\n    }\n  )\n  ;(indices as any).__max__ = i - 1\n  return indices\n}\nChartInternal.prototype.getShapeX = function(\n  offset,\n  targetsNum,\n  indices,\n  isSub\n) {\n  var $$ = this,\n    scale = isSub ? $$.subX : $$.x\n  return function(d) {\n    var index = d.id in indices ? indices[d.id] : 0\n    return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0\n  }\n}\nChartInternal.prototype.getShapeY = function(isSub) {\n  const $$ = this\n\n  return function(d) {\n    const scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id)\n    return scale(\n      $$.isTargetNormalized(d.id) ? $$.getRatio('index', d, true) : d.value\n    )\n  }\n}\nChartInternal.prototype.getShapeOffset = function(typeFilter, indices, isSub) {\n  var $$ = this,\n    targets = $$.orderTargets(\n      $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))\n    ),\n    targetIds = targets.map(function(t) {\n      return t.id\n    })\n  return function(d, i) {\n    var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id),\n      y0 = scale(0),\n      offset = y0\n    targets.forEach(function(t) {\n      const rowValues = $$.isStepType(d)\n        ? $$.convertValuesToStep(t.values)\n        : t.values\n      const isTargetNormalized = $$.isTargetNormalized(d.id)\n      const values = rowValues.map(v =>\n        isTargetNormalized ? $$.getRatio('index', v, true) : v.value\n      )\n\n      if (t.id === d.id || indices[t.id] !== indices[d.id]) {\n        return\n      }\n      if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) {\n        // check if the x values line up\n        if (isUndefined(rowValues[i]) || +rowValues[i].x !== +d.x) {\n          // \"+\" for timeseries\n          // if not, try to find the value that does line up\n          i = -1\n          rowValues.forEach(function(v, j) {\n            const x1 = v.x.constructor === Date ? +v.x : v.x\n            const x2 = d.x.constructor === Date ? +d.x : d.x\n\n            if (x1 === x2) {\n              i = j\n            }\n          })\n        }\n        if (i in rowValues && rowValues[i].value * d.value >= 0) {\n          offset += scale(values[i]) - y0\n        }\n      }\n    })\n    return offset\n  }\n}\nChartInternal.prototype.isWithinShape = function(that, d) {\n  var $$ = this,\n    shape = $$.d3.select(that),\n    isWithin\n  if (!$$.isTargetToShow(d.id)) {\n    isWithin = false\n  } else if (that.nodeName === 'circle') {\n    isWithin = $$.isStepType(d)\n      ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value))\n      : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5)\n  } else if (that.nodeName === 'path') {\n    isWithin = shape.classed(CLASS.bar)\n      ? $$.isWithinBar($$.d3.mouse(that), that)\n      : true\n  }\n  return isWithin\n}\n\nChartInternal.prototype.getInterpolate = function(d) {\n  var $$ = this,\n    d3 = $$.d3,\n    types = {\n      linear: d3.curveLinear,\n      'linear-closed': d3.curveLinearClosed,\n      basis: d3.curveBasis,\n      'basis-open': d3.curveBasisOpen,\n      'basis-closed': d3.curveBasisClosed,\n      bundle: d3.curveBundle,\n      cardinal: d3.curveCardinal,\n      'cardinal-open': d3.curveCardinalOpen,\n      'cardinal-closed': d3.curveCardinalClosed,\n      monotone: d3.curveMonotoneX,\n      step: d3.curveStep,\n      'step-before': d3.curveStepBefore,\n      'step-after': d3.curveStepAfter\n    },\n    type\n\n  if ($$.isSplineType(d)) {\n    type = types[$$.config.spline_interpolation_type] || types.cardinal\n  } else if ($$.isStepType(d)) {\n    type = types[$$.config.line_step_type]\n  } else {\n    type = types.linear\n  }\n  return type\n}\n"
  },
  {
    "path": "src/size.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport { isValue, ceil10, isDefined } from './util'\n\nChartInternal.prototype.getCurrentWidth = function() {\n  var $$ = this,\n    config = $$.config\n  return config.size_width ? config.size_width : $$.getParentWidth()\n}\nChartInternal.prototype.getCurrentHeight = function() {\n  var $$ = this,\n    config = $$.config,\n    h = config.size_height ? config.size_height : $$.getParentHeight()\n  return h > 0\n    ? h\n    : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1)\n}\nChartInternal.prototype.getCurrentPaddingTop = function() {\n  var $$ = this,\n    config = $$.config,\n    padding = isValue(config.padding_top) ? config.padding_top : 0\n  if ($$.title && $$.title.node()) {\n    padding += $$.getTitlePadding()\n  }\n  return padding\n}\nChartInternal.prototype.getCurrentPaddingBottom = function() {\n  var config = this.config\n  return isValue(config.padding_bottom) ? config.padding_bottom : 0\n}\nChartInternal.prototype.getCurrentPaddingLeft = function(withoutRecompute) {\n  var $$ = this,\n    config = $$.config\n  if (isValue(config.padding_left)) {\n    return config.padding_left\n  } else if (config.axis_rotated) {\n    return !config.axis_x_show || config.axis_x_inner\n      ? 1\n      : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40)\n  } else if (!config.axis_y_show || config.axis_y_inner) {\n    // && !config.axis_rotated\n    return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1\n  } else {\n    return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute))\n  }\n}\nChartInternal.prototype.getCurrentPaddingRight = function() {\n  var $$ = this,\n    config = $$.config,\n    padding = 0,\n    defaultPadding = 10,\n    legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0\n\n  if (isValue(config.padding_right)) {\n    padding = config.padding_right + 1 // 1 is needed not to hide tick line\n  } else if (config.axis_rotated) {\n    padding = defaultPadding + legendWidthOnRight\n  } else if (!config.axis_y2_show || config.axis_y2_inner) {\n    // && !config.axis_rotated\n    padding =\n      2 +\n      legendWidthOnRight +\n      ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0)\n  } else {\n    padding = ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight\n  }\n\n  if ($$.colorScale && $$.colorScale.node()) {\n    padding += $$.getColorScalePadding()\n  }\n\n  return padding\n}\n\nChartInternal.prototype.getParentRectValue = function(key) {\n  var parent = this.selectChart.node(),\n    v\n  while (parent && parent.tagName !== 'BODY') {\n    try {\n      v = parent.getBoundingClientRect()[key]\n    } catch (e) {\n      if (key === 'width') {\n        // In IE in certain cases getBoundingClientRect\n        // will cause an \"unspecified error\"\n        v = parent.offsetWidth\n      }\n    }\n    if (v) {\n      break\n    }\n    parent = parent.parentNode\n  }\n  return v\n}\nChartInternal.prototype.getParentWidth = function() {\n  return this.getParentRectValue('width')\n}\nChartInternal.prototype.getParentHeight = function() {\n  var h = this.selectChart.style('height')\n  return h.indexOf('px') > 0 ? +h.replace('px', '') : 0\n}\n\nChartInternal.prototype.getSvgLeft = function(withoutRecompute) {\n  var $$ = this,\n    config = $$.config,\n    hasLeftAxisRect =\n      config.axis_rotated || (!config.axis_rotated && !config.axis_y_inner),\n    leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY,\n    leftAxis = $$.main.select('.' + leftAxisClass).node(),\n    svgRect =\n      leftAxis && hasLeftAxisRect\n        ? leftAxis.getBoundingClientRect()\n        : { right: 0 },\n    chartRect = $$.selectChart.node().getBoundingClientRect(),\n    hasArc = $$.hasArcType(),\n    svgLeft =\n      svgRect.right -\n      chartRect.left -\n      (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute))\n  return svgLeft > 0 ? svgLeft : 0\n}\n\nChartInternal.prototype.getAxisWidthByAxisId = function(id, withoutRecompute) {\n  var $$ = this,\n    position = $$.axis.getLabelPositionById(id)\n  return (\n    $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40)\n  )\n}\nChartInternal.prototype.getHorizontalAxisHeight = function(axisId, isSubchart) {\n  var $$ = this,\n    config = $$.config,\n    h = 30\n  if (axisId === 'x' && !(isDefined(isSubchart) && isSubchart ? config.subchart_axis_x_show : config.axis_x_show)) {\n    return 8\n  }\n  if (axisId === 'x' && config.axis_x_height) {\n    return config.axis_x_height\n  }\n  if (axisId === 'y' && !config.axis_y_show) {\n    return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1\n  }\n  if (axisId === 'y2' && !config.axis_y2_show) {\n    return $$.rotated_padding_top\n  }\n  // Calculate x axis height when tick rotated\n  if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {\n    h =\n      30 +\n      $$.axis.getMaxTickWidth(axisId) *\n        Math.cos((Math.PI * (90 - Math.abs(config.axis_x_tick_rotate))) / 180)\n  }\n  // Calculate y axis height when tick rotated\n  if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) {\n    h =\n      30 +\n      $$.axis.getMaxTickWidth(axisId) *\n        Math.cos((Math.PI * (90 - Math.abs(config.axis_y_tick_rotate))) / 180)\n  }\n  return (\n    h +\n    ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) +\n    (axisId === 'y2' ? -10 : 0)\n  )\n}\n"
  },
  {
    "path": "src/stanford.ts",
    "content": "import { ChartInternal } from './core'\nimport { isFunction, sanitise } from './util'\n\nChartInternal.prototype.isStanfordGraphType = function() {\n  var $$ = this\n\n  return $$.config.data_type === 'stanford'\n}\n\nChartInternal.prototype.initStanfordData = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    target = $$.data.targets[0],\n    epochs,\n    maxEpochs,\n    minEpochs\n\n  // Make larger values appear on top\n  target.values.sort(compareEpochs)\n\n  // Get array of epochs\n  epochs = target.values.map(a => a.epochs)\n\n  minEpochs = !isNaN(config.stanford_scaleMin)\n    ? config.stanford_scaleMin\n    : d3.min(epochs)\n  maxEpochs = !isNaN(config.stanford_scaleMax)\n    ? config.stanford_scaleMax\n    : d3.max(epochs)\n\n  if (minEpochs > maxEpochs) {\n    throw Error('Number of minEpochs has to be smaller than maxEpochs')\n  }\n\n  target.colors = isFunction(config.stanford_colors)\n    ? config.stanford_colors\n    : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5))\n\n  target.colorscale = d3\n    .scaleSequentialLog(target.colors)\n    .domain([minEpochs, maxEpochs])\n\n  target.minEpochs = minEpochs\n  target.maxEpochs = maxEpochs\n}\n\nChartInternal.prototype.getStanfordPointColor = function(d) {\n  var $$ = this,\n    target = $$.data.targets[0]\n\n  return target.colorscale(d.epochs)\n}\n\n// http://jsfiddle.net/Xotic750/KtzLq/\nChartInternal.prototype.getCentroid = function(points) {\n  var area = getRegionArea(points)\n\n  var x = 0,\n    y = 0,\n    i,\n    j,\n    f,\n    point1,\n    point2\n\n  for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {\n    point1 = points[i]\n    point2 = points[j]\n    f = point1.x * point2.y - point2.x * point1.y\n    x += (point1.x + point2.x) * f\n    y += (point1.y + point2.y) * f\n  }\n\n  f = area * 6\n\n  return {\n    x: x / f,\n    y: y / f\n  }\n}\n\nChartInternal.prototype.getStanfordTooltipTitle = function(d) {\n  var $$ = this,\n    labelX = $$.axis.getLabelText('x'),\n    labelY = $$.axis.getLabelText('y')\n\n  return `\n      <tr><th>${labelX ? sanitise(labelX) : 'x'}</th><th class='value'>${\n    d.x\n  }</th></tr>\n      <tr><th>${labelY ? sanitise(labelY) : 'y'}</th><th class='value'>${\n    d.value\n  }</th></tr>\n    `\n}\n\nChartInternal.prototype.countEpochsInRegion = function(region) {\n  var $$ = this,\n    target = $$.data.targets[0],\n    total,\n    count\n\n  total = target.values.reduce(\n    (accumulator, currentValue) => accumulator + Number(currentValue.epochs),\n    0\n  )\n\n  count = target.values.reduce((accumulator, currentValue) => {\n    if (pointInRegion(currentValue, region)) {\n      return accumulator + Number(currentValue.epochs)\n    }\n\n    return accumulator\n  }, 0)\n\n  return {\n    value: count,\n    percentage: count !== 0 ? ((count / total) * 100).toFixed(1) : 0\n  }\n}\n\nexport var getRegionArea = function(points) {\n  // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript\n  var area = 0,\n    i,\n    j,\n    point1,\n    point2\n\n  for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {\n    point1 = points[i]\n    point2 = points[j]\n    area += point1.x * point2.y\n    area -= point1.y * point2.x\n  }\n\n  area /= 2\n\n  return area\n}\n\nexport var pointInRegion = function(point, region) {\n  // thanks to: http://bl.ocks.org/bycoffe/5575904\n  // ray-casting algorithm based on\n  // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html\n  let xi,\n    yi,\n    yj,\n    xj,\n    intersect,\n    x = point.x,\n    y = point.value,\n    inside = false\n\n  for (let i = 0, j = region.length - 1; i < region.length; j = i++) {\n    xi = region[i].x\n    yi = region[i].y\n\n    xj = region[j].x\n    yj = region[j].y\n\n    intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi\n\n    if (intersect) {\n      inside = !inside\n    }\n  }\n\n  return inside\n}\n\nexport var compareEpochs = function(a, b) {\n  if (a.epochs < b.epochs) {\n    return -1\n  }\n  if (a.epochs > b.epochs) {\n    return 1\n  }\n\n  return 0\n}\n"
  },
  {
    "path": "src/stanfordelements.ts",
    "content": "import { ChartInternal } from './chart-internal'\nimport CLASS from './class'\n\nChartInternal.prototype.initStanfordElements = function() {\n  var $$ = this\n\n  // Avoid blocking eventRect\n  $$.stanfordElements = $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.stanfordElements)\n\n  $$.stanfordElements.append('g').attr('class', CLASS.stanfordLines)\n  $$.stanfordElements.append('g').attr('class', CLASS.stanfordTexts)\n  $$.stanfordElements.append('g').attr('class', CLASS.stanfordRegions)\n}\n\nChartInternal.prototype.updateStanfordElements = function(duration) {\n  var $$ = this,\n    main = $$.main,\n    config = $$.config,\n    stanfordLine,\n    stanfordLineEnter,\n    stanfordRegion,\n    stanfordRegionEnter,\n    stanfordText,\n    stanfordTextEnter,\n    xvCustom = $$.xvCustom.bind($$),\n    yvCustom = $$.yvCustom.bind($$),\n    countPointsInRegion = $$.countEpochsInRegion.bind($$)\n\n  // Stanford-Lines\n  stanfordLine = main\n    .select('.' + CLASS.stanfordLines)\n    .style('shape-rendering', 'geometricprecision')\n    .selectAll('.' + CLASS.stanfordLine)\n    .data(config.stanford_lines)\n\n  // enter\n  stanfordLineEnter = stanfordLine\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : '')\n    })\n  stanfordLineEnter\n    .append('line')\n    .attr('x1', d =>\n      config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1')\n    )\n    .attr('x2', d =>\n      config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2')\n    )\n    .attr('y1', d =>\n      config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1')\n    )\n    .attr('y2', d =>\n      config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2')\n    )\n    .style('opacity', 0)\n\n  // update\n  $$.stanfordLines = stanfordLineEnter.merge(stanfordLine)\n  $$.stanfordLines\n    .select('line')\n    .transition()\n    .duration(duration)\n    .attr('x1', d =>\n      config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1')\n    )\n    .attr('x2', d =>\n      config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2')\n    )\n    .attr('y1', d =>\n      config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1')\n    )\n    .attr('y2', d =>\n      config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2')\n    )\n    .style('opacity', 1)\n\n  // exit\n  stanfordLine\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove()\n\n  // Stanford-Text\n  stanfordText = main\n    .select('.' + CLASS.stanfordTexts)\n    .selectAll('.' + CLASS.stanfordText)\n    .data(config.stanford_texts)\n\n  // enter\n  stanfordTextEnter = stanfordText\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : '')\n    })\n  stanfordTextEnter\n    .append('text')\n    .attr('x', d => (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')))\n    .attr('y', d => (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')))\n    .style('opacity', 0)\n\n  // update\n  $$.stanfordTexts = stanfordTextEnter.merge(stanfordText)\n  $$.stanfordTexts\n    .select('text')\n    .transition()\n    .duration(duration)\n    .attr('x', d => (config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x')))\n    .attr('y', d => (config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y')))\n    .text(function(d) {\n      return d.content\n    })\n    .style('opacity', 1)\n\n  // exit\n  stanfordText\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove()\n\n  // Stanford-Regions\n  stanfordRegion = main\n    .select('.' + CLASS.stanfordRegions)\n    .selectAll('.' + CLASS.stanfordRegion)\n    .data(config.stanford_regions)\n\n  // enter\n  stanfordRegionEnter = stanfordRegion\n    .enter()\n    .append('g')\n    .attr('class', function(d) {\n      return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : '')\n    })\n  stanfordRegionEnter\n    .append('polygon')\n    .attr('points', d => {\n      return d.points\n        .map(value => {\n          return [\n            config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'),\n            config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')\n          ].join(',')\n        })\n        .join(' ')\n    })\n    .style('opacity', 0)\n  stanfordRegionEnter\n    .append('text')\n    .attr('x', d => $$.getCentroid(d.points).x)\n    .attr('y', d => $$.getCentroid(d.points).y)\n    .style('opacity', 0)\n\n  // update\n  $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion)\n  $$.stanfordRegions\n    .select('polygon')\n    .transition()\n    .duration(duration)\n    .attr('points', d => {\n      return d.points\n        .map(value => {\n          return [\n            config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'),\n            config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')\n          ].join(',')\n        })\n        .join(' ')\n    })\n    .style('opacity', d => {\n      return d.opacity ? d.opacity : 0.2\n    })\n  $$.stanfordRegions\n    .select('text')\n    .transition()\n    .duration(duration)\n    .attr('x', d =>\n      config.axis_rotated\n        ? yvCustom($$.getCentroid(d.points), 'y')\n        : xvCustom($$.getCentroid(d.points), 'x')\n    )\n    .attr('y', d =>\n      config.axis_rotated\n        ? xvCustom($$.getCentroid(d.points), 'x')\n        : yvCustom($$.getCentroid(d.points), 'y')\n    )\n    .text(function(d) {\n      if (d.text) {\n        var value, percentage, temp\n\n        if ($$.isStanfordGraphType()) {\n          temp = countPointsInRegion(d.points)\n          value = temp.value\n          percentage = temp.percentage\n        }\n\n        return d.text(value, percentage)\n      }\n\n      return ''\n    })\n    .attr('text-anchor', 'middle')\n    .attr('dominant-baseline', 'middle')\n    .style('opacity', 1)\n  // exit\n  stanfordRegion\n    .exit()\n    .transition()\n    .duration(duration)\n    .style('opacity', 0)\n    .remove()\n}\n"
  },
  {
    "path": "src/subchart.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport { isFunction } from './util'\n\nChartInternal.prototype.initBrush = function(scale) {\n  var $$ = this,\n    d3 = $$.d3\n  // TODO: dynamically change brushY/brushX according to axis_rotated.\n  $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX())\n    .on('brush', function() {\n      var event = d3.event.sourceEvent\n      if (event && event.type === 'zoom') {\n        return\n      }\n      $$.redrawForBrush()\n    })\n    .on('end', function() {\n      var event = d3.event.sourceEvent\n      if (event && event.type === 'zoom') {\n        return\n      }\n      if ($$.brush.empty() && event && event.type !== 'end') {\n        $$.brush.clear()\n      }\n    })\n  $$.brush.updateExtent = function() {\n    var range = this.scale.range(),\n      extent\n    if ($$.config.axis_rotated) {\n      extent = [\n        [0, range[0]],\n        [$$.width2, range[1]]\n      ]\n    } else {\n      extent = [\n        [range[0], 0],\n        [range[1], $$.height2]\n      ]\n    }\n    this.extent(extent)\n    return this\n  }\n  $$.brush.updateScale = function(scale) {\n    this.scale = scale\n    return this\n  }\n  $$.brush.update = function(scale) {\n    this.updateScale(scale || $$.subX).updateExtent()\n    $$.context.select('.' + CLASS.brush).call(this)\n  }\n  $$.brush.clear = function() {\n    $$.context.select('.' + CLASS.brush).call($$.brush.move, null)\n  }\n  $$.brush.selection = function() {\n    return d3.brushSelection($$.context.select('.' + CLASS.brush).node())\n  }\n  $$.brush.selectionAsValue = function(selectionAsValue, withTransition) {\n    var selection, brush\n    if (selectionAsValue) {\n      if ($$.context) {\n        selection = [\n          this.scale(selectionAsValue[0]),\n          this.scale(selectionAsValue[1])\n        ]\n        brush = $$.context.select('.' + CLASS.brush)\n        if (withTransition) {\n          brush = brush.transition()\n        }\n        $$.brush.move(brush, selection)\n      }\n      return []\n    }\n    selection = $$.brush.selection() || [0, 0]\n    return [this.scale.invert(selection[0]), this.scale.invert(selection[1])]\n  }\n  $$.brush.empty = function() {\n    var selection = $$.brush.selection()\n    return !selection || selection[0] === selection[1]\n  }\n  return $$.brush.updateScale(scale)\n}\nChartInternal.prototype.initSubchart = function() {\n  var $$ = this,\n    config = $$.config,\n    context = ($$.context = $$.svg\n      .append('g')\n      .attr('transform', $$.getTranslate('context')))\n\n  // set style\n  context.style('visibility', 'visible')\n\n  // Define g for chart area\n  context\n    .append('g')\n    .attr('clip-path', $$.clipPathForSubchart)\n    .attr('class', CLASS.chart)\n\n  // Define g for bar chart area\n  context\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartBars)\n\n  // Define g for line chart area\n  context\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartLines)\n\n  // Add extent rect for Brush\n  context\n    .append('g')\n    .attr('clip-path', $$.clipPath)\n    .attr('class', CLASS.brush)\n\n  // ATTENTION: This must be called AFTER chart added\n  // Add Axis\n  $$.axes.subx = context\n    .append('g')\n    .attr('class', CLASS.axisX)\n    .attr('transform', $$.getTranslate('subx'))\n    .attr('clip-path', config.axis_rotated ? '' : $$.clipPathForXAxis)\n    .style('visibility', config.subchart_axis_x_show ? 'visible' : 'hidden');\n}\nChartInternal.prototype.initSubchartBrush = function() {\n  var $$ = this\n  // Add extent rect for Brush\n  $$.initBrush($$.subX).updateExtent()\n  $$.context.select('.' + CLASS.brush).call($$.brush)\n}\nChartInternal.prototype.updateTargetsForSubchart = function(targets) {\n  var $$ = this,\n    context = $$.context,\n    config = $$.config,\n    contextLineEnter,\n    contextLine,\n    contextBarEnter,\n    contextBar,\n    classChartBar = $$.classChartBar.bind($$),\n    classBars = $$.classBars.bind($$),\n    classChartLine = $$.classChartLine.bind($$),\n    classLines = $$.classLines.bind($$),\n    classAreas = $$.classAreas.bind($$)\n\n  //-- Bar --//\n  contextBar = context\n    .select('.' + CLASS.chartBars)\n    .selectAll('.' + CLASS.chartBar)\n    .data(targets)\n  contextBarEnter = contextBar\n    .enter()\n    .append('g')\n    .style('opacity', 0)\n  contextBarEnter.merge(contextBar).attr('class', classChartBar)\n  // Bars for each data\n  contextBarEnter.append('g').attr('class', classBars)\n\n  //-- Line --//\n  contextLine = context\n    .select('.' + CLASS.chartLines)\n    .selectAll('.' + CLASS.chartLine)\n    .data(targets)\n  contextLineEnter = contextLine\n    .enter()\n    .append('g')\n    .style('opacity', 0)\n  contextLineEnter.merge(contextLine).attr('class', classChartLine)\n  // Lines for each data\n  contextLineEnter.append('g').attr('class', classLines)\n  // Area\n  contextLineEnter.append('g').attr('class', classAreas)\n\n  //-- Brush --//\n  context\n    .selectAll('.' + CLASS.brush + ' rect')\n    .attr(\n      config.axis_rotated ? 'width' : 'height',\n      config.axis_rotated ? $$.width2 : $$.height2\n    )\n}\nChartInternal.prototype.updateBarForSubchart = function(durationForExit) {\n  var $$ = this\n  var contextBar = $$.context\n    .selectAll('.' + CLASS.bars)\n    .selectAll('.' + CLASS.bar)\n    .data($$.barData.bind($$))\n  var contextBarEnter = contextBar\n    .enter()\n    .append('path')\n    .attr('class', $$.classBar.bind($$))\n    .style('stroke', 'none')\n    .style('fill', $$.color)\n  contextBar\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n    .remove()\n  $$.contextBar = contextBarEnter\n    .merge(contextBar)\n    .style('opacity', $$.initialOpacity.bind($$))\n}\nChartInternal.prototype.redrawBarForSubchart = function(\n  drawBarOnSub,\n  withTransition,\n  duration\n) {\n  ;(withTransition\n    ? this.contextBar.transition(Math.random().toString()).duration(duration)\n    : this.contextBar\n  )\n    .attr('d', drawBarOnSub)\n    .style('opacity', 1)\n}\nChartInternal.prototype.updateLineForSubchart = function(durationForExit) {\n  var $$ = this\n  var contextLine = $$.context\n    .selectAll('.' + CLASS.lines)\n    .selectAll('.' + CLASS.line)\n    .data($$.lineData.bind($$))\n  var contextLineEnter = contextLine\n    .enter()\n    .append('path')\n    .attr('class', $$.classLine.bind($$))\n    .style('stroke', $$.color)\n  contextLine\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n    .remove()\n  $$.contextLine = contextLineEnter\n    .merge(contextLine)\n    .style('opacity', $$.initialOpacity.bind($$))\n}\nChartInternal.prototype.redrawLineForSubchart = function(\n  drawLineOnSub,\n  withTransition,\n  duration\n) {\n  ;(withTransition\n    ? this.contextLine.transition(Math.random().toString()).duration(duration)\n    : this.contextLine\n  )\n    .attr('d', drawLineOnSub)\n    .style('opacity', 1)\n}\nChartInternal.prototype.updateAreaForSubchart = function(durationForExit) {\n  var $$ = this,\n    d3 = $$.d3\n  var contextArea = $$.context\n    .selectAll('.' + CLASS.areas)\n    .selectAll('.' + CLASS.area)\n    .data($$.lineData.bind($$))\n  var contextAreaEnter = contextArea\n    .enter()\n    .append('path')\n    .attr('class', $$.classArea.bind($$))\n    .style('fill', $$.color)\n    .style('opacity', function() {\n      $$.orgAreaOpacity = +d3.select(this).style('opacity')\n      return 0\n    })\n  contextArea\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('opacity', 0)\n    .remove()\n  $$.contextArea = contextAreaEnter.merge(contextArea).style('opacity', 0)\n}\nChartInternal.prototype.redrawAreaForSubchart = function(\n  drawAreaOnSub,\n  withTransition,\n  duration\n) {\n  ;(withTransition\n    ? this.contextArea.transition(Math.random().toString()).duration(duration)\n    : this.contextArea\n  )\n    .attr('d', drawAreaOnSub)\n    .style('fill', this.color)\n    .style('opacity', this.orgAreaOpacity)\n}\nChartInternal.prototype.redrawSubchart = function(\n  withSubchart,\n  transitions,\n  duration,\n  durationForExit,\n  areaIndices,\n  barIndices,\n  lineIndices\n) {\n  var $$ = this,\n    d3 = $$.d3,\n    drawAreaOnSub,\n    drawBarOnSub,\n    drawLineOnSub\n\n  // reflect main chart to extent on subchart if zoomed\n  if (d3.event && d3.event.type === 'zoom') {\n    $$.brush.selectionAsValue($$.x.orgDomain())\n  }\n  // update subchart elements if needed\n  if (withSubchart) {\n    // extent rect\n    if (!$$.brush.empty()) {\n      $$.brush.selectionAsValue($$.x.orgDomain())\n    }\n    // setup drawer - MEMO: this must be called after axis updated\n    drawAreaOnSub = $$.generateDrawArea(areaIndices, true)\n    drawBarOnSub = $$.generateDrawBar(barIndices, true)\n    drawLineOnSub = $$.generateDrawLine(lineIndices, true)\n\n    $$.updateBarForSubchart(duration)\n    $$.updateLineForSubchart(duration)\n    $$.updateAreaForSubchart(duration)\n\n    $$.redrawBarForSubchart(drawBarOnSub, duration, duration)\n    $$.redrawLineForSubchart(drawLineOnSub, duration, duration)\n    $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration)\n  }\n}\nChartInternal.prototype.redrawForBrush = function() {\n  var $$ = this,\n    x = $$.x,\n    d3 = $$.d3,\n    s\n  $$.redraw({\n    withTransition: false,\n    withY: $$.config.zoom_rescale,\n    withSubchart: false,\n    withUpdateXDomain: true,\n    withEventRect: false,\n    withDimension: false\n  })\n  // update zoom transation binded to event rect\n  s = d3.event.selection || $$.brush.scale.range()\n  $$.main\n    .select('.' + CLASS.eventRect)\n    .call(\n      $$.zoom.transform,\n      d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0)\n    )\n  $$.config.subchart_onbrush.call($$.api, x.orgDomain())\n}\nChartInternal.prototype.transformContext = function(\n  withTransition,\n  transitions\n) {\n  var $$ = this,\n    subXAxis\n  if (transitions && transitions.axisSubX) {\n    subXAxis = transitions.axisSubX\n  } else {\n    subXAxis = $$.context.select('.' + CLASS.axisX)\n    if (withTransition) {\n      subXAxis = subXAxis.transition()\n    }\n  }\n  $$.context.attr('transform', $$.getTranslate('context'))\n  subXAxis.attr('transform', $$.getTranslate('subx'))\n}\nChartInternal.prototype.getDefaultSelection = function() {\n  var $$ = this,\n    config = $$.config,\n    selection = isFunction(config.axis_x_selection)\n      ? config.axis_x_selection($$.getXDomain($$.data.targets))\n      : config.axis_x_selection\n  if ($$.isTimeSeries()) {\n    selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])]\n  }\n  return selection\n}\n\nChartInternal.prototype.removeSubchart = function() {\n  const $$ = this\n\n  $$.brush = null\n  $$.context.remove()\n  $$.context = null\n}\n"
  },
  {
    "path": "src/text.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport { getBBox } from './util'\n\nChartInternal.prototype.initText = function() {\n  var $$ = this\n  $$.main\n    .select('.' + CLASS.chart)\n    .append('g')\n    .attr('class', CLASS.chartTexts)\n  $$.mainText = $$.d3.selectAll([])\n}\nChartInternal.prototype.updateTargetsForText = function(targets) {\n  var $$ = this,\n    classChartText = $$.classChartText.bind($$),\n    classTexts = $$.classTexts.bind($$),\n    classFocus = $$.classFocus.bind($$)\n  var mainText = $$.main\n    .select('.' + CLASS.chartTexts)\n    .selectAll('.' + CLASS.chartText)\n    .data(targets)\n  var mainTextEnter = mainText\n    .enter()\n    .append('g')\n    .attr('class', classChartText)\n    .style('opacity', 0)\n    .style('pointer-events', 'none')\n  mainTextEnter.append('g').attr('class', classTexts)\n  mainTextEnter.merge(mainText).attr('class', function(d) {\n    return classChartText(d) + classFocus(d)\n  })\n}\nChartInternal.prototype.updateText = function(\n  xForText,\n  yForText,\n  durationForExit\n) {\n  var $$ = this,\n    config = $$.config,\n    barOrLineData = $$.barOrLineData.bind($$),\n    classText = $$.classText.bind($$)\n  var mainText = $$.main\n    .selectAll('.' + CLASS.texts)\n    .selectAll('.' + CLASS.text)\n    .data(barOrLineData)\n  var mainTextEnter = mainText\n    .enter()\n    .append('text')\n    .attr('class', classText)\n    .attr('text-anchor', function(d) {\n      return config.axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle'\n    })\n    .style('stroke', 'none')\n    .attr('x', xForText)\n    .attr('y', yForText)\n    .style('fill', function(d) {\n      return $$.color(d)\n    })\n    .style('fill-opacity', 0)\n  $$.mainText = mainTextEnter.merge(mainText).text(function(d, i, j) {\n    return $$.dataLabelFormat(d.id)(d.value, d.id, i, j)\n  })\n  mainText\n    .exit()\n    .transition()\n    .duration(durationForExit)\n    .style('fill-opacity', 0)\n    .remove()\n}\nChartInternal.prototype.redrawText = function(\n  xForText,\n  yForText,\n  forFlow,\n  withTransition,\n  transition\n) {\n  return [\n    (withTransition ? this.mainText.transition(transition) : this.mainText)\n      .attr('x', xForText)\n      .attr('y', yForText)\n      .style('fill', this.color)\n      .style('fill-opacity', forFlow ? 0 : this.opacityForText.bind(this))\n  ]\n}\nChartInternal.prototype.getTextRect = function(text, cls, element) {\n  var dummy = this.d3\n      .select('body')\n      .append('div')\n      .classed('c3', true),\n    svg = dummy\n      .append('svg')\n      .style('visibility', 'hidden')\n      .style('position', 'fixed')\n      .style('top', 0)\n      .style('left', 0),\n    font = this.d3.select(element).style('font'),\n    rect\n  svg\n    .selectAll('.dummy')\n    .data([text])\n    .enter()\n    .append('text')\n    .classed(cls ? cls : '', true)\n    .style('font', font)\n    .text(text)\n    .each(function() {\n      rect = getBBox(this)\n    })\n  dummy.remove()\n  return rect\n}\nChartInternal.prototype.generateXYForText = function(\n  areaIndices,\n  barIndices,\n  lineIndices,\n  forX\n) {\n  var $$ = this,\n    getAreaPoints = $$.generateGetAreaPoints(areaIndices, false),\n    getBarPoints = $$.generateGetBarPoints(barIndices, false),\n    getLinePoints = $$.generateGetLinePoints(lineIndices, false),\n    getter = forX ? $$.getXForText : $$.getYForText\n  return function(d, i) {\n    var getPoints = $$.isAreaType(d)\n      ? getAreaPoints\n      : $$.isBarType(d)\n      ? getBarPoints\n      : getLinePoints\n    return getter.call($$, getPoints(d, i), d, this)\n  }\n}\nChartInternal.prototype.getXForText = function(points, d, textElement) {\n  var $$ = this,\n    box = getBBox(textElement),\n    xPos,\n    padding\n  if ($$.config.axis_rotated) {\n    padding = $$.isBarType(d) ? 4 : 6\n    xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1)\n  } else {\n    xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0]\n  }\n  // show labels regardless of the domain if value is null\n  if (d.value === null) {\n    if (xPos > $$.width) {\n      xPos = $$.width - box.width\n    } else if (xPos < 0) {\n      xPos = 4\n    }\n  }\n  return xPos\n}\nChartInternal.prototype.getYForText = function(points, d, textElement) {\n  var $$ = this,\n    box = getBBox(textElement),\n    yPos\n  if ($$.config.axis_rotated) {\n    yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2\n  } else {\n    yPos = points[2][1]\n    if (d.value < 0 || (d.value === 0 && !$$.hasPositiveValue)) {\n      yPos += box.height\n      if ($$.isBarType(d) && $$.isSafari()) {\n        yPos -= 3\n      } else if (!$$.isBarType(d) && $$.isChrome()) {\n        yPos += 3\n      }\n    } else {\n      yPos += $$.isBarType(d) ? -3 : -6\n    }\n  }\n  // show labels regardless of the domain if value is null\n  if (d.value === null && !$$.config.axis_rotated) {\n    if (yPos < box.height) {\n      yPos = box.height\n    } else if (yPos > this.height) {\n      yPos = this.height - 4\n    }\n  }\n  return yPos\n}\n"
  },
  {
    "path": "src/title.ts",
    "content": "import { ChartInternal } from './core'\n\nChartInternal.prototype.initTitle = function() {\n  var $$ = this\n  $$.title = $$.svg\n    .append('text')\n    .text($$.config.title_text)\n    .attr('class', $$.CLASS.title)\n}\nChartInternal.prototype.redrawTitle = function() {\n  var $$ = this\n  $$.title.attr('x', $$.xForTitle.bind($$)).attr('y', $$.yForTitle.bind($$))\n}\nChartInternal.prototype.xForTitle = function() {\n  var $$ = this,\n    config = $$.config,\n    position = config.title_position || 'left',\n    x\n  if (position.indexOf('right') >= 0) {\n    x =\n      $$.currentWidth -\n      $$.getTextRect(\n        $$.title.node().textContent,\n        $$.CLASS.title,\n        $$.title.node()\n      ).width -\n      config.title_padding.right\n  } else if (position.indexOf('center') >= 0) {\n    x = Math.max(\n      ($$.currentWidth -\n        $$.getTextRect(\n          $$.title.node().textContent,\n          $$.CLASS.title,\n          $$.title.node()\n        ).width) /\n        2,\n      0\n    )\n  } else {\n    // left\n    x = config.title_padding.left\n  }\n  return x\n}\nChartInternal.prototype.yForTitle = function() {\n  var $$ = this\n  return (\n    $$.config.title_padding.top +\n    $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node())\n      .height\n  )\n}\nChartInternal.prototype.getTitlePadding = function() {\n  var $$ = this\n  return $$.yForTitle() + $$.config.title_padding.bottom\n}\n"
  },
  {
    "path": "src/tooltip.ts",
    "content": "import CLASS from './class'\nimport { ChartInternal } from './core'\nimport { isValue, isFunction, isArray, isString, sanitise } from './util'\n\nChartInternal.prototype.initTooltip = function() {\n  var $$ = this,\n    config = $$.config,\n    i\n  $$.tooltip = $$.selectChart\n    .style('position', 'relative')\n    .append('div')\n    .attr('class', CLASS.tooltipContainer)\n    .style('position', 'absolute')\n    .style('pointer-events', 'none')\n    .style('display', 'none')\n  // Show tooltip if needed\n  if (config.tooltip_init_show) {\n    if ($$.isTimeSeries() && isString(config.tooltip_init_x)) {\n      config.tooltip_init_x = $$.parseDate(config.tooltip_init_x)\n      for (i = 0; i < $$.data.targets[0].values.length; i++) {\n        if ($$.data.targets[0].values[i].x - config.tooltip_init_x === 0) {\n          break\n        }\n      }\n      config.tooltip_init_x = i\n    }\n    $$.tooltip.html(\n      config.tooltip_contents.call(\n        $$,\n        $$.data.targets.map(function(d) {\n          return $$.addName(d.values[config.tooltip_init_x])\n        }),\n        $$.axis.getXAxisTickFormat(),\n        $$.getYFormat($$.hasArcType()),\n        $$.color\n      )\n    )\n    $$.tooltip\n      .style('top', config.tooltip_init_position.top)\n      .style('left', config.tooltip_init_position.left)\n      .style('display', 'block')\n  }\n}\nChartInternal.prototype.getTooltipSortFunction = function() {\n  var $$ = this,\n    config = $$.config\n\n  if (config.data_groups.length === 0 || config.tooltip_order !== undefined) {\n    // if data are not grouped or if an order is specified\n    // for the tooltip values we sort them by their values\n\n    var order = config.tooltip_order\n    if (order === undefined) {\n      order = config.data_order\n    }\n\n    var valueOf = function(obj) {\n      return obj ? obj.value : null\n    }\n\n    // if data are not grouped, we sort them by their value\n    if (isString(order) && order.toLowerCase() === 'asc') {\n      return function(a, b) {\n        return valueOf(a) - valueOf(b)\n      }\n    } else if (isString(order) && order.toLowerCase() === 'desc') {\n      return function(a, b) {\n        return valueOf(b) - valueOf(a)\n      }\n    } else if (isFunction(order)) {\n      // if the function is from data_order we need\n      // to wrap the returned function in order to format\n      // the sorted value to the expected format\n\n      var sortFunction = order\n\n      if (config.tooltip_order === undefined) {\n        sortFunction = function(a, b) {\n          return order(\n            a\n              ? {\n                  id: a.id,\n                  values: [a]\n                }\n              : null,\n            b\n              ? {\n                  id: b.id,\n                  values: [b]\n                }\n              : null\n          )\n        }\n      }\n\n      return sortFunction\n    } else if (isArray(order)) {\n      return function(a, b) {\n        return order.indexOf(a.id) - order.indexOf(b.id)\n      }\n    }\n  } else {\n    // if data are grouped, we follow the order of grouped targets\n    var ids = $$.orderTargets($$.data.targets).map(function(i) {\n      return i.id\n    })\n\n    // if it was either asc or desc we need to invert the order\n    // returned by orderTargets\n    if ($$.isOrderAsc() || $$.isOrderDesc()) {\n      ids = ids.reverse()\n    }\n\n    return function(a, b) {\n      return ids.indexOf(a.id) - ids.indexOf(b.id)\n    }\n  }\n}\nChartInternal.prototype.getTooltipContent = function(\n  d,\n  defaultTitleFormat,\n  defaultValueFormat,\n  color\n) {\n  var $$ = this,\n    config = $$.config,\n    titleFormat = config.tooltip_format_title || defaultTitleFormat,\n    nameFormat =\n      config.tooltip_format_name ||\n      function(name) {\n        return name\n      },\n    text,\n    i,\n    title,\n    value,\n    name,\n    bgcolor\n\n  var valueFormat = config.tooltip_format_value\n  if (!valueFormat) {\n    valueFormat = $$.isTargetNormalized(d.id)\n      ? (v, ratio) => `${(ratio * 100).toFixed(2)}%`\n      : defaultValueFormat\n  }\n\n  var tooltipSortFunction = this.getTooltipSortFunction()\n  if (tooltipSortFunction) {\n    d.sort(tooltipSortFunction)\n  }\n\n  for (i = 0; i < d.length; i++) {\n    if (!(d[i] && (d[i].value || d[i].value === 0))) {\n      continue\n    }\n\n    if ($$.isStanfordGraphType()) {\n      // Custom tooltip for stanford plots\n      if (!text) {\n        title = $$.getStanfordTooltipTitle(d[i])\n        text = \"<table class='\" + $$.CLASS.tooltip + \"'>\" + title\n      }\n\n      bgcolor = $$.getStanfordPointColor(d[i])\n      name = sanitise(config.data_epochs) // Epochs key name\n      value = d[i].epochs\n    } else {\n      // Regular tooltip\n      if (!text) {\n        title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x)\n        text =\n          \"<table class='\" +\n          $$.CLASS.tooltip +\n          \"'>\" +\n          (title || title === 0\n            ? \"<tr><th colspan='2'>\" + title + '</th></tr>'\n            : '')\n      }\n\n      value = sanitise(\n        valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d)\n      )\n      if (value !== undefined) {\n        // Skip elements when their name is set to null\n        if (d[i].name === null) {\n          continue\n        }\n\n        name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index))\n        bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id)\n      }\n    }\n\n    if (value !== undefined) {\n      text +=\n        \"<tr class='\" +\n        $$.CLASS.tooltipName +\n        '-' +\n        $$.getTargetSelectorSuffix(d[i].id) +\n        \"'>\"\n      text +=\n        \"<td class='name'><span style='background-color:\" +\n        bgcolor +\n        \"'></span>\" +\n        name +\n        '</td>'\n      text += \"<td class='value'>\" + value + '</td>'\n      text += '</tr>'\n    }\n  }\n  return text + '</table>'\n}\nChartInternal.prototype.tooltipPosition = function(\n  dataToShow,\n  tWidth,\n  tHeight,\n  element\n) {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3\n  var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight\n  var forArc = $$.hasArcType(),\n    mouse = d3.mouse(element)\n  // Determin tooltip position\n  if (forArc) {\n    tooltipLeft =\n      ($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2 + mouse[0]\n    tooltipTop =\n      ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20\n  } else {\n    svgLeft = $$.getSvgLeft(true)\n    if (config.axis_rotated) {\n      tooltipLeft = svgLeft + mouse[0] + 100\n      tooltipRight = tooltipLeft + tWidth\n      chartRight = $$.currentWidth - $$.getCurrentPaddingRight()\n      tooltipTop = $$.x(dataToShow[0].x) + 20\n    } else {\n      tooltipLeft =\n        svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20\n      tooltipRight = tooltipLeft + tWidth\n      chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight()\n      tooltipTop = mouse[1] + 15\n    }\n\n    if (tooltipRight > chartRight) {\n      // 20 is needed for Firefox to keep tooltip width\n      tooltipLeft -= tooltipRight - chartRight + 20\n    }\n    if (tooltipTop + tHeight > $$.currentHeight) {\n      tooltipTop -= tHeight + 30\n    }\n  }\n  if (tooltipTop < 0) {\n    tooltipTop = 0\n  }\n  return {\n    top: tooltipTop,\n    left: tooltipLeft\n  }\n}\nChartInternal.prototype.showTooltip = function(selectedData, element) {\n  var $$ = this,\n    config = $$.config\n  var tWidth, tHeight, position\n  var forArc = $$.hasArcType(),\n    dataToShow = selectedData.filter(function(d) {\n      return d && isValue(d.value)\n    }),\n    positionFunction =\n      config.tooltip_position || ChartInternal.prototype.tooltipPosition\n  if (dataToShow.length === 0 || !config.tooltip_show) {\n    $$.hideTooltip()\n    return\n  }\n  $$.tooltip\n    .html(\n      config.tooltip_contents.call(\n        $$,\n        selectedData,\n        $$.axis.getXAxisTickFormat(),\n        $$.getYFormat(forArc),\n        $$.color\n      )\n    )\n    .style('display', 'block')\n\n  // Get tooltip dimensions\n  tWidth = $$.tooltip.property('offsetWidth')\n  tHeight = $$.tooltip.property('offsetHeight')\n\n  position = positionFunction.call(this, dataToShow, tWidth, tHeight, element)\n  // Set tooltip\n  $$.tooltip\n    .style('top', position.top + 'px')\n    .style('left', position.left + 'px')\n}\nChartInternal.prototype.hideTooltip = function() {\n  this.tooltip.style('display', 'none')\n}\n"
  },
  {
    "path": "src/type.ts",
    "content": "import { ChartInternal } from './core'\nimport { isString } from './util'\n\nChartInternal.prototype.setTargetType = function(targetIds, type) {\n  var $$ = this,\n    config = $$.config\n  $$.mapToTargetIds(targetIds).forEach(function(id) {\n    $$.withoutFadeIn[id] = type === config.data_types[id]\n    config.data_types[id] = type\n  })\n  if (!targetIds) {\n    config.data_type = type\n  }\n}\nChartInternal.prototype.hasType = function(type, targets) {\n  var $$ = this,\n    types = $$.config.data_types,\n    has = false\n  targets = targets || $$.data.targets\n  if (targets && targets.length) {\n    targets.forEach(function(target) {\n      var t = types[target.id]\n      if ((t && t.indexOf(type) >= 0) || (!t && type === 'line')) {\n        has = true\n      }\n    })\n  } else if (Object.keys(types).length) {\n    Object.keys(types).forEach(function(id) {\n      if (types[id] === type) {\n        has = true\n      }\n    })\n  } else {\n    has = $$.config.data_type === type\n  }\n  return has\n}\nChartInternal.prototype.hasArcType = function(targets) {\n  return (\n    this.hasType('pie', targets) ||\n    this.hasType('donut', targets) ||\n    this.hasType('gauge', targets)\n  )\n}\nChartInternal.prototype.isLineType = function(d) {\n  var config = this.config,\n    id = isString(d) ? d : d.id\n  return (\n    !config.data_types[id] ||\n    ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(\n      config.data_types[id]\n    ) >= 0\n  )\n}\nChartInternal.prototype.isStepType = function(d) {\n  var id = isString(d) ? d : d.id\n  return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0\n}\nChartInternal.prototype.isSplineType = function(d) {\n  var id = isString(d) ? d : d.id\n  return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0\n}\nChartInternal.prototype.isAreaType = function(d) {\n  var id = isString(d) ? d : d.id\n  return (\n    ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >=\n    0\n  )\n}\nChartInternal.prototype.isBarType = function(d) {\n  var id = isString(d) ? d : d.id\n  return this.config.data_types[id] === 'bar'\n}\nChartInternal.prototype.isScatterType = function(d) {\n  var id = isString(d) ? d : d.id\n  return this.config.data_types[id] === 'scatter'\n}\nChartInternal.prototype.isStanfordType = function(d) {\n  var id = isString(d) ? d : d.id\n  return this.config.data_types[id] === 'stanford'\n}\nChartInternal.prototype.isPieType = function(d) {\n  var id = isString(d) ? d : d.id\n  return this.config.data_types[id] === 'pie'\n}\nChartInternal.prototype.isGaugeType = function(d) {\n  var id = isString(d) ? d : d.id\n  return this.config.data_types[id] === 'gauge'\n}\nChartInternal.prototype.isDonutType = function(d) {\n  var id = isString(d) ? d : d.id\n  return this.config.data_types[id] === 'donut'\n}\nChartInternal.prototype.isArcType = function(d) {\n  return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d)\n}\nChartInternal.prototype.lineData = function(d) {\n  return this.isLineType(d) ? [d] : []\n}\nChartInternal.prototype.arcData = function(d) {\n  return this.isArcType(d.data) ? [d] : []\n}\n/* not used\n function scatterData(d) {\n return isScatterType(d) ? d.values : [];\n }\n */\nChartInternal.prototype.barData = function(d) {\n  return this.isBarType(d) ? d.values : []\n}\nChartInternal.prototype.lineOrScatterOrStanfordData = function(d) {\n  return this.isLineType(d) || this.isScatterType(d) || this.isStanfordType(d)\n    ? d.values\n    : []\n}\nChartInternal.prototype.barOrLineData = function(d) {\n  return this.isBarType(d) || this.isLineType(d) ? d.values : []\n}\n"
  },
  {
    "path": "src/ua.ts",
    "content": "import { ChartInternal } from './core'\n\nChartInternal.prototype.isSafari = function() {\n  var ua = window.navigator.userAgent\n  return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0\n}\nChartInternal.prototype.isChrome = function() {\n  var ua = window.navigator.userAgent\n  return ua.indexOf('Chrome') >= 0\n}\n"
  },
  {
    "path": "src/util.ts",
    "content": "export var asHalfPixel = function(n) {\n  return Math.ceil(n) + 0.5\n}\nexport var ceil10 = function(v) {\n  return Math.ceil(v / 10) * 10\n}\nexport var diffDomain = function(d) {\n  return d[1] - d[0]\n}\nexport var getOption = function(options, key, defaultValue) {\n  return isDefined(options[key]) ? options[key] : defaultValue\n}\nexport var getPathBox = function(path) {\n  var box = getBBox(path),\n    items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)],\n    minX = items[0].x,\n    minY = Math.min(items[0].y, items[1].y)\n  return { x: minX, y: minY, width: box.width, height: box.height }\n}\nexport var getBBox = function(element) {\n  try {\n    return element.getBBox()\n  } catch (ignore) {\n    // Firefox will throw an exception if getBBox() is called whereas the\n    // element is rendered with display:none\n    // See https://github.com/c3js/c3/issues/2692\n\n    // The previous code was using `getBoundingClientRect` which was returning\n    // everything at 0 in this case so let's reproduce this behavior here.\n\n    return { x: 0, y: 0, width: 0, height: 0 }\n  }\n}\nexport var hasValue = function(dict, value) {\n  var found = false\n  Object.keys(dict).forEach(function(key) {\n    if (dict[key] === value) {\n      found = true\n    }\n  })\n  return found\n}\nexport var isArray = function(o) {\n  return Array.isArray(o)\n}\nexport var isDefined = function(v) {\n  return typeof v !== 'undefined'\n}\nexport var isEmpty = function(o) {\n  return (\n    typeof o === 'undefined' ||\n    o === null ||\n    (isString(o) && o.length === 0) ||\n    (typeof o === 'object' && Object.keys(o).length === 0)\n  )\n}\nexport var isFunction = function(o) {\n  return typeof o === 'function'\n}\nexport var isNumber = function(o) {\n  return typeof o === 'number'\n}\nexport var isString = function(o) {\n  return typeof o === 'string'\n}\nexport var isUndefined = function(v) {\n  return typeof v === 'undefined'\n}\nexport var isValue = function(v) {\n  return v || v === 0\n}\nexport var notEmpty = function(o) {\n  return !isEmpty(o)\n}\nexport var sanitise = function(str) {\n  return typeof str === 'string'\n    ? str.replace(/</g, '&lt;').replace(/>/g, '&gt;')\n    : str\n}\nexport var flattenArray = function(arr) {\n  return Array.isArray(arr) ? [].concat(...arr) : []\n}\n/**\n * Returns whether the point is within the given box.\n *\n * @param {Array} point An [x,y] coordinate\n * @param {Object} box An object with {x, y, width, height} keys\n * @param {Number} sensitivity An offset to ease check on very small boxes\n */\nexport var isWithinBox = function(point, box, sensitivity = 0) {\n  const xStart = box.x - sensitivity\n  const xEnd = box.x + box.width + sensitivity\n  const yStart = box.y + box.height + sensitivity\n  const yEnd = box.y - sensitivity\n\n  return (\n    xStart < point[0] && point[0] < xEnd && yEnd < point[1] && point[1] < yStart\n  )\n}\n\n/**\n * Returns Internet Explorer version number (or false if no Internet Explorer used).\n *\n * @param string agent Optional parameter to specify user agent\n */\nexport var getIEVersion = function(agent?: string) {\n  // https://stackoverflow.com/questions/19999388/check-if-user-is-using-ie\n  if (typeof agent === 'undefined') {\n    agent = window.navigator.userAgent\n  }\n\n  let pos = agent.indexOf('MSIE ') // up to IE10\n  if (pos > 0) {\n    return parseInt(agent.substring(pos + 5, agent.indexOf('.', pos)), 10)\n  }\n\n  pos = agent.indexOf('Trident/') // IE11\n  if (pos > 0) {\n    pos = agent.indexOf('rv:')\n    return parseInt(agent.substring(pos + 3, agent.indexOf('.', pos)), 10)\n  }\n\n  return false\n}\n\n/**\n * Returns whether the used browser is Internet Explorer.\n *\n * @param version Optional parameter to specify IE version\n */\nexport var isIE = function(version?: number) {\n  const ver = getIEVersion()\n\n  if (typeof version === 'undefined') {\n    return !!ver\n  }\n\n  return version === ver\n}\n"
  },
  {
    "path": "src/zoom.ts",
    "content": "import { ChartInternal } from './core'\nimport CLASS from './class'\n\nChartInternal.prototype.initZoom = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    startEvent\n\n  $$.zoom = d3\n    .zoom()\n    .on('start', function() {\n      if (config.zoom_type !== 'scroll') {\n        return\n      }\n\n      var e = d3.event.sourceEvent\n      if (e && e.type === 'brush') {\n        return\n      }\n      startEvent = e\n      config.zoom_onzoomstart.call($$.api, e)\n    })\n    .on('zoom', function() {\n      if (config.zoom_type !== 'scroll') {\n        return\n      }\n\n      var e = d3.event.sourceEvent\n      if (e && e.type === 'brush') {\n        return\n      }\n\n      $$.redrawForZoom()\n\n      config.zoom_onzoom.call($$.api, $$.x.orgDomain())\n    })\n    .on('end', function() {\n      if (config.zoom_type !== 'scroll') {\n        return\n      }\n\n      var e = d3.event.sourceEvent\n      if (e && e.type === 'brush') {\n        return\n      }\n      // if click, do nothing. otherwise, click interaction will be canceled.\n      if (\n        e &&\n        startEvent.clientX === e.clientX &&\n        startEvent.clientY === e.clientY\n      ) {\n        return\n      }\n      config.zoom_onzoomend.call($$.api, $$.x.orgDomain())\n    })\n\n  $$.zoom.updateDomain = function() {\n    if (d3.event && d3.event.transform) {\n      if (config.axis_rotated && config.zoom_type === 'scroll' && d3.event.sourceEvent.type === 'mousemove') {\n        // we're moving the mouse in a rotated chart with zoom = \"scroll\", so we need rescaleY (i.e. vertical)\n        $$.x.domain(d3.event.transform.rescaleY($$.subX).domain());\n      } else {\n        $$.x.domain(d3.event.transform.rescaleX($$.subX).domain());\n      }\n    }\n    return this\n  }\n  $$.zoom.updateExtent = function() {\n    this.scaleExtent([1, Infinity])\n      .translateExtent([\n        [0, 0],\n        [$$.width, $$.height]\n      ])\n      .extent([\n        [0, 0],\n        [$$.width, $$.height]\n      ])\n    return this\n  }\n  $$.zoom.update = function() {\n    return this.updateExtent().updateDomain()\n  }\n\n  return $$.zoom.updateExtent()\n}\nChartInternal.prototype.zoomTransform = function(range) {\n  var $$ = this,\n    s = [$$.x(range[0]), $$.x(range[1])]\n  return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0)\n}\n\nChartInternal.prototype.initDragZoom = function() {\n  const $$ = this\n  const d3 = $$.d3\n  const config = $$.config\n  const context = ($$.context = $$.svg)\n  const brushXPos = $$.margin.left + 20.5\n  const brushYPos = $$.margin.top + 0.5\n\n  if (!(config.zoom_type === 'drag' && config.zoom_enabled)) {\n    return\n  }\n\n  const getZoomedDomain = selection =>\n    selection && selection.map(x => $$.x.invert(x))\n\n  const brush = ($$.dragZoomBrush = d3\n    .brushX()\n    .on('start', () => {\n      $$.api.unzoom()\n\n      $$.svg.select('.' + CLASS.dragZoom).classed('disabled', false)\n\n      config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent)\n    })\n    .on('brush', () => {\n      config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection))\n    })\n    .on('end', () => {\n      if (d3.event.selection == null) {\n        return\n      }\n\n      const zoomedDomain = getZoomedDomain(d3.event.selection)\n\n      if (!config.zoom_disableDefaultBehavior) {\n        $$.api.zoom(zoomedDomain)\n      }\n\n      $$.svg.select('.' + CLASS.dragZoom).classed('disabled', true)\n\n      config.zoom_onzoomend.call($$.api, zoomedDomain)\n    }))\n\n  context\n    .append('g')\n    .classed(CLASS.dragZoom, true)\n    .attr('clip-path', $$.clipPath)\n    .attr('transform', 'translate(' + brushXPos + ',' + brushYPos + ')')\n    .call(brush)\n}\n\nChartInternal.prototype.getZoomDomain = function() {\n  var $$ = this,\n    config = $$.config,\n    d3 = $$.d3,\n    min = d3.min([$$.orgXDomain[0], config.zoom_x_min]),\n    max = d3.max([$$.orgXDomain[1], config.zoom_x_max])\n  return [min, max]\n}\nChartInternal.prototype.redrawForZoom = function() {\n  var $$ = this,\n    d3 = $$.d3,\n    config = $$.config,\n    zoom = $$.zoom,\n    x = $$.x\n  if (!config.zoom_enabled) {\n    return\n  }\n  if ($$.filterTargetsToShow($$.data.targets).length === 0) {\n    return\n  }\n\n  zoom.update()\n\n  if (config.zoom_disableDefaultBehavior) {\n    return\n  }\n\n  if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) {\n    x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]])\n  }\n\n  $$.redraw({\n    withTransition: false,\n    withY: config.zoom_rescale,\n    withSubchart: false,\n    withEventRect: false,\n    withDimension: false\n  })\n\n  if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') {\n    $$.cancelClick = true\n  }\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"module\": \"ESNext\",\n    \"strict\": false,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true\n  },\n  \"include\": [\"src\", \"spec\"]\n}\n"
  }
]