Full Code of c3js/c3 for AI

master 76d7760ee8d6 cached
559 files
3.5 MB
931.4k tokens
298 symbols
1 requests
Download .txt
Showing preview only (3,718K chars total). Download the full file or copy to clipboard to get everything.
Repository: c3js/c3
Branch: master
Commit: 76d7760ee8d6
Files: 559
Total size: 3.5 MB

Directory structure:
gitextract_oun3f7hq/

├── .bmp.yml
├── .circleci/
│   └── config.yml
├── .editorconfig
├── .github/
│   ├── ISSUE_TEMPLATE.md
│   └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .jshintrc
├── .prettierrc.json
├── .travis.yml
├── CONTRIBUTING.md
├── Gemfile
├── LICENSE
├── MAINTAINANCE.md
├── README.md
├── bower.json
├── c3.css
├── c3.esm.js
├── c3.js
├── codecov.yml
├── component.json
├── config.rb
├── data/
│   └── samples.yml
├── design/
│   └── c3-logo.sketch
├── docs/
│   ├── 404.html
│   ├── CNAME
│   ├── _footer.haml
│   ├── _index_item.haml
│   ├── _index_item_title.haml
│   ├── _reference_item_link.haml
│   ├── _reference_menu_item.haml
│   ├── _sample.haml
│   ├── _sample_editor.haml
│   ├── _samples_header.haml
│   ├── _script.haml
│   ├── _script_scroll.haml
│   ├── _sidemenu_item.haml
│   ├── crossdomain.xml
│   ├── css/
│   │   ├── c3.css
│   │   ├── examples.css
│   │   ├── foundation.css
│   │   ├── gettingstarted.css
│   │   ├── index.css
│   │   ├── normalize.css
│   │   ├── reference.css
│   │   ├── samples/
│   │   │   ├── api_axis_label.css
│   │   │   ├── api_axis_range.css
│   │   │   ├── api_data_color.css
│   │   │   ├── api_data_name.css
│   │   │   ├── api_flow.css
│   │   │   ├── api_grid_x.css
│   │   │   ├── api_resize.css
│   │   │   ├── axes_label.css
│   │   │   ├── axes_label_position.css
│   │   │   ├── axes_rotated.css
│   │   │   ├── axes_x_localtime.css
│   │   │   ├── axes_x_tick_count.css
│   │   │   ├── axes_x_tick_culling.css
│   │   │   ├── axes_x_tick_fit.css
│   │   │   ├── axes_x_tick_format.css
│   │   │   ├── axes_x_tick_rotate.css
│   │   │   ├── axes_x_tick_values.css
│   │   │   ├── axes_y2.css
│   │   │   ├── axes_y_padding.css
│   │   │   ├── axes_y_range.css
│   │   │   ├── axes_y_tick_format.css
│   │   │   ├── categorized.css
│   │   │   ├── chart_area.css
│   │   │   ├── chart_area_stacked.css
│   │   │   ├── chart_bar.css
│   │   │   ├── chart_bar_negative.css
│   │   │   ├── chart_bar_stacked.css
│   │   │   ├── chart_combination.css
│   │   │   ├── chart_donut.css
│   │   │   ├── chart_gauge.css
│   │   │   ├── chart_pie.css
│   │   │   ├── chart_scatter.css
│   │   │   ├── chart_spline.css
│   │   │   ├── chart_stanford.css
│   │   │   ├── chart_step.css
│   │   │   ├── data_color.css
│   │   │   ├── data_columned.css
│   │   │   ├── data_json.css
│   │   │   ├── data_label.css
│   │   │   ├── data_label_format.css
│   │   │   ├── data_load.css
│   │   │   ├── data_name.css
│   │   │   ├── data_order.css
│   │   │   ├── data_rowed.css
│   │   │   ├── data_stringx.css
│   │   │   ├── data_url.css
│   │   │   ├── data_xformat.css
│   │   │   ├── grid_x_lines.css
│   │   │   ├── grid_y_lines.css
│   │   │   ├── interaction_zoom.css
│   │   │   ├── legend_custom.css
│   │   │   ├── legend_position.css
│   │   │   ├── options_color.css
│   │   │   ├── options_gridline.css
│   │   │   ├── options_legend.css
│   │   │   ├── options_padding.css
│   │   │   ├── options_size.css
│   │   │   ├── options_subchart.css
│   │   │   ├── pie_label_format.css
│   │   │   ├── point_show.css
│   │   │   ├── region.css
│   │   │   ├── region_timeseries.css
│   │   │   ├── simple_multiple.css
│   │   │   ├── simple_regions.css
│   │   │   ├── simple_xy.css
│   │   │   ├── simple_xy_multiple.css
│   │   │   ├── style_grid.css
│   │   │   ├── style_region.css
│   │   │   ├── timeseries.css
│   │   │   ├── tooltip_format.css
│   │   │   ├── tooltip_grouped.css
│   │   │   ├── tooltip_show.css
│   │   │   ├── transform_area.css
│   │   │   ├── transform_areaspline.css
│   │   │   ├── transform_bar.css
│   │   │   ├── transform_donut.css
│   │   │   ├── transform_line.css
│   │   │   ├── transform_pie.css
│   │   │   ├── transform_scatter.css
│   │   │   ├── transform_spline.css
│   │   │   └── transition_duration.css
│   │   ├── style.css
│   │   └── tomorrow.css
│   ├── data/
│   │   ├── c3_string_x.csv
│   │   ├── c3_test.csv
│   │   ├── c3_test.json
│   │   └── c3_test2.csv
│   ├── examples.html.haml
│   ├── gettingstarted.html.haml
│   ├── img/
│   │   └── .gitignore
│   ├── index.html.haml
│   ├── js/
│   │   ├── ace/
│   │   │   ├── ace.js
│   │   │   ├── mode-javascript.js
│   │   │   ├── theme-tomorrow.js
│   │   │   └── worker-javascript.js
│   │   ├── c3.esm.js
│   │   ├── c3.js
│   │   ├── gettingstarted.js
│   │   ├── highlight.pack.js
│   │   ├── index.js
│   │   ├── main.js
│   │   ├── plugins.js
│   │   └── samples/
│   │       ├── api_axis_label.js
│   │       ├── api_axis_range.js
│   │       ├── api_data_color.js
│   │       ├── api_data_name.js
│   │       ├── api_flow.js
│   │       ├── api_grid_x.js
│   │       ├── api_resize.js
│   │       ├── axes_label.js
│   │       ├── axes_label_position.js
│   │       ├── axes_rotated.js
│   │       ├── axes_x_localtime.js
│   │       ├── axes_x_tick_count.js
│   │       ├── axes_x_tick_culling.js
│   │       ├── axes_x_tick_fit.js
│   │       ├── axes_x_tick_format.js
│   │       ├── axes_x_tick_rotate.js
│   │       ├── axes_x_tick_values.js
│   │       ├── axes_y2.js
│   │       ├── axes_y_padding.js
│   │       ├── axes_y_range.js
│   │       ├── axes_y_tick_format.js
│   │       ├── categorized.js
│   │       ├── chart_area.js
│   │       ├── chart_area_stacked.js
│   │       ├── chart_bar.js
│   │       ├── chart_bar_stacked.js
│   │       ├── chart_combination.js
│   │       ├── chart_donut.js
│   │       ├── chart_gauge.js
│   │       ├── chart_pie.js
│   │       ├── chart_scatter.js
│   │       ├── chart_spline.js
│   │       ├── chart_stanford.js
│   │       ├── chart_step.js
│   │       ├── data_color.js
│   │       ├── data_columned.js
│   │       ├── data_json.js
│   │       ├── data_label.js
│   │       ├── data_label_format.js
│   │       ├── data_load.js
│   │       ├── data_name.js
│   │       ├── data_number_format_l10n.js
│   │       ├── data_order.js
│   │       ├── data_rowed.js
│   │       ├── data_stringx.js
│   │       ├── data_url.js
│   │       ├── data_xformat.js
│   │       ├── grid_x_lines.js
│   │       ├── grid_y_lines.js
│   │       ├── interaction_zoom.js
│   │       ├── interaction_zoom_by_drag.js
│   │       ├── legend_custom.js
│   │       ├── legend_position.js
│   │       ├── options_color.js
│   │       ├── options_gridline.js
│   │       ├── options_legend.js
│   │       ├── options_padding.js
│   │       ├── options_size.js
│   │       ├── options_subchart.js
│   │       ├── pie_label_format.js
│   │       ├── point_show.js
│   │       ├── region.js
│   │       ├── region_timeseries.js
│   │       ├── simple.js
│   │       ├── simple_multiple.js
│   │       ├── simple_regions.js
│   │       ├── simple_xy.js
│   │       ├── simple_xy_multiple.js
│   │       ├── style_grid.js
│   │       ├── style_region.js
│   │       ├── timeseries.js
│   │       ├── tooltip_format.js
│   │       ├── tooltip_grouped.js
│   │       ├── tooltip_horizontal.js
│   │       ├── tooltip_show.js
│   │       ├── transform_area.js
│   │       ├── transform_areaspline.js
│   │       ├── transform_bar.js
│   │       ├── transform_donut.js
│   │       ├── transform_line.js
│   │       ├── transform_pie.js
│   │       ├── transform_scatter.js
│   │       ├── transform_spline.js
│   │       └── transition_duration.js
│   ├── layouts/
│   │   └── layout.haml
│   ├── reference.html.haml
│   ├── robots.txt
│   └── samples/
│       ├── api_axis_label.html.haml
│       ├── api_axis_range.html.haml
│       ├── api_data_color.html.haml
│       ├── api_data_name.html.haml
│       ├── api_flow.html.haml
│       ├── api_grid_x.html.haml
│       ├── api_resize.html.haml
│       ├── axes_label.html.haml
│       ├── axes_label_position.html.haml
│       ├── axes_rotated.html.haml
│       ├── axes_x_localtime.html.haml
│       ├── axes_x_tick_count.html.haml
│       ├── axes_x_tick_culling.html.haml
│       ├── axes_x_tick_fit.html.haml
│       ├── axes_x_tick_format.html.haml
│       ├── axes_x_tick_rotate.html.haml
│       ├── axes_x_tick_values.html.haml
│       ├── axes_y2.html.haml
│       ├── axes_y_padding.html.haml
│       ├── axes_y_range.html.haml
│       ├── axes_y_tick_format.html.haml
│       ├── categorized.html.haml
│       ├── chart_area.html.haml
│       ├── chart_area_stacked.html.haml
│       ├── chart_bar.html.haml
│       ├── chart_bar_stacked.html.haml
│       ├── chart_combination.html.haml
│       ├── chart_donut.html.haml
│       ├── chart_gauge.html.haml
│       ├── chart_pie.html.haml
│       ├── chart_scatter.html.haml
│       ├── chart_spline.html.haml
│       ├── chart_stanford.html.haml
│       ├── chart_step.html.haml
│       ├── data_color.html.haml
│       ├── data_columned.html.haml
│       ├── data_json.html.haml
│       ├── data_label.html.haml
│       ├── data_label_format.html.haml
│       ├── data_load.html.haml
│       ├── data_name.html.haml
│       ├── data_number_format_l10n.html.haml
│       ├── data_order.html.haml
│       ├── data_rowed.html.haml
│       ├── data_stringx.html.haml
│       ├── data_url.html.haml
│       ├── grid_x_lines.html.haml
│       ├── grid_y_lines.html.haml
│       ├── interaction_zoom.html.haml
│       ├── interaction_zoom_by_drag.html.haml
│       ├── legend_custom.html.haml
│       ├── legend_position.html.haml
│       ├── options_color.html.haml
│       ├── options_gridline.html.haml
│       ├── options_legend.html.haml
│       ├── options_padding.html.haml
│       ├── options_size.html.haml
│       ├── options_subchart.html.haml
│       ├── pie_label_format.html.haml
│       ├── point_show.html.haml
│       ├── region.html.haml
│       ├── region_timeseries.html.haml
│       ├── simple_multiple.html.haml
│       ├── simple_regions.html.haml
│       ├── simple_xy.html.haml
│       ├── simple_xy_multiple.html.haml
│       ├── style_grid.html.haml
│       ├── style_region.html.haml
│       ├── timeseries.html.haml
│       ├── tooltip_format.html.haml
│       ├── tooltip_grouped.html.haml
│       ├── tooltip_horizontal.html.haml
│       ├── tooltip_show.html.haml
│       ├── transform_area.html.haml
│       ├── transform_areaspline.html.haml
│       ├── transform_bar.html.haml
│       ├── transform_donut.html.haml
│       ├── transform_line.html.haml
│       ├── transform_pie.html.haml
│       ├── transform_scatter.html.haml
│       ├── transform_spline.html.haml
│       └── transition_duration.html.haml
├── extensions/
│   ├── chart-bubble/
│   │   ├── bubble.js
│   │   └── index.html
│   ├── exporter/
│   │   ├── config.json
│   │   └── phantom-exporter.js
│   └── js/
│       └── c3ext.js
├── htdocs/
│   ├── css/
│   │   ├── index.css
│   │   └── style.css
│   ├── data/
│   │   ├── c3_stanford_data.json
│   │   ├── c3_test.csv
│   │   ├── c3_test.json
│   │   ├── c3_test.tsv
│   │   ├── c3_test2.csv
│   │   ├── c3_test2_ts.csv
│   │   ├── c3_test3.csv
│   │   ├── c3_test_2.json
│   │   ├── c3_test_3.json
│   │   └── c3_test_ts.csv
│   ├── index.html
│   ├── js/
│   │   ├── require.js
│   │   └── samples/
│   │       ├── plugin.js
│   │       ├── requirejs.js
│   │       └── zoom_reduction.js
│   └── samples/
│       ├── api_axis_label.html
│       ├── api_axis_range.html
│       ├── api_category.html
│       ├── api_data_colors.html
│       ├── api_flow.html
│       ├── api_flow_timeseries.html
│       ├── api_legend.html
│       ├── api_tooltip_show.html
│       ├── api_transform.html
│       ├── api_xgrid_lines.html
│       ├── api_ygrid_lines.html
│       ├── api_zoom.html
│       ├── area_zerobased.html
│       ├── axes_log_scales.html
│       ├── axes_padding.html
│       ├── axes_range.html
│       ├── axes_x_localtime.html
│       ├── axes_x_range_timeseries.html
│       ├── axes_x_selection.html
│       ├── axes_x_tick_culling.html
│       ├── axes_x_tick_fit.html
│       ├── axes_x_tick_rotate.html
│       ├── axes_x_tick_values.html
│       ├── axes_y2.html
│       ├── axes_y_default.html
│       ├── bar_zerobased.html
│       ├── bindto.html
│       ├── categorized.html
│       ├── chart_arc.html
│       ├── chart_area.html
│       ├── chart_area_spline.html
│       ├── chart_area_spline_stacked.html
│       ├── chart_area_stacked.html
│       ├── chart_area_step.html
│       ├── chart_area_step_stacked.html
│       ├── chart_bar.html
│       ├── chart_bar_max_width.html
│       ├── chart_bar_space.html
│       ├── chart_bar_stacked.html
│       ├── chart_bar_stacked_normalized.html
│       ├── chart_combination.html
│       ├── chart_combination_normalized.html
│       ├── chart_donut.html
│       ├── chart_gauge.html
│       ├── chart_multi_arc_gauge.html
│       ├── chart_pie.html
│       ├── chart_pie_sort.html
│       ├── chart_scatter.html
│       ├── chart_spline.html
│       ├── chart_stanford.html
│       ├── chart_stanford_custom_elements.html
│       ├── chart_step.html
│       ├── chart_step_category.html
│       ├── custom_x_categorized.html
│       ├── custom_x_scale.html
│       ├── custom_xs_scale.html
│       ├── data_columned.html
│       ├── data_hide.html
│       ├── data_json.html
│       ├── data_label.html
│       ├── data_label_format.html
│       ├── data_load.html
│       ├── data_load_timeseries.html
│       ├── data_region.html
│       ├── data_region_timeseries.html
│       ├── data_rowed.html
│       ├── data_url.html
│       ├── different_category_datasets.html
│       ├── domain_y.html
│       ├── element.html
│       ├── emptydata.html
│       ├── grid_focus.html
│       ├── grid_x_lines.html
│       ├── grid_x_lines_timeseries.html
│       ├── grids.html
│       ├── grids_timeseries.html
│       ├── interaction_enabled.html
│       ├── legend.html
│       ├── padding.html
│       ├── padding_update.html
│       ├── plugin.html
│       ├── point_r.html
│       ├── point_show.html
│       ├── regions.html
│       ├── regions_timeseries.html
│       ├── requirejs.html
│       ├── resize.html
│       ├── selection.html
│       ├── simple.html
│       ├── subchart.html
│       ├── subchart_onbrush.html
│       ├── timeseries.html
│       ├── timeseries_date.html
│       ├── timeseries_descendent.html
│       ├── timeseries_raw.html
│       ├── tooltip_grouped.html
│       ├── tooltip_horizontal.html
│       ├── tooltip_show.html
│       ├── zoom.html
│       ├── zoom_category.html
│       ├── zoom_onzoom.html
│       ├── zoom_reduction.html
│       ├── zoom_type.html
│       └── zoom_type_disable_default_behavior.html
├── karma.conf.js
├── package.json
├── rollup.config.js
├── spec/
│   ├── api.axis-spec.ts
│   ├── api.data-spec.ts
│   ├── api.donut-spec.ts
│   ├── api.focus-spec.ts
│   ├── api.grid-spec.ts
│   ├── api.load-spec.ts
│   ├── api.pie-spec.ts
│   ├── api.region-spec.ts
│   ├── api.x-spec.ts
│   ├── api.zoom-spec.ts
│   ├── arc-spec.ts
│   ├── axis-spec.ts
│   ├── c3-helper.ts
│   ├── cache-spec.ts
│   ├── class-spec.ts
│   ├── core-spec.ts
│   ├── data-spec.ts
│   ├── data.convert-spec.ts
│   ├── domain-spec.ts
│   ├── drag-spec.ts
│   ├── grid-spec.ts
│   ├── interaction-spec.ts
│   ├── legend-spec.ts
│   ├── shape.bar-spec.ts
│   ├── shape.line-spec.ts
│   ├── stanford-spec.ts
│   ├── subchart-spec.ts
│   ├── svg-helper.ts
│   ├── title-spec.ts
│   ├── tooltip-spec.ts
│   ├── type-spec.ts
│   ├── util-spec.ts
│   └── zoom-spec.ts
├── src/
│   ├── api.axis.ts
│   ├── api.category.ts
│   ├── api.chart.ts
│   ├── api.color.ts
│   ├── api.data.ts
│   ├── api.donut.ts
│   ├── api.flow.ts
│   ├── api.focus.ts
│   ├── api.grid.ts
│   ├── api.group.ts
│   ├── api.legend.ts
│   ├── api.load.ts
│   ├── api.pie.ts
│   ├── api.region.ts
│   ├── api.selection.ts
│   ├── api.show.ts
│   ├── api.subchart.ts
│   ├── api.tooltip.ts
│   ├── api.transform.ts
│   ├── api.x.ts
│   ├── api.zoom.ts
│   ├── arc.ts
│   ├── axis-internal.ts
│   ├── axis.ts
│   ├── cache.ts
│   ├── category.ts
│   ├── chart-internal.ts
│   ├── chart.ts
│   ├── class-utils.ts
│   ├── class.ts
│   ├── clip.ts
│   ├── color.ts
│   ├── colorscale.ts
│   ├── config.ts
│   ├── core.ts
│   ├── data.convert.ts
│   ├── data.load.ts
│   ├── data.ts
│   ├── domain.ts
│   ├── drag.ts
│   ├── format.ts
│   ├── grid.ts
│   ├── index.ts
│   ├── interaction.ts
│   ├── legend.ts
│   ├── polyfill.ts
│   ├── region.ts
│   ├── scale.ts
│   ├── scss/
│   │   ├── arc.scss
│   │   ├── area.scss
│   │   ├── axis.scss
│   │   ├── bar.scss
│   │   ├── brush.scss
│   │   ├── chart.scss
│   │   ├── focus.scss
│   │   ├── grid.scss
│   │   ├── legend.scss
│   │   ├── line.scss
│   │   ├── main.scss
│   │   ├── point.scss
│   │   ├── region.scss
│   │   ├── select_drag.scss
│   │   ├── text.scss
│   │   ├── title.scss
│   │   ├── tooltip.scss
│   │   └── zoom.scss
│   ├── selection.ts
│   ├── shape.bar.ts
│   ├── shape.line.ts
│   ├── shape.ts
│   ├── size.ts
│   ├── stanford.ts
│   ├── stanfordelements.ts
│   ├── subchart.ts
│   ├── text.ts
│   ├── title.ts
│   ├── tooltip.ts
│   ├── type.ts
│   ├── ua.ts
│   ├── util.ts
│   └── zoom.ts
└── tsconfig.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .bmp.yml
================================================
---
version: 0.7.20
commit: 'chore(version): bump to v%.%.%'
files:
  src/core.ts: 'version: ''%.%.%'''
  package.json: '"version": "%.%.%"'
  component.json: '"version": "%.%.%"'


================================================
FILE: .circleci/config.yml
================================================
version: 2

node12: &node12
  working_directory: ~/c3
  docker:
    - image: circleci/node:12-browsers

node14: &node14
  working_directory: ~/c3
  docker:
    - image: circleci/node:14-browsers

restore_modules_cache: &restore_modules_cache
  restore_cache:
    keys:
    - npm-4-{{ checksum "package.json" }}
    # fallback to using the latest cache if no exact match is found
    - npm-4-

save_modules_cache: &save_modules_cache
  save_cache:
    key: npm-4-{{ checksum "package.json" }}
    paths: ./node_modules

install_and_test: &install_and_test
  steps:
    - checkout
    - run:
        name: Display versions
        command: |
          echo "node $(node -v)"
          echo "npm v$(npm --version)"
          echo "$(google-chrome --version)"
    - *restore_modules_cache
    - run:
        name: Installing Dependencies
        command: yarn
    - *save_modules_cache
    - run: yarn test
    - run: yarn codecov
    - store_artifacts:
        path: htdocs
        destination: htdocs
    - 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"

jobs:
  test_on_node12:
    <<: *node12
    <<: *install_and_test

  test_on_node14:
    <<: *node14
    <<: *install_and_test

  docs:
    docker:
      - image: circleci/ruby:2.4-node
        env:
          BUNDLE_PATH: vendor/bundle
    steps:
      - checkout
      - restore_cache:
          key: deps-bundle-{{ checksum "Gemfile.lock" }}
      - run: bundle install
      - save_cache:
          key: deps-bundle-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle
      - *restore_modules_cache
      - run: yarn
      - *save_modules_cache
      - run: yarn build
      - run: yarn copy-to-docs
      - run: yarn build:docs
      - store_artifacts:
          path: build
          destination: docs

workflows:
  version: 2
  test:
    jobs:
      - test_on_node12
      - test_on_node14
      - docs


================================================
FILE: .editorconfig
================================================
# editorconfig.org
root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.yml]
indent_size = 2

[*.json]
indent_size = 2

[*.haml]
indent_size = 2

[*.html]
indent_size = 2


================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
<!--

This is not a catch-all support forum, for general support enquiries, please use the Google Group at https://groups.google.com/forum/#!forum/c3js.
 
Thank you for reporting an issue.

Please fill in as much of the template below as you're able.

C3 version: The c3 version number which is available from `c3.version`.
D3 version: The d3 version number.
Browser: The browser version.
OS: The operating system.

If possible, please provide codepen or jsfiddle example that demonstrates the problem, keeping it as
simple and free of external dependencies as you are able.
-->

* **C3 version**:
* **D3 version**:
* **Browser**:
* **OS**:


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!--

Thank you for contributing!

Please make sure to:
 
- provide tests with your code changes to ensure they are working as expected.
- not commit any of the distribution file (`c3.js`, `c3.css`, `c3.min.js`, `c3.min.css`).

-->


================================================
FILE: .gitignore
================================================
# npm modules
node_modules
bower_components
d3.js
d3.min.js
components
package-lock.json

# build
/htdocs/js/c3.js
/htdocs/js/c3.min.js
/htdocs/js/c3.esm.js
/htdocs/css/c3.css
/htdocs/css/c3.min.css
/build

# sass
.sass-cache

# jetbrains
.idea/

# coverage report
/coverage

# OS related
.DS_Store

# IDE related
.idea
.iml

# bundle
.bundle/config
vendor/bundle


================================================
FILE: .jshintrc
================================================
{
    "esversion": 6,
    "eqeqeq": true,
    "curly": true,
    "strict": false,
    "trailing": true,
    "white": true,
    "maxlen": 210,
    "undef": true,
    "unused": true,
    "indent": 2,
    "eqnull": true,
    "expr": true,
    "newcap": false,
    "loopfunc": true,
    "bitwise": false,
    "asi": true,
    "laxbreak": true,

    "browser": true,
    "jasmine": true,

    "globals": {
        "d3": false,
        "require": false
    }
}


================================================
FILE: .prettierrc.json
================================================
{
  "tabWidth": 2,
  "semi": false,
  "singleQuote": true
}


================================================
FILE: .travis.yml
================================================
language: ruby
rvm:
  - 2.4

branches:
  only:
    - master

script:
  - bundle exec middleman build

deploy:
  provider: pages
  skip-cleanup: true
  local-dir: build
  github-token: $GITHUB_TOKEN
  keep-history: true
  on:
    branch: master


================================================
FILE: CONTRIBUTING.md
================================================
## Filing an issue

Before filing an issue, please [search the queue](https://github.com/c3js/c3/issues) to make sure it hasn't already been reported.

If a bug, please include the following —

1. What version of C3?
1. What browsers have you confirmed it in?
1. Can you isolate the issue by providing a jsFiddle demonstrating it in a minimalist capacity?

Please *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).

## Setup
 1. **Clone the repo from GitHub**

        git clone https://github.com/c3js/c3.git
        cd c3

 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:

        npm install -g grunt-cli
        npm install

    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.

## Building C3 from sources
    npm run build


## Distribution
    npm run dist

Now you'll find the built files in `c3.js`, `c3.min.js`, `c3.css` & `c3.min.css`.

## Running the tests
    npm run test

This command will automatically run the specification suite and report its results.

If you want to see specs running live in browser (e.g., for debugging), simply open `http://localhost:9876/` in your browser when phantomjs starts.

## Building the document site (c3js.org)

First you need ruby and [bundler][] to build the documentation site.

**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.)

```console
$ gem install bundler
```

Then you need to install bundler dependencies.

```console
$ bundle install
```

Then hit the following command to build the site.

```console
$ npm run watch:docs
```

Then access `http://0.0.0.0:4567`.

## Contributing your changes

Add 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

[bundler]: https://bundler.io
[rbenv]: https://github.com/rbenv/rbenv


================================================
FILE: Gemfile
================================================
# If you have OpenSSL installed, we recommend updating
# the following line to use "https"
source 'http://rubygems.org'

gem "middleman", "~>3.2.2"

# Live-reloading plugin
gem "middleman-livereload", "~> 3.1.0"

# Sync plugin
gem 'middleman-sync', '3.0.12'
gem 'unf'

# For faster file watcher updates on Windows:
gem "wdm", "~> 0.1.0", :platforms => [:mswin, :mingw]


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2013 Masayuki Tanaka

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: MAINTAINANCE.md
================================================
# Release process

If you don't have `bmp` command installed, first install `bmp` ruby gem:

    gem install bmp

When master is ready for the next release, hit the command:

    bmp -p

This automatically updates all the version numbers with a new one in the repository.

Then hit the command:

    npm run dist

This builds the scripts and stylesheets. Then hit:

    bmp -c

This commits all the changes (including the built assets) and git-tags a new version (like v0.4.16):

Then publish it to the npm registry (you need admin access to c3 module):

    npm publish

At this point, the new version is available through npm.

Then push master and the tag to github:

    git push origin master vX.Y.Z

That's all.


================================================
FILE: README.md
================================================
# c3

[![CircleCI](https://circleci.com/gh/c3js/c3.svg?style=shield)](https://circleci.com/gh/c3js/c3)
[![license](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/c3js/c3/blob/master/LICENSE)
[![codecov.io](https://codecov.io/github/c3js/c3/coverage.svg?branch=master)](https://codecov.io/github/c3js/c3?branch=master)

[![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/c3/badge?style=rounded)](https://www.jsdelivr.com/package/npm/c3)

> c3 is a D3-based reusable chart library that enables deeper integration of charts into web applications.

Follow the link for more information: [http://c3js.org](http://c3js.org/)

## Documentation

+ [Getting Started](http://c3js.org/gettingstarted.html)
+ [Examples](http://c3js.org/examples.html)
+ [Full API Reference](https://c3js.org/reference.html)

Additional samples can be found in this repository:
+ [https://github.com/c3js/c3/tree/master/htdocs/samples](https://github.com/c3js/c3/tree/master/htdocs/samples)

You can run these samples as:
```
$ npm run serve-static
```

## Google Group
For 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).

## Gitter
[![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)

## Using the issue queue
The [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!

Before reporting an issue, please do the following:

1. [Search for existing issues](https://github.com/c3js/c3/issues) to ensure you're not posting a duplicate.

1.  [Search the Google Group](https://groups.google.com/forum/#!forum/c3js) to ensure it hasn't been addressed there already.

1. 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!*

1. 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.

## Pull requests
Pull requests are welcome, though please post an issue first to see whether such a change is desirable.
If 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.

## Playground
Please fork this fiddle:

+ http://jsfiddle.net/7kYJu/4742/

## Dependency

+ [D3.js](https://github.com/mbostock/d3) `^5.0.0`

## License

MIT


================================================
FILE: bower.json
================================================
{
  "name": "c3",
  "main": ["c3.css", "c3.js"],
  "homepage": "https://github.com/c3js/c3",
  "authors": ["Masayuki Tanaka <masayuki0812@mac.com>"],
  "description": "D3-based reusable chart library",
  "keywords": ["chart", "d3"],
  "license": "MIT",
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "htdocs",
    "spec",
    "src/**/*.js",
    "package.json",
    "component.json",
    "Gruntfile.*"
  ],
  "dependencies": {
    "d3": "^5.0.0"
  }
}


================================================
FILE: c3.css
================================================
/*-- Chart --*/
.c3 svg {
  font: 10px sans-serif;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

.c3 path, .c3 line {
  fill: none;
  stroke: #000;
}

.c3 text {
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

.c3-legend-item-tile,
.c3-xgrid-focus,
.c3-ygrid,
.c3-event-rect,
.c3-bars path {
  shape-rendering: crispEdges;
}

.c3-chart-arc path {
  stroke: #fff;
}

.c3-chart-arc rect {
  stroke: white;
  stroke-width: 1;
}

.c3-chart-arc text {
  fill: #fff;
  font-size: 13px;
}

/*-- Axis --*/
/*-- Grid --*/
.c3-grid line {
  stroke: #aaa;
}

.c3-grid text {
  fill: #aaa;
}

.c3-xgrid, .c3-ygrid {
  stroke-dasharray: 3 3;
}

/*-- Text on Chart --*/
.c3-text.c3-empty {
  fill: #808080;
  font-size: 2em;
}

/*-- Line --*/
.c3-line {
  stroke-width: 1px;
}

/*-- Point --*/
.c3-circle {
  fill: currentColor;
}

.c3-circle._expanded_ {
  stroke-width: 1px;
  stroke: white;
}

.c3-selected-circle {
  fill: white;
  stroke-width: 2px;
}

/*-- Bar --*/
.c3-bar {
  stroke-width: 0;
}

.c3-bar._expanded_ {
  fill-opacity: 1;
  fill-opacity: 0.75;
}

/*-- Focus --*/
.c3-target.c3-focused {
  opacity: 1;
}

.c3-target.c3-focused path.c3-line, .c3-target.c3-focused path.c3-step {
  stroke-width: 2px;
}

.c3-target.c3-defocused {
  opacity: 0.3 !important;
}

/*-- Region --*/
.c3-region {
  fill: steelblue;
  fill-opacity: 0.1;
}
.c3-region text {
  fill-opacity: 1;
}

/*-- Brush --*/
.c3-brush .extent {
  fill-opacity: 0.1;
}

/*-- Select - Drag --*/
/*-- Legend --*/
.c3-legend-item {
  font-size: 12px;
}

.c3-legend-item-hidden {
  opacity: 0.15;
}

.c3-legend-background {
  opacity: 0.75;
  fill: white;
  stroke: lightgray;
  stroke-width: 1;
}

/*-- Title --*/
.c3-title {
  font: 14px sans-serif;
}

/*-- Tooltip --*/
.c3-tooltip-container {
  z-index: 10;
}

.c3-tooltip {
  border-collapse: collapse;
  border-spacing: 0;
  background-color: #fff;
  empty-cells: show;
  -webkit-box-shadow: 7px 7px 12px -9px #777777;
  -moz-box-shadow: 7px 7px 12px -9px #777777;
  box-shadow: 7px 7px 12px -9px #777777;
  opacity: 0.9;
}

.c3-tooltip tr {
  border: 1px solid #CCC;
}

.c3-tooltip th {
  background-color: #aaa;
  font-size: 14px;
  padding: 2px 5px;
  text-align: left;
  color: #FFF;
}

.c3-tooltip td {
  font-size: 13px;
  padding: 3px 6px;
  background-color: #fff;
  border-left: 1px dotted #999;
}

.c3-tooltip td > span {
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 6px;
}

.c3-tooltip .value {
  text-align: right;
}

/*-- Area --*/
.c3-area {
  stroke-width: 0;
  opacity: 0.2;
}

/*-- Arc --*/
.c3-chart-arcs-title {
  dominant-baseline: middle;
  font-size: 1.3em;
}

.c3-chart-arcs .c3-chart-arcs-background {
  fill: #e0e0e0;
  stroke: #FFF;
}

.c3-chart-arcs .c3-chart-arcs-gauge-unit {
  fill: #000;
  font-size: 16px;
}

.c3-chart-arcs .c3-chart-arcs-gauge-max {
  fill: #777;
}

.c3-chart-arcs .c3-chart-arcs-gauge-min {
  fill: #777;
}

.c3-chart-arc .c3-gauge-value {
  fill: #000;
  /*  font-size: 28px !important;*/
}

.c3-chart-arc.c3-target g path {
  opacity: 1;
}

.c3-chart-arc.c3-target.c3-focused g path {
  opacity: 1;
}

/*-- Zoom --*/
.c3-drag-zoom.enabled {
  pointer-events: all !important;
  visibility: visible;
}

.c3-drag-zoom.disabled {
  pointer-events: none !important;
  visibility: hidden;
}

.c3-drag-zoom .extent {
  fill-opacity: 0.1;
}


================================================
FILE: c3.esm.js
================================================
/* @license C3.js v0.7.18 | (c) C3 Team and other contributors | http://c3js.org/ */
import * as d3 from 'd3';

function ChartInternal(api) {
  var $$ = this;
  // Note: This part will be replaced by rollup-plugin-modify
  // When bundling esm output. Beware of changing this line.
  // TODO: Maybe we should check that the modification by rollup-plugin-modify
  // is valid during unit tests.
  $$.d3 = window.d3
    ? window.d3
    : typeof require !== 'undefined'
    ? require('d3')
    : undefined;
  $$.api = api;
  $$.config = $$.getDefaultConfig();
  $$.data = {};
  $$.cache = {};
  $$.axes = {};
}

/**
 * The Chart class
 *
 * The methods of this class is the public APIs of the chart object.
 */
function Chart(config) {
  this.internal = new ChartInternal(this);
  this.internal.loadConfig(config);

  this.internal.beforeInit(config);
  this.internal.init();
  this.internal.afterInit(config)

  // bind "this" to nested API
  ;(function bindThis(fn, target, argThis) {
    Object.keys(fn).forEach(function(key) {
      target[key] = fn[key].bind(argThis);
      if (Object.keys(fn[key]).length > 0) {
        bindThis(fn[key], target[key], argThis);
      }
    });
  })(Chart.prototype, this, this);
}

var asHalfPixel = function(n) {
  return Math.ceil(n) + 0.5
};
var ceil10 = function(v) {
  return Math.ceil(v / 10) * 10
};
var diffDomain = function(d) {
  return d[1] - d[0]
};
var getOption = function(options, key, defaultValue) {
  return isDefined(options[key]) ? options[key] : defaultValue
};
var getPathBox = function(path) {
  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);
  return { x: minX, y: minY, width: box.width, height: box.height }
};
var getBBox = function(element) {
  try {
    return element.getBBox()
  } catch (ignore) {
    // Firefox will throw an exception if getBBox() is called whereas the
    // element is rendered with display:none
    // See https://github.com/c3js/c3/issues/2692

    // The previous code was using `getBoundingClientRect` which was returning
    // everything at 0 in this case so let's reproduce this behavior here.

    return { x: 0, y: 0, width: 0, height: 0 }
  }
};
var hasValue = function(dict, value) {
  var found = false;
  Object.keys(dict).forEach(function(key) {
    if (dict[key] === value) {
      found = true;
    }
  });
  return found
};
var isArray = function(o) {
  return Array.isArray(o)
};
var isDefined = function(v) {
  return typeof v !== 'undefined'
};
var isEmpty = function(o) {
  return (
    typeof o === 'undefined' ||
    o === null ||
    (isString(o) && o.length === 0) ||
    (typeof o === 'object' && Object.keys(o).length === 0)
  )
};
var isFunction = function(o) {
  return typeof o === 'function'
};
var isNumber = function(o) {
  return typeof o === 'number'
};
var isString = function(o) {
  return typeof o === 'string'
};
var isUndefined = function(v) {
  return typeof v === 'undefined'
};
var isValue = function(v) {
  return v || v === 0
};
var notEmpty = function(o) {
  return !isEmpty(o)
};
var sanitise = function(str) {
  return typeof str === 'string'
    ? str.replace(/</g, '&lt;').replace(/>/g, '&gt;')
    : str
};
var flattenArray = function(arr) {
  return Array.isArray(arr) ? [].concat(...arr) : []
};
/**
 * Returns whether the point is within the given box.
 *
 * @param {Array} point An [x,y] coordinate
 * @param {Object} box An object with {x, y, width, height} keys
 * @param {Number} sensitivity An offset to ease check on very small boxes
 */
var isWithinBox = function(point, box, sensitivity = 0) {
  const xStart = box.x - sensitivity;
  const xEnd = box.x + box.width + sensitivity;
  const yStart = box.y + box.height + sensitivity;
  const yEnd = box.y - sensitivity;

  return (
    xStart < point[0] && point[0] < xEnd && yEnd < point[1] && point[1] < yStart
  )
};

/**
 * Returns Internet Explorer version number (or false if no Internet Explorer used).
 *
 * @param string agent Optional parameter to specify user agent
 */
var getIEVersion = function(agent) {
  // https://stackoverflow.com/questions/19999388/check-if-user-is-using-ie
  if (typeof agent === 'undefined') {
    agent = window.navigator.userAgent;
  }

  let pos = agent.indexOf('MSIE '); // up to IE10
  if (pos > 0) {
    return parseInt(agent.substring(pos + 5, agent.indexOf('.', pos)), 10)
  }

  pos = agent.indexOf('Trident/'); // IE11
  if (pos > 0) {
    pos = agent.indexOf('rv:');
    return parseInt(agent.substring(pos + 3, agent.indexOf('.', pos)), 10)
  }

  return false
};

/**
 * Returns whether the used browser is Internet Explorer.
 *
 * @param {Number} version Optional parameter to specify IE version
 */
var isIE = function(version) {
  const ver = getIEVersion();

  if (typeof version === 'undefined') {
    return !!ver
  }

  return version === ver
};

function AxisInternal(component, params) {
  var internal = this;
  internal.component = component;
  internal.params = params || {};

  internal.d3 = component.d3;
  internal.scale = internal.d3.scaleLinear();
  internal.range;
  internal.orient = 'bottom';
  internal.innerTickSize = 6;
  internal.outerTickSize = this.params.withOuterTick ? 6 : 0;
  internal.tickPadding = 3;
  internal.tickValues = null;
  internal.tickFormat;
  internal.tickArguments;

  internal.tickOffset = 0;
  internal.tickCulling = true;
  internal.tickCentered;
  internal.tickTextCharSize;
  internal.tickTextRotate = internal.params.tickTextRotate;
  internal.tickLength;

  internal.axis = internal.generateAxis();
}

AxisInternal.prototype.axisX = function(selection, x, tickOffset) {
  selection.attr('transform', function(d) {
    return 'translate(' + Math.ceil(x(d) + tickOffset) + ', 0)'
  });
};
AxisInternal.prototype.axisY = function(selection, y) {
  selection.attr('transform', function(d) {
    return 'translate(0,' + Math.ceil(y(d)) + ')'
  });
};
AxisInternal.prototype.scaleExtent = function(domain) {
  var start = domain[0],
    stop = domain[domain.length - 1];
  return start < stop ? [start, stop] : [stop, start]
};
AxisInternal.prototype.generateTicks = function(scale) {
  var internal = this;
  var i,
    domain,
    ticks = [];
  if (scale.ticks) {
    return scale.ticks.apply(scale, internal.tickArguments)
  }
  domain = scale.domain();
  for (i = Math.ceil(domain[0]); i < domain[1]; i++) {
    ticks.push(i);
  }
  if (ticks.length > 0 && ticks[0] > 0) {
    ticks.unshift(ticks[0] - (ticks[1] - ticks[0]));
  }
  return ticks
};
AxisInternal.prototype.copyScale = function() {
  var internal = this;
  var newScale = internal.scale.copy(),
    domain;
  if (internal.params.isCategory) {
    domain = internal.scale.domain();
    newScale.domain([domain[0], domain[1] - 1]);
  }
  return newScale
};
AxisInternal.prototype.textFormatted = function(v) {
  var internal = this,
    formatted = internal.tickFormat ? internal.tickFormat(v) : v;
  return typeof formatted !== 'undefined' ? formatted : ''
};
AxisInternal.prototype.updateRange = function() {
  var internal = this;
  internal.range = internal.scale.rangeExtent
    ? internal.scale.rangeExtent()
    : internal.scaleExtent(internal.scale.range());
  return internal.range
};
AxisInternal.prototype.updateTickTextCharSize = function(tick) {
  var internal = this;
  if (internal.tickTextCharSize) {
    return internal.tickTextCharSize
  }
  var size = {
    h: 11.5,
    w: 5.5
  };
  tick
    .select('text')
    .text(function(d) {
      return internal.textFormatted(d)
    })
    .each(function(d) {
      var box = getBBox(this),
        text = internal.textFormatted(d),
        h = box.height,
        w = text ? box.width / text.length : undefined;
      if (h && w) {
        size.h = h;
        size.w = w;
      }
    })
    .text('');
  internal.tickTextCharSize = size;
  return size
};
AxisInternal.prototype.isVertical = function() {
  return this.orient === 'left' || this.orient === 'right'
};
AxisInternal.prototype.tspanData = function(d, i, scale) {
  var internal = this;
  var splitted = internal.params.tickMultiline
    ? internal.splitTickText(d, scale)
    : [].concat(internal.textFormatted(d));

  if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) {
    splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax);
  }

  return splitted.map(function(s) {
    return { index: i, splitted: s, length: splitted.length }
  })
};
AxisInternal.prototype.splitTickText = function(d, scale) {
  var internal = this,
    tickText = internal.textFormatted(d),
    maxWidth = internal.params.tickWidth,
    subtext,
    spaceIndex,
    textWidth,
    splitted = [];

  if (Object.prototype.toString.call(tickText) === '[object Array]') {
    return tickText
  }

  if (!maxWidth || maxWidth <= 0) {
    maxWidth = internal.isVertical()
      ? 95
      : internal.params.isCategory
      ? Math.ceil(scale(1) - scale(0)) - 12
      : 110;
  }

  function split(splitted, text) {
    spaceIndex = undefined;
    for (var i = 1; i < text.length; i++) {
      if (text.charAt(i) === ' ') {
        spaceIndex = i;
      }
      subtext = text.substr(0, i + 1);
      textWidth = internal.tickTextCharSize.w * subtext.length;
      // if text width gets over tick width, split by space index or crrent index
      if (maxWidth < textWidth) {
        return split(
          splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)),
          text.slice(spaceIndex ? spaceIndex + 1 : i)
        )
      }
    }
    return splitted.concat(text)
  }

  return split(splitted, tickText + '')
};
AxisInternal.prototype.ellipsify = function(splitted, max) {
  if (splitted.length <= max) {
    return splitted
  }

  var ellipsified = splitted.slice(0, max);
  var remaining = 3;
  for (var i = max - 1; i >= 0; i--) {
    var available = ellipsified[i].length;

    ellipsified[i] = ellipsified[i]
      .substr(0, available - remaining)
      .padEnd(available, '.');

    remaining -= available;

    if (remaining <= 0) {
      break
    }
  }

  return ellipsified
};
AxisInternal.prototype.updateTickLength = function() {
  var internal = this;
  internal.tickLength =
    Math.max(internal.innerTickSize, 0) + internal.tickPadding;
};
AxisInternal.prototype.lineY2 = function(d) {
  var internal = this,
    tickPosition =
      internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset);
  return internal.range[0] < tickPosition && tickPosition < internal.range[1]
    ? internal.innerTickSize
    : 0
};
AxisInternal.prototype.textY = function() {
  var internal = this,
    rotate = internal.tickTextRotate;
  return rotate
    ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1)
    : internal.tickLength
};
AxisInternal.prototype.textTransform = function() {
  var internal = this,
    rotate = internal.tickTextRotate;
  return rotate ? 'rotate(' + rotate + ')' : ''
};
AxisInternal.prototype.textTextAnchor = function() {
  var internal = this,
    rotate = internal.tickTextRotate;
  return rotate ? (rotate > 0 ? 'start' : 'end') : 'middle'
};
AxisInternal.prototype.tspanDx = function() {
  var internal = this,
    rotate = internal.tickTextRotate;
  return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0
};
AxisInternal.prototype.tspanDy = function(d, i) {
  var internal = this,
    dy = internal.tickTextCharSize.h;
  if (i === 0) {
    if (internal.isVertical()) {
      dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3);
    } else {
      dy = '.71em';
    }
  }
  return dy
};

AxisInternal.prototype.generateAxis = function() {
  var internal = this,
    d3 = internal.d3,
    params = internal.params;
  function axis(g, transition) {
    var self;
    g.each(function() {
      var g = (axis.g = d3.select(this));

      var scale0 = this.__chart__ || internal.scale,
        scale1 = (this.__chart__ = internal.copyScale());

      var ticksValues = internal.tickValues
          ? internal.tickValues
          : internal.generateTicks(scale1),
        ticks = g.selectAll('.tick').data(ticksValues, scale1),
        tickEnter = ticks
          .enter()
          .insert('g', '.domain')
          .attr('class', 'tick')
          .style('opacity', 1e-6),
        // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks.
        tickExit = ticks.exit().remove(),
        tickUpdate = ticks.merge(tickEnter),
        tickTransform,
        tickX,
        tickY;

      if (params.isCategory) {
        internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);
        tickX = internal.tickCentered ? 0 : internal.tickOffset;
        tickY = internal.tickCentered ? internal.tickOffset : 0;
      } else {
        internal.tickOffset = tickX = 0;
      }

      internal.updateRange();
      internal.updateTickLength();
      internal.updateTickTextCharSize(g.select('.tick'));

      var lineUpdate = tickUpdate
          .select('line')
          .merge(tickEnter.append('line')),
        textUpdate = tickUpdate.select('text').merge(tickEnter.append('text'));

      var tspans = tickUpdate
          .selectAll('text')
          .selectAll('tspan')
          .data(function(d, i) {
            return internal.tspanData(d, i, scale1)
          }),
        tspanEnter = tspans.enter().append('tspan'),
        tspanUpdate = tspanEnter.merge(tspans).text(function(d) {
          return d.splitted
        });
      tspans.exit().remove();

      var path = g.selectAll('.domain').data([0]),
        pathUpdate = path
          .enter()
          .append('path')
          .merge(path)
          .attr('class', 'domain');

      // TODO: each attr should be one function and change its behavior by internal.orient, probably
      switch (internal.orient) {
        case 'bottom': {
          tickTransform = internal.axisX;
          lineUpdate
            .attr('x1', tickX)
            .attr('x2', tickX)
            .attr('y2', function(d, i) {
              return internal.lineY2(d, i)
            });
          textUpdate
            .attr('x', 0)
            .attr('y', function(d, i) {
              return internal.textY(d, i)
            })
            .attr('transform', function(d, i) {
              return internal.textTransform(d, i)
            })
            .style('text-anchor', function(d, i) {
              return internal.textTextAnchor(d, i)
            });
          tspanUpdate
            .attr('x', 0)
            .attr('dy', function(d, i) {
              return internal.tspanDy(d, i)
            })
            .attr('dx', function(d, i) {
              return internal.tspanDx(d, i)
            });
          pathUpdate.attr(
            'd',
            'M' +
              internal.range[0] +
              ',' +
              internal.outerTickSize +
              'V0H' +
              internal.range[1] +
              'V' +
              internal.outerTickSize
          );
          break
        }
        case 'top': {
          // TODO: rotated tick text
          tickTransform = internal.axisX;
          lineUpdate
            .attr('x1', tickX)
            .attr('x2', tickX)
            .attr('y2', function(d, i) {
              return -1 * internal.lineY2(d, i)
            });
          textUpdate
            .attr('x', 0)
            .attr('y', function(d, i) {
              return (
                -1 * internal.textY(d, i) -
                (params.isCategory ? 2 : internal.tickLength - 2)
              )
            })
            .attr('transform', function(d, i) {
              return internal.textTransform(d, i)
            })
            .style('text-anchor', function(d, i) {
              return internal.textTextAnchor(d, i)
            });
          tspanUpdate
            .attr('x', 0)
            .attr('dy', function(d, i) {
              return internal.tspanDy(d, i)
            })
            .attr('dx', function(d, i) {
              return internal.tspanDx(d, i)
            });
          pathUpdate.attr(
            'd',
            'M' +
              internal.range[0] +
              ',' +
              -internal.outerTickSize +
              'V0H' +
              internal.range[1] +
              'V' +
              -internal.outerTickSize
          );
          break
        }
        case 'left': {
          tickTransform = internal.axisY;
          lineUpdate
            .attr('x2', -internal.innerTickSize)
            .attr('y1', tickY)
            .attr('y2', tickY);
          textUpdate
            .attr('x', -internal.tickLength)
            .attr('y', internal.tickOffset)
            .style('text-anchor', 'end');
          tspanUpdate
            .attr('x', -internal.tickLength)
            .attr('dy', function(d, i) {
              return internal.tspanDy(d, i)
            });
          pathUpdate.attr(
            'd',
            'M' +
              -internal.outerTickSize +
              ',' +
              internal.range[0] +
              'H0V' +
              internal.range[1] +
              'H' +
              -internal.outerTickSize
          );
          break
        }
        case 'right': {
          tickTransform = internal.axisY;
          lineUpdate
            .attr('x2', internal.innerTickSize)
            .attr('y1', tickY)
            .attr('y2', tickY);
          textUpdate
            .attr('x', internal.tickLength)
            .attr('y', internal.tickOffset)
            .style('text-anchor', 'start');
          tspanUpdate.attr('x', internal.tickLength).attr('dy', function(d, i) {
            return internal.tspanDy(d, i)
          });
          pathUpdate.attr(
            'd',
            'M' +
              internal.outerTickSize +
              ',' +
              internal.range[0] +
              'H0V' +
              internal.range[1] +
              'H' +
              internal.outerTickSize
          );
          break
        }
      }
      if (scale1.rangeBand) {
        var x = scale1,
          dx = x.rangeBand() / 2;
        scale0 = scale1 = function(d) {
          return x(d) + dx
        };
      } else if (scale0.rangeBand) {
        scale0 = scale1;
      } else {
        tickExit.call(tickTransform, scale1, internal.tickOffset);
      }
      tickEnter.call(tickTransform, scale0, internal.tickOffset);
      self = (transition ? tickUpdate.transition(transition) : tickUpdate)
        .style('opacity', 1)
        .call(tickTransform, scale1, internal.tickOffset);
    });
    return self
  }
  axis.scale = function(x) {
    if (!arguments.length) {
      return internal.scale
    }
    internal.scale = x;
    return axis
  };
  axis.orient = function(x) {
    if (!arguments.length) {
      return internal.orient
    }
    internal.orient =
      x in { top: 1, right: 1, bottom: 1, left: 1 } ? x + '' : 'bottom';
    return axis
  };
  axis.tickFormat = function(format) {
    if (!arguments.length) {
      return internal.tickFormat
    }
    internal.tickFormat = format;
    return axis
  };
  axis.tickCentered = function(isCentered) {
    if (!arguments.length) {
      return internal.tickCentered
    }
    internal.tickCentered = isCentered;
    return axis
  };
  axis.tickOffset = function() {
    return internal.tickOffset
  };
  axis.tickInterval = function() {
    var interval, length;
    if (params.isCategory) {
      interval = internal.tickOffset * 2;
    } else {
      length =
        axis.g
          .select('path.domain')
          .node()
          .getTotalLength() -
        internal.outerTickSize * 2;
      interval = length / axis.g.selectAll('line').size();
    }
    return interval === Infinity ? 0 : interval
  };
  axis.ticks = function() {
    if (!arguments.length) {
      return internal.tickArguments
    }
    internal.tickArguments = arguments;
    return axis
  };
  axis.tickCulling = function(culling) {
    if (!arguments.length) {
      return internal.tickCulling
    }
    internal.tickCulling = culling;
    return axis
  };
  axis.tickValues = function(x) {
    if (typeof x === 'function') {
      internal.tickValues = function() {
        return x(internal.scale.domain())
      };
    } else {
      if (!arguments.length) {
        return internal.tickValues
      }
      internal.tickValues = x;
    }
    return axis
  };
  return axis
};

var CLASS = {
  target: 'c3-target',
  chart: 'c3-chart',
  chartLine: 'c3-chart-line',
  chartLines: 'c3-chart-lines',
  chartBar: 'c3-chart-bar',
  chartBars: 'c3-chart-bars',
  chartText: 'c3-chart-text',
  chartTexts: 'c3-chart-texts',
  chartArc: 'c3-chart-arc',
  chartArcs: 'c3-chart-arcs',
  chartArcsTitle: 'c3-chart-arcs-title',
  chartArcsBackground: 'c3-chart-arcs-background',
  chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit',
  chartArcsGaugeMax: 'c3-chart-arcs-gauge-max',
  chartArcsGaugeMin: 'c3-chart-arcs-gauge-min',
  selectedCircle: 'c3-selected-circle',
  selectedCircles: 'c3-selected-circles',
  eventRect: 'c3-event-rect',
  eventRects: 'c3-event-rects',
  eventRectsSingle: 'c3-event-rects-single',
  eventRectsMultiple: 'c3-event-rects-multiple',
  zoomRect: 'c3-zoom-rect',
  brush: 'c3-brush',
  dragZoom: 'c3-drag-zoom',
  focused: 'c3-focused',
  defocused: 'c3-defocused',
  region: 'c3-region',
  regions: 'c3-regions',
  title: 'c3-title',
  tooltipContainer: 'c3-tooltip-container',
  tooltip: 'c3-tooltip',
  tooltipName: 'c3-tooltip-name',
  shape: 'c3-shape',
  shapes: 'c3-shapes',
  line: 'c3-line',
  lines: 'c3-lines',
  bar: 'c3-bar',
  bars: 'c3-bars',
  circle: 'c3-circle',
  circles: 'c3-circles',
  arc: 'c3-arc',
  arcLabelLine: 'c3-arc-label-line',
  arcs: 'c3-arcs',
  area: 'c3-area',
  areas: 'c3-areas',
  empty: 'c3-empty',
  text: 'c3-text',
  texts: 'c3-texts',
  gaugeValue: 'c3-gauge-value',
  grid: 'c3-grid',
  gridLines: 'c3-grid-lines',
  xgrid: 'c3-xgrid',
  xgrids: 'c3-xgrids',
  xgridLine: 'c3-xgrid-line',
  xgridLines: 'c3-xgrid-lines',
  xgridFocus: 'c3-xgrid-focus',
  ygrid: 'c3-ygrid',
  ygrids: 'c3-ygrids',
  ygridLine: 'c3-ygrid-line',
  ygridLines: 'c3-ygrid-lines',
  colorScale: 'c3-colorscale',
  stanfordElements: 'c3-stanford-elements',
  stanfordLine: 'c3-stanford-line',
  stanfordLines: 'c3-stanford-lines',
  stanfordRegion: 'c3-stanford-region',
  stanfordRegions: 'c3-stanford-regions',
  stanfordText: 'c3-stanford-text',
  stanfordTexts: 'c3-stanford-texts',
  axis: 'c3-axis',
  axisX: 'c3-axis-x',
  axisXLabel: 'c3-axis-x-label',
  axisY: 'c3-axis-y',
  axisYLabel: 'c3-axis-y-label',
  axisY2: 'c3-axis-y2',
  axisY2Label: 'c3-axis-y2-label',
  legendBackground: 'c3-legend-background',
  legendItem: 'c3-legend-item',
  legendItemEvent: 'c3-legend-item-event',
  legendItemTile: 'c3-legend-item-tile',
  legendItemHidden: 'c3-legend-item-hidden',
  legendItemFocused: 'c3-legend-item-focused',
  dragarea: 'c3-dragarea',
  EXPANDED: '_expanded_',
  SELECTED: '_selected_',
  INCLUDED: '_included_'
};

class Axis {
  constructor(owner) {
    this.owner = owner;
    this.d3 = owner.d3;
    this.internal = AxisInternal;
  }
}
Axis.prototype.init = function init() {
  var $$ = this.owner,
    config = $$.config,
    main = $$.main;
  $$.axes.x = main
    .append('g')
    .attr('class', CLASS.axis + ' ' + CLASS.axisX)
    .attr('clip-path', config.axis_x_inner ? '' : $$.clipPathForXAxis)
    .attr('transform', $$.getTranslate('x'))
    .style('visibility', config.axis_x_show ? 'visible' : 'hidden');
  $$.axes.x
    .append('text')
    .attr('class', CLASS.axisXLabel)
    .attr('transform', config.axis_rotated ? 'rotate(-90)' : '')
    .style('text-anchor', this.textAnchorForXAxisLabel.bind(this));
  $$.axes.y = main
    .append('g')
    .attr('class', CLASS.axis + ' ' + CLASS.axisY)
    .attr('clip-path', config.axis_y_inner ? '' : $$.clipPathForYAxis)
    .attr('transform', $$.getTranslate('y'))
    .style('visibility', config.axis_y_show ? 'visible' : 'hidden');
  $$.axes.y
    .append('text')
    .attr('class', CLASS.axisYLabel)
    .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')
    .style('text-anchor', this.textAnchorForYAxisLabel.bind(this));

  $$.axes.y2 = main
    .append('g')
    .attr('class', CLASS.axis + ' ' + CLASS.axisY2)
    // clip-path?
    .attr('transform', $$.getTranslate('y2'))
    .style('visibility', config.axis_y2_show ? 'visible' : 'hidden');
  $$.axes.y2
    .append('text')
    .attr('class', CLASS.axisY2Label)
    .attr('transform', config.axis_rotated ? '' : 'rotate(-90)')
    .style('text-anchor', this.textAnchorForY2AxisLabel.bind(this));
};
Axis.prototype.getXAxis = function getXAxis(
  scale,
  orient,
  tickFormat,
  tickValues,
  withOuterTick,
  withoutTransition,
  withoutRotateTickText
) {
  var $$ = this.owner,
    config = $$.config,
    axisParams = {
      isCategory: $$.isCategorized(),
      withOuterTick: withOuterTick,
      tickMultiline: config.axis_x_tick_multiline,
      tickMultilineMax: config.axis_x_tick_multiline
        ? Number(config.axis_x_tick_multilineMax)
        : 0,
      tickWidth: config.axis_x_tick_width,
      tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate,
      withoutTransition: withoutTransition
    },
    axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient);

  if ($$.isTimeSeries() && tickValues && typeof tickValues !== 'function') {
    tickValues = tickValues.map(function(v) {
      return $$.parseDate(v)
    });
  }

  // Set tick
  axis.tickFormat(tickFormat).tickValues(tickValues);
  if ($$.isCategorized()) {
    axis.tickCentered(config.axis_x_tick_centered);
    if (isEmpty(config.axis_x_tick_culling)) {
      config.axis_x_tick_culling = false;
    }
  }

  return axis
};
Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues(
  targets,
  axis
) {
  var $$ = this.owner,
    config = $$.config,
    tickValues;
  if (config.axis_x_tick_fit || config.axis_x_tick_count) {
    tickValues = this.generateTickValues(
      $$.mapTargetsToUniqueXs(targets),
      config.axis_x_tick_count,
      $$.isTimeSeries()
    );
  }
  if (axis) {
    axis.tickValues(tickValues);
  } else {
    $$.xAxis.tickValues(tickValues);
    $$.subXAxis.tickValues(tickValues);
  }
  return tickValues
};
Axis.prototype.getYAxis = function getYAxis(
  axisId,
  scale,
  orient,
  tickValues,
  withOuterTick,
  withoutTransition,
  withoutRotateTickText
) {
  const $$ = this.owner;
  const config = $$.config;

  let tickFormat = config[`axis_${axisId}_tick_format`];
  if (!tickFormat && $$.isAxisNormalized(axisId)) {
    tickFormat = x => `${x}%`;
  }

  const axis = new this.internal(this, {
    withOuterTick: withOuterTick,
    withoutTransition: withoutTransition,
    tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate
  }).axis
    .scale(scale)
    .orient(orient);

  if (tickFormat) {
    axis.tickFormat(tickFormat);
  }

  if ($$.isTimeSeriesY()) {
    axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval);
  } else {
    axis.tickValues(tickValues);
  }
  return axis
};
Axis.prototype.getId = function getId(id) {
  var config = this.owner.config;
  return id in config.data_axes ? config.data_axes[id] : 'y'
};
Axis.prototype.getXAxisTickFormat = function getXAxisTickFormat() {
  // #2251 previously set any negative values to a whole number,
  // however both should be truncated according to the users format specification
  var $$ = this.owner,
    config = $$.config;
  let format = $$.isTimeSeries()
    ? $$.defaultAxisTimeFormat
    : $$.isCategorized()
    ? $$.categoryName
    : function(v) {
        return v
      };

  if (config.axis_x_tick_format) {
    if (isFunction(config.axis_x_tick_format)) {
      format = config.axis_x_tick_format;
    } else if ($$.isTimeSeries()) {
      format = function(date) {
        return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : ''
      };
    }
  }
  return isFunction(format)
    ? function(v) {
        return format.call($$, v)
      }
    : format
};
Axis.prototype.getTickValues = function getTickValues(tickValues, axis) {
  return tickValues ? tickValues : axis ? axis.tickValues() : undefined
};
Axis.prototype.getXAxisTickValues = function getXAxisTickValues() {
  return this.getTickValues(
    this.owner.config.axis_x_tick_values,
    this.owner.xAxis
  )
};
Axis.prototype.getYAxisTickValues = function getYAxisTickValues() {
  return this.getTickValues(
    this.owner.config.axis_y_tick_values,
    this.owner.yAxis
  )
};
Axis.prototype.getY2AxisTickValues = function getY2AxisTickValues() {
  return this.getTickValues(
    this.owner.config.axis_y2_tick_values,
    this.owner.y2Axis
  )
};
Axis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(
  axisId
) {
  var $$ = this.owner,
    config = $$.config,
    option;
  if (axisId === 'y') {
    option = config.axis_y_label;
  } else if (axisId === 'y2') {
    option = config.axis_y2_label;
  } else if (axisId === 'x') {
    option = config.axis_x_label;
  }
  return option
};
Axis.prototype.getLabelText = function getLabelText(axisId) {
  var option = this.getLabelOptionByAxisId(axisId);
  return isString(option) ? option : option ? option.text : null
};
Axis.prototype.setLabelText = function setLabelText(axisId, text) {
  var $$ = this.owner,
    config = $$.config,
    option = this.getLabelOptionByAxisId(axisId);
  if (isString(option)) {
    if (axisId === 'y') {
      config.axis_y_label = text;
    } else if (axisId === 'y2') {
      config.axis_y2_label = text;
    } else if (axisId === 'x') {
      config.axis_x_label = text;
    }
  } else if (option) {
    option.text = text;
  }
};
Axis.prototype.getLabelPosition = function getLabelPosition(
  axisId,
  defaultPosition
) {
  var option = this.getLabelOptionByAxisId(axisId),
    position =
      option && typeof option === 'object' && option.position
        ? option.position
        : defaultPosition;
  return {
    isInner: position.indexOf('inner') >= 0,
    isOuter: position.indexOf('outer') >= 0,
    isLeft: position.indexOf('left') >= 0,
    isCenter: position.indexOf('center') >= 0,
    isRight: position.indexOf('right') >= 0,
    isTop: position.indexOf('top') >= 0,
    isMiddle: position.indexOf('middle') >= 0,
    isBottom: position.indexOf('bottom') >= 0
  }
};
Axis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() {
  return this.getLabelPosition(
    'x',
    this.owner.config.axis_rotated ? 'inner-top' : 'inner-right'
  )
};
Axis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() {
  return this.getLabelPosition(
    'y',
    this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'
  )
};
Axis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() {
  return this.getLabelPosition(
    'y2',
    this.owner.config.axis_rotated ? 'inner-right' : 'inner-top'
  )
};
Axis.prototype.getLabelPositionById = function getLabelPositionById(id) {
  return id === 'y2'
    ? this.getY2AxisLabelPosition()
    : id === 'y'
    ? this.getYAxisLabelPosition()
    : this.getXAxisLabelPosition()
};
Axis.prototype.textForXAxisLabel = function textForXAxisLabel() {
  return this.getLabelText('x')
};
Axis.prototype.textForYAxisLabel = function textForYAxisLabel() {
  return this.getLabelText('y')
};
Axis.prototype.textForY2AxisLabel = function textForY2AxisLabel() {
  return this.getLabelText('y2')
};
Axis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) {
  var $$ = this.owner;
  if (forHorizontal) {
    return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width
  } else {
    return position.isBottom
      ? -$$.height
      : position.isMiddle
      ? -$$.height / 2
      : 0
  }
};
Axis.prototype.dxForAxisLabel = function dxForAxisLabel(
  forHorizontal,
  position
) {
  if (forHorizontal) {
    return position.isLeft ? '0.5em' : position.isRight ? '-0.5em' : '0'
  } else {
    return position.isTop ? '-0.5em' : position.isBottom ? '0.5em' : '0'
  }
};
Axis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(
  forHorizontal,
  position
) {
  if (forHorizontal) {
    return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end'
  } else {
    return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end'
  }
};
Axis.prototype.xForXAxisLabel = function xForXAxisLabel() {
  return this.xForAxisLabel(
    !this.owner.config.axis_rotated,
    this.getXAxisLabelPosition()
  )
};
Axis.prototype.xForYAxisLabel = function xForYAxisLabel() {
  return this.xForAxisLabel(
    this.owner.config.axis_rotated,
    this.getYAxisLabelPosition()
  )
};
Axis.prototype.xForY2AxisLabel = function xForY2AxisLabel() {
  return this.xForAxisLabel(
    this.owner.config.axis_rotated,
    this.getY2AxisLabelPosition()
  )
};
Axis.prototype.dxForXAxisLabel = function dxForXAxisLabel() {
  return this.dxForAxisLabel(
    !this.owner.config.axis_rotated,
    this.getXAxisLabelPosition()
  )
};
Axis.prototype.dxForYAxisLabel = function dxForYAxisLabel() {
  return this.dxForAxisLabel(
    this.owner.config.axis_rotated,
    this.getYAxisLabelPosition()
  )
};
Axis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() {
  return this.dxForAxisLabel(
    this.owner.config.axis_rotated,
    this.getY2AxisLabelPosition()
  )
};
Axis.prototype.dyForXAxisLabel = function dyForXAxisLabel() {
  var $$ = this.owner,
    config = $$.config,
    position = this.getXAxisLabelPosition();
  if (config.axis_rotated) {
    return position.isInner
      ? '1.2em'
      : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x'))
  } else {
    return position.isInner ? '-0.5em' : $$.getHorizontalAxisHeight('x') - 10
  }
};
Axis.prototype.dyForYAxisLabel = function dyForYAxisLabel() {
  var $$ = this.owner,
    position = this.getYAxisLabelPosition();
  if ($$.config.axis_rotated) {
    return position.isInner ? '-0.5em' : '3em'
  } else {
    return position.isInner
      ? '1.2em'
      : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10)
  }
};
Axis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() {
  var $$ = this.owner,
    position = this.getY2AxisLabelPosition();
  if ($$.config.axis_rotated) {
    return position.isInner ? '1.2em' : '-2.2em'
  } else {
    return position.isInner
      ? '-0.5em'
      : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15)
  }
};
Axis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() {
  var $$ = this.owner;
  return this.textAnchorForAxisLabel(
    !$$.config.axis_rotated,
    this.getXAxisLabelPosition()
  )
};
Axis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() {
  var $$ = this.owner;
  return this.textAnchorForAxisLabel(
    $$.config.axis_rotated,
    this.getYAxisLabelPosition()
  )
};
Axis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() {
  var $$ = this.owner;
  return this.textAnchorForAxisLabel(
    $$.config.axis_rotated,
    this.getY2AxisLabelPosition()
  )
};
Axis.prototype.getMaxTickWidth = function getMaxTickWidth(
  id,
  withoutRecompute
) {
  var $$ = this.owner,
    maxWidth = 0,
    targetsToShow,
    scale,
    axis,
    dummy,
    svg;
  if (withoutRecompute && $$.currentMaxTickWidths[id]) {
    return $$.currentMaxTickWidths[id]
  }
  if ($$.svg) {
    targetsToShow = $$.filterTargetsToShow($$.data.targets);
    if (id === 'y') {
      scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));
      axis = this.getYAxis(
        id,
        scale,
        $$.yOrient,
        $$.yAxisTickValues,
        false,
        true,
        true
      );
    } else if (id === 'y2') {
      scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));
      axis = this.getYAxis(
        id,
        scale,
        $$.y2Orient,
        $$.y2AxisTickValues,
        false,
        true,
        true
      );
    } else {
      scale = $$.x.copy().domain($$.getXDomain(targetsToShow));
      axis = this.getXAxis(
        scale,
        $$.xOrient,
        $$.xAxisTickFormat,
        $$.xAxisTickValues,
        false,
        true,
        true
      );
      this.updateXAxisTickValues(targetsToShow, axis);
    }
    dummy = $$.d3
      .select('body')
      .append('div')
      .classed('c3', true)
    ;(svg = dummy
      .append('svg')
      .style('visibility', 'hidden')
      .style('position', 'fixed')
      .style('top', 0)
      .style('left', 0)),
      svg
        .append('g')
        .call(axis)
        .each(function() {
          $$.d3
            .select(this)
            .selectAll('text')
            .each(function() {
              var box = getBBox(this);
              if (maxWidth < box.width) {
                maxWidth = box.width;
              }
            });
          dummy.remove();
        });
  }
  $$.currentMaxTickWidths[id] =
    maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth;
  return $$.currentMaxTickWidths[id]
};

Axis.prototype.updateLabels = function updateLabels(withTransition) {
  var $$ = this.owner;
  var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel),
    axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel),
    axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label)
  ;(withTransition ? axisXLabel.transition() : axisXLabel)
    .attr('x', this.xForXAxisLabel.bind(this))
    .attr('dx', this.dxForXAxisLabel.bind(this))
    .attr('dy', this.dyForXAxisLabel.bind(this))
    .text(this.textForXAxisLabel.bind(this))
  ;(withTransition ? axisYLabel.transition() : axisYLabel)
    .attr('x', this.xForYAxisLabel.bind(this))
    .attr('dx', this.dxForYAxisLabel.bind(this))
    .attr('dy', this.dyForYAxisLabel.bind(this))
    .text(this.textForYAxisLabel.bind(this))
  ;(withTransition ? axisY2Label.transition() : axisY2Label)
    .attr('x', this.xForY2AxisLabel.bind(this))
    .attr('dx', this.dxForY2AxisLabel.bind(this))
    .attr('dy', this.dyForY2AxisLabel.bind(this))
    .text(this.textForY2AxisLabel.bind(this));
};
Axis.prototype.getPadding = function getPadding(
  padding,
  key,
  defaultValue,
  domainLength
) {
  var p = typeof padding === 'number' ? padding : padding[key];
  if (!isValue(p)) {
    return defaultValue
  }
  if (padding.unit === 'ratio') {
    return padding[key] * domainLength
  }
  // assume padding is pixels if unit is not specified
  return this.convertPixelsToAxisPadding(p, domainLength)
};
Axis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(
  pixels,
  domainLength
) {
  var $$ = this.owner,
    length = $$.config.axis_rotated ? $$.width : $$.height;
  return domainLength * (pixels / length)
};
Axis.prototype.generateTickValues = function generateTickValues(
  values,
  tickCount,
  forTimeSeries
) {
  var tickValues = values,
    targetCount,
    start,
    end,
    count,
    interval,
    i,
    tickValue;
  if (tickCount) {
    targetCount = isFunction(tickCount) ? tickCount() : tickCount;
    // compute ticks according to tickCount
    if (targetCount === 1) {
      tickValues = [values[0]];
    } else if (targetCount === 2) {
      tickValues = [values[0], values[values.length - 1]];
    } else if (targetCount > 2) {
      count = targetCount - 2;
      start = values[0];
      end = values[values.length - 1];
      interval = (end - start) / (count + 1);
      // re-construct unique values
      tickValues = [start];
      for (i = 0; i < count; i++) {
        tickValue = +start + interval * (i + 1);
        tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue);
      }
      tickValues.push(end);
    }
  }
  if (!forTimeSeries) {
    tickValues = tickValues.sort(function(a, b) {
      return a - b
    });
  }
  return tickValues
};
Axis.prototype.generateTransitions = function generateTransitions(duration) {
  var $$ = this.owner,
    axes = $$.axes;
  return {
    axisX: duration ? axes.x.transition().duration(duration) : axes.x,
    axisY: duration ? axes.y.transition().duration(duration) : axes.y,
    axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2,
    axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx
  }
};
Axis.prototype.redraw = function redraw(duration, isHidden) {
  var $$ = this.owner,
    transition = duration ? $$.d3.transition().duration(duration) : null;
  $$.axes.x.style('opacity', isHidden ? 0 : 1).call($$.xAxis, transition);
  $$.axes.y.style('opacity', isHidden ? 0 : 1).call($$.yAxis, transition);
  $$.axes.y2.style('opacity', isHidden ? 0 : 1).call($$.y2Axis, transition);
  $$.axes.subx.style('opacity', isHidden ? 0 : 1).call($$.subXAxis, transition);
};

var c3 = {
  version: '0.7.18',
  chart: {
    fn: Chart.prototype,
    internal: {
      fn: ChartInternal.prototype,
      axis: {
        fn: Axis.prototype,
        internal: {
          fn: AxisInternal.prototype
        }
      }
    }
  },
  generate: function(config) {
    return new Chart(config)
  }
};

ChartInternal.prototype.beforeInit = function() {
  // can do something
};
ChartInternal.prototype.afterInit = function() {
  // can do something
};
ChartInternal.prototype.init = function() {
  var $$ = this,
    config = $$.config;

  $$.initParams();

  if (config.data_url) {
    $$.convertUrlToData(
      config.data_url,
      config.data_mimeType,
      config.data_headers,
      config.data_keys,
      $$.initWithData
    );
  } else if (config.data_json) {
    $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));
  } else if (config.data_rows) {
    $$.initWithData($$.convertRowsToData(config.data_rows));
  } else if (config.data_columns) {
    $$.initWithData($$.convertColumnsToData(config.data_columns));
  } else {
    throw Error('url or json or rows or columns is required.')
  }
};

ChartInternal.prototype.initParams = function() {
  var $$ = this,
    d3 = $$.d3,
    config = $$.config;

  // MEMO: clipId needs to be unique because it conflicts when multiple charts exist
  $$.clipId = 'c3-' + new Date().valueOf() + '-clip';
  $$.clipIdForXAxis = $$.clipId + '-xaxis';
  $$.clipIdForYAxis = $$.clipId + '-yaxis';
  $$.clipIdForGrid = $$.clipId + '-grid';
  $$.clipIdForSubchart = $$.clipId + '-subchart';
  $$.clipPath = $$.getClipPath($$.clipId);
  $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis);
  $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis);
  $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid);
  $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart);

  $$.dragStart = null;
  $$.dragging = false;
  $$.flowing = false;
  $$.cancelClick = false;
  $$.mouseover = undefined;
  $$.transiting = false;

  $$.color = $$.generateColor();
  $$.levelColor = $$.generateLevelColor();

  $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)(
    $$.config.data_xFormat
  );
  $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat;
  $$.defaultAxisTimeFormat = function(date) {
    if (date.getMilliseconds()) {
      return d3.timeFormat('.%L')(date)
    }
    if (date.getSeconds()) {
      return d3.timeFormat(':%S')(date)
    }
    if (date.getMinutes()) {
      return d3.timeFormat('%I:%M')(date)
    }
    if (date.getHours()) {
      return d3.timeFormat('%I %p')(date)
    }
    if (date.getDay() && date.getDate() !== 1) {
      return d3.timeFormat('%-m/%-d')(date)
    }
    if (date.getDate() !== 1) {
      return d3.timeFormat('%-m/%-d')(date)
    }
    if (date.getMonth()) {
      return d3.timeFormat('%-m/%-d')(date)
    }
    return d3.timeFormat('%Y/%-m/%-d')(date)
  };
  $$.hiddenTargetIds = [];
  $$.hiddenLegendIds = [];
  $$.focusedTargetIds = [];
  $$.defocusedTargetIds = [];

  $$.xOrient = config.axis_rotated
    ? config.axis_x_inner
      ? 'right'
      : 'left'
    : config.axis_x_inner
    ? 'top'
    : 'bottom';
  $$.yOrient = config.axis_rotated
    ? config.axis_y_inner
      ? 'top'
      : 'bottom'
    : config.axis_y_inner
    ? 'right'
    : 'left';
  $$.y2Orient = config.axis_rotated
    ? config.axis_y2_inner
      ? 'bottom'
      : 'top'
    : config.axis_y2_inner
    ? 'left'
    : 'right';
  $$.subXOrient = config.axis_rotated ? 'left' : 'bottom';

  $$.isLegendRight = config.legend_position === 'right';
  $$.isLegendInset = config.legend_position === 'inset';
  $$.isLegendTop =
    config.legend_inset_anchor === 'top-left' ||
    config.legend_inset_anchor === 'top-right';
  $$.isLegendLeft =
    config.legend_inset_anchor === 'top-left' ||
    config.legend_inset_anchor === 'bottom-left';
  $$.legendStep = 0;
  $$.legendItemWidth = 0;
  $$.legendItemHeight = 0;

  $$.currentMaxTickWidths = {
    x: 0,
    y: 0,
    y2: 0
  };

  $$.rotated_padding_left = 30;
  $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30;
  $$.rotated_padding_top = 5;

  $$.withoutFadeIn = {};

  $$.intervalForObserveInserted = undefined;

  $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js
};

ChartInternal.prototype.initChartElements = function() {
  if (this.initBar) {
    this.initBar();
  }
  if (this.initLine) {
    this.initLine();
  }
  if (this.initArc) {
    this.initArc();
  }
  if (this.initGauge) {
    this.initGauge();
  }
  if (this.initText) {
    this.initText();
  }
};

ChartInternal.prototype.initWithData = function(data) {
  var $$ = this,
    d3 = $$.d3,
    config = $$.config;
  var defs,
    main,
    binding = true;

  $$.axis = new Axis($$);

  if (!config.bindto) {
    $$.selectChart = d3.selectAll([]);
  } else if (typeof config.bindto.node === 'function') {
    $$.selectChart = config.bindto;
  } else {
    $$.selectChart = d3.select(config.bindto);
  }
  if ($$.selectChart.empty()) {
    $$.selectChart = d3
      .select(document.createElement('div'))
      .style('opacity', 0);
    $$.observeInserted($$.selectChart);
    binding = false;
  }
  $$.selectChart.html('').classed('c3', true);

  // Init data as targets
  $$.data.xs = {};
  $$.data.targets = $$.convertDataToTargets(data);

  if (config.data_filter) {
    $$.data.targets = $$.data.targets.filter(config.data_filter);
  }

  // Set targets to hide if needed
  if (config.data_hide) {
    $$.addHiddenTargetIds(
      config.data_hide === true
        ? $$.mapToIds($$.data.targets)
        : config.data_hide
    );
  }
  if (config.legend_hide) {
    $$.addHiddenLegendIds(
      config.legend_hide === true
        ? $$.mapToIds($$.data.targets)
        : config.legend_hide
    );
  }

  if ($$.isStanfordGraphType()) {
    $$.initStanfordData();
  }

  // Init sizes and scales
  $$.updateSizes();
  $$.updateScales();

  // Set domains for each scale
  $$.x.domain(d3.extent($$.getXDomain($$.data.targets)));
  $$.y.domain($$.getYDomain($$.data.targets, 'y'));
  $$.y2.domain($$.getYDomain($$.data.targets, 'y2'));
  $$.subX.domain($$.x.domain());
  $$.subY.domain($$.y.domain());
  $$.subY2.domain($$.y2.domain());

  // Save original x domain for zoom update
  $$.orgXDomain = $$.x.domain();

  /*-- Basic Elements --*/

  // Define svgs
  $$.svg = $$.selectChart
    .append('svg')
    .style('overflow', 'hidden')
    .on('mouseenter', function() {
      return config.onmouseover.call($$)
    })
    .on('mouseleave', function() {
      return config.onmouseout.call($$)
    });

  if ($$.config.svg_classname) {
    $$.svg.attr('class', $$.config.svg_classname);
  }

  // Define defs
  defs = $$.svg.append('defs');
  $$.clipChart = $$.appendClip(defs, $$.clipId);
  $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis);
  $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis);
  $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid);
  $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart);
  $$.updateSvgSize();

  // Define regions
  main = $$.main = $$.svg.append('g').attr('transform', $$.getTranslate('main'));

  if ($$.initPie) {
    $$.initPie();
  }
  if ($$.initDragZoom) {
    $$.initDragZoom();
  }
  if (config.subchart_show && $$.initSubchart) {
    $$.initSubchart();
  }
  if ($$.initTooltip) {
    $$.initTooltip();
  }
  if ($$.initLegend) {
    $$.initLegend();
  }
  if ($$.initTitle) {
    $$.initTitle();
  }
  if ($$.initZoom) {
    $$.initZoom();
  }
  if ($$.isStanfordGraphType()) {
    $$.drawColorScale();
  }

  // Update selection based on size and scale
  // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart.
  if (config.subchart_show && $$.initSubchartBrush) {
    $$.initSubchartBrush();
  }

  /*-- Main Region --*/

  // text when empty
  main
    .append('text')
    .attr('class', CLASS.text + ' ' + CLASS.empty)
    .attr('text-anchor', 'middle') // horizontal centering of text at x position in all browsers.
    .attr('dominant-baseline', 'middle'); // vertical centering of text at y position in all browsers, except IE.

  // Regions
  $$.initRegion();

  // Grids
  $$.initGrid();

  // Define g for chart area
  main
    .append('g')
    .attr('clip-path', $$.clipPath)
    .attr('class', CLASS.chart);

  // Grid lines
  if (config.grid_lines_front) {
    $$.initGridLines();
  }

  $$.initStanfordElements();

  // Cover whole with rects for events
  $$.initEventRect();

  // Define g for chart
  $$.initChartElements();

  // Add Axis
  $$.axis.init();

  // Set targets
  $$.updateTargets($$.data.targets);

  // Set default extent if defined
  if (config.axis_x_selection) {
    $$.brush.selectionAsValue($$.getDefaultSelection());
  }

  // Draw with targets
  if (binding) {
    $$.updateDimension();
    $$.config.oninit.call($$);
    $$.redraw({
      withTransition: false,
      withTransform: true,
      withUpdateXDomain: true,
      withUpdateOrgXDomain: true,
      withTransitionForAxis: false
    });
  }

  // Bind to resize event
  $$.bindResize();

  // Bind to window focus event
  $$.bindWindowFocus();

  // export element of the chart
  $$.api.element = $$.selectChart.node();
};

ChartInternal.prototype.smoothLines = function(el, type) {
  var $$ = this;
  if (type === 'grid') {
    el.each(function() {
      var g = $$.d3.select(this),
        x1 = g.attr('x1'),
        x2 = g.attr('x2'),
        y1 = g.attr('y1'),
        y2 = g.attr('y2');
      g.attr({
        x1: Math.ceil(x1),
        x2: Math.ceil(x2),
        y1: Math.ceil(y1),
        y2: Math.ceil(y2)
      });
    });
  }
};

ChartInternal.prototype.updateSizes = function() {
  var $$ = this,
    config = $$.config;
  var legendHeight = $$.legend ? $$.getLegendHeight() : 0,
    legendWidth = $$.legend ? $$.getLegendWidth() : 0,
    legendHeightForBottom =
      $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight,
    hasArc = $$.hasArcType(),
    xAxisHeight =
      config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'),
    subchartHeight =
      config.subchart_show && !hasArc
        ? config.subchart_size_height + xAxisHeight
        : 0;

  $$.currentWidth = $$.getCurrentWidth();
  $$.currentHeight = $$.getCurrentHeight();

  // for main
  $$.margin = config.axis_rotated
    ? {
        top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(),
        right: hasArc ? 0 : $$.getCurrentPaddingRight(),
        bottom:
          $$.getHorizontalAxisHeight('y') +
          legendHeightForBottom +
          $$.getCurrentPaddingBottom(),
        left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft())
      }
    : {
        top: 4 + $$.getCurrentPaddingTop(), // for top tick text
        right: hasArc ? 0 : $$.getCurrentPaddingRight(),
        bottom:
          xAxisHeight +
          subchartHeight +
          legendHeightForBottom +
          $$.getCurrentPaddingBottom(),
        left: hasArc ? 0 : $$.getCurrentPaddingLeft()
      };

  // for subchart
  $$.margin2 = config.axis_rotated
    ? {
        top: $$.margin.top,
        right: NaN,
        bottom: 20 + legendHeightForBottom,
        left: $$.rotated_padding_left
      }
    : {
        top: $$.currentHeight - subchartHeight - legendHeightForBottom,
        right: NaN,
        bottom: xAxisHeight + legendHeightForBottom,
        left: $$.margin.left
      };

  // for legend
  $$.margin3 = {
    top: 0,
    right: NaN,
    bottom: 0,
    left: 0
  };
  if ($$.updateSizeForLegend) {
    $$.updateSizeForLegend(legendHeight, legendWidth);
  }

  $$.width = $$.currentWidth - $$.margin.left - $$.margin.right;
  $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom;
  if ($$.width < 0) {
    $$.width = 0;
  }
  if ($$.height < 0) {
    $$.height = 0;
  }

  $$.width2 = config.axis_rotated
    ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right
    : $$.width;
  $$.height2 = config.axis_rotated
    ? $$.height
    : $$.currentHeight - $$.margin2.top - $$.margin2.bottom;
  if ($$.width2 < 0) {
    $$.width2 = 0;
  }
  if ($$.height2 < 0) {
    $$.height2 = 0;
  }

  // for arc
  $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0);
  $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10);
  if ($$.hasType('gauge') && !config.gauge_fullCircle) {
    $$.arcHeight += $$.height - $$.getGaugeLabelHeight();
  }
  if ($$.updateRadius) {
    $$.updateRadius();
  }

  if ($$.isLegendRight && hasArc) {
    $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1;
  }
};

ChartInternal.prototype.updateTargets = function(targets) {
  var $$ = this,
    config = $$.config;

  /*-- Main --*/

  //-- Text --//
  $$.updateTargetsForText(targets);

  //-- Bar --//
  $$.updateTargetsForBar(targets);

  //-- Line --//
  $$.updateTargetsForLine(targets);

  //-- Arc --//
  if ($$.hasArcType() && $$.updateTargetsForArc) {
    $$.updateTargetsForArc(targets);
  }

  /*-- Sub --*/

  if (config.subchart_show && $$.updateTargetsForSubchart) {
    $$.updateTargetsForSubchart(targets);
  }

  // Fade-in each chart
  $$.showTargets();
};
ChartInternal.prototype.showTargets = function() {
  var $$ = this;
  $$.svg
    .selectAll('.' + CLASS.target)
    .filter(function(d) {
      return $$.isTargetToShow(d.id)
    })
    .transition()
    .duration($$.config.transition_duration)
    .style('opacity', 1);
};

ChartInternal.prototype.redraw = function(options, transitions) {
  var $$ = this,
    main = $$.main,
    d3 = $$.d3,
    config = $$.config;
  var areaIndices = $$.getShapeIndices($$.isAreaType),
    barIndices = $$.getShapeIndices($$.isBarType),
    lineIndices = $$.getShapeIndices($$.isLineType);
  var withY,
    withSubchart,
    withTransition,
    withTransitionForExit,
    withTransitionForAxis,
    withTransform,
    withUpdateXDomain,
    withUpdateOrgXDomain,
    withTrimXDomain,
    withLegend,
    withEventRect,
    withDimension,
    withUpdateXAxis;
  var hideAxis = $$.hasArcType();
  var drawArea, drawBar, drawLine, xForText, yForText;
  var duration, durationForExit, durationForAxis;
  var transitionsToWait, waitForDraw, flow, transition;
  var targetsToShow = $$.filterTargetsToShow($$.data.targets),
    tickValues,
    i,
    intervalForCulling,
    xDomainForZoom;
  var xv = $$.xv.bind($$),
    cx,
    cy;

  options = options || {};
  withY = getOption(options, 'withY', true);
  withSubchart = getOption(options, 'withSubchart', true);
  withTransition = getOption(options, 'withTransition', true);
  withTransform = getOption(options, 'withTransform', false);
  withUpdateXDomain = getOption(options, 'withUpdateXDomain', false);
  withUpdateOrgXDomain = getOption(options, 'withUpdateOrgXDomain', false);
  withTrimXDomain = getOption(options, 'withTrimXDomain', true);
  withUpdateXAxis = getOption(options, 'withUpdateXAxis', withUpdateXDomain);
  withLegend = getOption(options, 'withLegend', false);
  withEventRect = getOption(options, 'withEventRect', true);
  withDimension = getOption(options, 'withDimension', true);
  withTransitionForExit = getOption(
    options,
    'withTransitionForExit',
    withTransition
  );
  withTransitionForAxis = getOption(
    options,
    'withTransitionForAxis',
    withTransition
  );

  duration = withTransition ? config.transition_duration : 0;
  durationForExit = withTransitionForExit ? duration : 0;
  durationForAxis = withTransitionForAxis ? duration : 0;

  transitions = transitions || $$.axis.generateTransitions(durationForAxis);

  // update legend and transform each g
  if (withLegend && config.legend_show) {
    $$.updateLegend($$.mapToIds($$.data.targets), options, transitions);
  } else if (withDimension) {
    // need to update dimension (e.g. axis.y.tick.values) because y tick values should change
    // no need to update axis in it because they will be updated in redraw()
    $$.updateDimension(true);
  }

  // MEMO: needed for grids calculation
  if ($$.isCategorized() && targetsToShow.length === 0) {
    $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]);
  }

  if (targetsToShow.length) {
    $$.updateXDomain(
      targetsToShow,
      withUpdateXDomain,
      withUpdateOrgXDomain,
      withTrimXDomain
    );
    if (!config.axis_x_tick_values) {
      tickValues = $$.axis.updateXAxisTickValues(targetsToShow);
    }
  } else {
    $$.xAxis.tickValues([]);
    $$.subXAxis.tickValues([]);
  }

  if (config.zoom_rescale && !options.flow) {
    xDomainForZoom = $$.x.orgDomain();
  }

  $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom));
  $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom));

  if (!config.axis_y_tick_values && config.axis_y_tick_count) {
    $$.yAxis.tickValues(
      $$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count)
    );
  }
  if (!config.axis_y2_tick_values && config.axis_y2_tick_count) {
    $$.y2Axis.tickValues(
      $$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count)
    );
  }

  // axes
  $$.axis.redraw(durationForAxis, hideAxis);

  // Update axis label
  $$.axis.updateLabels(withTransition);

  // show/hide if manual culling needed
  if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) {
    if (config.axis_x_tick_culling && tickValues) {
      for (i = 1; i < tickValues.length; i++) {
        if (tickValues.length / i < config.axis_x_tick_culling_max) {
          intervalForCulling = i;
          break
        }
      }
      $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function(e) {
        var index = tickValues.indexOf(e);
        if (index >= 0) {
          d3.select(this).style(
            'display',
            index % intervalForCulling ? 'none' : 'block'
          );
        }
      });
    } else {
      $$.svg
        .selectAll('.' + CLASS.axisX + ' .tick text')
        .style('display', 'block');
    }
  }

  // setup drawer - MEMO: these must be called after axis updated
  drawArea = $$.generateDrawArea
    ? $$.generateDrawArea(areaIndices, false)
    : undefined;
  drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined;
  drawLine = $$.generateDrawLine
    ? $$.generateDrawLine(lineIndices, false)
    : undefined;
  xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true);
  yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false);

  // update circleY based on updated parameters
  $$.updateCircleY();
  // generate circle x/y functions depending on updated params
  cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$);
  cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$);

  // Update sub domain
  if (withY) {
    $$.subY.domain($$.getYDomain(targetsToShow, 'y'));
    $$.subY2.domain($$.getYDomain(targetsToShow, 'y2'));
  }

  // xgrid focus
  $$.updateXgridFocus();

  // Data empty label positioning and text.
  main
    .select('text.' + CLASS.text + '.' + CLASS.empty)
    .attr('x', $$.width / 2)
    .attr('y', $$.height / 2)
    .text(config.data_empty_label_text)
    .transition()
    .style('opacity', targetsToShow.length ? 0 : 1);

  // event rect
  if (withEventRect) {
    $$.redrawEventRect();
  }

  // grid
  $$.updateGrid(duration);

  $$.updateStanfordElements(duration);

  // rect for regions
  $$.updateRegion(duration);

  // bars
  $$.updateBar(durationForExit);

  // lines, areas and circles
  $$.updateLine(durationForExit);
  $$.updateArea(durationForExit);
  $$.updateCircle(cx, cy);

  // text
  if ($$.hasDataLabel()) {
    $$.updateText(xForText, yForText, durationForExit);
  }

  // title
  if ($$.redrawTitle) {
    $$.redrawTitle();
  }

  // arc
  if ($$.redrawArc) {
    $$.redrawArc(duration, durationForExit, withTransform);
  }

  // subchart
  if (config.subchart_show && $$.redrawSubchart) {
    $$.redrawSubchart(
      withSubchart,
      transitions,
      duration,
      durationForExit,
      areaIndices,
      barIndices,
      lineIndices
    );
  }

  if ($$.isStanfordGraphType()) {
    $$.drawColorScale();
  }

  // circles for select
  main
    .selectAll('.' + CLASS.selectedCircles)
    .filter($$.isBarType.bind($$))
    .selectAll('circle')
    .remove();

  if (options.flow) {
    flow = $$.generateFlow({
      targets: targetsToShow,
      flow: options.flow,
      duration: options.flow.duration,
      drawBar: drawBar,
      drawLine: drawLine,
      drawArea: drawArea,
      cx: cx,
      cy: cy,
      xv: xv,
      xForText: xForText,
      yForText: yForText
    });
  }

  if (duration && $$.isTabVisible()) {
    // Only use transition if tab visible. See #938.
    // transition should be derived from one transition
    transition = d3.transition().duration(duration);
    transitionsToWait = []
    ;[
      $$.redrawBar(drawBar, true, transition),
      $$.redrawLine(drawLine, true, transition),
      $$.redrawArea(drawArea, true, transition),
      $$.redrawCircle(cx, cy, true, transition),
      $$.redrawText(xForText, yForText, options.flow, true, transition),
      $$.redrawRegion(true, transition),
      $$.redrawGrid(true, transition)
    ].forEach(function(transitions) {
      transitions.forEach(function(transition) {
        transitionsToWait.push(transition);
      });
    });
    // Wait for end of transitions to call flow and onrendered callback
    waitForDraw = $$.generateWait();
    transitionsToWait.forEach(function(t) {
      waitForDraw.add(t);
    });
    waitForDraw(function() {
      if (flow) {
        flow();
      }
      if (config.onrendered) {
        config.onrendered.call($$);
      }
    });
  } else {
    $$.redrawBar(drawBar);
    $$.redrawLine(drawLine);
    $$.redrawArea(drawArea);
    $$.redrawCircle(cx, cy);
    $$.redrawText(xForText, yForText, options.flow);
    $$.redrawRegion();
    $$.redrawGrid();
    if (flow) {
      flow();
    }
    if (config.onrendered) {
      config.onrendered.call($$);
    }
  }

  // update fadein condition
  $$.mapToIds($$.data.targets).forEach(function(id) {
    $$.withoutFadeIn[id] = true;
  });
};

ChartInternal.prototype.updateAndRedraw = function(options) {
  var $$ = this,
    config = $$.config,
    transitions;
  options = options || {};
  // same with redraw
  options.withTransition = getOption(options, 'withTransition', true);
  options.withTransform = getOption(options, 'withTransform', false);
  options.withLegend = getOption(options, 'withLegend', false);
  // NOT same with redraw
  options.withUpdateXDomain = getOption(options, 'withUpdateXDomain', true);
  options.withUpdateOrgXDomain = getOption(
    options,
    'withUpdateOrgXDomain',
    true
  );
  options.withTransitionForExit = false;
  options.withTransitionForTransform = getOption(
    options,
    'withTransitionForTransform',
    options.withTransition
  );
  // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called)
  $$.updateSizes();
  // MEMO: called in updateLegend in redraw if withLegend
  if (!(options.withLegend && config.legend_show)) {
    transitions = $$.axis.generateTransitions(
      options.withTransitionForAxis ? config.transition_duration : 0
    );
    // Update scales
    $$.updateScales();
    $$.updateSvgSize();
    // Update g positions
    $$.transformAll(options.withTransitionForTransform, transitions);
  }
  // Draw with new sizes & scales
  $$.redraw(options, transitions);
};
ChartInternal.prototype.redrawWithoutRescale = function() {
  this.redraw({
    withY: false,
    withSubchart: false,
    withEventRect: false,
    withTransitionForAxis: false
  });
};

ChartInternal.prototype.isTimeSeries = function() {
  return this.config.axis_x_type === 'timeseries'
};
ChartInternal.prototype.isCategorized = function() {
  return this.config.axis_x_type.indexOf('categor') >= 0
};
ChartInternal.prototype.isCustomX = function() {
  var $$ = this,
    config = $$.config;
  return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs))
};

ChartInternal.prototype.isTimeSeriesY = function() {
  return this.config.axis_y_type === 'timeseries'
};

ChartInternal.prototype.getTranslate = function(target) {
  var $$ = this,
    config = $$.config,
    x,
    y;
  if (target === 'main') {
    x = asHalfPixel($$.margin.left);
    y = asHalfPixel($$.margin.top);
  } else if (target === 'context') {
    x = asHalfPixel($$.margin2.left);
    y = asHalfPixel($$.margin2.top);
  } else if (target === 'legend') {
    x = $$.margin3.left;
    y = $$.margin3.top;
  } else if (target === 'x') {
    x = 0;
    y = config.axis_rotated ? 0 : $$.height;
  } else if (target === 'y') {
    x = 0;
    y = config.axis_rotated ? $$.height : 0;
  } else if (target === 'y2') {
    x = config.axis_rotated ? 0 : $$.width;
    y = config.axis_rotated ? 1 : 0;
  } else if (target === 'subx') {
    x = 0;
    y = config.axis_rotated ? 0 : $$.height2;
  } else if (target === 'arc') {
    x = $$.arcWidth / 2;
    y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label
  }
  return 'translate(' + x + ',' + y + ')'
};
ChartInternal.prototype.initialOpacity = function(d) {
  return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0
};
ChartInternal.prototype.initialOpacityForCircle = function(d) {
  return d.value !== null && this.withoutFadeIn[d.id]
    ? this.opacityForCircle(d)
    : 0
};
ChartInternal.prototype.opacityForCircle = function(d) {
  var isPointShouldBeShown = isFunction(this.config.point_show)
    ? this.config.point_show(d)
    : this.config.point_show;
  var opacity = isPointShouldBeShown || this.isStanfordType(d) ? 1 : 0;
  return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0
};
ChartInternal.prototype.opacityForText = function() {
  return this.hasDataLabel() ? 1 : 0
};
ChartInternal.prototype.xx = function(d) {
  return d ? this.x(d.x) : null
};
ChartInternal.prototype.xvCustom = function(d, xyValue) {
  var $$ = this,
    value = xyValue ? d[xyValue] : d.value;
  if ($$.isTimeSeries()) {
    value = $$.parseDate(d.value);
  } else if ($$.isCategorized() && typeof d.value === 'string') {
    value = $$.config.axis_x_categories.indexOf(d.value);
  }
  return Math.ceil($$.x(value))
};
ChartInternal.prototype.yvCustom = function(d, xyValue) {
  var $$ = this,
    yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y,
    value = xyValue ? d[xyValue] : d.value;
  return Math.ceil(yScale(value))
};
ChartInternal.prototype.xv = function(d) {
  var $$ = this,
    value = d.value;
  if ($$.isTimeSeries()) {
    value = $$.parseDate(d.value);
  } else if ($$.isCategorized() && typeof d.value === 'string') {
    value = $$.config.axis_x_categories.indexOf(d.value);
  }
  return Math.ceil($$.x(value))
};
ChartInternal.prototype.yv = function(d) {
  var $$ = this,
    yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y;
  return Math.ceil(yScale(d.value))
};
ChartInternal.prototype.subxx = function(d) {
  return d ? this.subX(d.x) : null
};

ChartInternal.prototype.transformMain = function(withTransition, transitions) {
  var $$ = this,
    xAxis,
    yAxis,
    y2Axis;
  if (transitions && transitions.axisX) {
    xAxis = transitions.axisX;
  } else {
    xAxis = $$.main.select('.' + CLASS.axisX);
    if (withTransition) {
      xAxis = xAxis.transition();
    }
  }
  if (transitions && transitions.axisY) {
    yAxis = transitions.axisY;
  } else {
    yAxis = $$.main.select('.' + CLASS.axisY);
    if (withTransition) {
      yAxis = yAxis.transition();
    }
  }
  if (transitions && transitions.axisY2) {
    y2Axis = transitions.axisY2;
  } else {
    y2Axis = $$.main.select('.' + CLASS.axisY2);
    if (withTransition) {
      y2Axis = y2Axis.transition();
    }
  }
(withTransition ? $$.main.transition() : $$.main).attr(
    'transform',
    $$.getTranslate('main')
  );
  xAxis.attr('transform', $$.getTranslate('x'));
  yAxis.attr('transform', $$.getTranslate('y'));
  y2Axis.attr('transform', $$.getTranslate('y2'));
  $$.main
    .select('.' + CLASS.chartArcs)
    .attr('transform', $$.getTranslate('arc'));
};
ChartInternal.prototype.transformAll = function(withTransition, transitions) {
  var $$ = this;
  $$.transformMain(withTransition, transitions);
  if ($$.config.subchart_show) {
    $$.transformContext(withTransition, transitions);
  }
  if ($$.legend) {
    $$.transformLegend(withTransition);
  }
};

ChartInternal.prototype.updateSvgSize = function() {
  var $$ = this,
    brush = $$.svg.select(`.${CLASS.brush} .overlay`);
  $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight);
  $$.svg
    .selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid])
    .select('rect')
    .attr('width', $$.width)
    .attr('height', $$.height);
  $$.svg
    .select('#' + $$.clipIdForXAxis)
    .select('rect')
    .attr('x', $$.getXAxisClipX.bind($$))
    .attr('y', $$.getXAxisClipY.bind($$))
    .attr('width', $$.getXAxisClipWidth.bind($$))
    .attr('height', $$.getXAxisClipHeight.bind($$));
  $$.svg
    .select('#' + $$.clipIdForYAxis)
    .select('rect')
    .attr('x', $$.getYAxisClipX.bind($$))
    .attr('y', $$.getYAxisClipY.bind($$))
    .attr('width', $$.getYAxisClipWidth.bind($$))
    .attr('height', $$.getYAxisClipHeight.bind($$));
  $$.svg
    .select('#' + $$.clipIdForSubchart)
    .select('rect')
    .attr('width', $$.width)
    .attr('height', (brush.size() && brush.attr('height')) || 0);
  // MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>
  $$.selectChart.style('max-height', $$.currentHeight + 'px');
};

ChartInternal.prototype.updateDimension = function(withoutAxis) {
  var $$ = this;
  if (!withoutAxis) {
    if ($$.config.axis_rotated) {
      $$.axes.x.call($$.xAxis);
      $$.axes.subx.call($$.subXAxis);
    } else {
      $$.axes.y.call($$.yAxis);
      $$.axes.y2.call($$.y2Axis);
    }
  }
  $$.updateSizes();
  $$.updateScales();
  $$.updateSvgSize();
  $$.transformAll(false);
};

ChartInternal.prototype.observeInserted = function(selection) {
  var $$ = this,
    observer;
  if (typeof MutationObserver === 'undefined') {
    window.console.error('MutationObserver not defined.');
    return
  }
  observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (mutation.type === 'childList' && mutation.previousSibling) {
        observer.disconnect();
        // need to wait for completion of load because size calculation requires the actual sizes determined after that completion
        $$.intervalForObserveInserted = window.setInterval(function() {
          // parentNode will NOT be null when completed
          if (selection.node().parentNode) {
            window.clearInterval($$.intervalForObserveInserted);
            $$.updateDimension();
            if ($$.brush) {
              $$.brush.update();
            }
            $$.config.oninit.call($$);
            $$.redraw({
              withTransform: true,
              withUpdateXDomain: true,
              withUpdateOrgXDomain: true,
              withTransition: false,
              withTransitionForTransform: false,
              withLegend: true
            });
            selection.transition().style('opacity', 1);
          }
        }, 10);
      }
    });
  });
  observer.observe(selection.node(), {
    attributes: true,
    childList: true,
    characterData: true
  });
};

/**
 * Binds handlers to the window resize event.
 */
ChartInternal.prototype.bindResize = function() {
  var $$ = this,
    config = $$.config;

  $$.resizeFunction = $$.generateResize(); // need to call .remove

  $$.resizeFunction.add(function() {
    config.onresize.call($$);
  });
  if (config.resize_auto) {
    $$.resizeFunction.add(function() {
      if ($$.resizeTimeout !== undefined) {
        window.clearTimeout($$.resizeTimeout);
      }
      $$.resizeTimeout = window.setTimeout(function() {
        delete $$.resizeTimeout;
        $$.updateAndRedraw({
          withUpdateXDomain: false,
          withUpdateOrgXDomain: false,
          withTransition: false,
          withTransitionForTransform: false,
          withLegend: true
        });
        if ($$.brush) {
          $$.brush.update();
        }
      }, 100);
    });
  }
  $$.resizeFunction.add(function() {
    config.onresized.call($$);
  });

  $$.resizeIfElementDisplayed = function() {
    // if element not displayed skip it
    if ($$.api == null || !$$.api.element.offsetParent) {
      return
    }

    $$.resizeFunction();
  };

  if (window.attachEvent) {
    window.attachEvent('onresize', $$.resizeIfElementDisplayed);
  } else if (window.addEventListener) {
    window.addEventListener('resize', $$.resizeIfElementDisplayed, false);
  } else {
    // fallback to this, if this is a very old browser
    var wrapper = window.onresize;
    if (!wrapper) {
      // create a wrapper that will call all charts
      wrapper = $$.generateResize();
    } else if (!wrapper.add || !wrapper.remove) {
      // there is already a handler registered, make sure we call it too
      wrapper = $$.generateResize();
      wrapper.add(window.onresize);
    }
    // add this graph to the wrapper, we will be removed if the user calls destroy
    wrapper.add($$.resizeFunction);
    window.onresize = function() {
      // if element not displayed skip it
      if (!$$.api.element.offsetParent) {
        return
      }

      wrapper();
    };
  }
};

/**
 * Binds handlers to the window focus event.
 */
ChartInternal.prototype.bindWindowFocus = function() {
  if (this.windowFocusHandler) {
    // The handler is already set
    return
  }

  this.windowFocusHandler = () => {
    this.redraw();
  };

  window.addEventListener('focus', this.windowFocusHandler);
};

/**
 * Unbinds from the window focus event.
 */
ChartInternal.prototype.unbindWindowFocus = function() {
  window.removeEventListener('focus', this.windowFocusHandler);
  delete this.windowFocusHandler;
};

ChartInternal.prototype.generateResize = function() {
  var resizeFunctions = [];

  function callResizeFunctions() {
    resizeFunctions.forEach(function(f) {
      f();
    });
  }
  callResizeFunctions.add = function(f) {
    resizeFunctions.push(f);
  };
  callResizeFunctions.remove = function(f) {
    for (var i = 0; i < resizeFunctions.length; i++) {
      if (resizeFunctions[i] === f) {
        resizeFunctions.splice(i, 1);
        break
      }
    }
  };
  return callResizeFunctions
};

ChartInternal.prototype.endall = function(transition, callback) {
  var n = 0;
  transition
    .each(function() {
      ++n;
    })
    .on('end', function() {
      if (!--n) {
        callback.apply(this, arguments);
      }
    });
};
ChartInternal.prototype.generateWait = function() {
  var $$ = this;
  var transitionsToWait = [],
    f = function(callback) {
      var timer = setInterval(function() {
        if (!$$.isTabVisible()) {
          return
        }

        var done = 0;
        transitionsToWait.forEach(function(t) {
          if (t.empty()) {
            done += 1;
            return
          }
          try {
            t.transition();
          } catch (e) {
            done += 1;
          }
        });
        if (done === transitionsToWait.length) {
          clearInterval(timer);
          if (callback) {
            callback();
          }
        }
      }, 50);
    };
  f.add = function(transition) {
    transitionsToWait.push(transition);
  };
  return f
};

ChartInternal.prototype.parseDate = function(date) {
  var $$ = this,
    parsedDate;
  if (date instanceof Date) {
    parsedDate = date;
  } else if (typeof date === 'string') {
    parsedDate = $$.dataTimeParse(date);
  } else if (typeof date === 'object') {
    parsedDate = new Date(+date);
  } else if (typeof date === 'number' && !isNaN(date)) {
    parsedDate = new Date(+date);
  }
  if (!parsedDate || isNaN(+parsedDate)) {
    window.console.error("Failed to parse x '" + date + "' to Date object");
  }
  return parsedDate
};

ChartInternal.prototype.isTabVisible = function() {
  return !document.hidden
};

ChartInternal.prototype.getPathBox = getPathBox;
ChartInternal.prototype.CLASS = CLASS;

/* jshint ignore:start */
(function() {
  if (!('SVGPathSeg' in window)) {
    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg
    window.SVGPathSeg = function(type, typeAsLetter, owningPathSegList) {
      this.pathSegType = type;
      this.pathSegTypeAsLetter = typeAsLetter;
      this._owningPathSegList = owningPathSegList;
    };

    window.SVGPathSeg.prototype.classname = 'SVGPathSeg';

    window.SVGPathSeg.PATHSEG_UNKNOWN = 0;
    window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;
    window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
    window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;
    window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;
    window.SVGPathSeg.PATHSEG_LINETO_REL = 5;
    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
    window.SVGPathSeg.PATHSEG_ARC_ABS = 10;
    window.SVGPathSeg.PATHSEG_ARC_REL = 11;
    window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
    window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
    window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
    window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
    window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
    window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;

    // Notify owning PathSegList on any changes so they can be synchronized back to the path element.
    window.SVGPathSeg.prototype._segmentChanged = function() {
      if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this);
    };

    window.SVGPathSegClosePath = function(owningPathSegList) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_CLOSEPATH,
        'z',
        owningPathSegList
      );
    };
    window.SVGPathSegClosePath.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegClosePath.prototype.toString = function() {
      return '[object SVGPathSegClosePath]'
    };
    window.SVGPathSegClosePath.prototype._asPathString = function() {
      return this.pathSegTypeAsLetter
    };
    window.SVGPathSegClosePath.prototype.clone = function() {
      return new window.SVGPathSegClosePath(undefined)
    };

    window.SVGPathSegMovetoAbs = function(owningPathSegList, x, y) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_MOVETO_ABS,
        'M',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
    };
    window.SVGPathSegMovetoAbs.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegMovetoAbs.prototype.toString = function() {
      return '[object SVGPathSegMovetoAbs]'
    };
    window.SVGPathSegMovetoAbs.prototype._asPathString = function() {
      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y
    };
    window.SVGPathSegMovetoAbs.prototype.clone = function() {
      return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y)
    };
    Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'x', {
      get: function() {
        return this._x
      },
      set: function(x) {
        this._x = x;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, 'y', {
      get: function() {
        return this._y
      },
      set: function(y) {
        this._y = y;
        this._segmentChanged();
      },
      enumerable: true
    });

    window.SVGPathSegMovetoRel = function(owningPathSegList, x, y) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_MOVETO_REL,
        'm',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
    };
    window.SVGPathSegMovetoRel.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegMovetoRel.prototype.toString = function() {
      return '[object SVGPathSegMovetoRel]'
    };
    window.SVGPathSegMovetoRel.prototype._asPathString = function() {
      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y
    };
    window.SVGPathSegMovetoRel.prototype.clone = function() {
      return new window.SVGPathSegMovetoRel(undefined, this._x, this._y)
    };
    Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'x', {
      get: function() {
        return this._x
      },
      set: function(x) {
        this._x = x;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegMovetoRel.prototype, 'y', {
      get: function() {
        return this._y
      },
      set: function(y) {
        this._y = y;
        this._segmentChanged();
      },
      enumerable: true
    });

    window.SVGPathSegLinetoAbs = function(owningPathSegList, x, y) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_LINETO_ABS,
        'L',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
    };
    window.SVGPathSegLinetoAbs.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegLinetoAbs.prototype.toString = function() {
      return '[object SVGPathSegLinetoAbs]'
    };
    window.SVGPathSegLinetoAbs.prototype._asPathString = function() {
      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y
    };
    window.SVGPathSegLinetoAbs.prototype.clone = function() {
      return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y)
    };
    Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'x', {
      get: function() {
        return this._x
      },
      set: function(x) {
        this._x = x;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, 'y', {
      get: function() {
        return this._y
      },
      set: function(y) {
        this._y = y;
        this._segmentChanged();
      },
      enumerable: true
    });

    window.SVGPathSegLinetoRel = function(owningPathSegList, x, y) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_LINETO_REL,
        'l',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
    };
    window.SVGPathSegLinetoRel.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegLinetoRel.prototype.toString = function() {
      return '[object SVGPathSegLinetoRel]'
    };
    window.SVGPathSegLinetoRel.prototype._asPathString = function() {
      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y
    };
    window.SVGPathSegLinetoRel.prototype.clone = function() {
      return new window.SVGPathSegLinetoRel(undefined, this._x, this._y)
    };
    Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'x', {
      get: function() {
        return this._x
      },
      set: function(x) {
        this._x = x;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegLinetoRel.prototype, 'y', {
      get: function() {
        return this._y
      },
      set: function(y) {
        this._y = y;
        this._segmentChanged();
      },
      enumerable: true
    });

    window.SVGPathSegCurvetoCubicAbs = function(
      owningPathSegList,
      x,
      y,
      x1,
      y1,
      x2,
      y2
    ) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS,
        'C',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
      this._x1 = x1;
      this._y1 = y1;
      this._x2 = x2;
      this._y2 = y2;
    };
    window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegCurvetoCubicAbs.prototype.toString = function() {
      return '[object SVGPathSegCurvetoCubicAbs]'
    };
    window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function() {
      return (
        this.pathSegTypeAsLetter +
        ' ' +
        this._x1 +
        ' ' +
        this._y1 +
        ' ' +
        this._x2 +
        ' ' +
        this._y2 +
        ' ' +
        this._x +
        ' ' +
        this._y
      )
    };
    window.SVGPathSegCurvetoCubicAbs.prototype.clone = function() {
      return new window.SVGPathSegCurvetoCubicAbs(
        undefined,
        this._x,
        this._y,
        this._x1,
        this._y1,
        this._x2,
        this._y2
      )
    };
    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x', {
      get: function() {
        return this._x
      },
      set: function(x) {
        this._x = x;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y', {
      get: function() {
        return this._y
      },
      set: function(y) {
        this._y = y;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x1', {
      get: function() {
        return this._x1
      },
      set: function(x1) {
        this._x1 = x1;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y1', {
      get: function() {
        return this._y1
      },
      set: function(y1) {
        this._y1 = y1;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'x2', {
      get: function() {
        return this._x2
      },
      set: function(x2) {
        this._x2 = x2;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, 'y2', {
      get: function() {
        return this._y2
      },
      set: function(y2) {
        this._y2 = y2;
        this._segmentChanged();
      },
      enumerable: true
    });

    window.SVGPathSegCurvetoCubicRel = function(
      owningPathSegList,
      x,
      y,
      x1,
      y1,
      x2,
      y2
    ) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL,
        'c',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
      this._x1 = x1;
      this._y1 = y1;
      this._x2 = x2;
      this._y2 = y2;
    };
    window.SVGPathSegCurvetoCubicRel.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegCurvetoCubicRel.prototype.toString = function() {
      return '[object SVGPathSegCurvetoCubicRel]'
    };
    window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function() {
      return (
        this.pathSegTypeAsLetter +
        ' ' +
        this._x1 +
        ' ' +
        this._y1 +
        ' ' +
        this._x2 +
        ' ' +
        this._y2 +
        ' ' +
        this._x +
        ' ' +
        this._y
      )
    };
    window.SVGPathSegCurvetoCubicRel.prototype.clone = function() {
      return new window.SVGPathSegCurvetoCubicRel(
        undefined,
        this._x,
        this._y,
        this._x1,
        this._y1,
        this._x2,
        this._y2
      )
    };
    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x', {
      get: function() {
        return this._x
      },
      set: function(x) {
        this._x = x;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y', {
      get: function() {
        return this._y
      },
      set: function(y) {
        this._y = y;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x1', {
      get: function() {
        return this._x1
      },
      set: function(x1) {
        this._x1 = x1;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y1', {
      get: function() {
        return this._y1
      },
      set: function(y1) {
        this._y1 = y1;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'x2', {
      get: function() {
        return this._x2
      },
      set: function(x2) {
        this._x2 = x2;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, 'y2', {
      get: function() {
        return this._y2
      },
      set: function(y2) {
        this._y2 = y2;
        this._segmentChanged();
      },
      enumerable: true
    });

    window.SVGPathSegCurvetoQuadraticAbs = function(
      owningPathSegList,
      x,
      y,
      x1,
      y1
    ) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS,
        'Q',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
      this._x1 = x1;
      this._y1 = y1;
    };
    window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function() {
      return '[object SVGPathSegCurvetoQuadraticAbs]'
    };
    window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function() {
      return (
        this.pathSegTypeAsLetter +
        ' ' +
        this._x1 +
        ' ' +
        this._y1 +
        ' ' +
        this._x +
        ' ' +
        this._y
      )
    };
    window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function() {
      return new window.SVGPathSegCurvetoQuadraticAbs(
        undefined,
        this._x,
        this._y,
        this._x1,
        this._y1
      )
    };
    Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'x', {
      get: function() {
        return this._x
      },
      set: function(x) {
        this._x = x;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, 'y', {
      get: function() {
        return this._y
      },
      set: function(y) {
        this._y = y;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(
      window.SVGPathSegCurvetoQuadraticAbs.prototype,
      'x1',
      {
        get: function() {
          return this._x1
        },
        set: function(x1) {
          this._x1 = x1;
          this._segmentChanged();
        },
        enumerable: true
      }
    );
    Object.defineProperty(
      window.SVGPathSegCurvetoQuadraticAbs.prototype,
      'y1',
      {
        get: function() {
          return this._y1
        },
        set: function(y1) {
          this._y1 = y1;
          this._segmentChanged();
        },
        enumerable: true
      }
    );

    window.SVGPathSegCurvetoQuadraticRel = function(
      owningPathSegList,
      x,
      y,
      x1,
      y1
    ) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL,
        'q',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
      this._x1 = x1;
      this._y1 = y1;
    };
    window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function() {
      return '[object SVGPathSegCurvetoQuadraticRel]'
    };
    window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function() {
      return (
        this.pathSegTypeAsLetter +
        ' ' +
        this._x1 +
        ' ' +
        this._y1 +
        ' ' +
        this._x +
        ' ' +
        this._y
      )
    };
    window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function() {
      return new window.SVGPathSegCurvetoQuadraticRel(
        undefined,
        this._x,
        this._y,
        this._x1,
        this._y1
      )
    };
    Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'x', {
      get: function() {
        return this._x
      },
      set: function(x) {
        this._x = x;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, 'y', {
      get: function() {
        return this._y
      },
      set: function(y) {
        this._y = y;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(
      window.SVGPathSegCurvetoQuadraticRel.prototype,
      'x1',
      {
        get: function() {
          return this._x1
        },
        set: function(x1) {
          this._x1 = x1;
          this._segmentChanged();
        },
        enumerable: true
      }
    );
    Object.defineProperty(
      window.SVGPathSegCurvetoQuadraticRel.prototype,
      'y1',
      {
        get: function() {
          return this._y1
        },
        set: function(y1) {
          this._y1 = y1;
          this._segmentChanged();
        },
        enumerable: true
      }
    );

    window.SVGPathSegArcAbs = function(
      owningPathSegList,
      x,
      y,
      r1,
      r2,
      angle,
      largeArcFlag,
      sweepFlag
    ) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_ARC_ABS,
        'A',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
      this._r1 = r1;
      this._r2 = r2;
      this._angle = angle;
      this._largeArcFlag = largeArcFlag;
      this._sweepFlag = sweepFlag;
    };
    window.SVGPathSegArcAbs.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegArcAbs.prototype.toString = function() {
      return '[object SVGPathSegArcAbs]'
    };
    window.SVGPathSegArcAbs.prototype._asPathString = function() {
      return (
        this.pathSegTypeAsLetter +
        ' ' +
        this._r1 +
        ' ' +
        this._r2 +
        ' ' +
        this._angle +
        ' ' +
        (this._largeArcFlag ? '1' : '0') +
        ' ' +
        (this._sweepFlag ? '1' : '0') +
        ' ' +
        this._x +
        ' ' +
        this._y
      )
    };
    window.SVGPathSegArcAbs.prototype.clone = function() {
      return new window.SVGPathSegArcAbs(
        undefined,
        this._x,
        this._y,
        this._r1,
        this._r2,
        this._angle,
        this._largeArcFlag,
        this._sweepFlag
      )
    };
    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'x', {
      get: function() {
        return this._x
      },
      set: function(x) {
        this._x = x;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'y', {
      get: function() {
        return this._y
      },
      set: function(y) {
        this._y = y;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r1', {
      get: function() {
        return this._r1
      },
      set: function(r1) {
        this._r1 = r1;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'r2', {
      get: function() {
        return this._r2
      },
      set: function(r2) {
        this._r2 = r2;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'angle', {
      get: function() {
        return this._angle
      },
      set: function(angle) {
        this._angle = angle;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'largeArcFlag', {
      get: function() {
        return this._largeArcFlag
      },
      set: function(largeArcFlag) {
        this._largeArcFlag = largeArcFlag;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegArcAbs.prototype, 'sweepFlag', {
      get: function() {
        return this._sweepFlag
      },
      set: function(sweepFlag) {
        this._sweepFlag = sweepFlag;
        this._segmentChanged();
      },
      enumerable: true
    });

    window.SVGPathSegArcRel = function(
      owningPathSegList,
      x,
      y,
      r1,
      r2,
      angle,
      largeArcFlag,
      sweepFlag
    ) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_ARC_REL,
        'a',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
      this._r1 = r1;
      this._r2 = r2;
      this._angle = angle;
      this._largeArcFlag = largeArcFlag;
      this._sweepFlag = sweepFlag;
    };
    window.SVGPathSegArcRel.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegArcRel.prototype.toString = function() {
      return '[object SVGPathSegArcRel]'
    };
    window.SVGPathSegArcRel.prototype._asPathString = function() {
      return (
        this.pathSegTypeAsLetter +
        ' ' +
        this._r1 +
        ' ' +
        this._r2 +
        ' ' +
        this._angle +
        ' ' +
        (this._largeArcFlag ? '1' : '0') +
        ' ' +
        (this._sweepFlag ? '1' : '0') +
        ' ' +
        this._x +
        ' ' +
        this._y
      )
    };
    window.SVGPathSegArcRel.prototype.clone = function() {
      return new window.SVGPathSegArcRel(
        undefined,
        this._x,
        this._y,
        this._r1,
        this._r2,
        this._angle,
        this._largeArcFlag,
        this._sweepFlag
      )
    };
    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'x', {
      get: function() {
        return this._x
      },
      set: function(x) {
        this._x = x;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'y', {
      get: function() {
        return this._y
      },
      set: function(y) {
        this._y = y;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r1', {
      get: function() {
        return this._r1
      },
      set: function(r1) {
        this._r1 = r1;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'r2', {
      get: function() {
        return this._r2
      },
      set: function(r2) {
        this._r2 = r2;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'angle', {
      get: function() {
        return this._angle
      },
      set: function(angle) {
        this._angle = angle;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'largeArcFlag', {
      get: function() {
        return this._largeArcFlag
      },
      set: function(largeArcFlag) {
        this._largeArcFlag = largeArcFlag;
        this._segmentChanged();
      },
      enumerable: true
    });
    Object.defineProperty(window.SVGPathSegArcRel.prototype, 'sweepFlag', {
      get: function() {
        return this._sweepFlag
      },
      set: function(sweepFlag) {
        this._sweepFlag = sweepFlag;
        this._segmentChanged();
      },
      enumerable: true
    });

    window.SVGPathSegLinetoHorizontalAbs = function(owningPathSegList, x) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS,
        'H',
        owningPathSegList
      );
      this._x = x;
    };
    window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function() {
      return '[object SVGPathSegLinetoHorizontalAbs]'
    };
    window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function() {
      return this.pathSegTypeAsLetter + ' ' + this._x
    };
    window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function() {
      return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x)
    };
    Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, 'x', {
      get: function() {
        return this._x
      },
      set: function(x) {
        this._x = x;
        this._segmentChanged();
      },
      enumerable: true
    });

    window.SVGPathSegLinetoHorizontalRel = function(owningPathSegList, x) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL,
        'h',
        owningPathSegList
      );
      this._x = x;
    };
    window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegLinetoHorizontalRel.prototype.toString = function() {
      return '[object SVGPathSegLinetoHorizontalRel]'
    };
    window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function() {
      return this.pathSegTypeAsLetter + ' ' + this._x
    };
    window.SVGPathSegLinetoHorizontalRel.prototype.clone = function() {
      return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x)
    };
    Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, 'x', {
      get: function() {
        return this._x
      },
      set: function(x) {
        this._x = x;
        this._segmentChanged();
      },
      enumerable: true
    });

    window.SVGPathSegLinetoVerticalAbs = function(owningPathSegList, y) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS,
        'V',
        owningPathSegList
      );
      this._y = y;
    };
    window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegLinetoVerticalAbs.prototype.toString = function() {
      return '[object SVGPathSegLinetoVerticalAbs]'
    };
    window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function() {
      return this.pathSegTypeAsLetter + ' ' + this._y
    };
    window.SVGPathSegLinetoVerticalAbs.prototype.clone = function() {
      return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y)
    };
    Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, 'y', {
      get: function() {
        return this._y
      },
      set: function(y) {
        this._y = y;
        this._segmentChanged();
      },
      enumerable: true
    });

    window.SVGPathSegLinetoVerticalRel = function(owningPathSegList, y) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL,
        'v',
        owningPathSegList
      );
      this._y = y;
    };
    window.SVGPathSegLinetoVerticalRel.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegLinetoVerticalRel.prototype.toString = function() {
      return '[object SVGPathSegLinetoVerticalRel]'
    };
    window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function() {
      return this.pathSegTypeAsLetter + ' ' + this._y
    };
    window.SVGPathSegLinetoVerticalRel.prototype.clone = function() {
      return new window.SVGPathSegLinetoVerticalRel(undefined, this._y)
    };
    Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, 'y', {
      get: function() {
        return this._y
      },
      set: function(y) {
        this._y = y;
        this._segmentChanged();
      },
      enumerable: true
    });

    window.SVGPathSegCurvetoCubicSmoothAbs = function(
      owningPathSegList,
      x,
      y,
      x2,
      y2
    ) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS,
        'S',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
      this._x2 = x2;
      this._y2 = y2;
    };
    window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function() {
      return '[object SVGPathSegCurvetoCubicSmoothAbs]'
    };
    window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function() {
      return (
        this.pathSegTypeAsLetter +
        ' ' +
        this._x2 +
        ' ' +
        this._y2 +
        ' ' +
        this._x +
        ' ' +
        this._y
      )
    };
    window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function() {
      return new window.SVGPathSegCurvetoCubicSmoothAbs(
        undefined,
        this._x,
        this._y,
        this._x2,
        this._y2
      )
    };
    Object.defineProperty(
      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,
      'x',
      {
        get: function() {
          return this._x
        },
        set: function(x) {
          this._x = x;
          this._segmentChanged();
        },
        enumerable: true
      }
    );
    Object.defineProperty(
      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,
      'y',
      {
        get: function() {
          return this._y
        },
        set: function(y) {
          this._y = y;
          this._segmentChanged();
        },
        enumerable: true
      }
    );
    Object.defineProperty(
      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,
      'x2',
      {
        get: function() {
          return this._x2
        },
        set: function(x2) {
          this._x2 = x2;
          this._segmentChanged();
        },
        enumerable: true
      }
    );
    Object.defineProperty(
      window.SVGPathSegCurvetoCubicSmoothAbs.prototype,
      'y2',
      {
        get: function() {
          return this._y2
        },
        set: function(y2) {
          this._y2 = y2;
          this._segmentChanged();
        },
        enumerable: true
      }
    );

    window.SVGPathSegCurvetoCubicSmoothRel = function(
      owningPathSegList,
      x,
      y,
      x2,
      y2
    ) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL,
        's',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
      this._x2 = x2;
      this._y2 = y2;
    };
    window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function() {
      return '[object SVGPathSegCurvetoCubicSmoothRel]'
    };
    window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function() {
      return (
        this.pathSegTypeAsLetter +
        ' ' +
        this._x2 +
        ' ' +
        this._y2 +
        ' ' +
        this._x +
        ' ' +
        this._y
      )
    };
    window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function() {
      return new window.SVGPathSegCurvetoCubicSmoothRel(
        undefined,
        this._x,
        this._y,
        this._x2,
        this._y2
      )
    };
    Object.defineProperty(
      window.SVGPathSegCurvetoCubicSmoothRel.prototype,
      'x',
      {
        get: function() {
          return this._x
        },
        set: function(x) {
          this._x = x;
          this._segmentChanged();
        },
        enumerable: true
      }
    );
    Object.defineProperty(
      window.SVGPathSegCurvetoCubicSmoothRel.prototype,
      'y',
      {
        get: function() {
          return this._y
        },
        set: function(y) {
          this._y = y;
          this._segmentChanged();
        },
        enumerable: true
      }
    );
    Object.defineProperty(
      window.SVGPathSegCurvetoCubicSmoothRel.prototype,
      'x2',
      {
        get: function() {
          return this._x2
        },
        set: function(x2) {
          this._x2 = x2;
          this._segmentChanged();
        },
        enumerable: true
      }
    );
    Object.defineProperty(
      window.SVGPathSegCurvetoCubicSmoothRel.prototype,
      'y2',
      {
        get: function() {
          return this._y2
        },
        set: function(y2) {
          this._y2 = y2;
          this._segmentChanged();
        },
        enumerable: true
      }
    );

    window.SVGPathSegCurvetoQuadraticSmoothAbs = function(
      owningPathSegList,
      x,
      y
    ) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS,
        'T',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
    };
    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function() {
      return '[object SVGPathSegCurvetoQuadraticSmoothAbs]'
    };
    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function() {
      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y
    };
    window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function() {
      return new window.SVGPathSegCurvetoQuadraticSmoothAbs(
        undefined,
        this._x,
        this._y
      )
    };
    Object.defineProperty(
      window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype,
      'x',
      {
        get: function() {
          return this._x
        },
        set: function(x) {
          this._x = x;
          this._segmentChanged();
        },
        enumerable: true
      }
    );
    Object.defineProperty(
      window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype,
      'y',
      {
        get: function() {
          return this._y
        },
        set: function(y) {
          this._y = y;
          this._segmentChanged();
        },
        enumerable: true
      }
    );

    window.SVGPathSegCurvetoQuadraticSmoothRel = function(
      owningPathSegList,
      x,
      y
    ) {
      window.SVGPathSeg.call(
        this,
        window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL,
        't',
        owningPathSegList
      );
      this._x = x;
      this._y = y;
    };
    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(
      window.SVGPathSeg.prototype
    );
    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function() {
      return '[object SVGPathSegCurvetoQuadraticSmoothRel]'
    };
    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function() {
      return this.pathSegTypeAsLetter + ' ' + this._x + ' ' + this._y
    };
    window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function() {
      return new window.SVGPathSegCurvetoQuadraticSmoothRel(
        undefined,
        this._x,
        this._y
      )
    };
    Object.defineProperty(
      window.SVGPathSegCurvetoQuadraticSmoothRel.prototype,
      'x',
      {
        get: function() {
          return this._x
        },
        set: function(x) {
          this._x = x;
          this._segmentChanged();
        },
        enumerable: true
      }
    );
    Object.defineProperty(
      window.SVGPathSegCurvetoQuadraticSmoothRel.prototype,
      'y',
      {
        get: function() {
          return this._y
        },
        set: function(y) {
          this._y = y;
          this._segmentChanged();
        },
        enumerable: true
      }
    );

    // Add createSVGPathSeg* functions to window.SVGPathElement.
    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.
    window.SVGPathElement.prototype.createSVGPathSegClosePath = function() {
      return new window.SVGPathSegClosePath(undefined)
    };
    window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function(x, y) {
      return new window.SVGPathSegMovetoAbs(undefined, x, y)
    };
    window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function(x, y) {
      return new window.SVGPathSegMovetoRel(undefined, x, y)
    };
    window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function(x, y) {
      return new window.SVGPathSegLinetoAbs(undefined, x, y)
    };
    window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function(x, y) {
      return new window.SVGPathSegLinetoRel(undefined, x, y)
    };
    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function(
      x,
      y,
      x1,
      y1,
      x2,
      y2
    ) {
      return new window.SVGPathSegCurvetoCubicAbs(
        undefined,
        x,
        y,
        x1,
        y1,
        x2,
        y2
      )
    };
    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function(
      x,
      y,
      x1,
      y1,
      x2,
      y2
    ) {
      return new window.SVGPathSegCurvetoCubicRel(
        undefined,
        x,
        y,
        x1,
        y1,
        x2,
        y2
      )
    };
    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function(
      x,
      y,
      x1,
      y1
    ) {
      return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1)
    };
    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function(
      x,
      y,
      x1,
      y1
    ) {
      return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1)
    };
    window.SVGPathElement.prototype.createSVGPathSegArcAbs = function(
      x,
      y,
      r1,
      r2,
      angle,
      largeArcFlag,
      sweepFlag
    ) {
      return new window.SVGPathSegArcAbs(
        undefined,
        x,
        y,
        r1,
        r2,
        angle,
        largeArcFlag,
        sweepFlag
      )
    };
    window.SVGPathElement.prototype.createSVGPathSegArcRel = function(
      x,
      y,
      r1,
      r2,
      angle,
      largeArcFlag,
      sweepFlag
    ) {
      return new window.SVGPathSegArcRel(
        undefined,
        x,
        y,
        r1,
        r2,
        angle,
        largeArcFlag,
        sweepFlag
      )
    };
    window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function(
      x
    ) {
      return new window.SVGPathSegLinetoHorizontalAbs(undefined, x)
    };
    window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function(
      x
    ) {
      return new window.SVGPathSegLinetoHorizontalRel(undefined, x)
    };
    window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function(
      y
    ) {
      return new window.SVGPathSegLinetoVerticalAbs(undefined, y)
    };
    window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function(
      y
    ) {
      return new window.SVGPathSegLinetoVerticalRel(undefined, y)
    };
    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function(
      x,
      y,
      x2,
      y2
    ) {
      return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2)
    };
    window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function(
      x,
      y,
      x2,
      y2
    ) {
      return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2)
    };
    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function(
      x,
      y
    ) {
      return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y)
    };
    window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function(
      x,
      y
    ) {
      return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y)
    };

    if (!('getPathSegAtLength' in window.SVGPathElement.prototype)) {
      // Add getPathSegAtLength to SVGPathElement.
      // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength
      // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.
      window.SVGPathElement.prototype.getPathSegAtLength = function(distance) {
        if (distance === undefined || !isFinite(distance))
          throw 'Invalid arguments.'

        var measurementElement = document.createElementNS(
          'http://www.w3.org/2000/svg',
          'path'
        );
        measurementElement.setAttribute('d', this.getAttribute('d'));
        var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1;

        // If the path is empty, return 0.
        if (lastPathSegment <= 0) return 0

        do {
          measurementElement.pathSegList.removeItem(lastPathSegment);
          if (distance > measurementElement.getTotalLength()) break
          lastPathSegment--;
        } while (lastPathSegment > 0)
        return lastPathSegment
      };
    }
  }

  if (!('SVGPathSegList' in window)) {
    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList
    window.SVGPathSegList = function(pathElement) {
      this._pathElement = pathElement;
      this._list = this._parsePath(this._pathElement.getAttribute('d'));

      // Use a MutationObserver to catch changes to the path's "d" attribute.
      this._mutationObserverConfig = {
        attributes: true,
        attributeFilter: ['d']
      };
      this._pathElementMutationObserver = new MutationObserver(
        this._updateListFromPathMutations.bind(this)
      );
      this._pathElementMutationObserver.observe(
        this._pathElement,
        this._mutationObserverConfig
      );
    };

    window.SVGPathSegList.prototype.classname = 'SVGPathSegList';

    Object.defineProperty(window.SVGPathSegList.prototype, 'numberOfItems', {
      get: function() {
        this._checkPathSynchronizedToList();
        return this._list.length
      },
      enumerable: true
    });

    // Add the pathSegList accessors to window.SVGPathElement.
    // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData
    Object.defineProperty(window.SVGPathElement.prototype, 'pathSegList', {
      get: function() {
        if (!this._pathSegList)
          this._pathSegList = new window.SVGPathSegList(this);
        return this._pathSegList
      },
      enumerable: true
    });
    // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.
    Object.defineProperty(
      window.SVGPathElement.prototype,
      'normalizedPathSegList',
      {
        get: function() {
          return this.pathSegList
        },
        enumerable: true
      }
    );
    Object.defineProperty(
      window.SVGPathElement.prototype,
      'animatedPathSegList',
      {
        get: function() {
          return this.pathSegList
        },
        enumerable: true
      }
    );
    Object.defineProperty(
      window.SVGPathElement.prototype,
      'animatedNormalizedPathSegList',
      {
        get: function() {
          return this.pathSegList
        },
        enumerable: true
      }
    );

    // Process any pending mutations to the path element and update the list as needed.
    // This should be the first call of all public functions and is needed because
    // MutationObservers are not synchronous so we can have pending asynchronous mutations.
    window.SVGPathSegList.prototype._checkPathSynchronizedToList = function() {
      this._updateListFromPathMutations(
        this._pathElementMutationObserver.takeRecords()
      );
    };

    window.SVGPathSegList.prototype._updateListFromPathMutations = function(
      mutationRecords
    ) {
      if (!this._pathElement) return
      var hasPathMutations = false;
      mutationRecords.forEach(function(record) {
        if (record.attributeName == 'd') hasPathMutations = true;
      });
      if (hasPathMutations)
        this._list = this._parsePath(this._pathElement.getAttribute('d'));
    };

    // Serialize the list and update the path's 'd' attribute.
    window.SVGPathSegList.prototype._writeListToPath = function() {
      this._pathElementMutationObserver.disconnect();
      this._pathElement.setAttribute(
        'd',
        window.SVGPathSegList._pathSegArrayAsString(this._list)
      );
      this._pathElementMutationObserver.observe(
        this._pathElement,
        this._mutationObserverConfig
      );
    };

    // When a path segment changes the list needs to be synchronized back to the path element.
    window.SVGPathSegList.prototype.segmentChanged = function(pathSeg) {
      this._writeListToPath();
    };

    window.SVGPathSegList.prototype.clear = function() {
      this._checkPathSynchronizedToList();

      this._list.forEach(function(pathSeg) {
        pathSeg._owningPathSegList = null;
      });
      this._list = [];
      this._writeListToPath();
    };

    window.SVGPathSegList.prototype.initialize = function(newItem) {
      this._checkPathSynchronizedToList();

      this._list = [newItem];
      newItem._owningPathSegList = this;
      this._writeListToPath();
      return newItem
    };

    window.SVGPathSegList.prototype._checkValidIndex = function(index) {
      if (isNaN(index) || index < 0 || index >= this.numberOfItems)
        throw 'INDEX_SIZE_ERR'
    };

    window.SVGPathSegList.prototype.getItem = function(index) {
      this._checkPathSynchronizedToList();

      this._checkValidIndex(index);
      return this._list[index]
    };

    window.SVGPathSegList.prototype.insertItemBefore = function(
      newItem,
      index
    ) {
      this._checkPathSynchronizedToList();

      // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
      if (index > this.numberOfItems) index = this.numberOfItems;
      if (newItem._owningPathSegList) {
        // SVG2 spec says to make a copy.
        newItem = newItem.clone();
      }
      this._list.splice(index, 0, newItem);
      newItem._owningPathSegList = this;
      this._writeListToPath();
      return newItem
    };

    window.SVGPathSegList.prototype.replaceItem = function(newItem, index) {
      this._checkPathSynchronizedToList();

      if (newItem._owningPathSegList) {
        // SVG2 spec says to make a copy.
        newItem = newItem.clone();
      }
      this._checkValidIndex(index);
      this._list[index] = newItem;
      newItem._owningPathSegList = this;
      this._writeListToPath();
      return newItem
    };

    window.SVGPathSegList.prototype.removeItem = function(index) {
      this._checkPathSynchronizedToList();

      this._checkValidIndex(index);
      var item = this._list[index];
      this._list.splice(index, 1);
      this._writeListToPath();
      return item
    };

    window.SVGPathSegList.prototype.appendItem = function(newItem) {
      this._checkPathSynchronizedToList();

      if (newItem._owningPathSegList) {
        // SVG2 spec says to make a copy.
        newItem = newItem.clone();
      }
      this._list.push(newItem);
      newItem._owningPathSegList = this;
      // TODO: Optimize this to just append to the existing attribute.
      this._writeListToPath();
      return newItem
    };

    window.SVGPathSegList._pathSegArrayAsString = function(pathSegArray) {
      var string = '';
      var first = true;
      pathSegArray.forEach(function(pathSeg) {
        if (first) {
          first = false;
          string += pathSeg._asPathString();
        } else {
          string += ' ' + pathSeg._asPathString();
        }
      });
      return string
    };

    // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.
    window.SVGPathSegList.prototype._parsePath = function(string) {
      if (!string || string.length == 0) return []

      var owningPathSegList = this;

      var Builder = function() {
        this.pathSegList = [];
      };

      Builder.prototype.appendSegment = function(pathSeg) {
        this.pathSegList.push(pathSeg);
      };

      var Source = function(string) {
        this._string = string;
        this._currentIndex = 0;
        this._endIndex = this._string.length;
        this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;

        this._skipOptionalSpaces();
      };

      Source.prototype._isCurrentSpace = function() {
        var character = this._string[this._currentIndex];
        return (
          character <= ' ' &&
          (character == ' ' ||
            character == '\n' ||
            character == '\t' ||
            character == '\r' ||
            character == '\f')
        )
      };

      Source.prototype._skipOptionalSpaces = function() {
        while (this._currentIndex < this._endIndex && this._isCurrentSpace())
          this._currentIndex++;
        return this._currentIndex < this._endIndex
      };

      Source.prototype._skipOptionalSpacesOrDelimiter = function() {
        if (
          this._currentIndex < this._endIndex &&
          !this._isCurrentSpace() &&
          this._string.charAt(this._currentIndex) != ','
        )
          return false
        if (this._skipOptionalSpaces()) {
          if (
            this._currentIndex < this._endIndex &&
            this._string.charAt(this._currentIndex) == ','
          ) {
            this._currentIndex++;
            this._skipOptionalSpaces();
          }
        }
        return this._currentIndex < this._endIndex
      };

      Source.prototype.hasMoreData = function() {
        return this._currentIndex < this._endIndex
      };

      Source.prototype.peekSegmentType = function() {
        var lookahead = this._string[this._currentIndex];
        return this._pathSegTypeFromChar(lookahead)
      };

      Source.prototype._pathSegTypeFromChar = function(lookahead) {
        switch (lookahead) {
          case 'Z':
          case 'z':
            return window.SVGPathSeg.PATHSEG_CLOSEPATH
          case 'M':
            return window.SVGPathSeg.PATHSEG_MOVETO_ABS
          case 'm':
            return window.SVGPathSeg.PATHSEG_MOVETO_REL
          case 'L':
            return window.SVGPathSeg.PATHSEG_LINETO_ABS
          case 'l':
            return window.SVGPathSeg.PATHSEG_LINETO_REL
          case 'C':
            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS
          case 'c':
            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL
          case 'Q':
            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS
          case 'q':
            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL
          case 'A':
            return window.SVGPathSeg.PATHSEG_ARC_ABS
          case 'a':
            return window.SVGPathSeg.PATHSEG_ARC_REL
          case 'H':
            return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS
          case 'h':
            return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL
          case 'V':
            return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS
          case 'v':
            return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL
          case 'S':
            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS
          case 's':
            return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL
          case 'T':
            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS
          case 't':
            return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL
          default:
            return window.SVGPathSeg.PATHSEG_UNKNOWN
        }
      };

      Source.prototype._nextCommandHelper = function(
        lookahead,
        previousCommand
      ) {
        // Check for remaining coordinates in the current command.
        if (
          (lookahead == '+' ||
            lookahead == '-' ||
            lookahead == '.' ||
            (lookahead >= '0' && lookahead <= '9')) &&
          previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH
        ) {
          if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS)
            return window.SVGPathSeg.PATHSEG_LINETO_ABS
          if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL)
            return window.SVGPathSeg.PATHSEG_LINETO_REL
          return previousCommand
        }
        return window.SVGPathSeg.PATHSEG_UNKNOWN
      };

      Source.prototype.initialCommandIsMoveTo = function() {
        // If the path is empty it is still valid, so return true.
        if (!this.hasMoreData()) return true
        var command = this.peekSegmentType();
        // Path must start with moveTo.
        return (
          command == window.SVGPathSeg.PATHSEG_MOVETO_ABS ||
          command == window.SVGPathSeg.PATHSEG_MOVETO_REL
        )
      };

      // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.
      // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF
      Source.prototype._parseNumber = function() {
        var exponent = 0;
        var integer = 0;
        var frac = 1;
        var decimal = 0;
        var sign = 1;
        var expsign = 1;

        var startIndex = this._currentIndex;

        this._skipOptionalSpaces();

        // Read the sign.
        if (
          this._currentIndex < this._endIndex &&
          this._string.charAt(this._currentIndex) == '+'
        )
          this._currentIndex++;
        else if (
          this._currentIndex < this._endIndex &&
          this._string.charAt(this._currentIndex) == '-'
        ) {
          this._currentIndex++;
          sign = -1;
        }

        if (
          this._currentIndex == this._endIndex ||
          ((this._string.charAt(this._currentIndex) < '0' ||
            this._string.charAt(this._currentIndex) > '9') &&
            this._string.charAt(this._currentIndex) != '.')
        )
          // The first character of a number must be one of [0-9+-.].
          return undefined

        // Read the integer part, build right-to-left.
        var startIntPartIndex = this._currentIndex;
        while (
          this._currentIndex < this._endIndex &&
          this._string.charAt(this._currentIndex) >= '0' &&
          this._string.charAt(this._currentIndex) <= '9'
        )
          this._currentIndex++; // Advance to first non-digit.

        if (this._currentIndex != startIntPartIndex) {
          var scanIntPartIndex = this._currentIndex - 1;
          var multiplier = 1;
          while (scanIntPartIndex >= startIntPartIndex) {
            integer +=
              multiplier * (this._string.charAt(scanIntPartIndex--) - '0');
            multiplier *= 10;
          }
        }

        // Read the decimals.
        if (
          this._currentIndex < this._endIndex &&
          this._string.charAt(this._currentIndex) == '.'
        ) {
          this._currentIndex++;

          // There must be a least one digit following the .
          if (
            this._currentIndex >= this._endIndex ||
            this._string.charAt(this._currentIndex) < '0' ||
            this._string.charAt(this._currentIndex) > '9'
          )
            return undefined
          while (
            this._currentIndex < this._endIndex &&
            this._string.charAt(this._currentIndex) >= '0' &&
            this._string.charAt(this._currentIndex) <= '9'
          ) {
            frac *= 10;
            decimal += (this._string.charAt(this._currentIndex) - '0') / frac;
            this._currentIndex += 1;
          }
        }

        // Read the exponent part.
        if (
          this._currentIndex != startIndex &&
          this._currentIndex + 1 < this._endIndex &&
          (this._string.charAt(this._currentIndex) == 'e' ||
            this._string.charAt(this._currentIndex) == 'E') &&
          this._string.charAt(this._currentIndex + 1) != 'x' &&
          this._string.charAt(this._currentIndex + 1) != 'm'
        ) {
          this._currentIndex++;

          // Read the sign of the exponent.
          if (this._string.charAt(this._currentIndex) == '+') {
            this._currentIndex++;
          } else if (this._string.charAt(this._currentIndex) == '-') {
            this._currentIndex++;
            expsign = -1;
          }

          // There must be an exponent.
          if (
            this._currentIndex >= this._endIndex ||
            this._string.charAt(this._currentIndex) < '0' ||
            this._string.charAt(this._currentIndex) > '9'
          )
            return undefined

          while (
            this._currentIndex < this._endIndex &&
            this._string.charAt(this._currentIndex) >= '0' &&
            this._string.charAt(this._currentIndex) <= '9'
          ) {
            exponent *= 10;
            exponent += this._string.charAt(this._currentIndex) - '0';
            this._currentIndex++;
          }
        }

        var number = integer + decimal;
        number *= sign;

        if (exponent) number *= Math.pow(10, expsign * exponent);

        if (startIndex == this._currentIndex) return undefined

        this._skipOptionalSpacesOrDelimiter();

        return number
      };

      Source.prototype._parseArcFlag = function() {
        if (this._currentIndex >= this._endIndex) return undefined
        var flag = false;
        var flagChar = this._string.charAt(this._currentIndex++);
        if (flagChar == '0') flag = false;
        else if (flagChar == '1') flag = true;
        else return undefined

        this._skipOptionalSpacesOrDelimiter();
        return flag
      };

      Source.prototype.parseSegment = function() {
        var lookahead = this._string[this._currentIndex];
        var command = this._pathSegTypeFromChar(lookahead);
        if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {
          // Possibly an implicit command. Not allowed if this is the first command.
          if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN)
            return null
          command = this._nextCommandHelper(lookahead, this._previousCommand);
          if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null
        } else {
          this._currentIndex++;
        }

        this._previousCommand = command;

        switch (command) {
          case window.SVGPathSeg.PATHSEG_MOVETO_REL:
            return new window.SVGPathSegMovetoRel(
              owningPathSegList,
              this._parseNumber(),
              this._parseNumber()
            )
          case window.SVGPathSeg.PATHSEG_MOVETO_ABS:
            return new window.SVGPathSegMovetoAbs(
              owningPathSegList,
              this._parseNumber(),
              this._parseNumber()
            )
          case window.SVGPathSeg.PATHSEG_LINETO_REL:
            return new window.SVGPathSegLinetoRel(
              owningPathSegList,
              this._parseNumber(),
              this._parseNumber()
            )
          case window.SVGPathSeg.PATHSEG_LINETO_ABS:
            return new window.SVGPathSegLinetoAbs(
              owningPathSegList,
              this._parseNumber(),
              this._parseNumber()
            )
          case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
            return new window.SVGPathSegLinetoHorizontalRel(
              owningPathSegList,
              this._parseNumber()
            )
          case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
            return new window.SVGPathSegLinetoHorizontalAbs(
              owningPathSegList,
              this._parseNumber()
            )
          case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
            return new window.SVGPathSegLinetoVerticalRel(
              owningPathSegList,
              this._parseNumber()
            )
          case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
            return new window.SVGPathSegLinetoVerticalAbs(
              owningPathSegList,
              this._parseNumber()
            )
          case window.SVGPathSeg.PATHSEG_CLOSEPATH:
            this._skipOptionalSpaces();
            return new window.SVGPathSegClosePath(owningPathSegList)
          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
            var points = {
              x1: this._parseNumber(),
              y1: this._parseNumber(),
              x2: this._parseNumber(),
              y2: this._parseNumber(),
              x: this._parseNumber(),
              y: this._parseNumber()
            };
            return new window.SVGPathSegCurvetoCubicRel(
              owningPathSegList,
              points.x,
              points.y,
              points.x1,
              points.y1,
              points.x2,
              points.y2
            )
          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
            var points = {
              x1: this._parseNumber(),
              y1: this._parseNumber(),
              x2: this._parseNumber(),
              y2: this._parseNumber(),
              x: this._parseNumber(),
              y: this._parseNumber()
            };
            return new window.SVGPathSegCurvetoCubicAbs(
              owningPathSegList,
              points.x,
              points.y,
              points.x1,
              points.y1,
              points.x2,
              points.y2
            )
          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
            var points = {
              x2: this._parseNumber(),
              y2: this._parseNumber(),
              x: this._parseNumber(),
              y: this._parseNumber()
            };
            return new window.SVGPathSegCurvetoCubicSmoothRel(
              owningPathSegList,
              points.x,
              points.y,
              points.x2,
              points.y2
            )
          case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
            var points = {
              x2: this._parseNumber(),
              y2: this._parseNumber(),
              x: this._parseNumber(),
              y: this._parseNumber()
            };
            return new window.SVGPathSegCurvetoCubicSmoothAbs(
              owningPathSegList,
              points.x,
              points.y,
              points.x2,
              points.y2
            )
          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
            var points = {
              x1: this._parseNumber(),
              y1: this._parseNumber(),
              x: this._parseNumber(),
              y: this._parseNumber()
            };
            return new window.SVGPathSegCurvetoQuadraticRel(
              owningPathSegList,
              points.x,
              points.y,
              points.x1,
              points.y1
            )
          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
            var points = {
              x1: this._parseNumber(),
              y1: this._parseNumber(),
              x: this._parseNumber(),
              y: this._parseNumber()
            };
            return new window.SVGPathSegCurvetoQuadraticAbs(
              owningPathSegList,
              points.x,
              points.y,
              points.x1,
              points.y1
            )
          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
            return new window.SVGPathSegCurvetoQuadraticSmoothRel(
              owningPathSegList,
              this._parseNumber(),
              this._parseNumber()
            )
          case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
            return new window.SVGPathSegCurvetoQuadraticSmoothAbs(
              owningPathSegList,
              this._parseNumber(),
              this._parseNumber()
            )
          case window.SVGPathSeg.PATHSEG_ARC_REL:
            var points = {
              x1: this._parseNumber(),
              y1: this._parseNumber(),
              arcAngle: this._parseNumber(),
              arcLarge: this._parseArcFlag(),
              arcSweep: this._parseArcFlag(),
              x: this._parseNumber(),
              y: this._parseNumber()
            };
            return new window.SVGPathSegArcRel(
              owningPathSegList,
              points.x,
              points.y,
              points.x1,
              points.y1,
              points.arcAngle,
              points.arcLarge,
              points.arcSweep
            )
          case window.SVGPathSeg.PATHSEG_ARC_ABS:
            var points = {
              x1: this._parseNumber(),
              y1: this._parseNumber(),
              arcAngle: this._parseNumber(),
              arcLarge: this._parseArcFlag(),
              arcSweep: this._parseArcFlag(),
              x: this._parseNumber(),
              y: this._parseNumber()
            };
            return new window.SVGPathSegArcAbs(
              owningPathSegList,
              points.x,
              points.y,
              points.x1,
              points.y1,
              points.arcAngle,
              points.arcLarge,
              points.arcSweep
            )
          default:
            throw 'Unknown path seg type.'
        }
      };

      var builder = new Builder();
      var source = new Source(string);

      if (!source.initialCommandIsMoveTo()) return []
      while (source.hasMoreData()) {
        var pathSeg = source.parseSegment();
        if (!pathSeg) return []
        builder.appendSegment(pathSeg);
      }

      return builder.pathSegList
    };
  }
})();

// String.padEnd polyfill for IE11
//
// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
if (!String.prototype.padEnd) {
  String.prototype.padEnd = function padEnd(targetLength, padString) {
    targetLength = targetLength >> 0; //floor if number or convert non-number to 0;
    padString = String(typeof padString !== 'undefined' ? padString : ' ');
    if (this.length > targetLength) {
      return String(this)
    } else {
      targetLength = targetLength - this.length;
      if (targetLength > padString.length) {
        padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
      }
      return String(this) + padString.slice(0, targetLength)
    }
  };
}

// Object.assign polyfill for IE11
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill
if (typeof Object.assign !== 'function') {
  // Must be writable: true, enumerable: false, configurable: true
  Object.defineProperty(Object, 'assign', {
    value: function assign(target, varArgs) {
      if (target === null || target === undefined) {
        throw new TypeError('Cannot convert undefined or null to object')
      }

      var to = Object(target);

      for (var index = 1; index < arguments.length; index++) {
        var nextSource = arguments[index];

        if (nextSource !== null && nextSource !== undefined) {
          for (var nextKey in nextSource) {
            // Avoid bugs when hasOwnProperty is shadowed
            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
              to[nextKey] = nextSource[nextKey];
            }
          }
        }
      }
      return to
    },
    writable: true,
    configurable: true
  });
}

/* jshint ignore:end */

Chart.prototype.axis = function() {};
Chart.prototype.axis.labels = function(labels) {
  var $$ = this.internal;
  if (arguments.length) {
    Object.keys(labels).forEach(function(axisId) {
      $$.axis.setLabelText(axisId, labels[axisId]);
    });
    $$.axis.updateLabels();
  }
  // TODO: return some values?
};
Chart.prototype.axis.max = function(max) {
  var $$ = this.internal,
    config = $$.config;
  if (arguments.length) {
    if (typeof max === 'object') {
      if (isValue(max.x)) {
        config.axis_x_max = max.x;
      }
      if (isValue(max.y)) {
        config.axis_y_max = max.y;
      }
      if (isValue(max.y2)) {
        config.axis_y2_max = max.y2;
      }
    } else {
      config.axis_y_max = config.axis_y2_max = max;
    }
    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });
  } else {
    return {
      x: config.axis_x_max,
      y: config.axis_y_max,
      y2: config.axis_y2_max
    }
  }
};
Chart.prototype.axis.min = function(min) {
  var $$ = this.internal,
    config = $$.config;
  if (arguments.length) {
    if (typeof min === 'object') {
      if (isValue(min.x)) {
        config.axis_x_min = min.x;
      }
      if (isValue(min.y)) {
        config.axis_y_min = min.y;
      }
      if (isValue(min.y2)) {
        config.axis_y2_min = min.y2;
      }
    } else {
      config.axis_y_min = config.axis_y2_min = min;
    }
    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });
  } else {
    return {
      x: config.axis_x_min,
      y: config.axis_y_min,
      y2: config.axis_y2_min
    }
  }
};
Chart.prototype.axis.range = function(range) {
  if (arguments.length) {
    if (isDefined(range.max)) {
      this.axis.max(range.max);
    }
    if (isDefined(range.min)) {
      this.axis.min(range.min);
    }
  } else {
    return {
      max: this.axis.max(),
      min: this.axis.min()
    }
  }
};

Chart.prototype.axis.types = function(types) {
  const $$ = this.internal;
  if (types === undefined) {
    return {
      y: $$.config.axis_y_type,
      y2: $$.config.axis_y2_type
    }
  } else {
    if (isDefined(types.y)) {
      $$.config.axis_y_type = types.y;
    }

    if (isDefined(types.y2)) {
      $$.config.axis_y2_type = types.y2;
    }

    $$.updateScales();
    $$.redraw();
  }
};

Chart.prototype.category = function(i, category) {
  var $$ = this.internal,
    config = $$.config;
  if (arguments.length > 1) {
    config.axis_x_categories[i] = category;
    $$.redraw();
  }
  return config.axis_x_categories[i]
};
Chart.prototype.categories = function(categories) {
  var $$ = this.internal,
    config = $$.config;
  if (!arguments.length) {
    return config.axis_x_categories
  }
  config.axis_x_categories = categories;
  $$.redraw();
  return config.axis_x_categories
};

Chart.prototype.resize = function(size) {
  var $$ = this.internal,
    config = $$.config;
  config.size_width = size ? size.width : null;
  config.size_height = size ? size.height : null;
  this.flush();
};

Chart.prototype.flush = function() {
  var $$ = this.internal;
  $$.updateAndRedraw({
    withLegend: true,
    withTransition: false,
    withTransitionForTransform: false
  });
};

Chart.prototype.destroy = function() {
  var $$ = this.internal;

  window.clearInterval($$.intervalForObserveInserted);

  if ($$.resizeTimeout !== undefined) {
    window.clearTimeout($$.resizeTimeout);
  }

  if (window.detachEvent) {
    window.detachEvent('onresize', $$.resizeIfElementDisplayed);
  } else if (window.removeEventListener) {
    window.removeEventListener('resize', $$.resizeIfElementDisplayed);
  } else {
    var wrapper = window.onresize;
    // check if no one else removed our wrapper and remove our resizeFunction from it
    if (wrapper && wrapper.add && wrapper.remove) {
      wrapper.remove($$.resizeFunction);
    }
  }

  // Removes the inner resize functions
  $$.resizeFunction.remove();

  // Unbinds from the window focus event
  $$.unbindWindowFocus();

  $$.selectChart.classed('c3', false).html('');

  // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen.
  Object.keys($$).forEach(function(key) {
    $$[key] = null;
  });

  return null
};

// TODO: fix
Chart.prototype.color = function(id) {
  var $$ = this.internal;
  return $$.color(id) // more patterns
};

Chart.prototype.data = function(targetIds) {
  var targets = this.internal.data.targets;
  return typeof targetIds === 'undefined'
    ? targets
    : targets.filter(function(t) {
        return [].concat(targetIds).indexOf(t.id) >= 0
      })
};
Chart.prototype.data.shown = function(targetIds) {
  return this.internal.filterTargetsToShow(this.data(targetIds))
};

/**
 * Get values of the data loaded in the chart.
 *
 * @param {String|Array} targetId This API returns the value of specified target.
 * @param flat
 * @return {Array} Data values
 */
Chart.prototype.data.values = function(targetId, flat = true) {
  let values = null;

  if (targetId) {
    const targets = this.data(targetId);
    if (targets && isArray(targets)) {
      values = targets.reduce((ret, v) => {
        const dataValue = v.values.map(d => d.value);
        if (flat) {
          ret = ret.concat(dataValue);
        } else {
          ret.push(dataValue);
        }
        return ret
      }, []);
    }
  }

  return values
};
Chart.prototype.data.names = function(names) {
  this.internal.clearLegendItemTextBoxCache();
  return this.internal.updateDataAttributes('names', names)
};
Chart.prototype.data.colors = function(colors) {
  return this.internal.updateDataAttributes('colors', colors)
};
Chart.prototype.data.axes = function(axes) {
  return this.internal.updateDataAttributes('axes', axes)
};

Chart.prototype.data.stackNormalized = function(normalized) {
  if (normalized === undefined) {
    return this.internal.isStackNormalized()
  }

  this.internal.config.data_stack_normalize = !!normalized;
  this.internal.redraw();
};

Chart.prototype.donut = function() {};

Chart.prototype.donut.padAngle = function(padAngle) {
  if (padAngle === undefined) {
    return this.internal.config.donut_padAngle
  }
  this.internal.config.donut_padAngle = padAngle;
  this.flush();
};

Chart.prototype.flow = function(args) {
  var $$ = this.internal,
    targets,
    data,
    notfoundIds = [],
    orgDataCount = $$.getMaxDataCount(),
    dataCount,
    domain,
    baseTarget,
    baseValue,
    length = 0,
    tail = 0,
    diff,
    to;

  if (args.json) {
    data = $$.convertJsonToData(args.json, args.keys);
  } else if (args.rows) {
    data = $$.convertRowsToData(args.rows);
  } else if (args.columns) {
    data = $$.convertColumnsToData(args.columns);
  } else {
    return
  }
  targets = $$.convertDataToTargets(data, true);

  // Update/Add data
  $$.data.targets.forEach(function(t) {
    var found = false,
      i,
      j;
    for (i = 0; i < targets.length; i++) {
      if (t.id === targets[i].id) {
        found = true;

        if (t.values[t.values.length - 1]) {
          tail = t.values[t.values.length - 1].index + 1;
        }
        length = targets[i].values.length;

        for (j = 0; j < length; j++) {
          targets[i].values[j].index = tail + j;
          if (!$$.isTimeSeries()) {
            targets[i].values[j].x = tail + j;
          }
        }
        t.values = t.values.concat(targets[i].values);

        targets.splice(i, 1);
        break
      }
    }
    if (!found) {
      notfoundIds.push(t.id);
    }
  });

  // Append null for not found targets
  $$.data.targets.forEach(function(t) {
    var i, j;
    for (i = 0; i < notfoundIds.length; i++) {
      if (t.id === notfoundIds[i]) {
        tail = t.values[t.values.length - 1].index + 1;
        for (j = 0; j < length; j++) {
          t.values.push({
            id: t.id,
            index: tail + j,
            x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,
            value: null
          });
        }
      }
    }
  });

  // Generate null values for new target
  if ($$.data.targets.length) {
    targets.forEach(function(t) {
      var i,
        missing = [];
      for (i = $$.data.targets[0].values[0].index; i < tail; i++) {
        missing.push({
          id: t.id,
          index: i,
          x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,
          value: null
        });
      }
      t.values.forEach(function(v) {
        v.index += tail;
        if (!$$.isTimeSeries()) {
          v.x += tail;
        }
      });
      t.values = missing.concat(t.values);
    });
  }
  $$.data.targets = $$.data.targets.concat(targets); // add remained

  // check data count because behavior needs to change when it's only one
  dataCount = $$.getMaxDataCount();
  baseTarget = $$.data.targets[0];
  baseValue = baseTarget.values[0];

  // Update length to flow if needed
  if (isDefined(args.to)) {
    length = 0;
    to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to;
    baseTarget.values.forEach(function(v) {
      if (v.x < to) {
        length++;
      }
    });
  } else if (isDefined(args.length)) {
    length = args.length;
  }

  // If only one data, update the domain to flow from left edge of the chart
  if (!orgDataCount) {
    if ($$.isTimeSeries()) {
      if (baseTarget.values.length > 1) {
        diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x;
      } else {
        diff = baseValue.x - $$.getXDomain($$.data.targets)[0];
      }
    } else {
      diff = 1;
    }
    domain = [baseValue.x - diff, baseValue.x];
    $$.updateXDomain(null, true, true, false, domain);
  } else if (orgDataCount === 1) {
    if ($$.isTimeSeries()) {
      diff =
        (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;
      domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];
      $$.updateXDomain(null, true, true, false, domain);
    }
  }

  // Set targets
  $$.updateTargets($$.data.targets);

  // Redraw with new targets
  $$.redraw({
    flow: {
      index: baseValue.index,
      length: length,
      duration: isValue(args.duration)
        ? args.duration
        : $$.config.transition_duration,
      done: args.done,
      orgDataCount: orgDataCount
    },
    withLegend: true,
    withTransition: orgDataCount > 1,
    withTrimXDomain: false,
    withUpdateXAxis: true
  });
};

ChartInternal.prototype.generateFlow = function(args) {
  var $$ = this,
    config = $$.config,
    d3 = $$.d3;

  return function() {
    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;

    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();

    var xgrid,
      xgridLines,
      mainRegion,
      mainText,
      mainBar,
      mainLine,
      mainArea,
      mainCircle;

    // set flag
    $$.flowing = true;

    // remove head data after rendered
    $$.data.targets.forEach(function(d) {
      d.values.splice(0, flowLength);
    });

    // update x domain to generate axis elements for flow
    domain = $$.updateXDomain(targets, true, true);
    // update elements related to x scale
    if ($$.updateXGrid) {
      $$.updateXGrid(true);
    }

    xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid
    xgridLines = $$.xgridLines || d3.selectAll([]);
    mainRegion = $$.mainRegion || d3.selectAll([]);
    mainText = $$.mainText || d3.selectAll([]);
    mainBar = $$.mainBar || d3.selectAll([]);
    mainLine = $$.mainLine || d3.selectAll([]);
    mainArea = $$.mainArea || d3.selectAll([]);
    mainCircle = $$.mainCircle || d3.selectAll([]);

    // generate transform to flow
    if (!flow.orgDataCount) {
      // if empty
      if ($$.data.targets[0].values.length !== 1) {
        translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
      } else {
        if ($$.isTimeSeries()) {
          flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0);
          flowEnd = $$.getValueOnIndex(
            $$.data.targets[0].values,
            $$.data.targets[0].values.length - 1
          );
          translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);
        } else {
          translateX = diffDomain(domain) / 2;
        }
      }
    } else if (
      flow.orgDataCount === 1 ||
      (flowStart && flowStart.x) === (flowEnd && flowEnd.x)
    ) {
      translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
    } else {
      if ($$.isTimeSeries()) {
        translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
      } else {
        translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);
      }
    }
    scaleX = diffDomain(orgDomain) / diffDomain(domain);
    transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)';

    $$.hideXGridFocus();

    var flowTransition = d3
      .transition()
      .ease(d3.easeLinear)
      .duration(durationForFlow);
    wait.add($$.xAxis($$.axes.x, flowTransition));
    wait.add(mainBar.transition(flowTransition).attr('transform', transform));
    wait.add(mainLine.transition(flowTransition).attr('transform', transform));
    wait.add(mainArea.transition(flowTransition).attr('transform', transform));
    wait.add(mainCircle.transition(flowTransition).attr('transform', transform));
    wait.add(mainText.transition(flowTransition).attr('transform', transform));
    wait.add(
      mainRegion
        .filter($$.isRegionOnX)
        .transition(flowTransition)
        .attr('transform', transform)
    );
    wait.add(xgrid.transition(flowTransition).attr('transform', transform));
    wait.add(xgridLines.transition(flowTransition).attr('transform', transform));
    wait(function() {
      var i,
        shapes = [],
        texts = [];

      // remove flowed elements
      if (flowLength) {
        for (i = 0; i < flowLength; i++) {
          shapes.push('.' + CLASS.shape + '-' + (flowIndex + i));
          texts.push('.' + CLASS.text + '-' + (flowIndex + i));
        }
        $$.svg
          .selectAll('.' + CLASS.shapes)
          .selectAll(shapes)
          .remove();
        $$.svg
          .selectAll('.' + CLASS.texts)
          .selectAll(texts)
          .remove();
        $$.svg.select('.' + CLASS.xgrid).remove();
      }

      // draw again for removing flowed elements and reverting attr
      xgrid
        .attr('transform', null)
        .attr('x1', $$.xgridAttr.x1)
        .attr('x2', $$.xgridAttr.x2)
        .attr('y1', $$.xgridAttr.y1)
        .attr('y2', $$.xgridAttr.y2)
        .style('opacity', $$.xgridAttr.opacity);
      xgridLines.attr('transform', null);
      xgridLines
        .select('line')
        .attr('x1', config.axis_rotated ? 0 : xv)
        .attr('x2', config.axis_rotated ? $$.width : xv);
      xgridLines
        .select('text')
        .attr('x', config.axis_rotated ? $$.width : 0)
        .attr('y', xv);
      mainBar.attr('transform', null).attr('d', drawBar);
      mainLine.attr('transform', null).attr('d', drawLine);
      mainArea.attr('transform', null).attr('d', drawArea);
      mainCircle
        .attr('transform', null)
        .attr('cx', cx)
        .attr('cy', cy);
      mainText
        .attr('transform', null)
        .attr('x', xForText)
        .attr('y', yForText)
        .style('fill-opacity', $$.opacityForText.bind($$));
      mainRegion.attr('transform', null);
      mainRegion
        .filter($$.isRegionOnX)
        .attr('x', $$.regionX.bind($$))
        .attr('width', $$.regionWidth.bind($$));

      // callback for end of flow
      done();

      $$.flowing = false;
    });
  }
};

Chart.prototype.focus = function(targetIds) {
  var $$ = this.internal,
    candidates;

  targetIds = $$.mapToTargetIds(targetIds)
  ;(candidates = $$.svg.selectAll(
    $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))
  )),
    this.revert();
  this.defocus();
  candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false);
  if ($$.hasArcType()) {
    $$.expandArc(targetIds);
  }
  $$.toggleFocusLegend(targetIds, true);

  $$.focusedTargetIds = targetIds;
  $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function(id) {
    return targetIds.indexOf(id) < 0
  });
};

Chart.prototype.defocus = function(targetIds) {
  var $$ = this.internal,
    candidates;

  targetIds = $$.mapToTargetIds(targetIds)
  ;(candidates = $$.svg.selectAll(
    $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))
  )),
    candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true);
  if ($$.hasArcType()) {
    $$.unexpandArc(targetIds);
  }
  $$.toggleFocusLegend(targetIds, false);

  $$.focusedTargetIds = $$.focusedTargetIds.filter(function(id) {
    return targetIds.indexOf(id) < 0
  });
  $$.defocusedTargetIds = targetIds;
};

Chart.prototype.revert = function(targetIds) {
  var $$ = this.internal,
    candidates;

  targetIds = $$.mapToTargetIds(targetIds);
  candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets

  candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false);
  if ($$.hasArcType()) {
    $$.unexpandArc(targetIds);
  }
  if ($$.config.legend_show) {
    $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$)));
    $$.legend
      .selectAll($$.selectorLegends(targetIds))
      .filter(function() {
        return $$.d3.select(this).classed(CLASS.legendItemFocused)
      })
      .classed(CLASS.legendItemFocused, false);
  }

  $$.focusedTargetIds = [];
  $$.defocusedTargetIds = [];
};

Chart.prototype.xgrids = function(grids) {
  var $$ = this.internal,
    config = $$.config;
  if (!grids) {
    return config.grid_x_lines
  }
  config.grid_x_lines = grids;
  $$.redrawWithoutRescale();
  return config.grid_x_lines
};
Chart.prototype.xgrids.add = function(grids) {
  var $$ = this.internal;
  return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : []))
};
Chart.prototype.xgrids.remove = function(params) {
  // TODO: multiple
  var $$ = this.internal;
  $$.removeGridLines(params, true);
};

Chart.prototype.ygrids = function(grids) {
  var $$ = this.internal,
    config = $$.config;
  if (!grids) {
    return config.grid_y_lines
  }
  config.grid_y_lines = grids;
  $$.redrawWithoutRescale();
  return config.grid_y_lines
};
Chart.prototype.ygrids.add = function(grids) {
  var $$ = this.internal;
  return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : []))
};
Chart.prototype.ygrids.remove = function(params) {
  // TODO: multiple
  var $$ = this.internal;
  $$.removeGridLines(params, false);
};

Chart.prototype.groups = function(groups) {
  var $$ = this.internal,
    config = $$.config;
  if (isUndefined(groups)) {
    return config.data_groups
  }
  config.data_groups = groups;
  $$.redraw();
  return config.data_groups
};

Chart.prototype.legend = function() {};
Chart.prototype.legend.show = function(targetIds) {
  var $$ = this.internal;
  $$.showLegend($$.mapToTargetIds(targetIds));
  $$.updateAndRedraw({ withLegend: true });
};
Chart.prototype.legend.hide = function(targetIds) {
  var $$ = this.internal;
  $$.hideLegend($$.mapToTargetIds(targetIds));
  $$.updateAndRedraw({ withLegend: false });
};

Chart.prototype.load = function(args) {
  var $$ = this.internal,
    config = $$.config;
  // update xs if specified
  if (args.xs) {
    $$.addXs(args.xs);
  }
  // update names if exists
  if ('names' in args) {
    Chart.prototype.data.names.bind(this)(args.names);
  }
  // update classes if exists
  if ('classes' in args) {
    Object.keys(args.classes).forEach(function(id) {
      config.data_classes[id] = args.classes[id];
    });
  }
  // update categories if exists
  if ('categories' in args && $$.isCategorized()) {
    config.axis_x_categories = args.categories;
  }
  // update axes if exists
  if ('axes' in args) {
    Object.keys(args.axes).forEach(function(id) {
      config.data_axes[id] = args.axes[id];
    });
  }
  // update colors if exists
  if ('colors' in args) {
    Object.keys(args.colors).forEach(function(id) {
      config.data_colors[id] = args.colors[id];
    });
  }
  // use cache if exists
  if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) {
    $$.load($$.getCaches(args.cacheIds), args.done);
    return
  }
  // unload if needed
  if (args.unload) {
    // TODO: do not unload if target will load (included in url/rows/columns)
    $$.unload(
      $$.mapToTargetIds(args.unload === true ? null : args.unload),
      function() {
        $$.loadFromArgs(args);
      }
    );
  } else {
    $$.loadFromArgs(args);
  }
};

Chart.prototype.unload = function(args) {
  var $$ = this.internal;
  args = args || {};
  if (args instanceof Array) {
    args = { ids: args };
  } else if (typeof args === 'string') {
    args = { ids: [args] };
  }
  $$.unload($$.mapToTargetIds(args.ids), function() {
    $$.redraw({
      withUpdateOrgXDomain: true,
      withUpdateXDomain: true,
      withLegend: true
    });
    if (args.done) {
      args.done();
    }
  });
};

Chart.prototype.pie = function() {};

Chart.prototype.pie.padAngle = function(padAngle) {
  if (padAngle === undefined) {
    return this.internal.config.pie_padAngle
  }
  this.internal.config.pie_padAngle = padAngle;
  this.flush();
};

Chart.prototype.regions = function(regions) {
  var $$ = this.internal,
    config = $$.config;
  if (!regions) {
    return config.regions
  }
  config.regions = regions;
  $$.redrawWithoutRescale();
  return config.regions
};
Chart.prototype.regions.add = function(regions) {
  var $$ = this.internal,
    config = $$.config;
  if (!regions) {
    return config.regions
  }
  config.regions = config.regions.concat(regions);
  $$.redrawWithoutRescale();
  return config.regions
};
Chart.prototype.regions.remove = function(options) {
  var $$ = this.internal,
    config = $$.config,
    duration,
    classes,
    regions;

  options = options || {};
  duration = getOption(options, 'duration', config.transition_duration);
  classes = getOption(options, 'classes', [CLASS.region]);

  regions = $$.main.select('.' + CLASS.regions).selectAll(
    classes.map(function(c) {
      return '.' + c
    })
  )
  ;(duration ? regions.transition().duration(duration) : regions)
    .style('opacity', 0)
    .remove();

  config.regions = config.regions.filter(function(region) {
    var found = false;
    if (!region['class']) {
      return true
    }
    region['class'].split(' ').forEach(function(c) {
      if (classes.indexOf(c) >= 0) {
        found = true;
      }
    });
    return !found
  });

  return config.regions
};

Chart.prototype.selected = function(targetId) {
  var $$ = this.internal,
    d3 = $$.d3;
  return $$.main
    .selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId))
    .selectAll('.' + CLASS.shape)
    .filter(function() {
      return d3.select(this).classed(CLASS.SELECTED)
    })
    .nodes()
    .map(function(d) {
      var data = d.__data__;
      return data.data ? data.data : data
    })
};
Chart.prototype.select = function(ids, indices, resetOther) {
  var $$ = this.internal,
    d3 = $$.d3,
    config = $$.config;
  if (!config.data_selection_enabled) {
    return
  }
  $$.main
    .selectAll('.' + CLASS.shapes)
    .selectAll('.' + CLASS.shape)
    .each(function(d, i) {
      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);
      // line/area selection not supported yet
      if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {
        return
      }
      if (isTargetId && isTargetIndex) {
        if (config.data_selection_isselectable(d) && !isSelected) {
          toggle(true, shape.classed(CLASS.SELECTED, true), d, i);
        }
      } else if (isDefined(resetOther) && resetOther) {
        if (isSelected) {
          toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
        }
      }
    });
};
Chart.prototype.unselect = function(ids, indices) {
  var $$ = this.internal,
    d3 = $$.d3,
    config = $$.config;
  if (!config.data_selection_enabled) {
    return
  }
  $$.main
    .selectAll('.' + CLASS.shapes)
    .selectAll('.' + CLASS.shape)
    .each(function(d, i) {
      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);
      // line/area selection not supported yet
      if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {
        return
      }
      if (isTargetId && isTargetIndex) {
        if (config.data_selection_isselectable(d)) {
          if (isSelected) {
            toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
          }
        }
      }
    });
};

Chart.prototype.show = function(targetIds, options) {
  var $$ = this.internal,
    targets;

  targetIds = $$.mapToTargetIds(targetIds);
  options = options || {};

  $$.removeHiddenTargetIds(targetIds);
  targets = $$.svg.selectAll($$.selectorTargets(targetIds));

  targets
    .transition()
    .style('display', isIE() ? 'block' : 'initial', 'important')
    .style('opacity', 1, 'important')
    .call($$.endall, function() {
      targets.style('opacity', null).style('opacity', 1);
    });

  if (options.withLegend) {
    $$.showLegend(targetIds);
  }

  $$.redraw({
    withUpdateOrgXDomain: true,
    withUpdateXDomain: true,
    withLegend: true
  });
};

Chart.prototype.hide = function(targetIds, options) {
  var $$ = this.internal,
    targets;

  targetIds = $$.mapToTargetIds(targetIds);
  options = options || {};

  $$.addHiddenTargetIds(targetIds);
  targets = $$.svg.selectAll($$.selectorTargets(targetIds));

  targets
    .transition()
    .style('opacity', 0, 'important')
    .call($$.endall, function() {
      targets.style('opacity', null).style('opacity', 0);
      targets.style('display', 'none');
    });

  if (options.withLegend) {
    $$.hideLegend(targetIds);
  }

  $$.redraw({
    withUpdateOrgXDomain: true,
    withUpdateXDomain: true,
    withLegend: true
  });
};

Chart.prototype.toggle = function(targetIds, options) {
  var that = this,
    $$ = this.internal;
  $$.mapToTargetIds(targetIds).forEach(function(targetId) {
    $$.isTargetToShow(targetId)
      ? that.hide(targetId, options)
      : that.show(targetId, options);
  });
};

Chart.prototype.subchart = function() {};

Chart.prototype.subchart.isShown = function() {
  const $$ = this.internal;

  return $$.config.subchart_show
};

Chart.prototype.subchart.show = function() {
  const $$ = this.internal;

  if ($$.config.subchart_show) {
    return
  }

  $$.config.subchart_show = true;

  // insert DOM
  $$.initSubchart();

  // update dimensions with sub chart now visible
  $$.updateDimension();

  // insert brush (depends on sizes previously updated)
  $$.initSubchartBrush();

  // attach data
  $$.updateTargetsForSubchart($$.getTargets());

  // reset fade-in state
  $$.mapToIds($$.data.targets).forEach(function(id) {
    $$.withoutFadeIn[id] = false;
  });

  // redraw chart !
  $$.updateAndRedraw();

  // update visible targets !
  $$.showTargets();
};

Chart.prototype.subchart.hide = function() {
  const $$ = this.internal;

  if (!$$.config.subchart_show) {
    return
  }

  $$.config.subchart_show = false;

  // remove DOM
  $$.removeSubchart();

  // re-render chart
  $$.redraw();
};

Chart.prototype.tooltip = function() {};
Chart.prototype.tooltip.show = function(args) {
  var $$ = this.internal,
    targets,
    data,
    mouse = {};

  // determine mouse position on the chart
  if (args.mouse) {
    mouse = args.mouse;
  } else {
    // determine focus data
    if (args.data) {
      data = args.data;
    } else if (typeof args.x !== 'undefined') {
      if (args.id) {
        targets = $$.data.targets.filter(function(t) {
          return t.id === args.id
        });
      } else {
        targets = $$.data.targets;
      }
      data = $$.filterByX(targets, args.x).slice(0, 1)[0];
    }
    mouse = data ? $$.getMousePosition(data) : null;
  }

  // emulate mouse events to show
  $$.dispatchEvent('mousemove', mouse);

  $$.config.tooltip_onshow.call($$, data);
};
Chart.prototype.tooltip.hide = function() {
  // TODO: get target data by checking the state of focus
  this.internal.dispatchEvent('mouseout', 0);

  this.internal.config.tooltip_onhide.call(this);
};

Chart.prototype.transform = function(type, targetIds) {
  var $$ = this.internal,
    options =
      ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null;
  $$.transformTo(targetIds, type, options);
};

ChartInternal.prototype.transformTo = function(
  targetIds,
  type,
  optionsForRedraw
) {
  var $$ = this,
    withTransitionForAxis = !$$.hasArcType(),
    options = optionsForRedraw || {
      withTransitionForAxis: withTransitionForAxis
    };
  options.withTransitionForTransform = false;
  $$.transiting = false;
  $$.setTargetType(targetIds, type);
  $$.updateTargets($$.data.targets); // this is needed when transforming to arc
  $$.updateAndRedraw(options);
};

Chart.prototype.x = function(x) {
  var $$ = this.internal;
  if (arguments.length) {
    $$.updateTargetX($$.data.targets, x);
    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });
  }
  return $$.data.xs
};
Chart.prototype.xs = function(xs) {
  var $$ = this.internal;
  if (arguments.length) {
    $$.updateTargetXs($$.data.targets, xs);
    $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });
  }
  return $$.data.xs
};

Chart.prototype.zoom = function(domain) {
  var $$ = this.internal;
  if (domain) {
    if ($$.isTimeSeries()) {
      domain = domain.map(function(x) {
        return $$.parseDate(x)
      });
    }
    if ($$.config.subchart_show) {
      $$.brush.selectionAsValue(domain, true);
    } else {
      $$.updateXDomain(null, true, false, false, domain);
      $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false });
    }
    $$.config.zoom_onzoom.call(this, $$.x.orgDomain());
    return domain
  } else {
    return $$.x.domain()
  }
};
Chart.prototype.zoom.enable = function(enabled) {
  var $$ = this.internal;
  $$.config.zoom_enabled = enabled;
  $$.updateAndRedraw();
};
Chart.prototype.unzoom = function() {
  var $$ = this.internal;
  if ($$.config.subchart_show) {
    $$.brush.clear();
  } else {
    $$.updateXDomain(null, true, false, false, $$.subX.domain());
    $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false });
  }
};

Chart.prototype.zoom.max = function(max) {
  var $$ = this.internal,
    config = $$.config,
    d3 = $$.d3;
  if (max === 0 || max) {
    config.zoom_x_max = d3.max([$$.orgXDomain[1], max]);
  } else {
    return config.zoom_x_max
  }
};

Chart.prototype.zoom.min = function(min) {
  var $$ = this.internal,
    config = $$.config,
    d3 = $$.d3;
  if (min === 0 || min) {
    config.zoom_x_min = d3.min([$$.orgXDomain[0], min]);
  } else {
    return config.zoom_x_min
  }
};

Chart.prototype.zoom.range = function(range) {
  if (arguments.length) {
    if (isDefined(range.max)) {
      this.domain.max(range.max);
    }
    if (isDefined(range.min)) {
      this.domain.min(range.min);
    }
  } else {
    return {
      max: this.domain.max(),
      min: this.domain.min()
    }
  }
};

ChartInternal.prototype.initPie = function() {
  var $$ = this,
    d3 = $$.d3;
  $$.pie = d3
    .pie()
    .padAngle(this.getPadAngle.bind(this))
    .value(function(d) {
      return d.values.reduce(function(a, b) {
        return a + b.value
      }, 0)
    });

  let orderFct = $$.getOrderFunction();

  // we need to reverse the returned order if asc or desc to have the slice in expected order.
  if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) {
    let defaultSort = orderFct;
    orderFct = (t1, t2) => defaultSort(t1, t2) * -1;
  }

  $$.pie.sort(orderFct || null);
};

ChartInternal.prototype.updateRadius = function() {
  var $$ = this,
    config = $$.config,
    w = config.gauge_width || config.donut_width,
    gaugeArcWidth =
      $$.filterTargetsToShow($$.data.targets).length *
      $$.config.gauge_arcs_minWidth;
  $$.radiusExpanded =
    (Math.min($$.arcWidth, $$.arcHeight) / 2) * ($$.hasType('gauge') ? 0.85 : 1);
  $$.radius = $$.radiusExpanded * 0.95;
  $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6;
  $$.innerRadius =
    $$.hasType('donut') || $$.hasType('gauge')
      ? $$.radius * $$.innerRadiusRatio
      : 0;
  $$.gaugeArcWidth = w
    ? w
    : gaugeArcWidth <= $$.radius - $$.innerRadius
    ? $$.radius - $$.innerRadius
    : gaugeArcWidth <= $$.radius
    ? gaugeArcWidth
    : $$.radius;
};

ChartInternal.prototype.getPadAngle = function() {
  if (this.hasType('pie')) {
    return this.config.pie_padAngle || 0
  } else if (this.hasType('donut')) {
    return this.config.donut_padAngle || 0
  } else {
    return 0
  }
};

ChartInternal.prototype.updateArc = function() {
  var $$ = this;
  $$.svgArc = $$.getSvgArc();
  $$.svgArcExpanded = $$.getSvgArcExpanded();
  $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98);
};

ChartInternal.prototype.updateAngle = function(d) {
  var $$ = this,
    config = $$.config,
    found = false,
    index = 0,
    gMin,
    gMax,
    gTic,
    gValue;

  if (!config) {
    return null
  }

  $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function(t) {
    if (!found && t.data.id === d.data.id) {
      found = true;
      d = t;
      d.index = index;
    }
    index++;
  });
  if (isNaN(d.startAngle)) {
    d.startAngle = 0;
  }
  if (isNaN(d.endAngle)) {
    d.endAngle = d.startAngle;
  }
  if ($$.isGaugeType(d.data)) {
    gMin = config.gauge_min;
    gMax = config.gauge_max;
    gTic = (Math.PI * (config.gauge_fullCircle ? 2 : 1)) / (gMax - gMin);
    gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin;
    d.startAngle = config.gauge_startingAngle;
    d.endAngle = d.startAngle + gTic * gValue;
  }
  return found ? d : null
};

ChartInternal.prototype.getSvgArc = function() {
  var $$ = this,
    hasGaugeType = $$.hasType('gauge'),
    singleArcWidth =
      $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,
    arc = $$.d3
      .arc()
      .outerRadius(function(d) {
        return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius
      })
      .innerRadius(function(d) {
        return hasGaugeType
          ? $$.radius - singleArcWidth * (d.index + 1)
          : $$.innerRadius
      }),
    newArc = function(d, withoutUpdate) {
      var updated;
      if (withoutUpdate) {
        return arc(d)
      } // for interpolate
      updated = $$.updateAngle(d);
      return updated ? arc(updated) : 'M 0 0'
    };
  // TODO: extends all function
  newArc.centroid = arc.centroid;
  return newArc
};

ChartInternal.prototype.getSvgArcExpanded = function(rate) {
  rate = rate || 1;
  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
      .arc()
      .outerRadius(function(d) {
        return hasGaugeType
          ? $$.radius - singleArcWidth * d.index + expandWidth
          : $$.radiusExpanded * rate
      })
      .innerRadius(function(d) {
        return hasGaugeType
          ? $$.radius - singleArcWidth * (d.index + 1)
          : $$.innerRadius
      });
  return function(d) {
    var updated = $$.updateAngle(d);
    return updated ? arc(updated) : 'M 0 0'
  }
};

ChartInternal.prototype.getArc = function(d, withoutUpdate, force) {
  return force || this.isArcType(d.data)
    ? this.svgArc(d, withoutUpdate)
    : 'M 0 0'
};

ChartInternal.prototype.transformForArcLabel = function(d) {
  var $$ = this,
    config = $$.config,
    updated = $$.updateAngle(d),
    c,
    x,
    y,
    h,
    ratio,
    translate = '',
    hasGauge = $$.hasType('gauge');
  if (updated && !hasGauge) {
    c = this.svgArc.centroid(updated);
    x = isNaN(c[0]) ? 0 : c[0];
    y = isNaN(c[1]) ? 0 : c[1];
    h = Math.sqrt(x * x + y * y);
    if ($$.hasType('donut') && config.donut_label_ratio) {
      ratio = isFunction(config.donut_label_ratio)
        ? config.donut_label_ratio(d, $$.radius, h)
        : config.donut_label_ratio;
    } else if ($$.hasType('pie') && config.pie_label_ratio) {
      ratio = isFunction(config.pie_label_ratio)
        ? config.pie_label_ratio(d, $$.radius, h)
        : config.pie_label_ratio;
    } else {
      ratio =
        $$.radius && h
          ? ((36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) *
              $$.rad
Download .txt
gitextract_oun3f7hq/

├── .bmp.yml
├── .circleci/
│   └── config.yml
├── .editorconfig
├── .github/
│   ├── ISSUE_TEMPLATE.md
│   └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .jshintrc
├── .prettierrc.json
├── .travis.yml
├── CONTRIBUTING.md
├── Gemfile
├── LICENSE
├── MAINTAINANCE.md
├── README.md
├── bower.json
├── c3.css
├── c3.esm.js
├── c3.js
├── codecov.yml
├── component.json
├── config.rb
├── data/
│   └── samples.yml
├── design/
│   └── c3-logo.sketch
├── docs/
│   ├── 404.html
│   ├── CNAME
│   ├── _footer.haml
│   ├── _index_item.haml
│   ├── _index_item_title.haml
│   ├── _reference_item_link.haml
│   ├── _reference_menu_item.haml
│   ├── _sample.haml
│   ├── _sample_editor.haml
│   ├── _samples_header.haml
│   ├── _script.haml
│   ├── _script_scroll.haml
│   ├── _sidemenu_item.haml
│   ├── crossdomain.xml
│   ├── css/
│   │   ├── c3.css
│   │   ├── examples.css
│   │   ├── foundation.css
│   │   ├── gettingstarted.css
│   │   ├── index.css
│   │   ├── normalize.css
│   │   ├── reference.css
│   │   ├── samples/
│   │   │   ├── api_axis_label.css
│   │   │   ├── api_axis_range.css
│   │   │   ├── api_data_color.css
│   │   │   ├── api_data_name.css
│   │   │   ├── api_flow.css
│   │   │   ├── api_grid_x.css
│   │   │   ├── api_resize.css
│   │   │   ├── axes_label.css
│   │   │   ├── axes_label_position.css
│   │   │   ├── axes_rotated.css
│   │   │   ├── axes_x_localtime.css
│   │   │   ├── axes_x_tick_count.css
│   │   │   ├── axes_x_tick_culling.css
│   │   │   ├── axes_x_tick_fit.css
│   │   │   ├── axes_x_tick_format.css
│   │   │   ├── axes_x_tick_rotate.css
│   │   │   ├── axes_x_tick_values.css
│   │   │   ├── axes_y2.css
│   │   │   ├── axes_y_padding.css
│   │   │   ├── axes_y_range.css
│   │   │   ├── axes_y_tick_format.css
│   │   │   ├── categorized.css
│   │   │   ├── chart_area.css
│   │   │   ├── chart_area_stacked.css
│   │   │   ├── chart_bar.css
│   │   │   ├── chart_bar_negative.css
│   │   │   ├── chart_bar_stacked.css
│   │   │   ├── chart_combination.css
│   │   │   ├── chart_donut.css
│   │   │   ├── chart_gauge.css
│   │   │   ├── chart_pie.css
│   │   │   ├── chart_scatter.css
│   │   │   ├── chart_spline.css
│   │   │   ├── chart_stanford.css
│   │   │   ├── chart_step.css
│   │   │   ├── data_color.css
│   │   │   ├── data_columned.css
│   │   │   ├── data_json.css
│   │   │   ├── data_label.css
│   │   │   ├── data_label_format.css
│   │   │   ├── data_load.css
│   │   │   ├── data_name.css
│   │   │   ├── data_order.css
│   │   │   ├── data_rowed.css
│   │   │   ├── data_stringx.css
│   │   │   ├── data_url.css
│   │   │   ├── data_xformat.css
│   │   │   ├── grid_x_lines.css
│   │   │   ├── grid_y_lines.css
│   │   │   ├── interaction_zoom.css
│   │   │   ├── legend_custom.css
│   │   │   ├── legend_position.css
│   │   │   ├── options_color.css
│   │   │   ├── options_gridline.css
│   │   │   ├── options_legend.css
│   │   │   ├── options_padding.css
│   │   │   ├── options_size.css
│   │   │   ├── options_subchart.css
│   │   │   ├── pie_label_format.css
│   │   │   ├── point_show.css
│   │   │   ├── region.css
│   │   │   ├── region_timeseries.css
│   │   │   ├── simple_multiple.css
│   │   │   ├── simple_regions.css
│   │   │   ├── simple_xy.css
│   │   │   ├── simple_xy_multiple.css
│   │   │   ├── style_grid.css
│   │   │   ├── style_region.css
│   │   │   ├── timeseries.css
│   │   │   ├── tooltip_format.css
│   │   │   ├── tooltip_grouped.css
│   │   │   ├── tooltip_show.css
│   │   │   ├── transform_area.css
│   │   │   ├── transform_areaspline.css
│   │   │   ├── transform_bar.css
│   │   │   ├── transform_donut.css
│   │   │   ├── transform_line.css
│   │   │   ├── transform_pie.css
│   │   │   ├── transform_scatter.css
│   │   │   ├── transform_spline.css
│   │   │   └── transition_duration.css
│   │   ├── style.css
│   │   └── tomorrow.css
│   ├── data/
│   │   ├── c3_string_x.csv
│   │   ├── c3_test.csv
│   │   ├── c3_test.json
│   │   └── c3_test2.csv
│   ├── examples.html.haml
│   ├── gettingstarted.html.haml
│   ├── img/
│   │   └── .gitignore
│   ├── index.html.haml
│   ├── js/
│   │   ├── ace/
│   │   │   ├── ace.js
│   │   │   ├── mode-javascript.js
│   │   │   ├── theme-tomorrow.js
│   │   │   └── worker-javascript.js
│   │   ├── c3.esm.js
│   │   ├── c3.js
│   │   ├── gettingstarted.js
│   │   ├── highlight.pack.js
│   │   ├── index.js
│   │   ├── main.js
│   │   ├── plugins.js
│   │   └── samples/
│   │       ├── api_axis_label.js
│   │       ├── api_axis_range.js
│   │       ├── api_data_color.js
│   │       ├── api_data_name.js
│   │       ├── api_flow.js
│   │       ├── api_grid_x.js
│   │       ├── api_resize.js
│   │       ├── axes_label.js
│   │       ├── axes_label_position.js
│   │       ├── axes_rotated.js
│   │       ├── axes_x_localtime.js
│   │       ├── axes_x_tick_count.js
│   │       ├── axes_x_tick_culling.js
│   │       ├── axes_x_tick_fit.js
│   │       ├── axes_x_tick_format.js
│   │       ├── axes_x_tick_rotate.js
│   │       ├── axes_x_tick_values.js
│   │       ├── axes_y2.js
│   │       ├── axes_y_padding.js
│   │       ├── axes_y_range.js
│   │       ├── axes_y_tick_format.js
│   │       ├── categorized.js
│   │       ├── chart_area.js
│   │       ├── chart_area_stacked.js
│   │       ├── chart_bar.js
│   │       ├── chart_bar_stacked.js
│   │       ├── chart_combination.js
│   │       ├── chart_donut.js
│   │       ├── chart_gauge.js
│   │       ├── chart_pie.js
│   │       ├── chart_scatter.js
│   │       ├── chart_spline.js
│   │       ├── chart_stanford.js
│   │       ├── chart_step.js
│   │       ├── data_color.js
│   │       ├── data_columned.js
│   │       ├── data_json.js
│   │       ├── data_label.js
│   │       ├── data_label_format.js
│   │       ├── data_load.js
│   │       ├── data_name.js
│   │       ├── data_number_format_l10n.js
│   │       ├── data_order.js
│   │       ├── data_rowed.js
│   │       ├── data_stringx.js
│   │       ├── data_url.js
│   │       ├── data_xformat.js
│   │       ├── grid_x_lines.js
│   │       ├── grid_y_lines.js
│   │       ├── interaction_zoom.js
│   │       ├── interaction_zoom_by_drag.js
│   │       ├── legend_custom.js
│   │       ├── legend_position.js
│   │       ├── options_color.js
│   │       ├── options_gridline.js
│   │       ├── options_legend.js
│   │       ├── options_padding.js
│   │       ├── options_size.js
│   │       ├── options_subchart.js
│   │       ├── pie_label_format.js
│   │       ├── point_show.js
│   │       ├── region.js
│   │       ├── region_timeseries.js
│   │       ├── simple.js
│   │       ├── simple_multiple.js
│   │       ├── simple_regions.js
│   │       ├── simple_xy.js
│   │       ├── simple_xy_multiple.js
│   │       ├── style_grid.js
│   │       ├── style_region.js
│   │       ├── timeseries.js
│   │       ├── tooltip_format.js
│   │       ├── tooltip_grouped.js
│   │       ├── tooltip_horizontal.js
│   │       ├── tooltip_show.js
│   │       ├── transform_area.js
│   │       ├── transform_areaspline.js
│   │       ├── transform_bar.js
│   │       ├── transform_donut.js
│   │       ├── transform_line.js
│   │       ├── transform_pie.js
│   │       ├── transform_scatter.js
│   │       ├── transform_spline.js
│   │       └── transition_duration.js
│   ├── layouts/
│   │   └── layout.haml
│   ├── reference.html.haml
│   ├── robots.txt
│   └── samples/
│       ├── api_axis_label.html.haml
│       ├── api_axis_range.html.haml
│       ├── api_data_color.html.haml
│       ├── api_data_name.html.haml
│       ├── api_flow.html.haml
│       ├── api_grid_x.html.haml
│       ├── api_resize.html.haml
│       ├── axes_label.html.haml
│       ├── axes_label_position.html.haml
│       ├── axes_rotated.html.haml
│       ├── axes_x_localtime.html.haml
│       ├── axes_x_tick_count.html.haml
│       ├── axes_x_tick_culling.html.haml
│       ├── axes_x_tick_fit.html.haml
│       ├── axes_x_tick_format.html.haml
│       ├── axes_x_tick_rotate.html.haml
│       ├── axes_x_tick_values.html.haml
│       ├── axes_y2.html.haml
│       ├── axes_y_padding.html.haml
│       ├── axes_y_range.html.haml
│       ├── axes_y_tick_format.html.haml
│       ├── categorized.html.haml
│       ├── chart_area.html.haml
│       ├── chart_area_stacked.html.haml
│       ├── chart_bar.html.haml
│       ├── chart_bar_stacked.html.haml
│       ├── chart_combination.html.haml
│       ├── chart_donut.html.haml
│       ├── chart_gauge.html.haml
│       ├── chart_pie.html.haml
│       ├── chart_scatter.html.haml
│       ├── chart_spline.html.haml
│       ├── chart_stanford.html.haml
│       ├── chart_step.html.haml
│       ├── data_color.html.haml
│       ├── data_columned.html.haml
│       ├── data_json.html.haml
│       ├── data_label.html.haml
│       ├── data_label_format.html.haml
│       ├── data_load.html.haml
│       ├── data_name.html.haml
│       ├── data_number_format_l10n.html.haml
│       ├── data_order.html.haml
│       ├── data_rowed.html.haml
│       ├── data_stringx.html.haml
│       ├── data_url.html.haml
│       ├── grid_x_lines.html.haml
│       ├── grid_y_lines.html.haml
│       ├── interaction_zoom.html.haml
│       ├── interaction_zoom_by_drag.html.haml
│       ├── legend_custom.html.haml
│       ├── legend_position.html.haml
│       ├── options_color.html.haml
│       ├── options_gridline.html.haml
│       ├── options_legend.html.haml
│       ├── options_padding.html.haml
│       ├── options_size.html.haml
│       ├── options_subchart.html.haml
│       ├── pie_label_format.html.haml
│       ├── point_show.html.haml
│       ├── region.html.haml
│       ├── region_timeseries.html.haml
│       ├── simple_multiple.html.haml
│       ├── simple_regions.html.haml
│       ├── simple_xy.html.haml
│       ├── simple_xy_multiple.html.haml
│       ├── style_grid.html.haml
│       ├── style_region.html.haml
│       ├── timeseries.html.haml
│       ├── tooltip_format.html.haml
│       ├── tooltip_grouped.html.haml
│       ├── tooltip_horizontal.html.haml
│       ├── tooltip_show.html.haml
│       ├── transform_area.html.haml
│       ├── transform_areaspline.html.haml
│       ├── transform_bar.html.haml
│       ├── transform_donut.html.haml
│       ├── transform_line.html.haml
│       ├── transform_pie.html.haml
│       ├── transform_scatter.html.haml
│       ├── transform_spline.html.haml
│       └── transition_duration.html.haml
├── extensions/
│   ├── chart-bubble/
│   │   ├── bubble.js
│   │   └── index.html
│   ├── exporter/
│   │   ├── config.json
│   │   └── phantom-exporter.js
│   └── js/
│       └── c3ext.js
├── htdocs/
│   ├── css/
│   │   ├── index.css
│   │   └── style.css
│   ├── data/
│   │   ├── c3_stanford_data.json
│   │   ├── c3_test.csv
│   │   ├── c3_test.json
│   │   ├── c3_test.tsv
│   │   ├── c3_test2.csv
│   │   ├── c3_test2_ts.csv
│   │   ├── c3_test3.csv
│   │   ├── c3_test_2.json
│   │   ├── c3_test_3.json
│   │   └── c3_test_ts.csv
│   ├── index.html
│   ├── js/
│   │   ├── require.js
│   │   └── samples/
│   │       ├── plugin.js
│   │       ├── requirejs.js
│   │       └── zoom_reduction.js
│   └── samples/
│       ├── api_axis_label.html
│       ├── api_axis_range.html
│       ├── api_category.html
│       ├── api_data_colors.html
│       ├── api_flow.html
│       ├── api_flow_timeseries.html
│       ├── api_legend.html
│       ├── api_tooltip_show.html
│       ├── api_transform.html
│       ├── api_xgrid_lines.html
│       ├── api_ygrid_lines.html
│       ├── api_zoom.html
│       ├── area_zerobased.html
│       ├── axes_log_scales.html
│       ├── axes_padding.html
│       ├── axes_range.html
│       ├── axes_x_localtime.html
│       ├── axes_x_range_timeseries.html
│       ├── axes_x_selection.html
│       ├── axes_x_tick_culling.html
│       ├── axes_x_tick_fit.html
│       ├── axes_x_tick_rotate.html
│       ├── axes_x_tick_values.html
│       ├── axes_y2.html
│       ├── axes_y_default.html
│       ├── bar_zerobased.html
│       ├── bindto.html
│       ├── categorized.html
│       ├── chart_arc.html
│       ├── chart_area.html
│       ├── chart_area_spline.html
│       ├── chart_area_spline_stacked.html
│       ├── chart_area_stacked.html
│       ├── chart_area_step.html
│       ├── chart_area_step_stacked.html
│       ├── chart_bar.html
│       ├── chart_bar_max_width.html
│       ├── chart_bar_space.html
│       ├── chart_bar_stacked.html
│       ├── chart_bar_stacked_normalized.html
│       ├── chart_combination.html
│       ├── chart_combination_normalized.html
│       ├── chart_donut.html
│       ├── chart_gauge.html
│       ├── chart_multi_arc_gauge.html
│       ├── chart_pie.html
│       ├── chart_pie_sort.html
│       ├── chart_scatter.html
│       ├── chart_spline.html
│       ├── chart_stanford.html
│       ├── chart_stanford_custom_elements.html
│       ├── chart_step.html
│       ├── chart_step_category.html
│       ├── custom_x_categorized.html
│       ├── custom_x_scale.html
│       ├── custom_xs_scale.html
│       ├── data_columned.html
│       ├── data_hide.html
│       ├── data_json.html
│       ├── data_label.html
│       ├── data_label_format.html
│       ├── data_load.html
│       ├── data_load_timeseries.html
│       ├── data_region.html
│       ├── data_region_timeseries.html
│       ├── data_rowed.html
│       ├── data_url.html
│       ├── different_category_datasets.html
│       ├── domain_y.html
│       ├── element.html
│       ├── emptydata.html
│       ├── grid_focus.html
│       ├── grid_x_lines.html
│       ├── grid_x_lines_timeseries.html
│       ├── grids.html
│       ├── grids_timeseries.html
│       ├── interaction_enabled.html
│       ├── legend.html
│       ├── padding.html
│       ├── padding_update.html
│       ├── plugin.html
│       ├── point_r.html
│       ├── point_show.html
│       ├── regions.html
│       ├── regions_timeseries.html
│       ├── requirejs.html
│       ├── resize.html
│       ├── selection.html
│       ├── simple.html
│       ├── subchart.html
│       ├── subchart_onbrush.html
│       ├── timeseries.html
│       ├── timeseries_date.html
│       ├── timeseries_descendent.html
│       ├── timeseries_raw.html
│       ├── tooltip_grouped.html
│       ├── tooltip_horizontal.html
│       ├── tooltip_show.html
│       ├── zoom.html
│       ├── zoom_category.html
│       ├── zoom_onzoom.html
│       ├── zoom_reduction.html
│       ├── zoom_type.html
│       └── zoom_type_disable_default_behavior.html
├── karma.conf.js
├── package.json
├── rollup.config.js
├── spec/
│   ├── api.axis-spec.ts
│   ├── api.data-spec.ts
│   ├── api.donut-spec.ts
│   ├── api.focus-spec.ts
│   ├── api.grid-spec.ts
│   ├── api.load-spec.ts
│   ├── api.pie-spec.ts
│   ├── api.region-spec.ts
│   ├── api.x-spec.ts
│   ├── api.zoom-spec.ts
│   ├── arc-spec.ts
│   ├── axis-spec.ts
│   ├── c3-helper.ts
│   ├── cache-spec.ts
│   ├── class-spec.ts
│   ├── core-spec.ts
│   ├── data-spec.ts
│   ├── data.convert-spec.ts
│   ├── domain-spec.ts
│   ├── drag-spec.ts
│   ├── grid-spec.ts
│   ├── interaction-spec.ts
│   ├── legend-spec.ts
│   ├── shape.bar-spec.ts
│   ├── shape.line-spec.ts
│   ├── stanford-spec.ts
│   ├── subchart-spec.ts
│   ├── svg-helper.ts
│   ├── title-spec.ts
│   ├── tooltip-spec.ts
│   ├── type-spec.ts
│   ├── util-spec.ts
│   └── zoom-spec.ts
├── src/
│   ├── api.axis.ts
│   ├── api.category.ts
│   ├── api.chart.ts
│   ├── api.color.ts
│   ├── api.data.ts
│   ├── api.donut.ts
│   ├── api.flow.ts
│   ├── api.focus.ts
│   ├── api.grid.ts
│   ├── api.group.ts
│   ├── api.legend.ts
│   ├── api.load.ts
│   ├── api.pie.ts
│   ├── api.region.ts
│   ├── api.selection.ts
│   ├── api.show.ts
│   ├── api.subchart.ts
│   ├── api.tooltip.ts
│   ├── api.transform.ts
│   ├── api.x.ts
│   ├── api.zoom.ts
│   ├── arc.ts
│   ├── axis-internal.ts
│   ├── axis.ts
│   ├── cache.ts
│   ├── category.ts
│   ├── chart-internal.ts
│   ├── chart.ts
│   ├── class-utils.ts
│   ├── class.ts
│   ├── clip.ts
│   ├── color.ts
│   ├── colorscale.ts
│   ├── config.ts
│   ├── core.ts
│   ├── data.convert.ts
│   ├── data.load.ts
│   ├── data.ts
│   ├── domain.ts
│   ├── drag.ts
│   ├── format.ts
│   ├── grid.ts
│   ├── index.ts
│   ├── interaction.ts
│   ├── legend.ts
│   ├── polyfill.ts
│   ├── region.ts
│   ├── scale.ts
│   ├── scss/
│   │   ├── arc.scss
│   │   ├── area.scss
│   │   ├── axis.scss
│   │   ├── bar.scss
│   │   ├── brush.scss
│   │   ├── chart.scss
│   │   ├── focus.scss
│   │   ├── grid.scss
│   │   ├── legend.scss
│   │   ├── line.scss
│   │   ├── main.scss
│   │   ├── point.scss
│   │   ├── region.scss
│   │   ├── select_drag.scss
│   │   ├── text.scss
│   │   ├── title.scss
│   │   ├── tooltip.scss
│   │   └── zoom.scss
│   ├── selection.ts
│   ├── shape.bar.ts
│   ├── shape.line.ts
│   ├── shape.ts
│   ├── size.ts
│   ├── stanford.ts
│   ├── stanfordelements.ts
│   ├── subchart.ts
│   ├── text.ts
│   ├── title.ts
│   ├── tooltip.ts
│   ├── type.ts
│   ├── ua.ts
│   ├── util.ts
│   └── zoom.ts
└── tsconfig.json
Download .txt
SYMBOL INDEX (298 symbols across 28 files)

FILE: c3.esm.js
  function ChartInternal (line 4) | function ChartInternal(api) {
  function Chart (line 27) | function Chart(config) {
  function AxisInternal (line 186) | function AxisInternal(component, params) {
  function split (line 332) | function split(splitted, text) {
  function axis (line 428) | function axis(g, transition) {
  class Axis (line 812) | class Axis {
    method constructor (line 813) | constructor(owner) {
  function callResizeFunctions (line 2647) | function callResizeFunctions() {
  function find (line 7689) | function find() {
  function mouseout (line 9903) | function mouseout() {
  function getTextBox (line 10370) | function getTextBox(textElement, id) {
  function updatePositions (line 10381) | function updatePositions(textElement, id, index) {
  function c3LogScale (line 10833) | function c3LogScale(d3, linearScale, logScale) {
  function isWithinRegions (line 11732) | function isWithinRegions(x, regions) {
  function generateM (line 11780) | function generateM(points) {
  function powerOfTen (line 12901) | function powerOfTen(d) {

FILE: c3.js
  function ChartInternal (line 8) | function ChartInternal(api) {
  function Chart (line 31) | function Chart(config) {
  function AxisInternal (line 172) | function AxisInternal(component, params) {
  function split (line 295) | function split(splitted, text) {
  function axis (line 373) | function axis(g, transition) {
  function AxisClass (line 729) | function AxisClass(owner) {
  function callResizeFunctions (line 2181) | function callResizeFunctions() {
  function find (line 6141) | function find() {
  function mouseout (line 8000) | function mouseout() {
  function getTextBox (line 8350) | function getTextBox(textElement, id) {
  function updatePositions (line 8356) | function updatePositions(textElement, id, index) {
  function c3LogScale (line 8757) | function c3LogScale(d3, linearScale, logScale) {
  function isWithinRegions (line 9468) | function isWithinRegions(x, regions) {
  function generateM (line 9515) | function generateM(points) {
  function powerOfTen (line 10433) | function powerOfTen(d) {

FILE: config.rb
  function js_as_plain (line 2) | def js_as_plain(id)
  function data_as_plain (line 8) | def data_as_plain(name)
  function css_as_plain (line 14) | def css_as_plain(name)
  function get_css_name (line 20) | def get_css_name(path)

FILE: docs/js/ace/ace.js
  function s (line 1) | function s(r){var i=function(e,t){return n("",e,t)},s=e;r&&(e[r]||(e[r]=...
  function o (line 1) | function o(e){return(e.global?"g":"")+(e.ignoreCase?"i":"")+(e.multiline...
  function u (line 1) | function u(e,t,n){if(Array.prototype.indexOf)return e.indexOf(t,n);for(v...
  function r (line 1) | function r(){}
  function w (line 1) | function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentine...
  function H (line 1) | function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-...
  function B (line 1) | function B(e){var t=typeof e;return e===null||t==="undefined"||t==="bool...
  function j (line 1) | function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="funct...
  function e (line 1) | function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}
  function o (line 1) | function o(e,t,n){var o=s(t);if(!i.isMac&&u){if(u[91]||u[92])o|=8;if(u.a...
  function i (line 1) | function i(e){n&&n(e),r&&r(e),t.removeListener(document,"mousemove",n,!0...
  function b (line 1) | function b(e){if(h)return;if(k)t=0,r=e?0:n.value.length-1;else var t=e?2...
  function w (line 1) | function w(){if(h)return;n.value=f,i.isWebKit&&y.schedule()}
  function R (line 1) | function R(){clearTimeout(q),q=setTimeout(function(){p&&(n.style.cssText...
  function u (line 1) | function u(e){e.$clickSelection=null;var t=e.editor;t.setDefaultHandler(...
  function a (line 1) | function a(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}
  function f (line 1) | function f(e,t){if(e.start.row==e.end.row)var n=2*t.column-e.start.colum...
  function s (line 1) | function s(e){this.isOpen=!1,this.$element=null,this.$parentNode=e}
  function u (line 1) | function u(e){function l(){var r=u.getDocumentPosition().row,s=n.$annota...
  function a (line 1) | function a(e){o.call(this,e)}
  function f (line 1) | function f(e){function T(e,n){var r=Date.now(),i=!n||e.row!=n.row,s=!n||...
  function l (line 1) | function l(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}
  function f (line 1) | function f(r){a.packaged=r||e.packaged||n.packaged||u.define&&define.pac...
  function l (line 1) | function l(e){return e.replace(/-(.)/g,function(e,t){return t.toUpperCas...
  function r (line 1) | function r(e){e.on("click",function(t){var n=t.getDocumentPosition(),r=e...
  function i (line 1) | function i(s){var o=r[s];o.processed=!0;for(var u=0;u<o.length;u++){var ...
  function r (line 1) | function r(e){var n=/\w{4}/g;for(var r in e)t.packages[r]=e[r].replace(n...
  function w (line 1) | function w(e){for(var t=n;t<=r;t++)e(i.getLine(t),t)}
  function i (line 1) | function i(e,t){this.foldData=e,Array.isArray(t)?this.folds=t:t=this.fol...
  function u (line 1) | function u(e,t){e.row-=t.row,e.row==0&&(e.column-=t.column)}
  function a (line 1) | function a(e,t){u(e.start,t),u(e.end,t)}
  function f (line 1) | function f(e,t){e.row==0&&(e.column+=t.column),e.row+=t.row}
  function l (line 1) | function l(e,t){f(e.start,t),f(e.end,t)}
  function u (line 1) | function u(){this.getFoldAt=function(e,t,n){var r=this.getFoldLine(e);if...
  function s (line 1) | function s(){this.findMatchingBracket=function(e,t){if(e.column==0)retur...
  function m (line 1) | function m(e){return e<4352?!1:e>=4352&&e<=4447||e>=4515&&e<=4519||e>=46...
  function r (line 1) | function r(e){var n=e.action==="insertText"||e.action==="insertLines";re...
  function c (line 1) | function c(t){var n=e.slice(o,t),r=n.length;n.join("").replace(/12/g,fun...
  function o (line 1) | function o(e,t){this.platform=t||(i.isMac?"mac":"win"),this.commands={},...
  function u (line 1) | function u(e,t){o.call(this,e,t),this.$singleCommand=!1}
  function o (line 1) | function o(e,t){return{win:e,mac:t}}
  function e (line 1) | function e(e){return e[e.length-1]}
  function i (line 1) | function i(e,t,n){var i=0,s=0;while(s+e[i].value.length<t){s+=e[i].value...
  function o (line 1) | function o(r){if(n.$themeId!=e)return t&&t();if(!r.cssClass)return;i.imp...
  function s (line 1) | function s(e,t){return e.row==t.row&&e.column==t.column}
  function o (line 1) | function o(e){var t=e.domEvent,n=t.altKey,o=t.shiftKey,u=t.ctrlKey,a=e.g...
  function h (line 1) | function h(e,t,n){return c.$options.wrap=!0,c.$options.needle=t,c.$optio...
  function v (line 1) | function v(e,t){return e.row==t.row&&e.column==t.column}
  function m (line 1) | function m(e){if(e.$multiselectOnSessionChange)return;e.$onAddRange=e.$o...
  function g (line 1) | function g(e){function r(t){n&&(e.renderer.setMouseCursor(""),n=!1)}var ...
  function u (line 1) | function u(e){return a.stringRepeat(" ",e)}
  function f (line 1) | function f(e){return e[2]?u(i)+e[2]+u(s-e[2].length+o)+e[4].replace(/^([...
  function l (line 1) | function l(e){return e[2]?u(i+s-e[2].length)+e[2]+u(o," ")+e[4].replace(...
  function c (line 1) | function c(e){return e[2]?u(i)+e[2]+u(o)+e[4].replace(/^([=:])\s+/,"$1 "...
  function o (line 1) | function o(e){this.session=e,this.session.widgetManager=this,this.sessio...
  function o (line 1) | function o(e,t,n){var r=0,i=e.length-1;while(r<=i){var s=r+i>>1,o=n(t,e[...
  function u (line 1) | function u(e,t,n){var r=e.getAnnotations().sort(s.comparePoints);if(!r.l...

FILE: docs/js/ace/worker-javascript.js
  function s (line 1) | function s(u,a){if(!n[u]){if(!t[u]){var f=typeof e=="function"&&e;if(!a&...
  function I (line 1) | function I(e,t){return e=e.trim(),/^[+-]W\d{3}$/g.test(e)?!0:p[e]===unde...
  function q (line 1) | function q(e){return Object.prototype.toString.call(e)==="[object String]"}
  function R (line 1) | function R(e,t){return e?!e.identifier||e.value!==t?!1:!0:!1}
  function U (line 1) | function U(e){if(!e.reserved)return!1;var t=e.meta;if(t&&t.isFutureReser...
  function z (line 1) | function z(e,t){return e.replace(/\{([^{}]*)\}/g,function(e,n){var r=t[n...
  function W (line 1) | function W(e,t){Object.keys(t).forEach(function(n){if(r.has(c.blacklist,...
  function X (line 1) | function X(){f.option.esnext&&W(M,s.newEcmaIdentifiers),f.option.couch&&...
  function V (line 1) | function V(e,t,n){var r=Math.floor(t/f.lines.length*100),i=o.errors[e].d...
  function $ (line 1) | function $(e,t,n,r){return c.undefs.push([e,t,n,r])}
  function J (line 1) | function J(){var e=f.ignoredLines;if(r.isEmpty(e))return;c.errors=r.reje...
  function K (line 1) | function K(e,t,n,r,i,s){var u,a,l,h;if(/^W\d{3}$/.test(e)){if(f.ignored[...
  function Q (line 1) | function Q(e,t,n,r,i,s,o){return K(e,{line:t,from:n},r,i,s,o)}
  function G (line 1) | function G(e,t,n,r,i,s){K(e,t,n,r,i,s)}
  function Y (line 1) | function Y(e,t,n,r,i,s,o){return G(e,{line:t,from:n},r,i,s,o)}
  function Z (line 1) | function Z(e,t){var n;return n={id:"(internal)",elem:e,value:t},c.intern...
  function et (line 1) | function et(e,t){t=t||{};var n=t.type,i=t.token,s=t.islet;n==="exception...
  function tt (line 1) | function tt(){var e=f.tokens.next,t=e.body.match(/(-\s+)?[^\s,:]+(?:\s*:...
  function nt (line 1) | function nt(e){var t=e||0,n=0,r;while(n<=t)r=C[n],r||(r=C[n]=k.token()),...
  function rt (line 1) | function rt(t,n){switch(f.tokens.curr.id){case"(number)":f.tokens.next.i...
  function it (line 1) | function it(e){return e.infix||!e.identifier&&!!e.led}
  function st (line 1) | function st(){var e=f.tokens.curr,t=f.tokens.next;return t.id===";"||t.i...
  function ot (line 1) | function ot(t,n){var i,s=!1,o=!1,u=!1;!n&&f.tokens.next.value==="let"&&n...
  function ut (line 1) | function ut(e,t){e=e||f.tokens.curr,t=t||f.tokens.next,!f.option.laxbrea...
  function at (line 1) | function at(e){e=e||f.tokens.curr,e.line!==f.tokens.next.line&&K("E022",...
  function ft (line 1) | function ft(e,t){e.line!==t.line&&(f.option.laxcomma||(lt.first&&(K("I00...
  function lt (line 1) | function lt(e){e=e||{},e.peek?ft(f.tokens.prev,f.tokens.curr):(ft(f.toke...
  function ct (line 1) | function ct(e,t){var n=f.syntax[e];if(!n||typeof n!="object")f.syntax[e]...
  function ht (line 1) | function ht(e){return ct(e,0)}
  function pt (line 1) | function pt(e,t){var n=ht(e);return n.identifier=n.reserved=!0,n.fud=t,n}
  function dt (line 1) | function dt(e,t){var n=pt(e,t);return n.block=!0,n}
  function vt (line 1) | function vt(e){var t=e.id.charAt(0);if(t>="a"&&t<="z"||t>="A"&&t<="Z")e....
  function mt (line 1) | function mt(e,t){var n=ct(e,150);return vt(n),n.nud=typeof t=="function"...
  function gt (line 1) | function gt(e,t){var n=ht(e);return n.type=e,n.nud=t,n}
  function yt (line 1) | function yt(e,t){var n=gt(e,t);return n.identifier=!0,n.reserved=!0,n}
  function bt (line 1) | function bt(e,t){var n=gt(e,t&&t.nud||function(){return this});return t=...
  function wt (line 1) | function wt(e,t){return yt(e,function(){return typeof t=="function"&&t(t...
  function Et (line 1) | function Et(e,t,n,r){var i=ct(e,n);return vt(i),i.infix=!0,i.led=functio...
  function St (line 1) | function St(e){var t=ct(e,42);return t.led=function(e){return f.option.i...
  function xt (line 1) | function xt(e,t){var n=ct(e,100);return n.led=function(e){ut(f.tokens.pr...
  function Tt (line 1) | function Tt(e){return e&&(e.type==="(number)"&&+e.value===0||e.type==="(...
  function Nt (line 1) | function Nt(e,t){if(f.option.notypeof)return!1;if(!e||!t)return!1;var n=...
  function Ct (line 1) | function Ct(e){function n(e){if(typeof e!="object")return;return e.right...
  function kt (line 1) | function kt(e,t,n){var r=Et(e,typeof t=="function"?t:function(e,t){t.lef...
  function Lt (line 1) | function Lt(e,t,n){var r=ct(e,n);return vt(r),r.led=typeof t=="function"...
  function At (line 1) | function At(e){return kt(e,function(e,t){f.option.bitwise&&K("W016",t,t....
  function Ot (line 1) | function Ot(e){var t=ct(e,150);return t.led=function(e){return f.option....
  function Mt (line 1) | function Mt(e,t){if(!f.tokens.next.identifier)return;rt();var n=f.tokens...
  function _t (line 1) | function _t(e,t){var n=Mt(e,t);if(n)return n;f.tokens.curr.id==="functio...
  function Dt (line 1) | function Dt(e){var t=0,n;if(f.tokens.next.id!==";"||O)return;for(;;){do ...
  function Pt (line 1) | function Pt(){f.tokens.next.id!==";"?f.option.asi||(!f.option.lastsemic|...
  function Ht (line 1) | function Ht(){var e,t=N,n,i=D,s=f.tokens.next;if(s.id===";"){rt(";");ret...
  function Bt (line 1) | function Bt(e){var t=[],n;while(!f.tokens.next.reach&&f.tokens.next.id!=...
  function jt (line 1) | function jt(){var e,t,n;for(;;){if(f.tokens.next.id==="(string)"){t=nt(0...
  function Ft (line 1) | 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.fu...
  function It (line 1) | function It(e){A&&typeof A[e]!="boolean"&&K("W036",f.tokens.curr,e),type...
  function qt (line 1) | function qt(e){var t=e.value,n=Object.getOwnPropertyDescriptor(x,t);n?n....
  function Ut (line 1) | function Ut(){var e={};e.exps=!0,w["(comparray)"].stack();var t=!1;retur...
  function zt (line 1) | function zt(){var e=Mt(!1,!0);return e||(f.tokens.next.id==="(string)"?(...
  function Wt (line 1) | function Wt(e){var t,n,i=[],s,o=[],u,a=!1;if(e){if(Array.isArray(e)){for...
  function Xt (line 1) | function Xt(e,t,n){e["(properties)"][t]||(e["(properties)"][t]={unused:!...
  function Vt (line 1) | function Vt(e,t,n){return e["(properties)"][t]?e["(properties)"][t][n]||...
  function $t (line 1) | function $t(e,t,n,i){var s={"(name)":e,"(breakage)":0,"(loopage)":0,"(sc...
  function Jt (line 1) | function Jt(t,n,i,s){var o,u=f.option,a=f.ignored,l=D;return f.option=Ob...
  function Kt (line 1) | function Kt(e){return{statementCount:0,nestedBlockDepth:-1,ComplexityCou...
  function Qt (line 1) | function Qt(){w["(metrics)"].ComplexityCount+=1}
  function Gt (line 1) | function Gt(e){var t,n;e&&(t=e.id,n=e.paren,t===","&&(e=e.exprs[e.exprs....
  function Yt (line 1) | function Yt(){var e,t,n=[];f.option.inESNext()||K("W104",f.tokens.curr,"...
  function Zt (line 1) | function Zt(e,t){var n=t.first;if(!n)return;r.zip(e,Array.isArray(n)?n:[...
  function rn (line 1) | function rn(e){return f.option.inESNext()||K("W104",f.tokens.curr,"class...
  function sn (line 1) | function sn(e){var t=f.directive["use strict"];f.tokens.next.value==="ex...
  function un (line 1) | function un(){var e=on();e.notJson?(!f.option.inESNext()&&e.isDestAssign...
  function fn (line 1) | function fn(){function e(){var e={},t=f.tokens.next;rt("{");if(f.tokens....
  function c (line 1) | function c(e,t){a[e]&&r.has(a,e)?K("W075",f.tokens.next,i):a[e]={},a[e]....
  function h (line 1) | function h(e,t){a[e]&&r.has(a,e)?(a[e].basic||a[e].setter)&&K("W075",f.t...
  function p (line 1) | function p(e){a[e]&&r.has(a,e)?(a[e].basic||a[e].getter)&&K("W075",f.tok...
  function t (line 1) | function t(){var e=D,t;rt("catch"),rt("("),D=Object.create(e),t=f.tokens...
  function i (line 1) | function i(e){var t=n.variables.filter(function(t){if(t.value===e)return...
  function s (line 1) | function s(e){var t=n.variables.filter(function(t){if(t.value===e&&!t.un...
  function n (line 1) | function n(){for(var t in e)if(e[t]["(type)"]==="unused"&&f.option.unuse...
  function v (line 1) | function v(e,t){if(!e)return;!Array.isArray(e)&&typeof e=="object"&&(e=O...
  method isJSON (line 1) | get isJSON(){return f.jsonMode}
  function c (line 1) | function c(){var e=[];return{push:function(t){e.push(t)},check:function(...
  function h (line 1) | function h(e){var t=e;typeof t=="string"&&(t=t.replace(/\r\n/g,"\n").rep...
  function s (line 1) | function s(e,t,n){var r=["jshint","jslint","members","member","globals",...
  function i (line 1) | function i(e){return e>256}
  function s (line 1) | function s(e){return e>256}
  function o (line 1) | function o(e){return/^[0-9a-fA-F]$/.test(e)}
  function s (line 1) | function s(e){return/^[0-9]$/.test(e)}
  function o (line 1) | function o(e){return/^[0-7]$/.test(e)}
  function u (line 1) | function u(e){return/^[0-9a-fA-F]$/.test(e)}
  function a (line 1) | function a(e){return e==="$"||e==="_"||e==="\\"||e>="a"&&e<="z"||e>="A"&...
  function n (line 1) | function n(e,t){if(!e.reserved)return!1;var n=e.meta;if(n&&n.isFutureRes...
  function r (line 1) | function r(){this._events=this._events||{},this._maxListeners=this._maxL...
  function i (line 1) | function i(e){return typeof e=="function"}
  function s (line 1) | function s(e){return typeof e=="number"}
  function o (line 1) | function o(e){return typeof e=="object"&&e!==null}
  function u (line 1) | function u(e){return e===void 0}
  function r (line 1) | function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}
  function startRegex (line 1) | function startRegex(e){return RegExp("^("+e.join("|")+")")}
  function r (line 1) | function r(){}
  function w (line 1) | function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentine...
  function H (line 1) | function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-...
  function B (line 1) | function B(e){var t=typeof e;return e===null||t==="undefined"||t==="bool...
  function j (line 1) | function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="funct...
  function e (line 1) | function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}

FILE: docs/js/c3.esm.js
  function ChartInternal (line 4) | function ChartInternal(api) {
  function Chart (line 27) | function Chart(config) {
  function AxisInternal (line 186) | function AxisInternal(component, params) {
  function split (line 332) | function split(splitted, text) {
  function axis (line 428) | function axis(g, transition) {
  class Axis (line 812) | class Axis {
    method constructor (line 813) | constructor(owner) {
  function callResizeFunctions (line 2647) | function callResizeFunctions() {
  function find (line 7689) | function find() {
  function mouseout (line 9903) | function mouseout() {
  function getTextBox (line 10370) | function getTextBox(textElement, id) {
  function updatePositions (line 10381) | function updatePositions(textElement, id, index) {
  function c3LogScale (line 10833) | function c3LogScale(d3, linearScale, logScale) {
  function isWithinRegions (line 11732) | function isWithinRegions(x, regions) {
  function generateM (line 11780) | function generateM(points) {
  function powerOfTen (line 12901) | function powerOfTen(d) {

FILE: docs/js/c3.js
  function ChartInternal (line 8) | function ChartInternal(api) {
  function Chart (line 31) | function Chart(config) {
  function AxisInternal (line 172) | function AxisInternal(component, params) {
  function split (line 295) | function split(splitted, text) {
  function axis (line 373) | function axis(g, transition) {
  function AxisClass (line 729) | function AxisClass(owner) {
  function callResizeFunctions (line 2181) | function callResizeFunctions() {
  function find (line 6141) | function find() {
  function mouseout (line 8000) | function mouseout() {
  function getTextBox (line 8350) | function getTextBox(textElement, id) {
  function updatePositions (line 8356) | function updatePositions(textElement, id, index) {
  function c3LogScale (line 8757) | function c3LogScale(d3, linearScale, logScale) {
  function isWithinRegions (line 9468) | function isWithinRegions(x, regions) {
  function generateM (line 9515) | function generateM(points) {
  function powerOfTen (line 10433) | function powerOfTen(d) {

FILE: docs/js/gettingstarted.js
  function example4_1 (line 132) | function example4_1() {
  function example4_2 (line 153) | function example4_2() {
  function example4_3_1 (line 170) | function example4_3_1() {
  function example4_3_2 (line 173) | function example4_3_2() {

FILE: docs/js/highlight.pack.js
  function l (line 1) | function l(o){return o.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").repl...
  function b (line 1) | function b(p){for(var o=p.firstChild;o;o=o.nextSibling){if(o.nodeName=="...
  function h (line 1) | function h(p,o){return Array.prototype.map.call(p.childNodes,function(q)...
  function a (line 1) | function a(q){var p=(q.className+" "+q.parentNode.className).split(/\s+/...
  function c (line 1) | function c(q){var o=[];(function p(r,s){for(var t=r.firstChild;t;t=t.nex...
  function j (line 1) | function j(x,v,w){var p=0;var y="";var r=[];function t(){if(x.length&&v....
  function f (line 1) | function f(q){function o(s,r){return RegExp(s,"m"+(q.cI?"i":"")+(r?"g":"...
  function d (line 1) | function d(D,E){function o(r,M){for(var L=0;L<M.c.length;L++){var K=M.c[...
  function g (line 1) | function g(s){var o={keyword_count:0,r:0,value:l(s)};var q=o;for(var p i...
  function i (line 1) | function i(q,p,o){if(p){q=q.replace(/^((<[^>]+>|\t)+)/gm,function(r,v,u,...
  function m (line 1) | function m(r,u,p){var v=h(r,p);var t=a(r);if(t=="no-highlight"){return}v...
  function n (line 1) | function n(){if(n.called){return}n.called=true;Array.prototype.map.call(...
  function k (line 1) | function k(){window.addEventListener("DOMContentLoaded",n,false);window....

FILE: docs/js/index.js
  function setMessage (line 152) | function setMessage(message) {
  function startDemo (line 157) | function startDemo() {
  function stopDemo (line 165) | function stopDemo() {

FILE: docs/js/samples/legend_custom.js
  function toggle (line 15) | function toggle(id) {

FILE: extensions/exporter/phantom-exporter.js
  function checkNum (line 39) | function checkNum(check) {
  function injectVerify (line 101) | function injectVerify(script) {

FILE: extensions/js/c3ext.js
  function onZoomChanged (line 32) | function onZoomChanged(e) {
  function zoomAndReduceData (line 55) | function zoomAndReduceData(list, zoomRange, func, maxItems) {
  function first (line 68) | function first(t) {
  function unload (line 113) | function unload(names) {
  function refresh (line 119) | function refresh() {
  function verifyZoom (line 153) | function verifyZoom(newZoom) {
  function zoomAndPan (line 169) | function zoomAndPan(zoomFactor, left) {
  function onZoomChanged (line 177) | function onZoomChanged() {
  function applyZoomAndPan (line 180) | function applyZoomAndPan() {
  function getItemsToShow (line 183) | function getItemsToShow() {
  function doZoom (line 248) | function doZoom() {
  function element_mousewheel (line 260) | function element_mousewheel(e) {

FILE: htdocs/js/require.js
  function G (line 7) | function G(b){return"[object Function]"===M.call(b)}
  function H (line 7) | function H(b){return"[object Array]"===M.call(b)}
  function v (line 7) | function v(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+...
  function U (line 7) | function U(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b))...
  function s (line 7) | function s(b,c){return ga.call(b,c)}
  function j (line 7) | function j(b,c){return s(b,c)&&b[c]}
  function B (line 7) | function B(b,c){for(var d in b)if(s(b,d)&&c(b[d],d))break}
  function V (line 7) | function V(b,c,d,g){c&&B(c,function(c,h){if(d||!s(b,h))g&&"object"===typ...
  function t (line 8) | function t(b,c){return function(){return c.apply(b,arguments)}}
  function da (line 8) | function da(b){throw b;}
  function ea (line 8) | function ea(b){if(!b)return b;var c=ca;v(b.split("."),function(b){c=c[b]...
  function C (line 8) | function C(b,c,d,g){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"...
  function ha (line 8) | function ha(b){function c(a,e,b){var f,n,c,d,g,h,i,I=e&&e.split("/");n=I...

FILE: htdocs/js/samples/zoom_reduction.js
  function refresh (line 2) | function refresh() {
  function getChart (line 13) | function getChart() {
  function main (line 16) | function main() {

FILE: spec/api.data-spec.ts
  function rgb2hex (line 304) | function rgb2hex(rgb) {

FILE: spec/svg-helper.ts
  function parseSvgPath (line 6) | function parseSvgPath(d) {

FILE: src/axis-internal.ts
  function AxisInternal (line 3) | function AxisInternal(component, params) {
  function split (line 149) | function split(splitted, text) {
  function axis (line 245) | function axis(g, transition) {

FILE: src/axis.ts
  class AxisClass (line 5) | class AxisClass {
    method constructor (line 10) | constructor(owner) {

FILE: src/chart-internal.ts
  function ChartInternal (line 1) | function ChartInternal(api) {

FILE: src/chart.ts
  function Chart (line 8) | function Chart(config) {

FILE: src/colorscale.ts
  function powerOfTen (line 5) | function powerOfTen(d) {

FILE: src/config.ts
  function find (line 293) | function find() {

FILE: src/core.ts
  function callResizeFunctions (line 1232) | function callResizeFunctions() {

FILE: src/interaction.ts
  function mouseout (line 35) | function mouseout() {

FILE: src/legend.ts
  function getTextBox (line 215) | function getTextBox(textElement, id) {
  function updatePositions (line 226) | function updatePositions(textElement, id, index) {

FILE: src/scale.ts
  function c3LogScale (line 3) | function c3LogScale(d3, linearScale?, logScale?) {

FILE: src/shape.line.ts
  function isWithinRegions (line 198) | function isWithinRegions(x, regions) {
  function generateM (line 246) | function generateM(points) {
Condensed preview — 559 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,802K chars).
[
  {
    "path": ".bmp.yml",
    "chars": 180,
    "preview": "---\nversion: 0.7.20\ncommit: 'chore(version): bump to v%.%.%'\nfiles:\n  src/core.ts: 'version: ''%.%.%'''\n  package.json: "
  },
  {
    "path": ".circleci/config.yml",
    "chars": 1999,
    "preview": "version: 2\n\nnode12: &node12\n  working_directory: ~/c3\n  docker:\n    - image: circleci/node:12-browsers\n\nnode14: &node14\n"
  },
  {
    "path": ".editorconfig",
    "chars": 269,
    "preview": "# editorconfig.org\nroot = true\n\n[*]\nindent_style = space\nindent_size = 4\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 641,
    "preview": "<!--\n\nThis is not a catch-all support forum, for general support enquiries, please use the Google Group at https://group"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 232,
    "preview": "<!--\n\nThank you for contributing!\n\nPlease make sure to:\n \n- provide tests with your code changes to ensure they are work"
  },
  {
    "path": ".gitignore",
    "chars": 364,
    "preview": "# npm modules\nnode_modules\nbower_components\nd3.js\nd3.min.js\ncomponents\npackage-lock.json\n\n# build\n/htdocs/js/c3.js\n/htdo"
  },
  {
    "path": ".jshintrc",
    "chars": 455,
    "preview": "{\n    \"esversion\": 6,\n    \"eqeqeq\": true,\n    \"curly\": true,\n    \"strict\": false,\n    \"trailing\": true,\n    \"white\": tru"
  },
  {
    "path": ".prettierrc.json",
    "chars": 60,
    "preview": "{\n  \"tabWidth\": 2,\n  \"semi\": false,\n  \"singleQuote\": true\n}\n"
  },
  {
    "path": ".travis.yml",
    "chars": 244,
    "preview": "language: ruby\nrvm:\n  - 2.4\n\nbranches:\n  only:\n    - master\n\nscript:\n  - bundle exec middleman build\n\ndeploy:\n  provider"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2437,
    "preview": "## Filing an issue\n\nBefore filing an issue, please [search the queue](https://github.com/c3js/c3/issues) to make sure it"
  },
  {
    "path": "Gemfile",
    "chars": 369,
    "preview": "# If you have OpenSSL installed, we recommend updating\n# the following line to use \"https\"\nsource 'http://rubygems.org'\n"
  },
  {
    "path": "LICENSE",
    "chars": 1082,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2013 Masayuki Tanaka\n\nPermission is hereby granted, free of charge, to any person o"
  },
  {
    "path": "MAINTAINANCE.md",
    "chars": 718,
    "preview": "# Release process\n\nIf you don't have `bmp` command installed, first install `bmp` ruby gem:\n\n    gem install bmp\n\nWhen m"
  },
  {
    "path": "README.md",
    "chars": 3233,
    "preview": "# c3\n\n[![CircleCI](https://circleci.com/gh/c3js/c3.svg?style=shield)](https://circleci.com/gh/c3js/c3)\n[![license](http:"
  },
  {
    "path": "bower.json",
    "chars": 479,
    "preview": "{\n  \"name\": \"c3\",\n  \"main\": [\"c3.css\", \"c3.js\"],\n  \"homepage\": \"https://github.com/c3js/c3\",\n  \"authors\": [\"Masayuki Tan"
  },
  {
    "path": "c3.css",
    "chars": 3369,
    "preview": "/*-- 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 lin"
  },
  {
    "path": "c3.esm.js",
    "chars": 387550,
    "preview": "/* @license C3.js v0.7.18 | (c) C3 Team and other contributors | http://c3js.org/ */\nimport * as d3 from 'd3';\n\nfunction"
  },
  {
    "path": "c3.js",
    "chars": 453057,
    "preview": "/* @license C3.js v0.7.20 | (c) C3 Team and other contributors | http://c3js.org/ */\n(function (global, factory) {\n  typ"
  },
  {
    "path": "codecov.yml",
    "chars": 23,
    "preview": "coverage:\n  status: no\n"
  },
  {
    "path": "component.json",
    "chars": 304,
    "preview": "{\n  \"name\": \"c3\",\n  \"repo\": \"masayuki0812/c3\",\n  \"description\": \"A D3-based reusable chart library\",\n  \"version\": \"0.7.2"
  },
  {
    "path": "config.rb",
    "chars": 601,
    "preview": "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"
  },
  {
    "path": "data/samples.yml",
    "chars": 6411,
    "preview": "simple_multiple:\n  title: 'Line Chart'\n  desc: 'Line chart with sequential data.'\n\ntimeseries:\n  title: Timeseries Chart"
  },
  {
    "path": "docs/404.html",
    "chars": 4464,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"utf-8\">\n        <title>Page Not Found :(</title>\n    "
  },
  {
    "path": "docs/CNAME",
    "chars": 9,
    "preview": "c3js.org\n"
  },
  {
    "path": "docs/_footer.haml",
    "chars": 46,
    "preview": "%footer\n  %hr\n  %p &copy Masayuki Tanaka 2014\n"
  },
  {
    "path": "docs/_index_item.haml",
    "chars": 185,
    "preview": ".large-4.columns\n  %h3 #{data.samples[id].title}\n  %p.margin-small-bottom #{data.samples[id].desc}\n  %a.btn.btn-default("
  },
  {
    "path": "docs/_index_item_title.haml",
    "chars": 79,
    "preview": "%a( href=\"/examples.html##{id}\" name=\"#{id}\" )\n  %h2<\n    \\#\n    %span #{name}\n"
  },
  {
    "path": "docs/_reference_item_link.haml",
    "chars": 151,
    "preview": "%a( href=\"##{ id.gsub(/\\./, '-') }\")< #{ id.gsub(/(api|class)\\./, '') }\n- if defined? experimental\n  <span class=\"second"
  },
  {
    "path": "docs/_reference_menu_item.haml",
    "chars": 179,
    "preview": "%li\n  - if defined? experimental\n    = partial :reference_item_link, locals: { id: id, experimental: experimental }\n  - "
  },
  {
    "path": "docs/_sample.haml",
    "chars": 639,
    "preview": ".container\n\n  %h1.title #{data.samples[id].title}\n\n  .chart\n    #chart\n\n  #ace-error\n\n  .sourcecode.margin-medium-v.marg"
  },
  {
    "path": "docs/_sample_editor.haml",
    "chars": 1003,
    "preview": "= javascript_include_tag \"ace/ace.js\"\n= javascript_include_tag \"ace/mode-javascript.js\"\n= javascript_include_tag \"ace/th"
  },
  {
    "path": "docs/_samples_header.haml",
    "chars": 244,
    "preview": ".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"
  },
  {
    "path": "docs/_script.haml",
    "chars": 291,
    "preview": "= javascript_include_tag 'jquery-1.11.0.min.js'\n= javascript_include_tag 'foundation.min.js'\n= javascript_include_tag 'h"
  },
  {
    "path": "docs/_script_scroll.haml",
    "chars": 589,
    "preview": ":javascript\n  $(function(){\n    function scrollToHash() {\n      var hash = document.location.hash,\n          target = $("
  },
  {
    "path": "docs/_sidemenu_item.haml",
    "chars": 36,
    "preview": "%li\n  %a( href=\"##{ id }\") #{ name }"
  },
  {
    "path": "docs/crossdomain.xml",
    "chars": 603,
    "preview": "<?xml version=\"1.0\"?>\n<!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n<cro"
  },
  {
    "path": "docs/css/c3.css",
    "chars": 3369,
    "preview": "/*-- 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 lin"
  },
  {
    "path": "docs/css/examples.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/foundation.css",
    "chars": 149591,
    "preview": "meta.foundation-version {\n  font-family: \"/5.2.2/\"; }\n\nmeta.foundation-mq-small {\n  font-family: \"/only screen/\";\n  widt"
  },
  {
    "path": "docs/css/gettingstarted.css",
    "chars": 49,
    "preview": "#chart5_1 .c3-line-data2 {\n  stroke-width: 5px;\n}"
  },
  {
    "path": "docs/css/index.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/normalize.css",
    "chars": 7583,
    "preview": "/*! normalize.css v3.0.0 | MIT License | git.io/normalize */\n\n/**\n * 1. Set default font family to sans-serif.\n * 2. Pre"
  },
  {
    "path": "docs/css/reference.css",
    "chars": 321,
    "preview": "section p {\n    margin-bottom: 0;\n}\nsection h5 {\n    margin-top: 1rem;\n}\nsection code {\n    padding-left: 0;\n}\n.sourceco"
  },
  {
    "path": "docs/css/samples/api_axis_label.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/api_axis_range.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/api_data_color.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/api_data_name.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/api_flow.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/api_grid_x.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/api_resize.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_label.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_label_position.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_rotated.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_x_localtime.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_x_tick_count.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_x_tick_culling.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_x_tick_fit.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_x_tick_format.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_x_tick_rotate.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_x_tick_values.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_y2.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_y_padding.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_y_range.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/axes_y_tick_format.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/categorized.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_area.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_area_stacked.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_bar.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_bar_negative.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_bar_stacked.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_combination.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_donut.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_gauge.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_pie.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_scatter.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_spline.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_stanford.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/chart_step.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/data_color.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/data_columned.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/data_json.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/data_label.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/data_label_format.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/data_load.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/data_name.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/data_order.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/data_rowed.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/data_stringx.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/data_url.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/data_xformat.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/grid_x_lines.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/grid_y_lines.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/interaction_zoom.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/legend_custom.css",
    "chars": 129,
    "preview": ".legend span {\n    width: 33.333333%;\n    display: inline-block;\n    text-align: center;\n    cursor: pointer;\n    color:"
  },
  {
    "path": "docs/css/samples/legend_position.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/options_color.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/options_gridline.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/options_legend.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/options_padding.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/options_size.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/options_subchart.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/pie_label_format.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/point_show.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/region.css",
    "chars": 75,
    "preview": ".c3-region.regionY {\n  fill: red;\n}\n.c3-region.regionY2 {\n  fill: green;\n}\n"
  },
  {
    "path": "docs/css/samples/region_timeseries.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/simple_multiple.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/simple_regions.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/simple_xy.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/simple_xy_multiple.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/style_grid.css",
    "chars": 276,
    "preview": ".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  "
  },
  {
    "path": "docs/css/samples/style_region.css",
    "chars": 64,
    "preview": ".c3-region-0 {\n  fill: red;\n}\n.c3-region.foo {\n  fill: green;\n}\n"
  },
  {
    "path": "docs/css/samples/timeseries.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/tooltip_format.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/tooltip_grouped.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/tooltip_show.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/transform_area.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/transform_areaspline.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/transform_bar.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/transform_donut.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/transform_line.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/transform_pie.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/transform_scatter.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/transform_spline.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/samples/transition_duration.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/css/style.css",
    "chars": 3454,
    "preview": "body {\n  background-color: #fdfdfd;\n}\nfooter {\n  text-align: right;\n}\nfooter hr {\n  margin-bottom: 10px;\n}\nfooter p {\n  "
  },
  {
    "path": "docs/css/tomorrow.css",
    "chars": 1355,
    "preview": "/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */\n.tomorrow-comment, pre .comment, pre .title {\n  "
  },
  {
    "path": "docs/data/c3_string_x.csv",
    "chars": 85,
    "preview": "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",
    "chars": 74,
    "preview": "data1,data2,data3\n120,80,200\n140,50,210\n170,100,250\n150,70,300\n180,120,280"
  },
  {
    "path": "docs/data/c3_test.json",
    "chars": 116,
    "preview": "{\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",
    "chars": 72,
    "preview": "data1,data2,data3\n20,180,400\n40,150,310\n70,120,470\n50,170,400\n80,200,380"
  },
  {
    "path": "docs/examples.html.haml",
    "chars": 7405,
    "preview": ".container\n  .section\n    = partial :index_item_title, locals: { id: 'chart', name: 'Chart' }\n    %div\n      .row\n      "
  },
  {
    "path": "docs/gettingstarted.html.haml",
    "chars": 13646,
    "preview": ".container.sidemenu\n  .row\n    .large-3.medium-4.columns.column-menu\n      .side-bar\n        %ul.side-nav\n          %li "
  },
  {
    "path": "docs/img/.gitignore",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/index.html.haml",
    "chars": 16646,
    "preview": ".container\n\n  %h1.title\n    C3.js\n    %small D3-based reusable chart library\n\n  .chart\n    #message\n      %a.button.smal"
  },
  {
    "path": "docs/js/ace/ace.js",
    "chars": 338411,
    "preview": "(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."
  },
  {
    "path": "docs/js/ace/mode-javascript.js",
    "chars": 22048,
    "preview": "ace.define(\"ace/mode/doc_comment_highlight_rules\",[\"require\",\"exports\",\"module\",\"ace/lib/oop\",\"ace/mode/text_highlight_r"
  },
  {
    "path": "docs/js/ace/theme-tomorrow.js",
    "chars": 2575,
    "preview": "ace.define(\"ace/theme/tomorrow\",[\"require\",\"exports\",\"module\",\"ace/lib/dom\"],function(e,t,n){t.isDark=!1,t.cssClass=\"ace"
  },
  {
    "path": "docs/js/ace/worker-javascript.js",
    "chars": 140768,
    "preview": "\"no use strict\";(function(e){if(typeof e.window!=\"undefined\"&&e.document)return;e.console=function(){var e=Array.prototy"
  },
  {
    "path": "docs/js/c3.esm.js",
    "chars": 387550,
    "preview": "/* @license C3.js v0.7.18 | (c) C3 Team and other contributors | http://c3js.org/ */\nimport * as d3 from 'd3';\n\nfunction"
  },
  {
    "path": "docs/js/c3.js",
    "chars": 453057,
    "preview": "/* @license C3.js v0.7.20 | (c) C3 Team and other contributors | http://c3js.org/ */\n(function (global, factory) {\n  typ"
  },
  {
    "path": "docs/js/gettingstarted.js",
    "chars": 3755,
    "preview": "c3.generate({\n    bindto: '#chart2_1',\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250]"
  },
  {
    "path": "docs/js/highlight.pack.js",
    "chars": 7025,
    "preview": "var hljs=new function(){function l(o){return o.replace(/&/gm,\"&amp;\").replace(/</gm,\"&lt;\").replace(/>/gm,\"&gt;\")}functi"
  },
  {
    "path": "docs/js/index.js",
    "chars": 4587,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250, 50, 100, 250"
  },
  {
    "path": "docs/js/main.js",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "docs/js/plugins.js",
    "chars": 639,
    "preview": "// Avoid `console` errors in browsers that lack a console.\nif (!(window.console && console.log)) {\n    (function() {\n   "
  },
  {
    "path": "docs/js/samples/api_axis_label.js",
    "chars": 611,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n           "
  },
  {
    "path": "docs/js/samples/api_axis_range.js",
    "chars": 999,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n           "
  },
  {
    "path": "docs/js/samples/api_data_color.js",
    "chars": 789,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n            ['da"
  },
  {
    "path": "docs/js/samples/api_data_name.js",
    "chars": 474,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n           "
  },
  {
    "path": "docs/js/samples/api_flow.js",
    "chars": 2104,
    "preview": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        columns: [\n            ['x', '2012-12-29', '2012-12-30', '"
  },
  {
    "path": "docs/js/samples/api_grid_x.js",
    "chars": 775,
    "preview": "var chart = c3.generate({\n    bindto: '#chart',\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400,"
  },
  {
    "path": "docs/js/samples/api_resize.js",
    "chars": 375,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n           "
  },
  {
    "path": "docs/js/samples/axes_label.js",
    "chars": 440,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250],\n          "
  },
  {
    "path": "docs/js/samples/axes_label_position.js",
    "chars": 1295,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample1', 30, 200, 100, 400, 150, 250],\n         "
  },
  {
    "path": "docs/js/samples/axes_rotated.js",
    "chars": 270,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n           "
  },
  {
    "path": "docs/js/samples/axes_x_localtime.js",
    "chars": 686,
    "preview": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        xFormat: '%Y',\n        columns: [\n//            ['x', '201"
  },
  {
    "path": "docs/js/samples/axes_x_tick_count.js",
    "chars": 530,
    "preview": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        columns: [\n            ['x', '2013-01-01', '2013-01-02', '"
  },
  {
    "path": "docs/js/samples/axes_x_tick_culling.js",
    "chars": 556,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250, 30, 200, 10"
  },
  {
    "path": "docs/js/samples/axes_x_tick_fit.js",
    "chars": 384,
    "preview": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        columns: [\n            ['x', '2013-10-31', '2013-12-31', '"
  },
  {
    "path": "docs/js/samples/axes_x_tick_format.js",
    "chars": 508,
    "preview": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        columns: [\n            ['x', '2010-01-01', '2011-01-01', '"
  },
  {
    "path": "docs/js/samples/axes_x_tick_rotate.js",
    "chars": 707,
    "preview": "var chart = c3.generate({\n    data: {\n        x : 'x',\n        columns: [\n            ['x', 'www.somesitename1.com', 'ww"
  },
  {
    "path": "docs/js/samples/axes_x_tick_values.js",
    "chars": 581,
    "preview": "var chart = c3.generate({\n    data: {\n        x: 'x',\n        columns: [\n            ['x', '2013-01-01', '2013-01-02', '"
  },
  {
    "path": "docs/js/samples/axes_y2.js",
    "chars": 316,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n           "
  },
  {
    "path": "docs/js/samples/axes_y_padding.js",
    "chars": 429,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n           "
  },
  {
    "path": "docs/js/samples/axes_y_range.js",
    "chars": 324,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n "
  },
  {
    "path": "docs/js/samples/axes_y_tick_format.js",
    "chars": 307,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 2500]\n        ]\n"
  },
  {
    "path": "docs/js/samples/categorized.js",
    "chars": 311,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250, 50, 100, 250"
  },
  {
    "path": "docs/js/samples/chart_area.js",
    "chars": 263,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 300, 350, 300, 0, 0, 0],\n            ['da"
  },
  {
    "path": "docs/js/samples/chart_area_stacked.js",
    "chars": 399,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 300, 350, 300, 0, 0, 120],\n            ['"
  },
  {
    "path": "docs/js/samples/chart_bar.js",
    "chars": 529,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n           "
  },
  {
    "path": "docs/js/samples/chart_bar_stacked.js",
    "chars": 692,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', -30, 200, 200, 400, -150, 250],\n         "
  },
  {
    "path": "docs/js/samples/chart_combination.js",
    "chars": 573,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n            ['da"
  },
  {
    "path": "docs/js/samples/chart_donut.js",
    "chars": 1479,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30],\n            ['data2', 120],\n        "
  },
  {
    "path": "docs/js/samples/chart_gauge.js",
    "chars": 1570,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data', 91.4]\n        ],\n        type: 'gauge',\n  "
  },
  {
    "path": "docs/js/samples/chart_pie.js",
    "chars": 1451,
    "preview": "var chart = c3.generate({\n    data: {\n        // iris data from R\n        columns: [\n            ['data1', 30],\n        "
  },
  {
    "path": "docs/js/samples/chart_scatter.js",
    "chars": 2689,
    "preview": "var chart = c3.generate({\n    data: {\n        xs: {\n            setosa: 'setosa_x',\n            versicolor: 'versicolor_"
  },
  {
    "path": "docs/js/samples/chart_spline.js",
    "chars": 204,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n           "
  },
  {
    "path": "docs/js/samples/chart_stanford.js",
    "chars": 4750,
    "preview": "// More samples available at:\n// - htdocs/samples/chart_stanford.html\n// - htdocs/samples/chart_stanford_custom_elements"
  },
  {
    "path": "docs/js/samples/chart_step.js",
    "chars": 263,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 300, 350, 300, 0, 0, 100],\n            ['"
  },
  {
    "path": "docs/js/samples/data_color.js",
    "chars": 560,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n            ['da"
  },
  {
    "path": "docs/js/samples/data_columned.js",
    "chars": 228,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 20, 50, 40, 60, 50],\n            ['da"
  },
  {
    "path": "docs/js/samples/data_json.js",
    "chars": 1393,
    "preview": "var chart = c3.generate({\n    data: {\n        json: {\n            data1: [30, 20, 50, 40, 60, 50],\n            data2: [2"
  },
  {
    "path": "docs/js/samples/data_label.js",
    "chars": 417,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, -200, -100, 400, 150, 250],\n         "
  },
  {
    "path": "docs/js/samples/data_label_format.js",
    "chars": 654,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, -200, -100, 400, 150, 250],\n         "
  },
  {
    "path": "docs/js/samples/data_load.js",
    "chars": 1858,
    "preview": "var chart = c3.generate({\n    data: {\n        url: '/data/c3_test.csv',\n        type: 'line'\n    }\n});\n\nsetTimeout(funct"
  },
  {
    "path": "docs/js/samples/data_name.js",
    "chars": 259,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n           "
  },
  {
    "path": "docs/js/samples/data_number_format_l10n.js",
    "chars": 1273,
    "preview": "// Locale for Russian (ru_RU)\nvar d3locale = d3.formatDefaultLocale({\n    \"decimal\": \",\",\n    \"thousands\": \"\\u00A0\",\n   "
  },
  {
    "path": "docs/js/samples/data_order.js",
    "chars": 1006,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 130, 200, 320, 400, 530, 750],\n          "
  },
  {
    "path": "docs/js/samples/data_rowed.js",
    "chars": 284,
    "preview": "var chart = c3.generate({\n    data: {\n        rows: [\n            ['data1', 'data2', 'data3'],\n            [90, 120, 300"
  },
  {
    "path": "docs/js/samples/data_stringx.js",
    "chars": 1515,
    "preview": "var chart = c3.generate({\n    data: {\n        x : 'x',\n        columns: [\n            ['x', 'www.site1.com', 'www.site2."
  },
  {
    "path": "docs/js/samples/data_url.js",
    "chars": 236,
    "preview": "var chart = c3.generate({\n    data: {\n        url: '/data/c3_test.csv'\n    }\n});\n\nsetTimeout(function () {\n    c3.genera"
  },
  {
    "path": "docs/js/samples/data_xformat.js",
    "chars": 368,
    "preview": "var chart = c3.generate({\n    data: {\n        x: 'date',\n        xFormat : '%Y%m%d', // default '%Y-%m-%d'\n        colum"
  },
  {
    "path": "docs/js/samples/grid_x_lines.js",
    "chars": 383,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250]\n        ]\n "
  },
  {
    "path": "docs/js/samples/grid_y_lines.js",
    "chars": 603,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250],\n          "
  },
  {
    "path": "docs/js/samples/interaction_zoom.js",
    "chars": 405,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250, 150, 200, 1"
  },
  {
    "path": "docs/js/samples/interaction_zoom_by_drag.js",
    "chars": 428,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250, 150, 200, 1"
  },
  {
    "path": "docs/js/samples/legend_custom.js",
    "chars": 820,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 100],\n            ['data2', 300],\n       "
  },
  {
    "path": "docs/js/samples/legend_position.js",
    "chars": 577,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n           "
  },
  {
    "path": "docs/js/samples/options_color.js",
    "chars": 645,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['data1', 30, 200, 100, 400, 150, 250],\n           "
  },
  {
    "path": "docs/js/samples/options_gridline.js",
    "chars": 251,
    "preview": "var chart = c3.generate({\n    data: {\n        columns: [\n            ['sample', 30, 200, 100, 400, 150, 250, 120, 200]\n "
  }
]

// ... and 359 more files (download for full content)

About this extraction

This page contains the full source code of the c3js/c3 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 559 files (3.5 MB), approximately 931.4k tokens, and a symbol index with 298 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!