myCRED - Version 2.4.4.2-beta.2

Version Description

= 2.4.4.2 = * Improvements * Patched security vulnerability.

= 2.4.4.1 = * Improvements * Patched security vulnerability. * Badge UI Fix.

= 2.4.4 = New features and Bug fixes.

= 2.4.3 = Code improvement.

= 2.4.2 = Code improvement.

= 2.4.1 = New features and Bug fixes.

= 2.4 = New features and Bug fixes.

= 2.3.2 = Code improvement.

= 2.3.1 = Improve license system.

= 2.3 = New features and Bug fixes.

= 2.2 = New features and Bug fixes.

= 2.1.1 = New features and Bug fixes.

= 2.1 = New features and Bug fixes.

= 2.0 = The banking module have been replaced by Central deposite module, and interest related functionality has been removed. If you are using simple interest or compound interest related functionality, you will fine the respective functionalities missing after the update.

Download this release

Release Info

Developer wpexpertsio
Plugin Icon 128x128 myCRED
Version 2.4.4.2-beta.2
Comparing to
See all releases

Code changes from version 2.4.4.2-beta.1 to 2.4.4.2-beta.2

abstracts/mycred-abstract-hook.php CHANGED
@@ -113,7 +113,7 @@ if (! class_exists('myCRED_Hook') ) :
113
  public function preferences()
114
  {
115
 
116
- echo '<p>' . __('This Hook has no settings', 'mycred') . '</p>';
117
 
118
  }
119
 
@@ -447,10 +447,10 @@ if (! class_exists('myCRED_Hook') ) :
447
  );
448
  $limits = apply_filters('mycred_hook_impose_limits', $limits, $this);
449
 
450
- echo '<select name="' . $this->field_name($pref_id) . '" id="' . $this->field_id($pref_id) . '" class="form-control">';
451
 
452
  if ($use_select ) {
453
- echo '<option value="">' . __('Select', 'mycred') . '</option>';
454
  }
455
 
456
  if (is_array($pref_id) ) {
@@ -467,10 +467,10 @@ if (! class_exists('myCRED_Hook') ) :
467
  }
468
 
469
  foreach ( $limits as $value => $description ) {
470
- echo '<option value="' . $value . '"';
471
  if ($settings == $value ) { echo ' selected="selected"';
472
  }
473
- echo '>' . $description . '</option>';
474
  }
475
  echo '</select>';
476
 
113
  public function preferences()
114
  {
115
 
116
+ echo '<p>' . esc_html__('This Hook has no settings', 'mycred') . '</p>';
117
 
118
  }
119
 
447
  );
448
  $limits = apply_filters('mycred_hook_impose_limits', $limits, $this);
449
 
450
+ echo '<select name="' . esc_attr( $this->field_name($pref_id) ) . '" id="' . esc_attr( $this->field_id($pref_id) ) . '" class="form-control">';
451
 
452
  if ($use_select ) {
453
+ echo '<option value="">' . esc_html__('Select', 'mycred') . '</option>';
454
  }
455
 
456
  if (is_array($pref_id) ) {
467
  }
468
 
469
  foreach ( $limits as $value => $description ) {
470
+ echo '<option value="' . esc_attr( $value ) . '"';
471
  if ($settings == $value ) { echo ' selected="selected"';
472
  }
473
+ echo '>' . esc_html( $description ) . '</option>';
474
  }
475
  echo '</select>';
476
 
abstracts/mycred-abstract-module.php CHANGED
@@ -515,10 +515,11 @@ if (! class_exists('myCRED_Module') ) :
515
  public function set_entries_per_page()
516
  {
517
 
518
- if (! isset($_REQUEST['wp_screen_options']['option']) || ! isset($_REQUEST['wp_screen_options']['value']) ) { return;
 
519
  }
520
 
521
- $settings_key = 'mycred_epp_' . $_GET['page'];
522
 
523
  if ($_REQUEST['wp_screen_options']['option'] == $settings_key ) {
524
  $value = absint($_REQUEST['wp_screen_options']['value']);
@@ -593,8 +594,8 @@ if (! class_exists('myCRED_Module') ) :
593
  <!-- myCRED Accordion Styling -->
594
  <style type="text/css">
595
  h4:before { float:right; padding-right: 12px; font-size: 14px; font-weight: normal; color: silver; }
596
- h4.ui-accordion-header.ui-state-active:before { content: "<?php _e('click to close', 'mycred'); ?>"; }
597
- h4.ui-accordion-header:before { content: "<?php _e('click to open', 'mycred'); ?>"; }
598
  </style>
599
  <?php
600
 
@@ -639,7 +640,7 @@ h4.ui-accordion-header:before { content: "<?php _e('click to open', 'mycred'); ?
639
  }
640
 
641
  if (isset($_GET[ $get ]) ) {
642
- echo '<div class="' . $class . '"><p>' . $message . '</p></div>';
643
  }
644
 
645
  }
515
  public function set_entries_per_page()
516
  {
517
 
518
+ if (! isset($_REQUEST['wp_screen_options']['option']) || ! isset($_REQUEST['wp_screen_options']['value']) || ! isset( $_GET['page'] ) ) {
519
+ return;
520
  }
521
 
522
+ $settings_key = 'mycred_epp_' . sanitize_key( $_GET['page'] );
523
 
524
  if ($_REQUEST['wp_screen_options']['option'] == $settings_key ) {
525
  $value = absint($_REQUEST['wp_screen_options']['value']);
594
  <!-- myCRED Accordion Styling -->
595
  <style type="text/css">
596
  h4:before { float:right; padding-right: 12px; font-size: 14px; font-weight: normal; color: silver; }
597
+ h4.ui-accordion-header.ui-state-active:before { content: "<?php esc_html_e('click to close', 'mycred'); ?>"; }
598
+ h4.ui-accordion-header:before { content: "<?php esc_html_e('click to open', 'mycred'); ?>"; }
599
  </style>
600
  <?php
601
 
640
  }
641
 
642
  if (isset($_GET[ $get ]) ) {
643
+ echo '<div class="' . esc_attr( $class ) . '"><p>' . esc_html( $message ) . '</p></div>';
644
  }
645
 
646
  }
addons/badges/includes/mycred-badge-functions.php CHANGED
@@ -317,9 +317,9 @@ if (! function_exists('mycred_display_badge_requirement') ) :
317
  }
318
 
319
  if ($requirement['by'] == 'count' ) {
320
- $rendered_row = sprintf(_x('%s for "%s" x %d', '"Points" for "reference" x times', 'mycred'), $mycred->plural(), $requirement['ref'], $requirement['amount']);
321
  } else {
322
- $rendered_row = sprintf(_x('%s %s for "%s"', '"Gained/Lost" "x points" for "reference"', 'mycred'), ( ( $requirement['amount'] < 0 ) ? __('Lost', 'mycred') : __('Gained', 'mycred') ), $mycred->format_creds($requirement['amount']), $requirement['ref']);
323
  }
324
 
325
  $compare = _x('OR', 'Comparison of badge requirements. A OR B', 'mycred');
@@ -343,7 +343,7 @@ if (! function_exists('mycred_display_badge_requirement') ) :
343
  }
344
 
345
  if ((int) mycred_get_post_meta($badge_id, 'manual_badge', true) === 1 ) {
346
- $output[] = '<strong><small><em>' . __('This badge is manually awarded.', 'mycred') . '</em></small></strong>';
347
  }
348
 
349
  $reply = implode('', $output);
@@ -750,7 +750,7 @@ if (! function_exists('mycred_display_users_badges') ) :
750
  }
751
 
752
  if (!empty($badge_image) ) {
753
- echo apply_filters('mycred_the_badge', $badge_image, $badge_id, $badge, $user_id);
754
  }
755
 
756
  }
@@ -919,9 +919,9 @@ if(!function_exists('mycred_show_badge_requirements') ) :
919
  }
920
 
921
  if ($requirement['by'] == 'count') {
922
- $rendered_row = sprintf(_x('%s for "%s" x %d', '"Points" for "reference" x times', 'mycred'), $mycred->plural(), $requirement['ref'], $requirement['amount']);
923
  } else {
924
- $rendered_row = sprintf(_x('%s %s for "%s"', '"Gained/Lost" "x points" for "reference"', 'mycred'), (($requirement['amount'] < 0) ? __('Lost', 'mycred') : __('Gained', 'mycred')), $mycred->format_creds($requirement['amount']), $requirement['ref']);
925
  }
926
 
927
  $compare = _x('OR', 'Comparison of badge requirements. A OR B', 'mycred');
317
  }
318
 
319
  if ($requirement['by'] == 'count' ) {
320
+ $rendered_row = sprintf(esc_html_x('%s for "%s" x %d', '"Points" for "reference" x times', 'mycred'), $mycred->plural(), $requirement['ref'], $requirement['amount']);
321
  } else {
322
+ $rendered_row = sprintf(esc_html_x('%s %s for "%s"', '"Gained/Lost" "x points" for "reference"', 'mycred'), ( ( $requirement['amount'] < 0 ) ? esc_html__('Lost', 'mycred') : esc_html__('Gained', 'mycred') ), $mycred->format_creds($requirement['amount']), $requirement['ref']);
323
  }
324
 
325
  $compare = _x('OR', 'Comparison of badge requirements. A OR B', 'mycred');
343
  }
344
 
345
  if ((int) mycred_get_post_meta($badge_id, 'manual_badge', true) === 1 ) {
346
+ $output[] = '<strong><small><em>' . esc_html__('This badge is manually awarded.', 'mycred') . '</em></small></strong>';
347
  }
348
 
349
  $reply = implode('', $output);
750
  }
751
 
752
  if (!empty($badge_image) ) {
753
+ echo apply_filters('mycred_the_badge', wp_kses_post( $badge_image ), $badge_id, $badge, $user_id);
754
  }
755
 
756
  }
919
  }
920
 
921
  if ($requirement['by'] == 'count') {
922
+ $rendered_row = sprintf(esc_html_x('%s for "%s" x %d', '"Points" for "reference" x times', 'mycred'), $mycred->plural(), $requirement['ref'], $requirement['amount']);
923
  } else {
924
+ $rendered_row = sprintf(esc_html_x('%s %s for "%s"', '"Gained/Lost" "x points" for "reference"', 'mycred'), (($requirement['amount'] < 0) ? __('Lost', 'mycred') : __('Gained', 'mycred')), $mycred->format_creds($requirement['amount']), $requirement['ref']);
925
  }
926
 
927
  $compare = _x('OR', 'Comparison of badge requirements. A OR B', 'mycred');
addons/badges/includes/mycred-badge-secondary.php CHANGED
@@ -95,7 +95,7 @@ if (! class_exists('myCRED_Badge_Secondary') ) :
95
  $form_list .= '<option value="'.$form->id.'">'. htmlentities($form->title, ENT_QUOTES) .'</option>';
96
  }
97
  $data = '<div class="form-group"><select name="{{element_name}}" class="form-control specific" data-row="{{reqlevel}}" >'.$form_list.'</select></div>';
98
- echo "var mycred_badge_gravity_form_submission = '".$data."';";
99
  }
100
  ?>
101
  </script>
95
  $form_list .= '<option value="'.$form->id.'">'. htmlentities($form->title, ENT_QUOTES) .'</option>';
96
  }
97
  $data = '<div class="form-group"><select name="{{element_name}}" class="form-control specific" data-row="{{reqlevel}}" >'.$form_list.'</select></div>';
98
+ echo "var mycred_badge_gravity_form_submission = '".wp_kses_post($data)."';";
99
  }
100
  ?>
101
  </script>
addons/badges/includes/mycred-badge-shortcodes.php CHANGED
@@ -71,28 +71,24 @@ if (! function_exists('mycred_render_my_badges') ) :
71
 
72
  if ($badge->main_image !== false ) {
73
 
74
-
75
-
76
- echo '<div class="demo-badge-image">' . $badge_img . '</div>';
77
 
78
  if($title == 'show') {
79
 
80
-
81
-
82
- echo '<div class="demo-badge-title">' . $badge_title . ' '.'</div>';
83
 
84
  } else {
85
 
86
- echo '<div class="demo-badge-title" style="display:none;">' . $badge_title . ' '.'</div>';
87
 
88
  }
89
 
90
  if($post_excerpt == 'show') {
91
 
92
- echo '<div class="page-excerpt">' . $page_id->post_excerpt . ' '.'</div>';
93
 
94
  } else {
95
- echo '<div class="page-excerpt" style="display:none;">' . $page_id->post_excerpt . ' '.'</div>';;
96
  }
97
 
98
  }
@@ -114,26 +110,26 @@ if (! function_exists('mycred_render_my_badges') ) :
114
  if ($badge->level_image !== false ) {
115
 
116
 
117
- echo '<div class="demo-badge-image">' . $badge->get_image($level) . '</div>';
118
 
119
  if($title == 'show') {
120
 
121
- echo '<div class="demo-badge-title">' . $badge->title . ' '.'</div>';
122
 
123
  }
124
 
125
  else {
126
 
127
- echo '<div class="demo-badge-title" style="display:none;">' . $badge->title . ' '.'</div>';
128
 
129
  }
130
 
131
  if($post_excerpt == 'show') {
132
 
133
- echo '<div class="page-excerpt">' . $badge_page_id->post_excerpt . ' '.'</div>';
134
 
135
  } else {
136
- echo '<div class="page-excerpt" style="display:none;">' . $badge_page_id->post_excerpt . ' '.'</div>';;
137
  }
138
 
139
  }
@@ -269,7 +265,7 @@ if(!function_exists('mycred_render_badges_list') ) :
269
  <?php
270
  foreach ( $badges['tabs'] as $id => $element ) {
271
 
272
- echo $element;
273
 
274
  }
275
  ?>
@@ -279,7 +275,7 @@ if(!function_exists('mycred_render_badges_list') ) :
279
  <?php
280
  foreach ( $badges['panels'] as $id => $element ) {
281
 
282
- echo $element;
283
 
284
  }
285
  ?>
@@ -291,7 +287,7 @@ if(!function_exists('mycred_render_badges_list') ) :
291
  else {
292
 
293
  echo '<div class="mycred-badges-list-all">';
294
- echo mycred_get_uncategorized_badge_list();
295
  echo '</div>';
296
 
297
  }
71
 
72
  if ($badge->main_image !== false ) {
73
 
74
+ echo '<div class="demo-badge-image">' . wp_kses_post( $badge_img ) . '</div>';
 
 
75
 
76
  if($title == 'show') {
77
 
78
+ echo '<div class="demo-badge-title">' . esc_html( $badge_title ) . ' '.'</div>';
 
 
79
 
80
  } else {
81
 
82
+ echo '<div class="demo-badge-title" style="display:none;">' . esc_html( $badge_title ) . ' '.'</div>';
83
 
84
  }
85
 
86
  if($post_excerpt == 'show') {
87
 
88
+ echo '<div class="page-excerpt">' . wp_kses_post( $page_id->post_excerpt ) . ' '.'</div>';
89
 
90
  } else {
91
+ echo '<div class="page-excerpt" style="display:none;">' . wp_kses_post( $page_id->post_excerpt ) . ' '.'</div>';
92
  }
93
 
94
  }
110
  if ($badge->level_image !== false ) {
111
 
112
 
113
+ echo '<div class="demo-badge-image">' . wp_kses_post( $badge->get_image($level) ) . '</div>';
114
 
115
  if($title == 'show') {
116
 
117
+ echo '<div class="demo-badge-title">' . esc_html( $badge->title ) . ' '.'</div>';
118
 
119
  }
120
 
121
  else {
122
 
123
+ echo '<div class="demo-badge-title" style="display:none;">' . esc_html( $badge->title ) . ' '.'</div>';
124
 
125
  }
126
 
127
  if($post_excerpt == 'show') {
128
 
129
+ echo '<div class="page-excerpt">' . wp_kses_post( $badge_page_id->post_excerpt ) . ' '.'</div>';
130
 
131
  } else {
132
+ echo '<div class="page-excerpt" style="display:none;">' . wp_kses_post( $badge_page_id->post_excerpt ) . ' '.'</div>';;
133
  }
134
 
135
  }
265
  <?php
266
  foreach ( $badges['tabs'] as $id => $element ) {
267
 
268
+ echo wp_kses_post( $element );
269
 
270
  }
271
  ?>
275
  <?php
276
  foreach ( $badges['panels'] as $id => $element ) {
277
 
278
+ echo wp_kses_post( $element );
279
 
280
  }
281
  ?>
287
  else {
288
 
289
  echo '<div class="mycred-badges-list-all">';
290
+ echo wp_kses_post( mycred_get_uncategorized_badge_list() );
291
  echo '</div>';
292
 
293
  }
addons/badges/myCRED-addon-badges.php CHANGED
@@ -502,7 +502,7 @@ if ( ! class_exists( 'myCRED_Badge_Module' ) ) :
502
 
503
  }
504
 
505
- elseif ( $pagenow == 'post.php' && isset( $_GET['post'] ) && mycred_get_post_type( $_GET['post'] ) == MYCRED_BADGE_KEY ) {
506
 
507
  return MYCRED_MAIN_SLUG;
508
 
@@ -534,7 +534,7 @@ if ( ! class_exists( 'myCRED_Badge_Module' ) ) :
534
 
535
  }
536
 
537
- elseif ( $pagenow == 'post.php' && isset( $_GET['post'] ) && mycred_get_post_type( $_GET['post'] ) == MYCRED_BADGE_KEY ) {
538
 
539
  return 'edit.php?post_type=' . MYCRED_BADGE_KEY;
540
 
@@ -624,7 +624,7 @@ if ( ! class_exists( 'myCRED_Badge_Module' ) ) :
624
  echo '-';
625
 
626
  elseif ( $badge->main_image !== false )
627
- echo $badge->main_image;
628
 
629
  }
630
 
@@ -636,14 +636,14 @@ if ( ! class_exists( 'myCRED_Badge_Module' ) ) :
636
  if ( $badge->open_badge || $image === false )
637
  echo '-';
638
  else
639
- echo $image;
640
 
641
  }
642
 
643
  // Badge Requirements
644
  elseif ( $column_name == 'badge-reqs' ) {
645
 
646
- echo mycred_display_badge_requirements( $badge_id );
647
 
648
  }
649
 
@@ -655,7 +655,7 @@ if ( ! class_exists( 'myCRED_Badge_Module' ) ) :
655
  echo 0;
656
 
657
  else
658
- echo $badge->earnedby;
659
 
660
  }
661
 
@@ -664,7 +664,7 @@ if ( ! class_exists( 'myCRED_Badge_Module' ) ) :
664
 
665
  $badge = mycred_get_badge_type( $badge_id );
666
 
667
- echo $badge == false ? 'No Acheivement Type' : $badge;
668
 
669
  }
670
 
@@ -929,9 +929,9 @@ th#badge-users { width: 10%; }
929
 
930
  <?php do_action( 'mycred_edit_badge_before_actions', $post ); ?>
931
 
932
- <input type="hidden" name="mycred-badge-edit" value="<?php echo wp_create_nonce( 'edit-mycred-badge' ); ?>" />
933
- <input type="button" id="mycred-assign-badge-connections"<?php if ( $manual_badge || $post->post_status != 'publish' ) echo ' disabled="disabled"'; ?> value="<?php _e( 'Assign Badge', 'mycred' ); ?>" class="button button-secondary mycred-badge-action-button" data-action="mycred-assign-badge" data-token="<?php echo wp_create_nonce( 'mycred-assign-badge' ); ?>" />
934
- <input type="button" id="mycred-remove-badge-connections"<?php if ( $post->post_status != 'publish' ) echo ' disabled="disabled"'; ?> value="<?php _e( 'Remove Connections', 'mycred' ); ?>" class="button button-secondary mycred-badge-action-button" data-action="mycred-remove-connections" data-token="<?php echo wp_create_nonce( 'mycred-remove-badge-connection' ); ?>" />
935
 
936
  <?php do_action( 'mycred_edit_badge_after_actions', $post ); ?>
937
 
@@ -947,7 +947,7 @@ th#badge-users { width: 10%; }
947
  data : {
948
  action : button.attr( 'data-action' ),
949
  token : button.attr( 'data-token' ),
950
- badge_id : <?php echo $post->ID; ?>
951
  },
952
  dataType : "JSON",
953
  url : ajaxurl,
@@ -970,7 +970,7 @@ th#badge-users { width: 10%; }
970
 
971
  </div>
972
  <div id="mycred-manual-badge" class="seperate-bottom">
973
- <label for="mycred-badge-is-manual"><input type="checkbox" name="mycred_badge[manual]" id="mycred-badge-is-manual"<?php if ( $manual_badge ) echo ' checked="checked"'; ?> value="1" /> <?php _e( 'This badge is manually awarded.', 'mycred' ); ?></label>
974
  </div>
975
  <?php
976
 
@@ -998,16 +998,16 @@ th#badge-users { width: 10%; }
998
  <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
999
  <div class="default-image text-center seperate-bottom">
1000
  <div class="default-image-wrapper image-wrapper<?php if ( $default_image == '' ) echo ' empty dashicons'; ?>">
1001
- <?php echo $default_image; ?>
1002
  <input type="hidden" name="mycred_badge[main_image]" id="badge-main-image-id" value="<?php if ( $attachment ) echo esc_attr( $di ); ?>" />
1003
  <input type="hidden" name="mycred_badge[main_image_url]" id="badge-main-image-url" value="<?php if ( $di != '' && strpos( '://', $di ) !== false ) echo esc_attr( $default_image ); ?>" />
1004
  </div>
1005
  <div class="level-image-actions">
1006
- <button type="button" class="button button-secondary" id="badges-change-default-image" data-do="<?php if ( $default_image == '' ) echo 'set'; else echo 'change'; ?>"><?php if ( $default_image == '' ) _e( 'Set Image', 'mycred' ); else _e( 'Change Image', 'mycred' ); ?></button>
1007
- <button type="button" class="button button-secondary <?php echo ( ( ! $attachment ) ? 'hidden' : '' ); ?>" id="badges-remove-default-image"><?php _e( 'Remove Image', 'mycred' ); ?></button>
1008
  </div>
1009
  </div>
1010
- <span class="description"><?php _e( 'Optional image to show when a user has not earned this badge.', 'mycred' ); ?></span>
1011
  </div>
1012
  </div>
1013
  <?php
502
 
503
  }
504
 
505
+ elseif ( $pagenow == 'post.php' && isset( $_GET['post'] ) && mycred_get_post_type( sanitize_key( $_GET['post'] ) ) == MYCRED_BADGE_KEY ) {
506
 
507
  return MYCRED_MAIN_SLUG;
508
 
534
 
535
  }
536
 
537
+ elseif ( $pagenow == 'post.php' && isset( $_GET['post'] ) && mycred_get_post_type( sanitize_key( $_GET['post'] ) ) == MYCRED_BADGE_KEY ) {
538
 
539
  return 'edit.php?post_type=' . MYCRED_BADGE_KEY;
540
 
624
  echo '-';
625
 
626
  elseif ( $badge->main_image !== false )
627
+ echo wp_kses_post($badge->main_image);
628
 
629
  }
630
 
636
  if ( $badge->open_badge || $image === false )
637
  echo '-';
638
  else
639
+ echo wp_kses_post($image);
640
 
641
  }
642
 
643
  // Badge Requirements
644
  elseif ( $column_name == 'badge-reqs' ) {
645
 
646
+ echo wp_kses_post( mycred_display_badge_requirements( $badge_id ) );
647
 
648
  }
649
 
655
  echo 0;
656
 
657
  else
658
+ echo esc_html( $badge->earnedby );
659
 
660
  }
661
 
664
 
665
  $badge = mycred_get_badge_type( $badge_id );
666
 
667
+ echo esc_html( $badge == false ? 'No Acheivement Type' : $badge );
668
 
669
  }
670
 
929
 
930
  <?php do_action( 'mycred_edit_badge_before_actions', $post ); ?>
931
 
932
+ <input type="hidden" name="mycred-badge-edit" value="<?php echo esc_attr( wp_create_nonce( 'edit-mycred-badge' ) ); ?>" />
933
+ <input type="button" id="mycred-assign-badge-connections"<?php if ( $manual_badge || $post->post_status != 'publish' ) echo ' disabled="disabled"'; ?> value="<?php esc_attr_e( 'Assign Badge', 'mycred' ); ?>" class="button button-secondary mycred-badge-action-button" data-action="mycred-assign-badge" data-token="<?php echo esc_attr( wp_create_nonce( 'mycred-assign-badge' ) ); ?>" />
934
+ <input type="button" id="mycred-remove-badge-connections"<?php if ( $post->post_status != 'publish' ) echo ' disabled="disabled"'; ?> value="<?php esc_attr_e( 'Remove Connections', 'mycred' ); ?>" class="button button-secondary mycred-badge-action-button" data-action="mycred-remove-connections" data-token="<?php echo esc_attr( wp_create_nonce( 'mycred-remove-badge-connection' ) ); ?>" />
935
 
936
  <?php do_action( 'mycred_edit_badge_after_actions', $post ); ?>
937
 
947
  data : {
948
  action : button.attr( 'data-action' ),
949
  token : button.attr( 'data-token' ),
950
+ badge_id : <?php echo esc_js( $post->ID ); ?>
951
  },
952
  dataType : "JSON",
953
  url : ajaxurl,
970
 
971
  </div>
972
  <div id="mycred-manual-badge" class="seperate-bottom">
973
+ <label for="mycred-badge-is-manual"><input type="checkbox" name="mycred_badge[manual]" id="mycred-badge-is-manual" <?php checked( $manual_badge );?> value="1" /> <?php esc_html_e( 'This badge is manually awarded.', 'mycred' ); ?></label>
974
  </div>
975
  <?php
976
 
998
  <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
999
  <div class="default-image text-center seperate-bottom">
1000
  <div class="default-image-wrapper image-wrapper<?php if ( $default_image == '' ) echo ' empty dashicons'; ?>">
1001
+ <?php echo wp_kses_post($default_image); ?>
1002
  <input type="hidden" name="mycred_badge[main_image]" id="badge-main-image-id" value="<?php if ( $attachment ) echo esc_attr( $di ); ?>" />
1003
  <input type="hidden" name="mycred_badge[main_image_url]" id="badge-main-image-url" value="<?php if ( $di != '' && strpos( '://', $di ) !== false ) echo esc_attr( $default_image ); ?>" />
1004
  </div>
1005
  <div class="level-image-actions">
1006
+ <button type="button" class="button button-secondary" id="badges-change-default-image" data-do="<?php if ( $default_image == '' ) echo 'set'; else echo 'change'; ?>"><?php if ( $default_image == '' ) esc_html_e( 'Set Image', 'mycred' ); else esc_html_e( 'Change Image', 'mycred' ); ?></button>
1007
+ <button type="button" class="button button-secondary <?php echo ( ( ! $attachment ) ? 'hidden' : '' ); ?>" id="badges-remove-default-image"><?php esc_html_e( 'Remove Image', 'mycred' ); ?></button>
1008
  </div>
1009
  </div>
1010
+ <span class="description"><?php esc_html_e( 'Optional image to show when a user has not earned this badge.', 'mycred' ); ?></span>
1011
  </div>
1012
  </div>
1013
  <?php
addons/buy-creds/abstracts/mycred-abstract-payment-gateway.php CHANGED
@@ -2252,11 +2252,11 @@ if (! class_exists('myCRED_Payment_Gateway') ) :
2252
  {
2253
 
2254
  if ($method == 'POST' ) {
2255
- $post_id = $_POST[ $sales_data_key ];
2256
  } elseif ($method == 'GET' ) {
2257
- $post_id = $_GET[ $sales_data_key ];
2258
  } else {
2259
- $post_id = $_REQUEST[ $sales_data_key ];
2260
  }
2261
 
2262
  $pending_payment = $this->get_pending_payment($post_id);
@@ -2266,11 +2266,11 @@ if (! class_exists('myCRED_Payment_Gateway') ) :
2266
  $result = true;
2267
 
2268
  if ($method == 'POST' ) {
2269
- $price = $_POST[ $cost_key ];
2270
  } elseif ($method == 'GET' ) {
2271
- $price = $_GET[ $cost_key ];
2272
  } else {
2273
- $price = $_REQUEST[ $cost_key ];
2274
  }
2275
 
2276
  if ($result === true && $pending_payment['cost'] != $price ) {
@@ -2282,11 +2282,11 @@ if (! class_exists('myCRED_Payment_Gateway') ) :
2282
  }
2283
 
2284
  if ($method == 'POST' ) {
2285
- $transaction_id = $_POST[ $transactionid_key ];
2286
  } elseif ($method == 'GET' ) {
2287
- $transaction_id = $_GET[ $transactionid_key ];
2288
  } else {
2289
- $transaction_id = $_REQUEST[ $transactionid_key ];
2290
  }
2291
 
2292
  if ($result === true && ! $this->transaction_id_is_unique($transaction_id) ) {
2252
  {
2253
 
2254
  if ($method == 'POST' ) {
2255
+ $post_id = absint( $_POST[ $sales_data_key ] );
2256
  } elseif ($method == 'GET' ) {
2257
+ $post_id = absint( $_GET[ $sales_data_key ] );
2258
  } else {
2259
+ $post_id = absint( $_REQUEST[ $sales_data_key ] );
2260
  }
2261
 
2262
  $pending_payment = $this->get_pending_payment($post_id);
2266
  $result = true;
2267
 
2268
  if ($method == 'POST' ) {
2269
+ $price = floatval( $_POST[ $cost_key ] );
2270
  } elseif ($method == 'GET' ) {
2271
+ $price = floatval( $_GET[ $cost_key ] );
2272
  } else {
2273
+ $price = floatval( $_REQUEST[ $cost_key ] );
2274
  }
2275
 
2276
  if ($result === true && $pending_payment['cost'] != $price ) {
2282
  }
2283
 
2284
  if ($method == 'POST' ) {
2285
+ $transaction_id = sanitize_title( $_POST[ $transactionid_key ] );
2286
  } elseif ($method == 'GET' ) {
2287
+ $transaction_id = sanitize_title( $_GET[ $transactionid_key ] );
2288
  } else {
2289
+ $transaction_id = sanitize_title( $_REQUEST[ $transactionid_key ] );
2290
  }
2291
 
2292
  if ($result === true && ! $this->transaction_id_is_unique($transaction_id) ) {
addons/buy-creds/gateways/netbilling.php CHANGED
@@ -103,13 +103,13 @@ if (! class_exists('myCRED_NETbilling') ) :
103
 
104
  // Check amount paid
105
  if ($_REQUEST['Ecom_Cost_Total'] != $pending_payment->cost ) {
106
- $new_call[] = sprintf(__('Price mismatch. Expected: %s Received: %s', 'mycred'), $pending_payment->cost, $_REQUEST['Ecom_Cost_Total']);
107
  $errors = true;
108
  }
109
 
110
  // Check status
111
  if ($_REQUEST['Ecom_Ezic_Response_StatusCode'] != 1 ) {
112
- $new_call[] = sprintf(__('Payment not completed. Received: %s', 'mycred'), $_REQUEST['Ecom_Ezic_Response_StatusCode']);
113
  $errors = true;
114
  }
115
 
@@ -117,7 +117,7 @@ if (! class_exists('myCRED_NETbilling') ) :
117
  if ($errors === false ) {
118
 
119
  // If account is credited, delete the post and it's comments.
120
- if ($this->complete_payment($pending_payment, $_REQUEST['Ecom_Ezic_Response_TransactionID']) ) {
121
  $this->trash_pending_payment($pending_post_id);
122
  } else {
123
  $new_call[] = __('Failed to credit users account.', 'mycred');
103
 
104
  // Check amount paid
105
  if ($_REQUEST['Ecom_Cost_Total'] != $pending_payment->cost ) {
106
+ $new_call[] = sprintf(__('Price mismatch. Expected: %s Received: %s', 'mycred'), $pending_payment->cost, floatval( $_REQUEST['Ecom_Cost_Total'] ));
107
  $errors = true;
108
  }
109
 
110
  // Check status
111
  if ($_REQUEST['Ecom_Ezic_Response_StatusCode'] != 1 ) {
112
+ $new_call[] = sprintf(__('Payment not completed. Received: %s', 'mycred'), intval( $_REQUEST['Ecom_Ezic_Response_StatusCode'] ));
113
  $errors = true;
114
  }
115
 
117
  if ($errors === false ) {
118
 
119
  // If account is credited, delete the post and it's comments.
120
+ if ($this->complete_payment($pending_payment, sanitize_title( $_REQUEST['Ecom_Ezic_Response_TransactionID'] )) ) {
121
  $this->trash_pending_payment($pending_post_id);
122
  } else {
123
  $new_call[] = __('Failed to credit users account.', 'mycred');
addons/cash-creds/abstracts/cashcred-abstract-payment-gateway.php CHANGED
@@ -727,10 +727,10 @@ if (! class_exists('myCRED_Cash_Payment_Gateway') ) :
727
  );
728
 
729
  foreach ( $months as $number => $text ) {
730
- echo '<option value="' . $number . '"';
731
  if ($selected == $number ) { echo ' selected="selected"';
732
  }
733
- echo '>' . $text . '</option>';
734
  }
735
 
736
  }
@@ -760,10 +760,10 @@ if (! class_exists('myCRED_Cash_Payment_Gateway') ) :
760
  }
761
 
762
  foreach ( $options as $key => $value ) {
763
- echo '<option value="' . $key . '"';
764
  if ($selected == $key ) { echo ' selected="selected"';
765
  }
766
- echo '>' . $value . '</option>';
767
  }
768
 
769
  }
727
  );
728
 
729
  foreach ( $months as $number => $text ) {
730
+ echo '<option value="' . esc_attr( $number ) . '"';
731
  if ($selected == $number ) { echo ' selected="selected"';
732
  }
733
+ echo '>' . esc_html( $text ) . '</option>';
734
  }
735
 
736
  }
760
  }
761
 
762
  foreach ( $options as $key => $value ) {
763
+ echo '<option value="' . esc_attr( $key ) . '"';
764
  if ($selected == $key ) { echo ' selected="selected"';
765
  }
766
+ echo '>' . esc_html( $value ) . '</option>';
767
  }
768
 
769
  }
addons/email-notices/myCRED-addon-email-notices.php CHANGED
@@ -940,7 +940,7 @@ if ( ! class_exists( 'myCRED_Email_Notice_Module' ) ) :
940
  else {
941
 
942
  $reference_list = array();
943
- $custom_reference = explode( ',', $_POST['mycred_email']['custom_reference'] );
944
 
945
  foreach ( $custom_reference as $reference_id ) {
946
 
940
  else {
941
 
942
  $reference_list = array();
943
+ $custom_reference = explode( ',', sanitize_text_field( $_POST['mycred_email']['custom_reference'] ) );
944
 
945
  foreach ( $custom_reference as $reference_id ) {
946
 
addons/stats/assets/js/Chart.js CHANGED
@@ -1,3767 +1,13269 @@
1
- /*
2
- * Chart.js
3
- * http://chartjs.org/
4
- * Version: 1.1
 
5
  */
6
- (function () {
7
-
8
- "use strict";
9
-
10
- //Declare root variable - window in the browser, global on the server
11
- var root = this,
12
- previous = root.Chart;
13
-
14
- //Occupy the global variable of Chart, and create a simple base class
15
- var Chart = function (context) {
16
- var chart = this;
17
- this.canvas = context.canvas;
18
-
19
- this.ctx = context;
20
-
21
- //Variables global to the chart
22
- var width = this.width = context.canvas.width;
23
- var height = this.height = context.canvas.height;
24
- this.aspectRatio = this.width / this.height;
25
- //High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
26
- helpers.retinaScale(this);
27
-
28
- return this;
29
  };
30
- //Globally expose the defaults to allow for user updating/changing
31
- Chart.defaults = {
32
- global: {
33
- // Boolean - Whether to animate the chart
34
- animation: true,
35
-
36
- // Number - Number of animation steps
37
- animationSteps: 60,
38
-
39
- // String - Animation easing effect
40
- animationEasing: "easeOutQuart",
41
-
42
- // Boolean - If we should show the scale at all
43
- showScale: true,
44
-
45
- // Boolean - If we want to override with a hard coded scale
46
- scaleOverride: false,
47
-
48
- // ** Required if scaleOverride is true **
49
- // Number - The number of steps in a hard coded scale
50
- scaleSteps: null,
51
- // Number - The value jump in the hard coded scale
52
- scaleStepWidth: null,
53
- // Number - The scale starting value
54
- scaleStartValue: null,
55
-
56
- // String - Colour of the scale line
57
- scaleLineColor: "rgba(0,0,0,.1)",
58
-
59
- // Number - Pixel width of the scale line
60
- scaleLineWidth: 1,
61
-
62
- // Boolean - Whether to show labels on the scale
63
- scaleShowLabels: true,
64
-
65
- // Interpolated JS string - can access value
66
- scaleLabel: "<%=value%>",
67
-
68
- // Boolean - Whether the scale should stick to integers, and not show any floats even if drawing space is there
69
- scaleIntegersOnly: true,
70
-
71
- // Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
72
- scaleBeginAtZero: false,
73
-
74
- // String - Scale label font declaration for the scale label
75
- scaleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
76
-
77
- // Number - Scale label font size in pixels
78
- scaleFontSize: 12,
79
-
80
- // String - Scale label font weight style
81
- scaleFontStyle: "normal",
82
-
83
- // String - Scale label font colour
84
- scaleFontColor: "#666",
85
-
86
- // Boolean - Limit number of x labels
87
- scaleLimitXLabels: false,
88
-
89
- // Number - Limit number of x labels to
90
- scaleLimitXLabelsTo: 32,
91
-
92
- // Boolean - whether or not the chart should be responsive and resize when the browser does.
93
- responsive: false,
94
-
95
- // Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
96
- maintainAspectRatio: true,
97
-
98
- // Boolean - Determines whether to draw tooltips on the canvas or not - attaches events to touchmove & mousemove
99
- showTooltips: true,
100
-
101
- // Array - Array of string names to attach tooltip events
102
- tooltipEvents: ["mousemove", "touchstart", "touchmove", "mouseout"],
103
-
104
- // String - Tooltip background colour
105
- tooltipFillColor: "rgba(0,0,0,0.8)",
106
-
107
- // String - Tooltip label font declaration for the scale label
108
- tooltipFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
109
-
110
- // Number - Tooltip label font size in pixels
111
- tooltipFontSize: 14,
112
-
113
- // String - Tooltip font weight style
114
- tooltipFontStyle: "normal",
115
-
116
- // String - Tooltip label font colour
117
- tooltipFontColor: "#fff",
118
-
119
- // String - Tooltip title font declaration for the scale label
120
- tooltipTitleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
121
-
122
- // Number - Tooltip title font size in pixels
123
- tooltipTitleFontSize: 14,
124
-
125
- // String - Tooltip title font weight style
126
- tooltipTitleFontStyle: "bold",
127
-
128
- // String - Tooltip title font colour
129
- tooltipTitleFontColor: "#fff",
130
-
131
- // Number - pixel width of padding around tooltip text
132
- tooltipYPadding: 6,
133
-
134
- // Number - pixel width of padding around tooltip text
135
- tooltipXPadding: 6,
136
-
137
- // Number - Size of the caret on the tooltip
138
- tooltipCaretSize: 8,
139
-
140
- // Number - Pixel radius of the tooltip border
141
- tooltipCornerRadius: 6,
142
-
143
- // Number - Pixel offset from point x to tooltip edge
144
- tooltipXOffset: 10,
145
-
146
- // String - Template string for single tooltips
147
- tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>",
148
-
149
- // String - Template string for single tooltips
150
- multiTooltipTemplate: "<%= value %>",
151
-
152
- // String - Colour behind the legend colour block
153
- multiTooltipKeyBackground: '#fff',
154
-
155
- // Function - Will fire on animation progression.
156
- onAnimationProgress: function (){},
157
-
158
- // Function - Will fire on animation completion.
159
- onAnimationComplete: function (){}
160
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  };
163
-
164
- //Create a dictionary of chart types, to allow for extension of existing types
165
- Chart.types = {};
166
-
167
- //Global Chart helpers object for utility methods and classes
168
- var helpers = Chart.helpers = {};
169
-
170
- //-- Basic js utility methods
171
- var each = helpers.each = function (loopable,callback,self) {
172
- var additionalArgs = Array.prototype.slice.call(arguments, 3);
173
- // Check to see if null or undefined firstly.
174
- if (loopable) {
175
- if (loopable.length === +loopable.length) {
176
- var i;
177
- for (i=0; i<loopable.length; i++){
178
- callback.apply(self,[loopable[i], i].concat(additionalArgs));
179
- }
180
- }
181
- else{
182
- for (var item in loopable){
183
- callback.apply(self,[loopable[item],item].concat(additionalArgs));
184
- }
185
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  }
187
- },
188
- clone = helpers.clone = function (obj) {
189
- var objClone = {};
190
- each(
191
- obj,function (value,key) {
192
- if (obj.hasOwnProperty(key)) { objClone[key] = value;
193
- }
194
- }
195
- );
196
- return objClone;
197
- },
198
- extend = helpers.extend = function (base) {
199
- each(
200
- Array.prototype.slice.call(arguments,1), function (extensionObject) {
201
- each(
202
- extensionObject,function (value,key) {
203
- if (extensionObject.hasOwnProperty(key)) { base[key] = value;
204
- }
205
- }
206
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  }
208
- );
209
- return base;
210
- },
211
- merge = helpers.merge = function (base,master) {
212
- //Merge properties in left object over to a shallow clone of object right.
213
- var args = Array.prototype.slice.call(arguments,0);
214
- args.unshift({});
215
- return extend.apply(null, args);
216
- },
217
- indexOf = helpers.indexOf = function (arrayToSearch, item) {
218
- if (Array.prototype.indexOf) {
219
- return arrayToSearch.indexOf(item);
220
  }
221
- else{
222
- for (var i = 0; i < arrayToSearch.length; i++) {
223
- if (arrayToSearch[i] === item) { return i;
224
- }
225
- }
226
- return -1;
 
 
 
 
 
 
 
 
 
 
227
  }
228
- },
229
- where = helpers.where = function (collection, filterCallback) {
230
- var filtered = [];
231
-
232
- helpers.each(
233
- collection, function (item) {
234
- if (filterCallback(item)) {
235
- filtered.push(item);
236
- }
237
- }
238
- );
239
-
240
- return filtered;
241
- },
242
- findNextWhere = helpers.findNextWhere = function (arrayToSearch, filterCallback, startIndex) {
243
- // Default to start of the array
244
- if (!startIndex) {
245
- startIndex = -1;
246
  }
247
- for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
248
- var currentItem = arrayToSearch[i];
249
- if (filterCallback(currentItem)) {
250
- return currentItem;
251
- }
 
 
 
 
 
252
  }
253
- },
254
- findPreviousWhere = helpers.findPreviousWhere = function (arrayToSearch, filterCallback, startIndex) {
255
- // Default to end of the array
256
- if (!startIndex) {
257
- startIndex = arrayToSearch.length;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  }
259
- for (var i = startIndex - 1; i >= 0; i--) {
260
- var currentItem = arrayToSearch[i];
261
- if (filterCallback(currentItem)) {
262
- return currentItem;
263
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  }
265
- },
266
- inherits = helpers.inherits = function (extensions) {
267
- //Basic javascript inheritance based on the model created in Backbone.js
268
- var parent = this;
269
- var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function () {
270
- return parent.apply(this, arguments); };
271
-
272
- var Surrogate = function () {
273
- this.constructor = ChartElement;};
274
- Surrogate.prototype = parent.prototype;
275
- ChartElement.prototype = new Surrogate();
276
-
277
- ChartElement.extend = inherits;
278
-
279
- if (extensions) { extend(ChartElement.prototype, extensions);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  }
281
-
282
- ChartElement.__super__ = parent.prototype;
283
-
284
- return ChartElement;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  },
286
- noop = helpers.noop = function (){},
287
- uid = helpers.uid = (function () {
288
- var id=0;
289
- return function () {
290
- return "chart-" + id++;
291
- };
292
- })(),
293
- warn = helpers.warn = function (str) {
294
- //Method for warning of errors
295
- if (window.console && typeof window.console.warn == "function") { console.warn(str);
 
 
296
  }
 
 
297
  },
298
- amd = helpers.amd = (typeof define == 'function' && define.amd),
299
- //-- Math methods
300
- isNumber = helpers.isNumber = function (n) {
301
- return !isNaN(parseFloat(n)) && isFinite(n);
302
  },
303
- max = helpers.max = function (array) {
304
- return Math.max.apply(Math, array);
 
 
305
  },
306
- min = helpers.min = function (array) {
307
- return Math.min.apply(Math, array);
308
  },
309
- cap = helpers.cap = function (valueToCap,maxValue,minValue) {
310
- if(isNumber(maxValue)) {
311
- if(valueToCap > maxValue ) {
312
- return maxValue;
313
- }
314
- }
315
- else if(isNumber(minValue)) {
316
- if (valueToCap < minValue ) {
317
- return minValue;
318
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  }
320
- return valueToCap;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  },
322
- getDecimalPlaces = helpers.getDecimalPlaces = function (num) {
323
- if (num%1!==0 && isNumber(num)) {
324
- return num.toString().split(".")[1].length;
325
- }
326
- else {
327
- return 0;
328
- }
329
  },
330
- toRadians = helpers.radians = function (degrees) {
331
- return degrees * (Math.PI/180);
332
  },
333
- // Gets the angle from vertical upright to the point about a centre.
334
- getAngleFromPoint = helpers.getAngleFromPoint = function (centrePoint, anglePoint) {
335
- var distanceFromXCenter = anglePoint.x - centrePoint.x,
336
- distanceFromYCenter = anglePoint.y - centrePoint.y,
337
- radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
338
-
339
-
340
- var angle = Math.PI * 2 + Math.atan2(distanceFromYCenter, distanceFromXCenter);
341
-
342
- //If the segment is in the top left quadrant, we need to add another rotation to the angle
343
- if (distanceFromXCenter < 0 && distanceFromYCenter < 0) {
344
- angle += Math.PI*2;
345
- }
346
-
347
- return {
348
- angle: angle,
349
- distance: radialDistanceFromCenter
350
- };
351
  },
352
- aliasPixel = helpers.aliasPixel = function (pixelWidth) {
353
- return (pixelWidth % 2 === 0) ? 0 : 0.5;
354
  },
355
- splineCurve = helpers.splineCurve = function (FirstPoint,MiddlePoint,AfterPoint,t) {
356
- //Props to Rob Spencer at scaled innovation for his post on splining between points
357
- //http://scaledinnovation.com/analytics/splines/aboutSplines.html
358
- var d01=Math.sqrt(Math.pow(MiddlePoint.x-FirstPoint.x,2)+Math.pow(MiddlePoint.y-FirstPoint.y,2)),
359
- d12=Math.sqrt(Math.pow(AfterPoint.x-MiddlePoint.x,2)+Math.pow(AfterPoint.y-MiddlePoint.y,2)),
360
- fa=t*d01/(d01+d12),// scaling factor for triangle Ta
361
- fb=t*d12/(d01+d12);
362
- return {
363
- inner : {
364
- x : MiddlePoint.x-fa*(AfterPoint.x-FirstPoint.x),
365
- y : MiddlePoint.y-fa*(AfterPoint.y-FirstPoint.y)
366
- },
367
- outer : {
368
- x: MiddlePoint.x+fb*(AfterPoint.x-FirstPoint.x),
369
- y : MiddlePoint.y+fb*(AfterPoint.y-FirstPoint.y)
370
- }
371
- };
372
  },
373
- calculateOrderOfMagnitude = helpers.calculateOrderOfMagnitude = function (val) {
374
- return Math.floor(Math.log(val) / Math.LN10);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
375
  },
376
- calculateScaleRange = helpers.calculateScaleRange = function (valuesArray, drawingSize, textSize, startFromZero, integersOnly) {
377
-
378
- //Set a minimum step of two - a point at the top of the graph, and a point at the base
379
- var minSteps = 2,
380
- maxSteps = Math.floor(drawingSize/(textSize * 1.5)),
381
- skipFitting = (minSteps >= maxSteps);
382
-
383
- var maxValue = max(valuesArray),
384
- minValue = Number.POSITIVE_INFINITY;
385
-
386
- // Ignore nulls since we don't construct points for them (since Math.min treats them as 0)
387
- each(
388
- valuesArray, function ( value ) {
389
- if (value < minValue && value != null) {
390
- minValue = value;
391
- }
392
- }
393
- );
394
-
395
- // We need some degree of seperation here to calculate the scales if all the values are the same
396
- // Adding/minusing 0.5 will give us a range of 1.
397
- if (maxValue === minValue) {
398
- maxValue += 0.5;
399
- // So we don't end up with a graph with a negative start value if we've said always start from zero
400
- if (minValue >= 0.5 && !startFromZero) {
401
- minValue -= 0.5;
402
- }
403
- else{
404
- // Make up a whole number above the values
405
- maxValue += 0.5;
406
- }
407
- }
408
-
409
- var valueRange = Math.abs(maxValue - minValue),
410
- rangeOrderOfMagnitude = calculateOrderOfMagnitude(valueRange),
411
- graphMax = Math.ceil(maxValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),
412
- graphMin = (startFromZero) ? 0 : Math.floor(minValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),
413
- graphRange = graphMax - graphMin,
414
- stepValue = Math.pow(10, rangeOrderOfMagnitude),
415
- numberOfSteps = Math.round(graphRange / stepValue);
416
-
417
- //If we have more space on the graph we'll use it to give more definition to the data
418
- while((numberOfSteps > maxSteps || (numberOfSteps * 2) < maxSteps) && !skipFitting) {
419
- if(numberOfSteps > maxSteps) {
420
- stepValue *=2;
421
- numberOfSteps = Math.round(graphRange/stepValue);
422
- // Don't ever deal with a decimal number of steps - cancel fitting and just use the minimum number of steps.
423
- if (numberOfSteps % 1 !== 0) {
424
- skipFitting = true;
425
- }
426
- }
427
- //We can fit in double the amount of scale points on the scale
428
- else{
429
- //If user has declared ints only, and the step value isn't a decimal
430
- if (integersOnly && rangeOrderOfMagnitude >= 0) {
431
- //If the user has said integers only, we need to check that making the scale more granular wouldn't make it a float
432
- if((numberOfSteps * 5) < maxSteps && stepValue/5 % 1 === 0) {
433
- stepValue /=5;
434
- numberOfSteps = Math.round(graphRange/stepValue);
435
- }
436
- else if(stepValue/2 % 1 === 0) {
437
- stepValue /=2;
438
- numberOfSteps = Math.round(graphRange/stepValue);
439
- }
440
- //If it would make it a float break out of the loop
441
- else{
442
- break;
443
- }
444
- }
445
- //If the scale doesn't have to be an int, make the scale more granular anyway.
446
- else{
447
- stepValue /=2;
448
- numberOfSteps = Math.round(graphRange/stepValue);
449
- }
450
-
451
- }
452
- }
453
-
454
- if (skipFitting) {
455
- numberOfSteps = minSteps;
456
- stepValue = graphRange / numberOfSteps;
457
- }
458
-
459
- // Drop unnecessary steps
460
- if(!startFromZero) {
461
- while(minValue > graphMin + stepValue) {
462
- numberOfSteps--;
463
- graphMin += stepValue;
464
- }
465
- }
466
-
467
- while(maxValue < graphMax - stepValue) {
468
- numberOfSteps--;
469
- graphMax -= stepValue;
470
- }
471
-
472
- return {
473
- steps : numberOfSteps,
474
- stepValue : stepValue,
475
- min : graphMin,
476
- max : graphMin + (numberOfSteps * stepValue)
477
- };
478
-
479
  },
480
- /* jshint ignore:start */
481
- // Blows up jshint errors based on the new Function constructor
482
- //Templating methods
483
- //Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/
484
- template = helpers.template = function (templateString, valuesObject) {
485
- // If templateString is function rather than string-template - call the function for valuesObject
486
- if(templateString instanceof Function) {
487
- return templateString(valuesObject);
488
- }
489
-
490
- var cache = {};
491
- function tmpl(str, data)
492
- {
493
- // Figure out if we're getting a template, or if we need to
494
- // load the template - and be sure to cache the result.
495
- var fn = !/\W/.test(str) ?
496
- cache[str] = cache[str] :
497
-
498
- // Generate a reusable function that will serve as a template
499
- // generator (and which will be cached).
500
- new Function(
501
- "obj",
502
- "var p=[],print=function(){p.push.apply(p,arguments);};" +
503
-
504
- // Introduce the data as local variables using with(){}
505
- "with(obj){p.push('" +
506
-
507
- // Convert the template into pure JavaScript
508
- str
509
- .replace(/[\r\t\n]/g, " ")
510
- .split("<%").join("\t")
511
- .replace(/((^|%>)[^\t]*)'/g, "$1\r")
512
- .replace(/\t=(.*?)%>/g, "',$1,'")
513
- .split("\t").join("');")
514
- .split("%>").join("p.push('")
515
- .split("\r").join("\\'") +
516
- "');}return p.join('');"
517
- );
518
-
519
- // Provide some basic currying to the user
520
- return data ? fn(data) : fn;
521
- }
522
- return tmpl(templateString,valuesObject);
523
  },
524
- /* jshint ignore:end */
525
- generateLabels = helpers.generateLabels = function (templateString,numberOfSteps,graphMin,stepValue) {
526
- var labelsArray = new Array(numberOfSteps);
527
- if (labelTemplateString) {
528
- each(
529
- labelsArray,function (val,index) {
530
- labelsArray[index] = template(templateString,{value: (graphMin + (stepValue*(index+1)))});
531
- }
532
- );
533
- }
534
- return labelsArray;
535
  },
536
- //--Animation methods
537
- //Easing functions adapted from Robert Penner's easing equations
538
- //http://www.robertpenner.com/easing/
539
- easingEffects = helpers.easingEffects = {
540
- linear: function (t) {
541
- return t;
542
- },
543
- easeInQuad: function (t) {
544
- return t * t;
545
- },
546
- easeOutQuad: function (t) {
547
- return -1 * t * (t - 2);
548
- },
549
- easeInOutQuad: function (t) {
550
- if ((t /= 1 / 2) < 1) { return 1 / 2 * t * t;
551
- }
552
- return -1 / 2 * ((--t) * (t - 2) - 1);
553
- },
554
- easeInCubic: function (t) {
555
- return t * t * t;
556
- },
557
- easeOutCubic: function (t) {
558
- return 1 * ((t = t / 1 - 1) * t * t + 1);
559
- },
560
- easeInOutCubic: function (t) {
561
- if ((t /= 1 / 2) < 1) { return 1 / 2 * t * t * t;
562
- }
563
- return 1 / 2 * ((t -= 2) * t * t + 2);
564
- },
565
- easeInQuart: function (t) {
566
- return t * t * t * t;
567
- },
568
- easeOutQuart: function (t) {
569
- return -1 * ((t = t / 1 - 1) * t * t * t - 1);
570
- },
571
- easeInOutQuart: function (t) {
572
- if ((t /= 1 / 2) < 1) { return 1 / 2 * t * t * t * t;
573
- }
574
- return -1 / 2 * ((t -= 2) * t * t * t - 2);
575
- },
576
- easeInQuint: function (t) {
577
- return 1 * (t /= 1) * t * t * t * t;
578
- },
579
- easeOutQuint: function (t) {
580
- return 1 * ((t = t / 1 - 1) * t * t * t * t + 1);
581
- },
582
- easeInOutQuint: function (t) {
583
- if ((t /= 1 / 2) < 1) { return 1 / 2 * t * t * t * t * t;
584
- }
585
- return 1 / 2 * ((t -= 2) * t * t * t * t + 2);
586
- },
587
- easeInSine: function (t) {
588
- return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;
589
- },
590
- easeOutSine: function (t) {
591
- return 1 * Math.sin(t / 1 * (Math.PI / 2));
592
- },
593
- easeInOutSine: function (t) {
594
- return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);
595
- },
596
- easeInExpo: function (t) {
597
- return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));
598
- },
599
- easeOutExpo: function (t) {
600
- return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);
601
- },
602
- easeInOutExpo: function (t) {
603
- if (t === 0) { return 0;
604
- }
605
- if (t === 1) { return 1;
606
- }
607
- if ((t /= 1 / 2) < 1) { return 1 / 2 * Math.pow(2, 10 * (t - 1));
608
- }
609
- return 1 / 2 * (-Math.pow(2, -10 * --t) + 2);
610
- },
611
- easeInCirc: function (t) {
612
- if (t >= 1) { return t;
613
- }
614
- return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);
615
- },
616
- easeOutCirc: function (t) {
617
- return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);
618
- },
619
- easeInOutCirc: function (t) {
620
- if ((t /= 1 / 2) < 1) { return -1 / 2 * (Math.sqrt(1 - t * t) - 1);
621
- }
622
- return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);
623
- },
624
- easeInElastic: function (t) {
625
- var s = 1.70158;
626
- var p = 0;
627
- var a = 1;
628
- if (t === 0) { return 0;
629
- }
630
- if ((t /= 1) == 1) { return 1;
631
- }
632
- if (!p) { p = 1 * 0.3;
633
- }
634
- if (a < Math.abs(1)) {
635
- a = 1;
636
- s = p / 4;
637
- } else { s = p / (2 * Math.PI) * Math.asin(1 / a);
638
- }
639
- return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
640
- },
641
- easeOutElastic: function (t) {
642
- var s = 1.70158;
643
- var p = 0;
644
- var a = 1;
645
- if (t === 0) { return 0;
646
- }
647
- if ((t /= 1) == 1) { return 1;
648
- }
649
- if (!p) { p = 1 * 0.3;
650
- }
651
- if (a < Math.abs(1)) {
652
- a = 1;
653
- s = p / 4;
654
- } else { s = p / (2 * Math.PI) * Math.asin(1 / a);
655
- }
656
- return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;
657
- },
658
- easeInOutElastic: function (t) {
659
- var s = 1.70158;
660
- var p = 0;
661
- var a = 1;
662
- if (t === 0) { return 0;
663
- }
664
- if ((t /= 1 / 2) == 2) { return 1;
665
- }
666
- if (!p) { p = 1 * (0.3 * 1.5);
667
- }
668
- if (a < Math.abs(1)) {
669
- a = 1;
670
- s = p / 4;
671
- } else { s = p / (2 * Math.PI) * Math.asin(1 / a);
672
- }
673
- if (t < 1) { return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
674
- }
675
- return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;
676
- },
677
- easeInBack: function (t) {
678
- var s = 1.70158;
679
- return 1 * (t /= 1) * t * ((s + 1) * t - s);
680
- },
681
- easeOutBack: function (t) {
682
- var s = 1.70158;
683
- return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);
684
- },
685
- easeInOutBack: function (t) {
686
- var s = 1.70158;
687
- if ((t /= 1 / 2) < 1) { return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));
688
- }
689
- return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
690
- },
691
- easeInBounce: function (t) {
692
- return 1 - easingEffects.easeOutBounce(1 - t);
693
- },
694
- easeOutBounce: function (t) {
695
- if ((t /= 1) < (1 / 2.75)) {
696
- return 1 * (7.5625 * t * t);
697
- } else if (t < (2 / 2.75)) {
698
- return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);
699
- } else if (t < (2.5 / 2.75)) {
700
- return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);
701
- } else {
702
- return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);
703
- }
704
- },
705
- easeInOutBounce: function (t) {
706
- if (t < 1 / 2) { return easingEffects.easeInBounce(t * 2) * 0.5;
707
- }
708
- return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;
709
- }
710
  },
711
- //Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
712
- requestAnimFrame = helpers.requestAnimFrame = (function () {
713
- return window.requestAnimationFrame ||
714
- window.webkitRequestAnimationFrame ||
715
- window.mozRequestAnimationFrame ||
716
- window.oRequestAnimationFrame ||
717
- window.msRequestAnimationFrame ||
718
- function (callback) {
719
- return window.setTimeout(callback, 1000 / 60);
720
- };
721
- })(),
722
- cancelAnimFrame = helpers.cancelAnimFrame = (function () {
723
- return window.cancelAnimationFrame ||
724
- window.webkitCancelAnimationFrame ||
725
- window.mozCancelAnimationFrame ||
726
- window.oCancelAnimationFrame ||
727
- window.msCancelAnimationFrame ||
728
- function (callback) {
729
- return window.clearTimeout(callback, 1000 / 60);
730
- };
731
- })(),
732
- animationLoop = helpers.animationLoop = function (callback,totalSteps,easingString,onProgress,onComplete,chartInstance) {
733
-
734
- var currentStep = 0,
735
- easingFunction = easingEffects[easingString] || easingEffects.linear;
736
-
737
- var animationFrame = function () {
738
- currentStep++;
739
- var stepDecimal = currentStep/totalSteps;
740
- var easeDecimal = easingFunction(stepDecimal);
741
-
742
- callback.call(chartInstance,easeDecimal,stepDecimal, currentStep);
743
- onProgress.call(chartInstance,easeDecimal,stepDecimal);
744
- if (currentStep < totalSteps) {
745
- chartInstance.animationFrame = requestAnimFrame(animationFrame);
746
- } else{
747
- onComplete.apply(chartInstance);
748
- }
749
- };
750
- requestAnimFrame(animationFrame);
751
  },
752
- //-- DOM methods
753
- getRelativePosition = helpers.getRelativePosition = function (evt) {
754
- var mouseX, mouseY;
755
- var e = evt.originalEvent || evt,
756
- canvas = evt.currentTarget || evt.srcElement,
757
- boundingRect = canvas.getBoundingClientRect();
758
-
759
- if (e.touches) {
760
- mouseX = e.touches[0].clientX - boundingRect.left;
761
- mouseY = e.touches[0].clientY - boundingRect.top;
762
-
763
- }
764
- else{
765
- mouseX = e.clientX - boundingRect.left;
766
- mouseY = e.clientY - boundingRect.top;
767
- }
768
-
769
- return {
770
- x : mouseX,
771
- y : mouseY
772
- };
773
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
774
  },
775
- addEvent = helpers.addEvent = function (node,eventType,method) {
776
- if (node.addEventListener) {
777
- node.addEventListener(eventType,method);
778
- } else if (node.attachEvent) {
779
- node.attachEvent("on"+eventType, method);
780
- } else {
781
- node["on"+eventType] = method;
782
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
783
  },
784
- removeEvent = helpers.removeEvent = function (node, eventType, handler) {
785
- if (node.removeEventListener) {
786
- node.removeEventListener(eventType, handler, false);
787
- } else if (node.detachEvent) {
788
- node.detachEvent("on"+eventType,handler);
789
- } else{
790
- node["on" + eventType] = noop;
791
- }
792
  },
793
- bindEvents = helpers.bindEvents = function (chartInstance, arrayOfEvents, handler) {
794
- // Create the events object if it's not already present
795
- if (!chartInstance.events) { chartInstance.events = {};
796
- }
797
-
798
- each(
799
- arrayOfEvents,function (eventName) {
800
- chartInstance.events[eventName] = function () {
801
- handler.apply(chartInstance, arguments);
802
- };
803
- addEvent(chartInstance.chart.canvas,eventName,chartInstance.events[eventName]);
804
- }
805
- );
806
  },
807
- unbindEvents = helpers.unbindEvents = function (chartInstance, arrayOfEvents) {
808
- each(
809
- arrayOfEvents, function (handler,eventName) {
810
- removeEvent(chartInstance.chart.canvas, eventName, handler);
811
- }
812
- );
813
  },
814
- getMaximumWidth = helpers.getMaximumWidth = function (domNode) {
815
- var container = domNode.parentNode;
816
- // TODO = check cross browser stuff with this.
817
- return container.clientWidth;
818
  },
819
- getMaximumHeight = helpers.getMaximumHeight = function (domNode) {
820
- var container = domNode.parentNode;
821
- // TODO = check cross browser stuff with this.
822
- return container.clientHeight;
 
 
823
  },
824
- getMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support
825
- retinaScale = helpers.retinaScale = function (chart) {
826
- var ctx = chart.ctx,
827
- width = chart.canvas.width,
828
- height = chart.canvas.height;
829
-
830
- if (window.devicePixelRatio) {
831
- ctx.canvas.style.width = width + "px";
832
- ctx.canvas.style.height = height + "px";
833
- ctx.canvas.height = height * window.devicePixelRatio;
834
- ctx.canvas.width = width * window.devicePixelRatio;
835
- ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
836
- }
837
  },
838
- //-- Canvas methods
839
- clear = helpers.clear = function (chart) {
840
- chart.ctx.clearRect(0,0,chart.width,chart.height);
841
  },
842
- fontString = helpers.fontString = function (pixelSize,fontStyle,fontFamily) {
843
- return fontStyle + " " + pixelSize+"px " + fontFamily;
844
  },
845
- longestText = helpers.longestText = function (ctx,font,arrayOfStrings) {
846
- ctx.font = font;
847
- var longest = 0;
848
- each(
849
- arrayOfStrings,function (string) {
850
- var textWidth = ctx.measureText(string).width;
851
- longest = (textWidth > longest) ? textWidth : longest;
852
- }
853
- );
854
- return longest;
855
  },
856
- drawRoundedRectangle = helpers.drawRoundedRectangle = function (ctx,x,y,width,height,radius) {
857
- ctx.beginPath();
858
- ctx.moveTo(x + radius, y);
859
- ctx.lineTo(x + width - radius, y);
860
- ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
861
- ctx.lineTo(x + width, y + height - radius);
862
- ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
863
- ctx.lineTo(x + radius, y + height);
864
- ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
865
- ctx.lineTo(x, y + radius);
866
- ctx.quadraticCurveTo(x, y, x + radius, y);
867
- ctx.closePath();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
868
  };
869
-
870
-
871
- //Store a reference to each instance - allowing us to globally resize chart instances on window resize.
872
- //Destroy method on the chart will remove the instance of the chart from this reference.
873
- Chart.instances = {};
874
-
875
- Chart.Type = function (data,options,chart) {
876
- this.options = options;
877
- this.chart = chart;
878
- this.id = uid();
879
- //Add the chart instance to the global namespace
880
- Chart.instances[this.id] = this;
881
-
882
- // Initialize is always called when a chart type is created
883
- // By default it is a no op, but it should be extended
884
- if (options.responsive) {
885
- this.resize();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
886
  }
887
- this.initialize.call(this,data);
888
- };
889
-
890
- //Core methods that'll be a part of every chart type
891
- extend(
892
- Chart.Type.prototype,{
893
- initialize : function () {
894
- return this;},
895
- clear : function () {
896
- clear(this.chart);
897
- return this;
898
- },
899
- stop : function () {
900
- // Stops any current animation loop occuring
901
- helpers.cancelAnimFrame.call(root, this.animationFrame);
902
- return this;
903
- },
904
- resize : function (callback) {
905
- this.stop();
906
- var canvas = this.chart.canvas,
907
- newWidth = getMaximumWidth(this.chart.canvas),
908
- newHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas);
909
-
910
- canvas.width = this.chart.width = newWidth;
911
- canvas.height = this.chart.height = newHeight;
912
-
913
- retinaScale(this.chart);
914
-
915
- if (typeof callback === "function") {
916
- callback.apply(this, Array.prototype.slice.call(arguments, 1));
917
- }
918
- return this;
919
- },
920
- reflow : noop,
921
- render : function (reflow) {
922
- if (reflow) {
923
- this.reflow();
924
- }
925
- if (this.options.animation && !reflow) {
926
- helpers.animationLoop(
927
- this.draw,
928
- this.options.animationSteps,
929
- this.options.animationEasing,
930
- this.options.onAnimationProgress,
931
- this.options.onAnimationComplete,
932
- this
933
- );
934
- }
935
- else{
936
- this.draw();
937
- this.options.onAnimationComplete.call(this);
938
- }
939
- return this;
940
- },
941
- generateLegend : function () {
942
- return template(this.options.legendTemplate,this);
943
- },
944
- destroy : function () {
945
- this.clear();
946
- unbindEvents(this, this.events);
947
- delete Chart.instances[this.id];
948
- },
949
- showTooltip : function (ChartElements, forceRedraw) {
950
- // Only redraw the chart if we've actually changed what we're hovering on.
951
- if (typeof this.activeElements === 'undefined') { this.activeElements = [];
952
- }
953
-
954
- var isChanged = (function (Elements) {
955
- var changed = false;
956
-
957
- if (Elements.length !== this.activeElements.length) {
958
- changed = true;
959
- return changed;
960
- }
961
-
962
- each(
963
- Elements, function (element, index) {
964
- if (element !== this.activeElements[index]) {
965
- changed = true;
966
- }
967
- }, this
968
- );
969
- return changed;
970
- }).call(this, ChartElements);
971
-
972
- if (!isChanged && !forceRedraw) {
973
- return;
974
- }
975
- else{
976
- this.activeElements = ChartElements;
977
- }
978
- this.draw();
979
- if (ChartElements.length > 0) {
980
- // If we have multiple datasets, show a MultiTooltip for all of the data points at that index
981
- if (this.datasets && this.datasets.length > 1) {
982
- var dataArray,
983
- dataIndex;
984
-
985
- for (var i = this.datasets.length - 1; i >= 0; i--) {
986
- dataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;
987
- dataIndex = indexOf(dataArray, ChartElements[0]);
988
- if (dataIndex !== -1) {
989
- break;
990
- }
991
- }
992
- var tooltipLabels = [],
993
- tooltipColors = [],
994
- medianPosition = (function (index) {
995
-
996
- // Get all the points at that particular index
997
- var Elements = [],
998
- dataCollection,
999
- xPositions = [],
1000
- yPositions = [],
1001
- xMax,
1002
- yMax,
1003
- xMin,
1004
- yMin;
1005
- helpers.each(
1006
- this.datasets, function (dataset) {
1007
- dataCollection = dataset.points || dataset.bars || dataset.segments;
1008
- if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()) {
1009
- Elements.push(dataCollection[dataIndex]);
1010
- }
1011
- }
1012
- );
1013
-
1014
- helpers.each(
1015
- Elements, function (element) {
1016
- xPositions.push(element.x);
1017
- yPositions.push(element.y);
1018
-
1019
-
1020
- //Include any colour information about the element
1021
- tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));
1022
- tooltipColors.push(
1023
- {
1024
- fill: element._saved.fillColor || element.fillColor,
1025
- stroke: element._saved.strokeColor || element.strokeColor
1026
- }
1027
- );
1028
-
1029
- }, this
1030
- );
1031
-
1032
- yMin = min(yPositions);
1033
- yMax = max(yPositions);
1034
-
1035
- xMin = min(xPositions);
1036
- xMax = max(xPositions);
1037
-
1038
- return {
1039
- x: (xMin > this.chart.width/2) ? xMin : xMax,
1040
- y: (yMin + yMax)/2
1041
- };
1042
- }).call(this, dataIndex);
1043
-
1044
- new Chart.MultiTooltip(
1045
- {
1046
- x: medianPosition.x,
1047
- y: medianPosition.y,
1048
- xPadding: this.options.tooltipXPadding,
1049
- yPadding: this.options.tooltipYPadding,
1050
- xOffset: this.options.tooltipXOffset,
1051
- fillColor: this.options.tooltipFillColor,
1052
- textColor: this.options.tooltipFontColor,
1053
- fontFamily: this.options.tooltipFontFamily,
1054
- fontStyle: this.options.tooltipFontStyle,
1055
- fontSize: this.options.tooltipFontSize,
1056
- titleTextColor: this.options.tooltipTitleFontColor,
1057
- titleFontFamily: this.options.tooltipTitleFontFamily,
1058
- titleFontStyle: this.options.tooltipTitleFontStyle,
1059
- titleFontSize: this.options.tooltipTitleFontSize,
1060
- cornerRadius: this.options.tooltipCornerRadius,
1061
- labels: tooltipLabels,
1062
- legendColors: tooltipColors,
1063
- legendColorBackground : this.options.multiTooltipKeyBackground,
1064
- title: ChartElements[0].label,
1065
- chart: this.chart,
1066
- ctx: this.chart.ctx
1067
- }
1068
- ).draw();
1069
-
1070
- } else {
1071
- each(
1072
- ChartElements, function (Element) {
1073
- var tooltipPosition = Element.tooltipPosition();
1074
- new Chart.Tooltip(
1075
- {
1076
- x: Math.round(tooltipPosition.x),
1077
- y: Math.round(tooltipPosition.y),
1078
- xPadding: this.options.tooltipXPadding,
1079
- yPadding: this.options.tooltipYPadding,
1080
- fillColor: this.options.tooltipFillColor,
1081
- textColor: this.options.tooltipFontColor,
1082
- fontFamily: this.options.tooltipFontFamily,
1083
- fontStyle: this.options.tooltipFontStyle,
1084
- fontSize: this.options.tooltipFontSize,
1085
- caretHeight: this.options.tooltipCaretSize,
1086
- cornerRadius: this.options.tooltipCornerRadius,
1087
- text: template(this.options.tooltipTemplate, Element),
1088
- chart: this.chart
1089
- }
1090
- ).draw();
1091
- }, this
1092
- );
1093
- }
1094
- }
1095
- return this;
1096
- },
1097
- toBase64Image : function () {
1098
- return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
1099
- }
1100
  }
1101
- );
1102
-
1103
- Chart.Type.extend = function (extensions) {
1104
-
1105
- var parent = this;
1106
-
1107
- var ChartType = function () {
1108
- return parent.apply(this,arguments);
1109
- };
1110
-
1111
- //Copy the prototype object of the this class
1112
- ChartType.prototype = clone(parent.prototype);
1113
- //Now overwrite some of the properties in the base class with the new extensions
1114
- extend(ChartType.prototype, extensions);
1115
-
1116
- ChartType.extend = Chart.Type.extend;
1117
-
1118
- if (extensions.name || parent.prototype.name) {
1119
-
1120
- var chartName = extensions.name || parent.prototype.name;
1121
- //Assign any potential default values of the new chart type
1122
-
1123
- //If none are defined, we'll use a clone of the chart type this is being extended from.
1124
- //I.e. if we extend a line chart, we'll use the defaults from the line chart if our new chart
1125
- //doesn't define some defaults of their own.
1126
-
1127
- var baseDefaults = (Chart.defaults[parent.prototype.name]) ? clone(Chart.defaults[parent.prototype.name]) : {};
1128
-
1129
- Chart.defaults[chartName] = extend(baseDefaults,extensions.defaults);
1130
-
1131
- Chart.types[chartName] = ChartType;
1132
-
1133
- //Register this new chart type in the Chart prototype
1134
- Chart.prototype[chartName] = function (data,options) {
1135
- var config = merge(Chart.defaults.global, Chart.defaults[chartName], options || {});
1136
- return new ChartType(data,config,this);
1137
- };
1138
- } else{
1139
- warn("Name not provided for this chart, so it hasn't been registered");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1140
  }
1141
- return parent;
1142
- };
1143
-
1144
- Chart.Element = function (configuration) {
1145
- extend(this,configuration);
1146
- this.initialize.apply(this,arguments);
1147
- this.save();
1148
- };
1149
- extend(
1150
- Chart.Element.prototype,{
1151
- initialize : function (){},
1152
- restore : function (props) {
1153
- if (!props) {
1154
- extend(this,this._saved);
1155
- } else {
1156
- each(
1157
- props,function (key) {
1158
- this[key] = this._saved[key];
1159
- },this
1160
- );
1161
- }
1162
- return this;
1163
- },
1164
- save : function () {
1165
- this._saved = clone(this);
1166
- delete this._saved._saved;
1167
- return this;
1168
- },
1169
- update : function (newProps) {
1170
- each(
1171
- newProps,function (value,key) {
1172
- this._saved[key] = this[key];
1173
- this[key] = value;
1174
- },this
1175
- );
1176
- return this;
1177
- },
1178
- transition : function (props,ease) {
1179
- each(
1180
- props,function (value,key) {
1181
- this[key] = ((value - this._saved[key]) * ease) + this._saved[key];
1182
- },this
1183
- );
1184
- return this;
1185
- },
1186
- tooltipPosition : function () {
1187
- return {
1188
- x : this.x,
1189
- y : this.y
1190
- };
1191
- },
1192
- hasValue: function () {
1193
- return isNumber(this.value);
1194
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1195
  }
1196
- );
1197
-
1198
- Chart.Element.extend = inherits;
1199
-
1200
-
1201
- Chart.Point = Chart.Element.extend(
1202
- {
1203
- display: true,
1204
- inRange: function (chartX,chartY) {
1205
- var hitDetectionRange = this.hitDetectionRadius + this.radius;
1206
- return ((Math.pow(chartX-this.x, 2)+Math.pow(chartY-this.y, 2)) < Math.pow(hitDetectionRange,2));
1207
- },
1208
- draw : function () {
1209
- if (this.display) {
1210
- var ctx = this.ctx;
1211
- ctx.beginPath();
1212
-
1213
- ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);
1214
- ctx.closePath();
1215
-
1216
- ctx.strokeStyle = this.strokeColor;
1217
- ctx.lineWidth = this.strokeWidth;
1218
-
1219
- ctx.fillStyle = this.fillColor;
1220
-
1221
- ctx.fill();
1222
- ctx.stroke();
1223
- }
1224
-
1225
-
1226
- //Quick debug for bezier curve splining
1227
- //Highlights control points and the line between them.
1228
- //Handy for dev - stripped in the min version.
1229
-
1230
- // ctx.save();
1231
- // ctx.fillStyle = "black";
1232
- // ctx.strokeStyle = "black"
1233
- // ctx.beginPath();
1234
- // ctx.arc(this.controlPoints.inner.x,this.controlPoints.inner.y, 2, 0, Math.PI*2);
1235
- // ctx.fill();
1236
-
1237
- // ctx.beginPath();
1238
- // ctx.arc(this.controlPoints.outer.x,this.controlPoints.outer.y, 2, 0, Math.PI*2);
1239
- // ctx.fill();
1240
-
1241
- // ctx.moveTo(this.controlPoints.inner.x,this.controlPoints.inner.y);
1242
- // ctx.lineTo(this.x, this.y);
1243
- // ctx.lineTo(this.controlPoints.outer.x,this.controlPoints.outer.y);
1244
- // ctx.stroke();
1245
-
1246
- // ctx.restore();
1247
-
1248
-
1249
-
1250
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1251
  }
1252
- );
1253
-
1254
- Chart.Arc = Chart.Element.extend(
1255
- {
1256
- inRange : function (chartX,chartY) {
1257
-
1258
- var pointRelativePosition = helpers.getAngleFromPoint(
1259
- this, {
1260
- x: chartX,
1261
- y: chartY
1262
- }
1263
- );
1264
-
1265
- //Check if within the range of the open/close angle
1266
- var betweenAngles = (pointRelativePosition.angle >= this.startAngle && pointRelativePosition.angle <= this.endAngle),
1267
- withinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius);
1268
-
1269
- return (betweenAngles && withinRadius);
1270
- //Ensure within the outside of the arc centre, but inside arc outer
1271
- },
1272
- tooltipPosition : function () {
1273
- var centreAngle = this.startAngle + ((this.endAngle - this.startAngle) / 2),
1274
- rangeFromCentre = (this.outerRadius - this.innerRadius) / 2 + this.innerRadius;
1275
- return {
1276
- x : this.x + (Math.cos(centreAngle) * rangeFromCentre),
1277
- y : this.y + (Math.sin(centreAngle) * rangeFromCentre)
1278
- };
1279
- },
1280
- draw : function (animationPercent) {
1281
-
1282
- var easingDecimal = animationPercent || 1;
1283
-
1284
- var ctx = this.ctx;
1285
-
1286
- ctx.beginPath();
1287
-
1288
- ctx.arc(this.x, this.y, this.outerRadius, this.startAngle, this.endAngle);
1289
-
1290
- ctx.arc(this.x, this.y, this.innerRadius, this.endAngle, this.startAngle, true);
1291
-
1292
- ctx.closePath();
1293
- ctx.strokeStyle = this.strokeColor;
1294
- ctx.lineWidth = this.strokeWidth;
1295
-
1296
- ctx.fillStyle = this.fillColor;
1297
-
1298
- ctx.fill();
1299
- ctx.lineJoin = 'bevel';
1300
-
1301
- if (this.showStroke) {
1302
- ctx.stroke();
1303
- }
1304
- }
1305
  }
1306
- );
1307
-
1308
- Chart.Rectangle = Chart.Element.extend(
1309
- {
1310
- draw : function () {
1311
- var ctx = this.ctx,
1312
- halfWidth = this.width/2,
1313
- leftX = this.x - halfWidth,
1314
- rightX = this.x + halfWidth,
1315
- top = this.base - (this.base - this.y),
1316
- halfStroke = this.strokeWidth / 2;
1317
-
1318
- // Canvas doesn't allow us to stroke inside the width so we can
1319
- // adjust the sizes to fit if we're setting a stroke on the line
1320
- if (this.showStroke) {
1321
- leftX += halfStroke;
1322
- rightX -= halfStroke;
1323
- top += halfStroke;
1324
- }
1325
-
1326
- ctx.beginPath();
1327
-
1328
- ctx.fillStyle = this.fillColor;
1329
- ctx.strokeStyle = this.strokeColor;
1330
- ctx.lineWidth = this.strokeWidth;
1331
-
1332
- // It'd be nice to keep this class totally generic to any rectangle
1333
- // and simply specify which border to miss out.
1334
- ctx.moveTo(leftX, this.base);
1335
- ctx.lineTo(leftX, top);
1336
- ctx.lineTo(rightX, top);
1337
- ctx.lineTo(rightX, this.base);
1338
- ctx.fill();
1339
- if (this.showStroke) {
1340
- ctx.stroke();
1341
- }
1342
- },
1343
- height : function () {
1344
- return this.base - this.y;
1345
- },
1346
- inRange : function (chartX,chartY) {
1347
- return (chartX >= this.x - this.width/2 && chartX <= this.x + this.width/2) && (chartY >= this.y && chartY <= this.base);
1348
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1349
  }
1350
- );
1351
-
1352
- Chart.Tooltip = Chart.Element.extend(
1353
- {
1354
- draw : function () {
1355
-
1356
- var ctx = this.chart.ctx;
1357
-
1358
- ctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
1359
-
1360
- this.xAlign = "center";
1361
- this.yAlign = "above";
1362
-
1363
- //Distance between the actual element.y position and the start of the tooltip caret
1364
- var caretPadding = 2;
1365
-
1366
- var tooltipWidth = ctx.measureText(this.text).width + 2*this.xPadding,
1367
- tooltipRectHeight = this.fontSize + 2*this.yPadding,
1368
- tooltipHeight = tooltipRectHeight + this.caretHeight + caretPadding;
1369
-
1370
- if (this.x + tooltipWidth/2 >this.chart.width) {
1371
- this.xAlign = "left";
1372
- } else if (this.x - tooltipWidth/2 < 0) {
1373
- this.xAlign = "right";
1374
- }
1375
-
1376
- if (this.y - tooltipHeight < 0) {
1377
- this.yAlign = "below";
1378
- }
1379
-
1380
-
1381
- var tooltipX = this.x - tooltipWidth/2,
1382
- tooltipY = this.y - tooltipHeight;
1383
-
1384
- ctx.fillStyle = this.fillColor;
1385
-
1386
- switch(this.yAlign)
1387
- {
1388
- case "above":
1389
- //Draw a caret above the x/y
1390
- ctx.beginPath();
1391
- ctx.moveTo(this.x,this.y - caretPadding);
1392
- ctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight));
1393
- ctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight));
1394
- ctx.closePath();
1395
- ctx.fill();
1396
- break;
1397
- case "below":
1398
- tooltipY = this.y + caretPadding + this.caretHeight;
1399
- //Draw a caret below the x/y
1400
- ctx.beginPath();
1401
- ctx.moveTo(this.x, this.y + caretPadding);
1402
- ctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight);
1403
- ctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight);
1404
- ctx.closePath();
1405
- ctx.fill();
1406
- break;
1407
- }
1408
-
1409
- switch(this.xAlign)
1410
- {
1411
- case "left":
1412
- tooltipX = this.x - tooltipWidth + (this.cornerRadius + this.caretHeight);
1413
- break;
1414
- case "right":
1415
- tooltipX = this.x - (this.cornerRadius + this.caretHeight);
1416
- break;
1417
- }
1418
-
1419
- drawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,this.cornerRadius);
1420
-
1421
- ctx.fill();
1422
-
1423
- ctx.fillStyle = this.textColor;
1424
- ctx.textAlign = "center";
1425
- ctx.textBaseline = "middle";
1426
- ctx.fillText(this.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2);
1427
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1428
  }
1429
- );
1430
-
1431
- Chart.MultiTooltip = Chart.Element.extend(
1432
- {
1433
- initialize : function () {
1434
- this.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
1435
-
1436
- this.titleFont = fontString(this.titleFontSize,this.titleFontStyle,this.titleFontFamily);
1437
-
1438
- this.height = (this.labels.length * this.fontSize) + ((this.labels.length-1) * (this.fontSize/2)) + (this.yPadding*2) + this.titleFontSize *1.5;
1439
-
1440
- this.ctx.font = this.titleFont;
1441
-
1442
- var titleWidth = this.ctx.measureText(this.title).width,
1443
- //Label has a legend square as well so account for this.
1444
- labelWidth = longestText(this.ctx,this.font,this.labels) + this.fontSize + 3,
1445
- longestTextWidth = max([labelWidth,titleWidth]);
1446
-
1447
- this.width = longestTextWidth + (this.xPadding*2);
1448
-
1449
-
1450
- var halfHeight = this.height/2;
1451
-
1452
- //Check to ensure the height will fit on the canvas
1453
- //The three is to buffer form the very
1454
- if (this.y - halfHeight < 0 ) {
1455
- this.y = halfHeight;
1456
- } else if (this.y + halfHeight > this.chart.height) {
1457
- this.y = this.chart.height - halfHeight;
1458
- }
1459
-
1460
- //Decide whether to align left or right based on position on canvas
1461
- if (this.x > this.chart.width/2) {
1462
- this.x -= this.xOffset + this.width;
1463
- } else {
1464
- this.x += this.xOffset;
1465
- }
1466
-
1467
-
1468
- },
1469
- getLineHeight : function (index) {
1470
- var baseLineHeight = this.y - (this.height/2) + this.yPadding,
1471
- afterTitleIndex = index-1;
1472
-
1473
- //If the index is zero, we're getting the title
1474
- if (index === 0) {
1475
- return baseLineHeight + this.titleFontSize/2;
1476
- } else{
1477
- return baseLineHeight + ((this.fontSize*1.5*afterTitleIndex) + this.fontSize/2) + this.titleFontSize * 1.5;
1478
- }
1479
-
1480
- },
1481
- draw : function () {
1482
- drawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius);
1483
- var ctx = this.ctx;
1484
- ctx.fillStyle = this.fillColor;
1485
- ctx.fill();
1486
- ctx.closePath();
1487
-
1488
- ctx.textAlign = "left";
1489
- ctx.textBaseline = "middle";
1490
- ctx.fillStyle = this.titleTextColor;
1491
- ctx.font = this.titleFont;
1492
-
1493
- ctx.fillText(this.title,this.x + this.xPadding, this.getLineHeight(0));
1494
-
1495
- ctx.font = this.font;
1496
- helpers.each(
1497
- this.labels,function (label,index) {
1498
- ctx.fillStyle = this.textColor;
1499
- ctx.fillText(label,this.x + this.xPadding + this.fontSize + 3, this.getLineHeight(index + 1));
1500
-
1501
- //A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas)
1502
- //ctx.clearRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
1503
- //Instead we'll make a white filled block to put the legendColour palette over.
1504
-
1505
- ctx.fillStyle = this.legendColorBackground;
1506
- ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
1507
-
1508
- ctx.fillStyle = this.legendColors[index].fill;
1509
- ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);
1510
-
1511
-
1512
- },this
1513
- );
1514
- }
1515
  }
1516
- );
1517
-
1518
- Chart.Scale = Chart.Element.extend(
1519
- {
1520
- initialize : function () {
1521
- this.fit();
1522
- },
1523
- buildYLabels : function () {
1524
- this.yLabels = [];
1525
-
1526
- var stepDecimalPlaces = getDecimalPlaces(this.stepValue);
1527
-
1528
- for (var i=0; i<=this.steps; i++){
1529
- this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));
1530
- }
1531
- this.yLabelWidth = (this.display && this.showLabels) ? longestText(this.ctx,this.font,this.yLabels) : 0;
1532
- },
1533
- addXLabel : function (label) {
1534
- this.xLabels.push(label);
1535
- this.valuesCount++;
1536
- this.fit();
1537
- },
1538
- removeXLabel : function () {
1539
- this.xLabels.shift();
1540
- this.valuesCount--;
1541
- this.fit();
1542
- },
1543
- // Fitting loop to rotate x Labels and figure out what fits there, and also calculate how many Y steps to use
1544
- fit: function () {
1545
- // First we need the width of the yLabels, assuming the xLabels aren't rotated
1546
-
1547
- // To do that we need the base line at the top and base of the chart, assuming there is no x label rotation
1548
- this.startPoint = (this.display) ? this.fontSize : 0;
1549
- this.endPoint = (this.display) ? this.height - (this.fontSize * 1.5) - 5 : this.height; // -5 to pad labels
1550
-
1551
- // Apply padding settings to the start and end point.
1552
- this.startPoint += this.padding;
1553
- this.endPoint -= this.padding;
1554
-
1555
- // Cache the starting height, so can determine if we need to recalculate the scale yAxis
1556
- var cachedHeight = this.endPoint - this.startPoint,
1557
- cachedYLabelWidth;
1558
-
1559
- // Build the current yLabels so we have an idea of what size they'll be to start
1560
- /*
1561
- * This sets what is returned from calculateScaleRange as static properties of this class:
1562
- *
1563
- this.steps;
1564
- this.stepValue;
1565
- this.min;
1566
- this.max;
1567
- *
1568
- */
1569
- this.calculateYRange(cachedHeight);
1570
-
1571
- // With these properties set we can now build the array of yLabels
1572
- // and also the width of the largest yLabel
1573
- this.buildYLabels();
1574
-
1575
- this.calculateXLabelRotation();
1576
-
1577
- while((cachedHeight > this.endPoint - this.startPoint)){
1578
- cachedHeight = this.endPoint - this.startPoint;
1579
- cachedYLabelWidth = this.yLabelWidth;
1580
-
1581
- this.calculateYRange(cachedHeight);
1582
- this.buildYLabels();
1583
-
1584
- // Only go through the xLabel loop again if the yLabel width has changed
1585
- if (cachedYLabelWidth < this.yLabelWidth) {
1586
- this.calculateXLabelRotation();
1587
- }
1588
- }
1589
-
1590
- },
1591
- calculateXLabelRotation : function () {
1592
- //Get the width of each grid by calculating the difference
1593
- //between x offsets between 0 and 1.
1594
-
1595
- this.ctx.font = this.font;
1596
-
1597
- var firstWidth = this.ctx.measureText(this.xLabels[0]).width,
1598
- lastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width,
1599
- firstRotated,
1600
- lastRotated;
1601
-
1602
-
1603
- this.xScalePaddingRight = lastWidth/2 + 3;
1604
- this.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth + 10) ? firstWidth/2 : this.yLabelWidth + 10;
1605
-
1606
- this.xLabelRotation = 0;
1607
- if (this.display) {
1608
- var originalLabelWidth = longestText(this.ctx,this.font,this.xLabels),
1609
- cosRotation,
1610
- firstRotatedWidth;
1611
- this.xLabelWidth = originalLabelWidth;
1612
- //Allow 3 pixels x2 padding either side for label readability
1613
- var xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;
1614
-
1615
- //Max label rotate should be 90 - also act as a loop counter
1616
- while ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)){
1617
- cosRotation = Math.cos(toRadians(this.xLabelRotation));
1618
-
1619
- firstRotated = cosRotation * firstWidth;
1620
- lastRotated = cosRotation * lastWidth;
1621
-
1622
- // We're right aligning the text now.
1623
- if (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8) {
1624
- this.xScalePaddingLeft = firstRotated + this.fontSize / 2;
1625
- }
1626
- this.xScalePaddingRight = this.fontSize/2;
1627
-
1628
-
1629
- this.xLabelRotation++;
1630
- this.xLabelWidth = cosRotation * originalLabelWidth;
1631
-
1632
- }
1633
- if (this.xLabelRotation > 0) {
1634
- this.endPoint -= Math.sin(toRadians(this.xLabelRotation))*originalLabelWidth + 3;
1635
- }
1636
- }
1637
- else{
1638
- this.xLabelWidth = 0;
1639
- this.xScalePaddingRight = this.padding;
1640
- this.xScalePaddingLeft = this.padding;
1641
- }
1642
-
1643
- },
1644
- // Needs to be overidden in each Chart type
1645
- // Otherwise we need to pass all the data into the scale class
1646
- calculateYRange: noop,
1647
- drawingArea: function () {
1648
- return this.startPoint - this.endPoint;
1649
- },
1650
- calculateY : function (value) {
1651
- var scalingFactor = this.drawingArea() / (this.min - this.max);
1652
- return this.endPoint - (scalingFactor * (value - this.min));
1653
- },
1654
- calculateX : function (index) {
1655
- var isRotated = (this.xLabelRotation > 0),
1656
- // innerWidth = (this.offsetGridLines) ? this.width - offsetLeft - this.padding : this.width - (offsetLeft + halfLabelWidth * 2) - this.padding,
1657
- innerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),
1658
- valueWidth = innerWidth/(this.valuesCount - ((this.offsetGridLines) ? 0 : 1)),
1659
- valueOffset = (valueWidth * index) + this.xScalePaddingLeft;
1660
-
1661
- if (this.offsetGridLines) {
1662
- valueOffset += (valueWidth/2);
1663
- }
1664
-
1665
- return Math.round(valueOffset);
1666
- },
1667
- update : function (newProps) {
1668
- helpers.extend(this, newProps);
1669
- this.fit();
1670
- },
1671
- draw : function () {
1672
- var ctx = this.ctx,
1673
- yLabelGap = (this.endPoint - this.startPoint) / this.steps,
1674
- xStart = Math.round(this.xScalePaddingLeft);
1675
- if (this.display) {
1676
- ctx.fillStyle = this.textColor;
1677
- ctx.font = this.font;
1678
- each(
1679
- this.yLabels,function (labelString,index) {
1680
- var yLabelCenter = this.endPoint - (yLabelGap * index),
1681
- linePositionY = Math.round(yLabelCenter);
1682
-
1683
- ctx.textAlign = "right";
1684
- ctx.textBaseline = "middle";
1685
- if (this.showLabels) {
1686
- ctx.fillText(labelString,xStart - 10,yLabelCenter);
1687
- }
1688
- ctx.beginPath();
1689
- if (index > 0) {
1690
- // This is a grid line in the centre, so drop that
1691
- ctx.lineWidth = this.gridLineWidth;
1692
- ctx.strokeStyle = this.gridLineColor;
1693
- } else {
1694
- // This is the first line on the scale
1695
- ctx.lineWidth = this.lineWidth;
1696
- ctx.strokeStyle = this.lineColor;
1697
- }
1698
-
1699
- linePositionY += helpers.aliasPixel(ctx.lineWidth);
1700
-
1701
- ctx.moveTo(xStart, linePositionY);
1702
- ctx.lineTo(this.width, linePositionY);
1703
- ctx.stroke();
1704
- ctx.closePath();
1705
-
1706
- ctx.lineWidth = this.lineWidth;
1707
- ctx.strokeStyle = this.lineColor;
1708
- ctx.beginPath();
1709
- ctx.moveTo(xStart - 5, linePositionY);
1710
- ctx.lineTo(xStart, linePositionY);
1711
- ctx.stroke();
1712
- ctx.closePath();
1713
-
1714
- },this
1715
- );
1716
-
1717
- if(this.limitXLabels) {
1718
- var xDrawEvery = Math.round(this.xLabels.length / (this.limitXLabelsTo-1));
1719
- }
1720
- else {
1721
- var xDrawEvery = 1;
1722
- }
1723
-
1724
- each(
1725
- this.xLabels,function (label,index) {
1726
- var xPos = this.calculateX(index) + aliasPixel(this.lineWidth),
1727
- // Check to see if line/bar here and decide where to place the line
1728
- linePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),
1729
- isRotated = (this.xLabelRotation > 0);
1730
-
1731
- ctx.beginPath();
1732
-
1733
- if (index > 0) {
1734
- // This is a grid line in the centre, so drop that
1735
- ctx.lineWidth = this.gridLineWidth;
1736
- ctx.strokeStyle = this.gridLineColor;
1737
- } else {
1738
- // This is the first line on the scale
1739
- ctx.lineWidth = this.lineWidth;
1740
- ctx.strokeStyle = this.lineColor;
1741
- }
1742
- if(index == 0 || (index+1) % xDrawEvery == 0 || index == this.xLabels.length-1) {
1743
- ctx.moveTo(linePos,this.endPoint);
1744
- ctx.lineTo(linePos,this.startPoint - 3);
1745
- ctx.stroke();
1746
- ctx.closePath();
1747
- }
1748
-
1749
- ctx.lineWidth = this.lineWidth;
1750
- ctx.strokeStyle = this.lineColor;
1751
-
1752
-
1753
- // Small lines at the bottom of the base grid line
1754
- ctx.beginPath();
1755
- ctx.moveTo(linePos,this.endPoint);
1756
- ctx.lineTo(linePos,this.endPoint + 5);
1757
- ctx.stroke();
1758
- ctx.closePath();
1759
-
1760
- ctx.save();
1761
- ctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8);
1762
- ctx.rotate(toRadians(this.xLabelRotation)*-1);
1763
- ctx.font = this.font;
1764
- ctx.textAlign = (isRotated) ? "right" : "center";
1765
- ctx.textBaseline = (isRotated) ? "middle" : "top";
1766
- ctx.fillText(label, 0, 0);
1767
- ctx.restore();
1768
- },this
1769
- );
1770
-
1771
- }
1772
- }
1773
-
1774
  }
1775
- );
1776
-
1777
- Chart.RadialScale = Chart.Element.extend(
1778
- {
1779
- initialize: function () {
1780
- this.size = min([this.height, this.width]);
1781
- this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);
1782
- },
1783
- calculateCenterOffset: function (value) {
1784
- // Take into account half font size + the yPadding of the top value
1785
- var scalingFactor = this.drawingArea / (this.max - this.min);
1786
-
1787
- return (value - this.min) * scalingFactor;
1788
- },
1789
- update : function () {
1790
- if (!this.lineArc) {
1791
- this.setScaleSize();
1792
- } else {
1793
- this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);
1794
- }
1795
- this.buildYLabels();
1796
- },
1797
- buildYLabels: function () {
1798
- this.yLabels = [];
1799
-
1800
- var stepDecimalPlaces = getDecimalPlaces(this.stepValue);
1801
-
1802
- for (var i=0; i<=this.steps; i++){
1803
- this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));
1804
- }
1805
- },
1806
- getCircumference : function () {
1807
- return ((Math.PI*2) / this.valuesCount);
1808
- },
1809
- setScaleSize: function () {
1810
- /*
1811
- * Right, this is really confusing and there is a lot of maths going on here
1812
- * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9
1813
- *
1814
- * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif
1815
- *
1816
- * Solution:
1817
- *
1818
- * We assume the radius of the polygon is half the size of the canvas at first
1819
- * at each index we check if the text overlaps.
1820
- *
1821
- * Where it does, we store that angle and that index.
1822
- *
1823
- * After finding the largest index and angle we calculate how much we need to remove
1824
- * from the shape radius to move the point inwards by that x.
1825
- *
1826
- * We average the left and right distances to get the maximum shape radius that can fit in the box
1827
- * along with labels.
1828
- *
1829
- * Once we have that, we can find the centre point for the chart, by taking the x text protrusion
1830
- * on each side, removing that from the size, halving it and adding the left x protrusion width.
1831
- *
1832
- * This will mean we have a shape fitted to the canvas, as large as it can be with the labels
1833
- * and position it in the most space efficient manner
1834
- *
1835
- * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
1836
- */
1837
-
1838
-
1839
- // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
1840
- // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
1841
- var largestPossibleRadius = min([(this.height/2 - this.pointLabelFontSize - 5), this.width/2]),
1842
- pointPosition,
1843
- i,
1844
- textWidth,
1845
- halfTextWidth,
1846
- furthestRight = this.width,
1847
- furthestRightIndex,
1848
- furthestRightAngle,
1849
- furthestLeft = 0,
1850
- furthestLeftIndex,
1851
- furthestLeftAngle,
1852
- xProtrusionLeft,
1853
- xProtrusionRight,
1854
- radiusReductionRight,
1855
- radiusReductionLeft,
1856
- maxWidthRadius;
1857
- this.ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);
1858
- for (i=0;i<this.valuesCount;i++){
1859
- // 5px to space the text slightly out - similar to what we do in the draw function.
1860
- pointPosition = this.getPointPosition(i, largestPossibleRadius);
1861
- textWidth = this.ctx.measureText(template(this.templateString, { value: this.labels[i] })).width + 5;
1862
- if (i === 0 || i === this.valuesCount/2) {
1863
- // If we're at index zero, or exactly the middle, we're at exactly the top/bottom
1864
- // of the radar chart, so text will be aligned centrally, so we'll half it and compare
1865
- // w/left and right text sizes
1866
- halfTextWidth = textWidth/2;
1867
- if (pointPosition.x + halfTextWidth > furthestRight) {
1868
- furthestRight = pointPosition.x + halfTextWidth;
1869
- furthestRightIndex = i;
1870
- }
1871
- if (pointPosition.x - halfTextWidth < furthestLeft) {
1872
- furthestLeft = pointPosition.x - halfTextWidth;
1873
- furthestLeftIndex = i;
1874
- }
1875
- }
1876
- else if (i < this.valuesCount/2) {
1877
- // Less than half the values means we'll left align the text
1878
- if (pointPosition.x + textWidth > furthestRight) {
1879
- furthestRight = pointPosition.x + textWidth;
1880
- furthestRightIndex = i;
1881
- }
1882
- }
1883
- else if (i > this.valuesCount/2) {
1884
- // More than half the values means we'll right align the text
1885
- if (pointPosition.x - textWidth < furthestLeft) {
1886
- furthestLeft = pointPosition.x - textWidth;
1887
- furthestLeftIndex = i;
1888
- }
1889
- }
1890
- }
1891
-
1892
- xProtrusionLeft = furthestLeft;
1893
-
1894
- xProtrusionRight = Math.ceil(furthestRight - this.width);
1895
-
1896
- furthestRightAngle = this.getIndexAngle(furthestRightIndex);
1897
-
1898
- furthestLeftAngle = this.getIndexAngle(furthestLeftIndex);
1899
-
1900
- radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI/2);
1901
-
1902
- radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI/2);
1903
-
1904
- // Ensure we actually need to reduce the size of the chart
1905
- radiusReductionRight = (isNumber(radiusReductionRight)) ? radiusReductionRight : 0;
1906
- radiusReductionLeft = (isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;
1907
-
1908
- this.drawingArea = largestPossibleRadius - (radiusReductionLeft + radiusReductionRight)/2;
1909
-
1910
- //this.drawingArea = min([maxWidthRadius, (this.height - (2 * (this.pointLabelFontSize + 5)))/2])
1911
- this.setCenterPoint(radiusReductionLeft, radiusReductionRight);
1912
-
1913
- },
1914
- setCenterPoint: function (leftMovement, rightMovement) {
1915
-
1916
- var maxRight = this.width - rightMovement - this.drawingArea,
1917
- maxLeft = leftMovement + this.drawingArea;
1918
-
1919
- this.xCenter = (maxLeft + maxRight)/2;
1920
- // Always vertically in the centre as the text height doesn't change
1921
- this.yCenter = (this.height/2);
1922
- },
1923
-
1924
- getIndexAngle : function (index) {
1925
- var angleMultiplier = (Math.PI * 2) / this.valuesCount;
1926
- // Start from the top instead of right, so remove a quarter of the circle
1927
-
1928
- return index * angleMultiplier - (Math.PI/2);
1929
- },
1930
- getPointPosition : function (index, distanceFromCenter) {
1931
- var thisAngle = this.getIndexAngle(index);
1932
- return {
1933
- x : (Math.cos(thisAngle) * distanceFromCenter) + this.xCenter,
1934
- y : (Math.sin(thisAngle) * distanceFromCenter) + this.yCenter
1935
- };
1936
- },
1937
- draw: function () {
1938
- if (this.display) {
1939
- var ctx = this.ctx;
1940
- each(
1941
- this.yLabels, function (label, index) {
1942
- // Don't draw a centre value
1943
- if (index > 0) {
1944
- var yCenterOffset = index * (this.drawingArea/this.steps),
1945
- yHeight = this.yCenter - yCenterOffset,
1946
- pointPosition;
1947
-
1948
- // Draw circular lines around the scale
1949
- if (this.lineWidth > 0) {
1950
- ctx.strokeStyle = this.lineColor;
1951
- ctx.lineWidth = this.lineWidth;
1952
-
1953
- if(this.lineArc) {
1954
- ctx.beginPath();
1955
- ctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI*2);
1956
- ctx.closePath();
1957
- ctx.stroke();
1958
- } else{
1959
- ctx.beginPath();
1960
- for (var i=0;i<this.valuesCount;i++)
1961
- {
1962
- pointPosition = this.getPointPosition(i, this.calculateCenterOffset(this.min + (index * this.stepValue)));
1963
- if (i === 0) {
1964
- ctx.moveTo(pointPosition.x, pointPosition.y);
1965
- } else {
1966
- ctx.lineTo(pointPosition.x, pointPosition.y);
1967
- }
1968
- }
1969
- ctx.closePath();
1970
- ctx.stroke();
1971
- }
1972
- }
1973
- if(this.showLabels) {
1974
- ctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);
1975
- if (this.showLabelBackdrop) {
1976
- var labelWidth = ctx.measureText(label).width;
1977
- ctx.fillStyle = this.backdropColor;
1978
- ctx.fillRect(
1979
- this.xCenter - labelWidth/2 - this.backdropPaddingX,
1980
- yHeight - this.fontSize/2 - this.backdropPaddingY,
1981
- labelWidth + this.backdropPaddingX*2,
1982
- this.fontSize + this.backdropPaddingY*2
1983
- );
1984
- }
1985
- ctx.textAlign = 'center';
1986
- ctx.textBaseline = "middle";
1987
- ctx.fillStyle = this.fontColor;
1988
- ctx.fillText(label, this.xCenter, yHeight);
1989
- }
1990
- }
1991
- }, this
1992
- );
1993
-
1994
- if (!this.lineArc) {
1995
- ctx.lineWidth = this.angleLineWidth;
1996
- ctx.strokeStyle = this.angleLineColor;
1997
- for (var i = this.valuesCount - 1; i >= 0; i--) {
1998
- if (this.angleLineWidth > 0) {
1999
- var outerPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max));
2000
- ctx.beginPath();
2001
- ctx.moveTo(this.xCenter, this.yCenter);
2002
- ctx.lineTo(outerPosition.x, outerPosition.y);
2003
- ctx.stroke();
2004
- ctx.closePath();
2005
- }
2006
- // Extra 3px out for some label spacing
2007
- var pointLabelPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max) + 5);
2008
- ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);
2009
- ctx.fillStyle = this.pointLabelFontColor;
2010
-
2011
- var labelsCount = this.labels.length,
2012
- halfLabelsCount = this.labels.length/2,
2013
- quarterLabelsCount = halfLabelsCount/2,
2014
- upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),
2015
- exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);
2016
- if (i === 0) {
2017
- ctx.textAlign = 'center';
2018
- } else if(i === halfLabelsCount) {
2019
- ctx.textAlign = 'center';
2020
- } else if (i < halfLabelsCount) {
2021
- ctx.textAlign = 'left';
2022
- } else {
2023
- ctx.textAlign = 'right';
2024
- }
2025
-
2026
- // Set the correct text baseline based on outer positioning
2027
- if (exactQuarter) {
2028
- ctx.textBaseline = 'middle';
2029
- } else if (upperHalf) {
2030
- ctx.textBaseline = 'bottom';
2031
- } else {
2032
- ctx.textBaseline = 'top';
2033
- }
2034
-
2035
- ctx.fillText(this.labels[i], pointLabelPosition.x, pointLabelPosition.y);
2036
- }
2037
- }
2038
- }
2039
- }
2040
  }
2041
- );
2042
-
2043
- // Attach global event to resize each chart instance when the browser resizes
2044
- helpers.addEvent(
2045
- window, "resize", (function () {
2046
- // Basic debounce of resize function so it doesn't hurt performance when resizing browser.
2047
- var timeout;
2048
- return function () {
2049
- clearTimeout(timeout);
2050
- timeout = setTimeout(
2051
- function () {
2052
- each(
2053
- Chart.instances,function (instance) {
2054
- // If the responsive flag is set in the chart instance config
2055
- // Cascade the resize event down to the chart.
2056
- if (instance.options.responsive) {
2057
- instance.resize(instance.render, true);
2058
- }
2059
- }
2060
- );
2061
- }, 50
2062
- );
2063
- };
2064
- })()
2065
- );
2066
-
2067
-
2068
- if (amd) {
2069
- define(
2070
- function () {
2071
- return Chart;
2072
- }
2073
- );
2074
- } else if (typeof module === 'object' && module.exports) {
2075
- module.exports = Chart;
2076
  }
2077
-
2078
- root.Chart = Chart;
2079
-
2080
- Chart.noConflict = function () {
2081
- root.Chart = previous;
2082
- return Chart;
2083
- };
2084
-
2085
- }).call(this);
2086
-
2087
- (function () {
2088
- "use strict";
2089
-
2090
- var root = this,
2091
- Chart = root.Chart,
2092
- helpers = Chart.helpers;
2093
-
2094
-
2095
- var defaultConfig = {
2096
- //Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
2097
- scaleBeginAtZero : true,
2098
-
2099
- //Boolean - Whether grid lines are shown across the chart
2100
- scaleShowGridLines : true,
2101
-
2102
- //String - Colour of the grid lines
2103
- scaleGridLineColor : "rgba(0,0,0,.05)",
2104
-
2105
- //Number - Width of the grid lines
2106
- scaleGridLineWidth : 1,
2107
-
2108
- //Boolean - If there is a stroke on each bar
2109
- barShowStroke : true,
2110
-
2111
- //Number - Pixel width of the bar stroke
2112
- barStrokeWidth : 2,
2113
-
2114
- //Number - Spacing between each of the X value sets
2115
- barValueSpacing : 5,
2116
-
2117
- //Number - Spacing between data sets within X values
2118
- barDatasetSpacing : 1,
2119
-
2120
- //String - A legend template
2121
- legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
2122
-
2123
- };
2124
-
2125
-
2126
- Chart.Type.extend(
2127
- {
2128
- name: "Bar",
2129
- defaults : defaultConfig,
2130
- initialize: function (data) {
2131
-
2132
- //Expose options as a scope variable here so we can access it in the ScaleClass
2133
- var options = this.options;
2134
-
2135
- this.ScaleClass = Chart.Scale.extend(
2136
- {
2137
- offsetGridLines : true,
2138
- calculateBarX : function (datasetCount, datasetIndex, barIndex) {
2139
- //Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar
2140
- var xWidth = this.calculateBaseWidth(),
2141
- xAbsolute = this.calculateX(barIndex) - (xWidth/2),
2142
- barWidth = this.calculateBarWidth(datasetCount);
2143
-
2144
- return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2;
2145
- },
2146
- calculateBaseWidth : function () {
2147
- return (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);
2148
- },
2149
- calculateBarWidth : function (datasetCount) {
2150
- //The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
2151
- var baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);
2152
-
2153
- return (baseWidth / datasetCount);
2154
- }
2155
- }
2156
- );
2157
-
2158
- this.datasets = [];
2159
-
2160
- //Set up tooltip events on the chart
2161
- if (this.options.showTooltips) {
2162
- helpers.bindEvents(
2163
- this, this.options.tooltipEvents, function (evt) {
2164
- var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];
2165
-
2166
- this.eachBars(
2167
- function (bar) {
2168
- bar.restore(['fillColor', 'strokeColor']);
2169
- }
2170
- );
2171
- helpers.each(
2172
- activeBars, function (activeBar) {
2173
- activeBar.fillColor = activeBar.highlightFill;
2174
- activeBar.strokeColor = activeBar.highlightStroke;
2175
- }
2176
- );
2177
- this.showTooltip(activeBars);
2178
- }
2179
- );
2180
- }
2181
-
2182
- //Declare the extension of the default point, to cater for the options passed in to the constructor
2183
- this.BarClass = Chart.Rectangle.extend(
2184
- {
2185
- strokeWidth : this.options.barStrokeWidth,
2186
- showStroke : this.options.barShowStroke,
2187
- ctx : this.chart.ctx
2188
- }
2189
- );
2190
-
2191
- //Iterate through each of the datasets, and build this into a property of the chart
2192
- helpers.each(
2193
- data.datasets,function (dataset,datasetIndex) {
2194
-
2195
- var datasetObject = {
2196
- label : dataset.label || null,
2197
- fillColor : dataset.fillColor,
2198
- strokeColor : dataset.strokeColor,
2199
- bars : []
2200
- };
2201
-
2202
- this.datasets.push(datasetObject);
2203
-
2204
- helpers.each(
2205
- dataset.data,function (dataPoint,index) {
2206
- //Add a new point for each piece of data, passing any required data to draw.
2207
- datasetObject.bars.push(
2208
- new this.BarClass(
2209
- {
2210
- value : dataPoint,
2211
- label : data.labels[index],
2212
- datasetLabel: dataset.label,
2213
- strokeColor : dataset.strokeColor,
2214
- fillColor : dataset.fillColor,
2215
- highlightFill : dataset.highlightFill || dataset.fillColor,
2216
- highlightStroke : dataset.highlightStroke || dataset.strokeColor
2217
- }
2218
- )
2219
- );
2220
- },this
2221
- );
2222
-
2223
- },this
2224
- );
2225
-
2226
- this.buildScale(data.labels);
2227
-
2228
- this.BarClass.prototype.base = this.scale.endPoint;
2229
-
2230
- this.eachBars(
2231
- function (bar, index, datasetIndex) {
2232
- helpers.extend(
2233
- bar, {
2234
- width : this.scale.calculateBarWidth(this.datasets.length),
2235
- x: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
2236
- y: this.scale.endPoint
2237
- }
2238
- );
2239
- bar.save();
2240
- }, this
2241
- );
2242
-
2243
- this.render();
2244
- },
2245
- update : function () {
2246
- this.scale.update();
2247
- // Reset any highlight colours before updating.
2248
- helpers.each(
2249
- this.activeElements, function (activeElement) {
2250
- activeElement.restore(['fillColor', 'strokeColor']);
2251
- }
2252
- );
2253
-
2254
- this.eachBars(
2255
- function (bar) {
2256
- bar.save();
2257
- }
2258
- );
2259
- this.render();
2260
- },
2261
- eachBars : function (callback) {
2262
- helpers.each(
2263
- this.datasets,function (dataset, datasetIndex) {
2264
- helpers.each(dataset.bars, callback, this, datasetIndex);
2265
- },this
2266
- );
2267
- },
2268
- getBarsAtEvent : function (e) {
2269
- var barsArray = [],
2270
- eventPosition = helpers.getRelativePosition(e),
2271
- datasetIterator = function (dataset) {
2272
- barsArray.push(dataset.bars[barIndex]);
2273
- },
2274
- barIndex;
2275
-
2276
- for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {
2277
- for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {
2278
- if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)) {
2279
- helpers.each(this.datasets, datasetIterator);
2280
- return barsArray;
2281
- }
2282
- }
2283
- }
2284
-
2285
- return barsArray;
2286
- },
2287
- buildScale : function (labels) {
2288
- var self = this;
2289
-
2290
- var dataTotal = function () {
2291
- var values = [];
2292
- self.eachBars(
2293
- function (bar) {
2294
- values.push(bar.value);
2295
- }
2296
- );
2297
- return values;
2298
- };
2299
-
2300
- var scaleOptions = {
2301
- templateString : this.options.scaleLabel,
2302
- height : this.chart.height,
2303
- width : this.chart.width,
2304
- ctx : this.chart.ctx,
2305
- textColor : this.options.scaleFontColor,
2306
- fontSize : this.options.scaleFontSize,
2307
- fontStyle : this.options.scaleFontStyle,
2308
- fontFamily : this.options.scaleFontFamily,
2309
- valuesCount : labels.length,
2310
- beginAtZero : this.options.scaleBeginAtZero,
2311
- integersOnly : this.options.scaleIntegersOnly,
2312
- calculateYRange: function (currentHeight) {
2313
- var updatedRanges = helpers.calculateScaleRange(
2314
- dataTotal(),
2315
- currentHeight,
2316
- this.fontSize,
2317
- this.beginAtZero,
2318
- this.integersOnly
2319
- );
2320
- helpers.extend(this, updatedRanges);
2321
- },
2322
- xLabels : labels,
2323
- limitXLabels: this.options.scaleLimitXLabels,
2324
- limitXLabelsTo: this.options.scaleLimitXLabelsTo,
2325
- font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
2326
- lineWidth : this.options.scaleLineWidth,
2327
- lineColor : this.options.scaleLineColor,
2328
- gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
2329
- gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
2330
- padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,
2331
- showLabels : this.options.scaleShowLabels,
2332
- display : this.options.showScale
2333
- };
2334
-
2335
- if (this.options.scaleOverride) {
2336
- helpers.extend(
2337
- scaleOptions, {
2338
- calculateYRange: helpers.noop,
2339
- steps: this.options.scaleSteps,
2340
- stepValue: this.options.scaleStepWidth,
2341
- min: this.options.scaleStartValue,
2342
- max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
2343
- }
2344
- );
2345
- }
2346
-
2347
- this.scale = new this.ScaleClass(scaleOptions);
2348
- },
2349
- addData : function (valuesArray,label) {
2350
- //Map the values array for each of the datasets
2351
- helpers.each(
2352
- valuesArray,function (value,datasetIndex) {
2353
- //Add a new point for each piece of data, passing any required data to draw.
2354
- this.datasets[datasetIndex].bars.push(
2355
- new this.BarClass(
2356
- {
2357
- value : value,
2358
- label : label,
2359
- x: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),
2360
- y: this.scale.endPoint,
2361
- width : this.scale.calculateBarWidth(this.datasets.length),
2362
- base : this.scale.endPoint,
2363
- strokeColor : this.datasets[datasetIndex].strokeColor,
2364
- fillColor : this.datasets[datasetIndex].fillColor
2365
- }
2366
- )
2367
- );
2368
- },this
2369
- );
2370
-
2371
- this.scale.addXLabel(label);
2372
- //Then re-render the chart.
2373
- this.update();
2374
- },
2375
- removeData : function () {
2376
- this.scale.removeXLabel();
2377
- //Then re-render the chart.
2378
- helpers.each(
2379
- this.datasets,function (dataset) {
2380
- dataset.bars.shift();
2381
- },this
2382
- );
2383
- this.update();
2384
- },
2385
- reflow : function () {
2386
- helpers.extend(
2387
- this.BarClass.prototype,{
2388
- y: this.scale.endPoint,
2389
- base : this.scale.endPoint
2390
- }
2391
- );
2392
- var newScaleProps = helpers.extend(
2393
- {
2394
- height : this.chart.height,
2395
- width : this.chart.width
2396
- }
2397
- );
2398
- this.scale.update(newScaleProps);
2399
- },
2400
- draw : function (ease) {
2401
- var easingDecimal = ease || 1;
2402
- this.clear();
2403
-
2404
- var ctx = this.chart.ctx;
2405
-
2406
- this.scale.draw(easingDecimal);
2407
-
2408
- //Draw all the bars for each dataset
2409
- helpers.each(
2410
- this.datasets,function (dataset,datasetIndex) {
2411
- helpers.each(
2412
- dataset.bars,function (bar,index) {
2413
- if (bar.hasValue()) {
2414
- bar.base = this.scale.endPoint;
2415
- //Transition then draw
2416
- bar.transition(
2417
- {
2418
- x : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
2419
- y : this.scale.calculateY(bar.value),
2420
- width : this.scale.calculateBarWidth(this.datasets.length)
2421
- }, easingDecimal
2422
- ).draw();
2423
- }
2424
- },this
2425
- );
2426
-
2427
- },this
2428
- );
2429
- }
2430
  }
2431
- );
2432
-
2433
-
2434
- }).call(this);
2435
- (function () {
2436
- "use strict";
2437
-
2438
- var root = this,
2439
- Chart = root.Chart,
2440
- //Cache a local reference to Chart.helpers
2441
- helpers = Chart.helpers;
2442
-
2443
- var defaultConfig = {
2444
- //Boolean - Whether we should show a stroke on each segment
2445
- segmentShowStroke : true,
2446
-
2447
- //String - The colour of each segment stroke
2448
- segmentStrokeColor : "#fff",
2449
-
2450
- //Number - The width of each segment stroke
2451
- segmentStrokeWidth : 2,
2452
-
2453
- //The percentage of the chart that we cut out of the middle.
2454
- percentageInnerCutout : 50,
2455
-
2456
- //Number - Amount of animation steps
2457
- animationSteps : 100,
2458
-
2459
- //String - Animation easing effect
2460
- animationEasing : "easeOutBounce",
2461
-
2462
- //Boolean - Whether we animate the rotation of the Doughnut
2463
- animateRotate : true,
2464
-
2465
- //Boolean - Whether we animate scaling the Doughnut from the centre
2466
- animateScale : false,
2467
-
2468
- //String - A legend template
2469
- legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
2470
-
2471
- };
2472
-
2473
-
2474
- Chart.Type.extend(
2475
- {
2476
- //Passing in a name registers this chart in the Chart namespace
2477
- name: "Doughnut",
2478
- //Providing a defaults will also register the deafults in the chart namespace
2479
- defaults : defaultConfig,
2480
- //Initialize is fired when the chart is initialized - Data is passed in as a parameter
2481
- //Config is automatically merged by the core of Chart.js, and is available at this.options
2482
- initialize: function (data) {
2483
-
2484
- //Declare segments as a static property to prevent inheriting across the Chart type prototype
2485
- this.segments = [];
2486
- this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
2487
-
2488
- this.SegmentArc = Chart.Arc.extend(
2489
- {
2490
- ctx : this.chart.ctx,
2491
- x : this.chart.width/2,
2492
- y : this.chart.height/2
2493
- }
2494
- );
2495
-
2496
- //Set up tooltip events on the chart
2497
- if (this.options.showTooltips) {
2498
- helpers.bindEvents(
2499
- this, this.options.tooltipEvents, function (evt) {
2500
- var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
2501
-
2502
- helpers.each(
2503
- this.segments,function (segment) {
2504
- segment.restore(["fillColor"]);
2505
- }
2506
- );
2507
- helpers.each(
2508
- activeSegments,function (activeSegment) {
2509
- activeSegment.fillColor = activeSegment.highlightColor;
2510
- }
2511
- );
2512
- this.showTooltip(activeSegments);
2513
- }
2514
- );
2515
- }
2516
- this.calculateTotal(data);
2517
-
2518
- helpers.each(
2519
- data,function (datapoint, index) {
2520
- this.addData(datapoint, index, true);
2521
- },this
2522
- );
2523
-
2524
- this.render();
2525
- },
2526
- getSegmentsAtEvent : function (e) {
2527
- var segmentsArray = [];
2528
-
2529
- var location = helpers.getRelativePosition(e);
2530
-
2531
- helpers.each(
2532
- this.segments,function (segment) {
2533
- if (segment.inRange(location.x,location.y)) { segmentsArray.push(segment);
2534
- }
2535
- },this
2536
- );
2537
- return segmentsArray;
2538
- },
2539
- addData : function (segment, atIndex, silent) {
2540
- var index = atIndex || this.segments.length;
2541
- this.segments.splice(
2542
- index, 0, new this.SegmentArc(
2543
- {
2544
- value : segment.value,
2545
- outerRadius : (this.options.animateScale) ? 0 : this.outerRadius,
2546
- innerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout,
2547
- fillColor : segment.color,
2548
- highlightColor : segment.highlight || segment.color,
2549
- showStroke : this.options.segmentShowStroke,
2550
- strokeWidth : this.options.segmentStrokeWidth,
2551
- strokeColor : this.options.segmentStrokeColor,
2552
- startAngle : Math.PI * 1.5,
2553
- circumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value),
2554
- label : segment.label
2555
- }
2556
- )
2557
- );
2558
- if (!silent) {
2559
- this.reflow();
2560
- this.update();
2561
- }
2562
- },
2563
- calculateCircumference : function (value) {
2564
- if (this.total > 0 ) {
2565
- return (Math.PI*2)*(value / this.total);
2566
- } else {
2567
- return 0;
2568
- }
2569
- },
2570
- calculateTotal : function (data) {
2571
- this.total = 0;
2572
- helpers.each(
2573
- data,function (segment) {
2574
- this.total += segment.value;
2575
- },this
2576
- );
2577
- },
2578
- update : function () {
2579
- this.calculateTotal(this.segments);
2580
-
2581
- // Reset any highlight colours before updating.
2582
- helpers.each(
2583
- this.activeElements, function (activeElement) {
2584
- activeElement.restore(['fillColor']);
2585
- }
2586
- );
2587
-
2588
- helpers.each(
2589
- this.segments,function (segment) {
2590
- segment.save();
2591
- }
2592
- );
2593
- this.render();
2594
- },
2595
-
2596
- removeData: function (atIndex) {
2597
- var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
2598
- this.segments.splice(indexToDelete, 1);
2599
- this.reflow();
2600
- this.update();
2601
- },
2602
-
2603
- reflow : function () {
2604
- helpers.extend(
2605
- this.SegmentArc.prototype,{
2606
- x : this.chart.width/2,
2607
- y : this.chart.height/2
2608
- }
2609
- );
2610
- this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
2611
- helpers.each(
2612
- this.segments, function (segment) {
2613
- segment.update(
2614
- {
2615
- outerRadius : this.outerRadius,
2616
- innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
2617
- }
2618
- );
2619
- }, this
2620
- );
2621
- },
2622
- draw : function (easeDecimal) {
2623
- var animDecimal = (easeDecimal) ? easeDecimal : 1;
2624
- this.clear();
2625
- helpers.each(
2626
- this.segments,function (segment,index) {
2627
- segment.transition(
2628
- {
2629
- circumference : this.calculateCircumference(segment.value),
2630
- outerRadius : this.outerRadius,
2631
- innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
2632
- },animDecimal
2633
- );
2634
-
2635
- segment.endAngle = segment.startAngle + segment.circumference;
2636
-
2637
- segment.draw();
2638
- if (index === 0) {
2639
- segment.startAngle = Math.PI * 1.5;
2640
- }
2641
- //Check to see if it's the last segment, if not get the next and update the start angle
2642
- if (index < this.segments.length-1) {
2643
- this.segments[index+1].startAngle = segment.endAngle;
2644
- }
2645
- },this
2646
- );
2647
-
2648
- }
2649
  }
2650
- );
2651
-
2652
- Chart.types.Doughnut.extend(
2653
- {
2654
- name : "Pie",
2655
- defaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0})
 
 
 
 
 
 
2656
  }
2657
- );
2658
-
2659
- }).call(this);
2660
-
2661
- (function () {
2662
- "use strict";
2663
-
2664
- var root = this,
2665
- Chart = root.Chart,
2666
- helpers = Chart.helpers;
2667
-
2668
- var defaultConfig = {
2669
-
2670
- ///Boolean - Whether grid lines are shown across the chart
2671
- scaleShowGridLines : true,
2672
-
2673
- //String - Colour of the grid lines
2674
- scaleGridLineColor : "rgba(0,0,0,.05)",
2675
-
2676
- //Number - Width of the grid lines
2677
- scaleGridLineWidth : 1,
2678
-
2679
- //Boolean - Whether the line is curved between points
2680
- bezierCurve : true,
2681
-
2682
- //Number - Tension of the bezier curve between points
2683
- bezierCurveTension : 0.4,
2684
-
2685
- //Boolean - Whether to show a dot for each point
2686
- pointDot : true,
2687
-
2688
- //Number - Radius of each point dot in pixels
2689
- pointDotRadius : 4,
2690
-
2691
- //Number - Pixel width of point dot stroke
2692
- pointDotStrokeWidth : 1,
2693
-
2694
- //Number - amount extra to add to the radius to cater for hit detection outside the drawn point
2695
- pointHitDetectionRadius : 0,
2696
-
2697
- //Boolean - Whether to show a stroke for datasets
2698
- datasetStroke : true,
2699
-
2700
- //Number - Pixel width of dataset stroke
2701
- datasetStrokeWidth : 2,
2702
-
2703
- //Boolean - Whether to fill the dataset with a colour
2704
- datasetFill : true,
2705
-
2706
- //String - A legend template
2707
- legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
2708
-
2709
- };
2710
-
2711
-
2712
- Chart.Type.extend(
2713
- {
2714
- name: "Line",
2715
- defaults : defaultConfig,
2716
- initialize: function (data) {
2717
- //Declare the extension of the default point, to cater for the options passed in to the constructor
2718
- this.PointClass = Chart.Point.extend(
2719
- {
2720
- strokeWidth : this.options.pointDotStrokeWidth,
2721
- radius : this.options.pointDotRadius,
2722
- display: this.options.pointDot,
2723
- hitDetectionRadius : this.options.pointHitDetectionRadius,
2724
- ctx : this.chart.ctx,
2725
- inRange : function (mouseX) {
2726
- return (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2));
2727
- }
2728
- }
2729
- );
2730
-
2731
- this.datasets = [];
2732
-
2733
- //Set up tooltip events on the chart
2734
- if (this.options.showTooltips) {
2735
- helpers.bindEvents(
2736
- this, this.options.tooltipEvents, function (evt) {
2737
- var activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
2738
- this.eachPoints(
2739
- function (point) {
2740
- point.restore(['fillColor', 'strokeColor']);
2741
- }
2742
- );
2743
- helpers.each(
2744
- activePoints, function (activePoint) {
2745
- activePoint.fillColor = activePoint.highlightFill;
2746
- activePoint.strokeColor = activePoint.highlightStroke;
2747
- }
2748
- );
2749
- this.showTooltip(activePoints);
2750
- }
2751
- );
2752
- }
2753
-
2754
- //Iterate through each of the datasets, and build this into a property of the chart
2755
- helpers.each(
2756
- data.datasets,function (dataset) {
2757
-
2758
- var datasetObject = {
2759
- label : dataset.label || null,
2760
- fillColor : dataset.fillColor,
2761
- strokeColor : dataset.strokeColor,
2762
- pointColor : dataset.pointColor,
2763
- pointStrokeColor : dataset.pointStrokeColor,
2764
- points : []
2765
- };
2766
-
2767
- this.datasets.push(datasetObject);
2768
-
2769
-
2770
- helpers.each(
2771
- dataset.data,function (dataPoint,index) {
2772
- //Add a new point for each piece of data, passing any required data to draw.
2773
- datasetObject.points.push(
2774
- new this.PointClass(
2775
- {
2776
- value : dataPoint,
2777
- label : data.labels[index],
2778
- datasetLabel: dataset.label,
2779
- strokeColor : dataset.pointStrokeColor,
2780
- fillColor : dataset.pointColor,
2781
- highlightFill : dataset.pointHighlightFill || dataset.pointColor,
2782
- highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
2783
- }
2784
- )
2785
- );
2786
- },this
2787
- );
2788
-
2789
- this.buildScale(data.labels);
2790
-
2791
-
2792
- this.eachPoints(
2793
- function (point, index) {
2794
- helpers.extend(
2795
- point, {
2796
- x: this.scale.calculateX(index),
2797
- y: this.scale.endPoint
2798
- }
2799
- );
2800
- point.save();
2801
- }, this
2802
- );
2803
-
2804
- },this
2805
- );
2806
-
2807
-
2808
- this.render();
2809
- },
2810
- update : function () {
2811
- this.scale.update();
2812
- // Reset any highlight colours before updating.
2813
- helpers.each(
2814
- this.activeElements, function (activeElement) {
2815
- activeElement.restore(['fillColor', 'strokeColor']);
2816
- }
2817
- );
2818
- this.eachPoints(
2819
- function (point) {
2820
- point.save();
2821
- }
2822
- );
2823
- this.render();
2824
- },
2825
- eachPoints : function (callback) {
2826
- helpers.each(
2827
- this.datasets,function (dataset) {
2828
- helpers.each(dataset.points,callback,this);
2829
- },this
2830
- );
2831
- },
2832
- getPointsAtEvent : function (e) {
2833
- var pointsArray = [],
2834
- eventPosition = helpers.getRelativePosition(e);
2835
- helpers.each(
2836
- this.datasets,function (dataset) {
2837
- helpers.each(
2838
- dataset.points,function (point) {
2839
- if (point.inRange(eventPosition.x,eventPosition.y)) { pointsArray.push(point);
2840
- }
2841
- }
2842
- );
2843
- },this
2844
- );
2845
- return pointsArray;
2846
- },
2847
- buildScale : function (labels) {
2848
- var self = this;
2849
-
2850
- var dataTotal = function () {
2851
- var values = [];
2852
- self.eachPoints(
2853
- function (point) {
2854
- values.push(point.value);
2855
- }
2856
- );
2857
-
2858
- return values;
2859
- };
2860
-
2861
- var scaleOptions = {
2862
- templateString : this.options.scaleLabel,
2863
- height : this.chart.height,
2864
- width : this.chart.width,
2865
- ctx : this.chart.ctx,
2866
- textColor : this.options.scaleFontColor,
2867
- fontSize : this.options.scaleFontSize,
2868
- fontStyle : this.options.scaleFontStyle,
2869
- fontFamily : this.options.scaleFontFamily,
2870
- valuesCount : labels.length,
2871
- beginAtZero : this.options.scaleBeginAtZero,
2872
- integersOnly : this.options.scaleIntegersOnly,
2873
- calculateYRange : function (currentHeight) {
2874
- var updatedRanges = helpers.calculateScaleRange(
2875
- dataTotal(),
2876
- currentHeight,
2877
- this.fontSize,
2878
- this.beginAtZero,
2879
- this.integersOnly
2880
- );
2881
- helpers.extend(this, updatedRanges);
2882
- },
2883
- xLabels : labels,
2884
- limitXLabels: this.options.scaleLimitXLabels,
2885
- limitXLabelsTo: this.options.scaleLimitXLabelsTo,
2886
- font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
2887
- lineWidth : this.options.scaleLineWidth,
2888
- lineColor : this.options.scaleLineColor,
2889
- gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
2890
- gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
2891
- padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,
2892
- showLabels : this.options.scaleShowLabels,
2893
- display : this.options.showScale
2894
- };
2895
-
2896
- if (this.options.scaleOverride) {
2897
- helpers.extend(
2898
- scaleOptions, {
2899
- calculateYRange: helpers.noop,
2900
- steps: this.options.scaleSteps,
2901
- stepValue: this.options.scaleStepWidth,
2902
- min: this.options.scaleStartValue,
2903
- max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
2904
- }
2905
- );
2906
- }
2907
-
2908
-
2909
- this.scale = new Chart.Scale(scaleOptions);
2910
- },
2911
- addData : function (valuesArray,label) {
2912
- //Map the values array for each of the datasets
2913
-
2914
- helpers.each(
2915
- valuesArray,function (value,datasetIndex) {
2916
- //Add a new point for each piece of data, passing any required data to draw.
2917
- this.datasets[datasetIndex].points.push(
2918
- new this.PointClass(
2919
- {
2920
- value : value,
2921
- label : label,
2922
- x: this.scale.calculateX(this.scale.valuesCount+1),
2923
- y: this.scale.endPoint,
2924
- strokeColor : this.datasets[datasetIndex].pointStrokeColor,
2925
- fillColor : this.datasets[datasetIndex].pointColor
2926
- }
2927
- )
2928
- );
2929
- },this
2930
- );
2931
-
2932
- this.scale.addXLabel(label);
2933
- //Then re-render the chart.
2934
- this.update();
2935
- },
2936
- removeData : function () {
2937
- this.scale.removeXLabel();
2938
- //Then re-render the chart.
2939
- helpers.each(
2940
- this.datasets,function (dataset) {
2941
- dataset.points.shift();
2942
- },this
2943
- );
2944
- this.update();
2945
- },
2946
- reflow : function () {
2947
- var newScaleProps = helpers.extend(
2948
- {
2949
- height : this.chart.height,
2950
- width : this.chart.width
2951
- }
2952
- );
2953
- this.scale.update(newScaleProps);
2954
- },
2955
- draw : function (ease) {
2956
- var easingDecimal = ease || 1;
2957
- this.clear();
2958
-
2959
- var ctx = this.chart.ctx;
2960
-
2961
- // Some helper methods for getting the next/prev points
2962
- var hasValue = function (item) {
2963
- return item.value !== null;
2964
- },
2965
- nextPoint = function (point, collection, index) {
2966
- return helpers.findNextWhere(collection, hasValue, index) || point;
2967
- },
2968
- previousPoint = function (point, collection, index) {
2969
- return helpers.findPreviousWhere(collection, hasValue, index) || point;
2970
- };
2971
-
2972
- this.scale.draw(easingDecimal);
2973
-
2974
-
2975
- helpers.each(
2976
- this.datasets,function (dataset) {
2977
- var pointsWithValues = helpers.where(dataset.points, hasValue);
2978
-
2979
- //Transition each point first so that the line and point drawing isn't out of sync
2980
- //We can use this extra loop to calculate the control points of this dataset also in this loop
2981
-
2982
- helpers.each(
2983
- dataset.points, function (point, index) {
2984
- if (point.hasValue()) {
2985
- point.transition(
2986
- {
2987
- y : this.scale.calculateY(point.value),
2988
- x : this.scale.calculateX(index)
2989
- }, easingDecimal
2990
- );
2991
- }
2992
- },this
2993
- );
2994
-
2995
-
2996
- // Control points need to be calculated in a seperate loop, because we need to know the current x/y of the point
2997
- // This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed
2998
- if (this.options.bezierCurve) {
2999
- helpers.each(
3000
- pointsWithValues, function (point, index) {
3001
- var tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0;
3002
- point.controlPoints = helpers.splineCurve(
3003
- previousPoint(point, pointsWithValues, index),
3004
- point,
3005
- nextPoint(point, pointsWithValues, index),
3006
- tension
3007
- );
3008
-
3009
- // Prevent the bezier going outside of the bounds of the graph
3010
-
3011
- // Cap puter bezier handles to the upper/lower scale bounds
3012
- if (point.controlPoints.outer.y > this.scale.endPoint) {
3013
- point.controlPoints.outer.y = this.scale.endPoint;
3014
- }
3015
- else if (point.controlPoints.outer.y < this.scale.startPoint) {
3016
- point.controlPoints.outer.y = this.scale.startPoint;
3017
- }
3018
-
3019
- // Cap inner bezier handles to the upper/lower scale bounds
3020
- if (point.controlPoints.inner.y > this.scale.endPoint) {
3021
- point.controlPoints.inner.y = this.scale.endPoint;
3022
- }
3023
- else if (point.controlPoints.inner.y < this.scale.startPoint) {
3024
- point.controlPoints.inner.y = this.scale.startPoint;
3025
- }
3026
- },this
3027
- );
3028
- }
3029
-
3030
-
3031
- //Draw the line between all the points
3032
- ctx.lineWidth = this.options.datasetStrokeWidth;
3033
- ctx.strokeStyle = dataset.strokeColor;
3034
- ctx.beginPath();
3035
-
3036
- helpers.each(
3037
- pointsWithValues, function (point, index) {
3038
- if (index === 0) {
3039
- ctx.moveTo(point.x, point.y);
3040
- }
3041
- else{
3042
- if(this.options.bezierCurve) {
3043
- var previous = previousPoint(point, pointsWithValues, index);
3044
-
3045
- ctx.bezierCurveTo(
3046
- previous.controlPoints.outer.x,
3047
- previous.controlPoints.outer.y,
3048
- point.controlPoints.inner.x,
3049
- point.controlPoints.inner.y,
3050
- point.x,
3051
- point.y
3052
- );
3053
- }
3054
- else{
3055
- ctx.lineTo(point.x,point.y);
3056
- }
3057
- }
3058
- }, this
3059
- );
3060
-
3061
- ctx.stroke();
3062
-
3063
- if (this.options.datasetFill && pointsWithValues.length > 0) {
3064
- //Round off the line by going to the base of the chart, back to the start, then fill.
3065
- ctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint);
3066
- ctx.lineTo(pointsWithValues[0].x, this.scale.endPoint);
3067
- ctx.fillStyle = dataset.fillColor;
3068
- ctx.closePath();
3069
- ctx.fill();
3070
- }
3071
-
3072
- //Now draw the points over the line
3073
- //A little inefficient double looping, but better than the line
3074
- //lagging behind the point positions
3075
- helpers.each(
3076
- pointsWithValues,function (point) {
3077
- point.draw();
3078
- }
3079
- );
3080
- },this
3081
- );
3082
- }
3083
  }
3084
- );
3085
-
3086
-
3087
- }).call(this);
3088
- (function () {
3089
- "use strict";
3090
-
3091
- var root = this,
3092
- Chart = root.Chart,
3093
- //Cache a local reference to Chart.helpers
3094
- helpers = Chart.helpers;
3095
-
3096
- var defaultConfig = {
3097
- //Boolean - Show a backdrop to the scale label
3098
- scaleShowLabelBackdrop : true,
3099
-
3100
- //String - The colour of the label backdrop
3101
- scaleBackdropColor : "rgba(255,255,255,0.75)",
3102
-
3103
- // Boolean - Whether the scale should begin at zero
3104
- scaleBeginAtZero : true,
3105
-
3106
- //Number - The backdrop padding above & below the label in pixels
3107
- scaleBackdropPaddingY : 2,
3108
-
3109
- //Number - The backdrop padding to the side of the label in pixels
3110
- scaleBackdropPaddingX : 2,
3111
-
3112
- //Boolean - Show line for each value in the scale
3113
- scaleShowLine : true,
3114
-
3115
- //Boolean - Stroke a line around each segment in the chart
3116
- segmentShowStroke : true,
3117
-
3118
- //String - The colour of the stroke on each segement.
3119
- segmentStrokeColor : "#fff",
3120
-
3121
- //Number - The width of the stroke value in pixels
3122
- segmentStrokeWidth : 2,
3123
-
3124
- //Number - Amount of animation steps
3125
- animationSteps : 100,
3126
-
3127
- //String - Animation easing effect.
3128
- animationEasing : "easeOutBounce",
3129
-
3130
- //Boolean - Whether to animate the rotation of the chart
3131
- animateRotate : true,
3132
-
3133
- //Boolean - Whether to animate scaling the chart from the centre
3134
- animateScale : false,
3135
-
3136
- //String - A legend template
3137
- legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
3138
- };
3139
-
3140
-
3141
- Chart.Type.extend(
3142
- {
3143
- //Passing in a name registers this chart in the Chart namespace
3144
- name: "PolarArea",
3145
- //Providing a defaults will also register the deafults in the chart namespace
3146
- defaults : defaultConfig,
3147
- //Initialize is fired when the chart is initialized - Data is passed in as a parameter
3148
- //Config is automatically merged by the core of Chart.js, and is available at this.options
3149
- initialize: function (data) {
3150
- this.segments = [];
3151
- //Declare segment class as a chart instance specific class, so it can share props for this instance
3152
- this.SegmentArc = Chart.Arc.extend(
3153
- {
3154
- showStroke : this.options.segmentShowStroke,
3155
- strokeWidth : this.options.segmentStrokeWidth,
3156
- strokeColor : this.options.segmentStrokeColor,
3157
- ctx : this.chart.ctx,
3158
- innerRadius : 0,
3159
- x : this.chart.width/2,
3160
- y : this.chart.height/2
3161
- }
3162
- );
3163
- this.scale = new Chart.RadialScale(
3164
- {
3165
- display: this.options.showScale,
3166
- fontStyle: this.options.scaleFontStyle,
3167
- fontSize: this.options.scaleFontSize,
3168
- fontFamily: this.options.scaleFontFamily,
3169
- fontColor: this.options.scaleFontColor,
3170
- showLabels: this.options.scaleShowLabels,
3171
- showLabelBackdrop: this.options.scaleShowLabelBackdrop,
3172
- backdropColor: this.options.scaleBackdropColor,
3173
- backdropPaddingY : this.options.scaleBackdropPaddingY,
3174
- backdropPaddingX: this.options.scaleBackdropPaddingX,
3175
- lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
3176
- lineColor: this.options.scaleLineColor,
3177
- lineArc: true,
3178
- width: this.chart.width,
3179
- height: this.chart.height,
3180
- xCenter: this.chart.width/2,
3181
- yCenter: this.chart.height/2,
3182
- ctx : this.chart.ctx,
3183
- templateString: this.options.scaleLabel,
3184
- valuesCount: data.length
3185
- }
3186
- );
3187
-
3188
- this.updateScaleRange(data);
3189
-
3190
- this.scale.update();
3191
-
3192
- helpers.each(
3193
- data,function (segment,index) {
3194
- this.addData(segment,index,true);
3195
- },this
3196
- );
3197
-
3198
- //Set up tooltip events on the chart
3199
- if (this.options.showTooltips) {
3200
- helpers.bindEvents(
3201
- this, this.options.tooltipEvents, function (evt) {
3202
- var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
3203
- helpers.each(
3204
- this.segments,function (segment) {
3205
- segment.restore(["fillColor"]);
3206
- }
3207
- );
3208
- helpers.each(
3209
- activeSegments,function (activeSegment) {
3210
- activeSegment.fillColor = activeSegment.highlightColor;
3211
- }
3212
- );
3213
- this.showTooltip(activeSegments);
3214
- }
3215
- );
3216
- }
3217
-
3218
- this.render();
3219
- },
3220
- getSegmentsAtEvent : function (e) {
3221
- var segmentsArray = [];
3222
-
3223
- var location = helpers.getRelativePosition(e);
3224
-
3225
- helpers.each(
3226
- this.segments,function (segment) {
3227
- if (segment.inRange(location.x,location.y)) { segmentsArray.push(segment);
3228
- }
3229
- },this
3230
- );
3231
- return segmentsArray;
3232
- },
3233
- addData : function (segment, atIndex, silent) {
3234
- var index = atIndex || this.segments.length;
3235
-
3236
- this.segments.splice(
3237
- index, 0, new this.SegmentArc(
3238
- {
3239
- fillColor: segment.color,
3240
- highlightColor: segment.highlight || segment.color,
3241
- label: segment.label,
3242
- value: segment.value,
3243
- outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),
3244
- circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),
3245
- startAngle: Math.PI * 1.5
3246
- }
3247
- )
3248
- );
3249
- if (!silent) {
3250
- this.reflow();
3251
- this.update();
3252
- }
3253
- },
3254
- removeData: function (atIndex) {
3255
- var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
3256
- this.segments.splice(indexToDelete, 1);
3257
- this.reflow();
3258
- this.update();
3259
- },
3260
- calculateTotal: function (data) {
3261
- this.total = 0;
3262
- helpers.each(
3263
- data,function (segment) {
3264
- this.total += segment.value;
3265
- },this
3266
- );
3267
- this.scale.valuesCount = this.segments.length;
3268
- },
3269
- updateScaleRange: function (datapoints) {
3270
- var valuesArray = [];
3271
- helpers.each(
3272
- datapoints,function (segment) {
3273
- valuesArray.push(segment.value);
3274
- }
3275
- );
3276
-
3277
- var scaleSizes = (this.options.scaleOverride) ?
3278
- {
3279
- steps: this.options.scaleSteps,
3280
- stepValue: this.options.scaleStepWidth,
3281
- min: this.options.scaleStartValue,
3282
- max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
3283
- } :
3284
- helpers.calculateScaleRange(
3285
- valuesArray,
3286
- helpers.min([this.chart.width, this.chart.height])/2,
3287
- this.options.scaleFontSize,
3288
- this.options.scaleBeginAtZero,
3289
- this.options.scaleIntegersOnly
3290
- );
3291
-
3292
- helpers.extend(
3293
- this.scale,
3294
- scaleSizes,
3295
- {
3296
- size: helpers.min([this.chart.width, this.chart.height]),
3297
- xCenter: this.chart.width/2,
3298
- yCenter: this.chart.height/2
3299
- }
3300
- );
3301
-
3302
- },
3303
- update : function () {
3304
- this.calculateTotal(this.segments);
3305
-
3306
- helpers.each(
3307
- this.segments,function (segment) {
3308
- segment.save();
3309
- }
3310
- );
3311
- this.render();
3312
- },
3313
- reflow : function () {
3314
- helpers.extend(
3315
- this.SegmentArc.prototype,{
3316
- x : this.chart.width/2,
3317
- y : this.chart.height/2
3318
- }
3319
- );
3320
- this.updateScaleRange(this.segments);
3321
- this.scale.update();
3322
-
3323
- helpers.extend(
3324
- this.scale,{
3325
- xCenter: this.chart.width/2,
3326
- yCenter: this.chart.height/2
3327
- }
3328
- );
3329
-
3330
- helpers.each(
3331
- this.segments, function (segment) {
3332
- segment.update(
3333
- {
3334
- outerRadius : this.scale.calculateCenterOffset(segment.value)
3335
- }
3336
- );
3337
- }, this
3338
- );
3339
-
3340
- },
3341
- draw : function (ease) {
3342
- var easingDecimal = ease || 1;
3343
- //Clear & draw the canvas
3344
- this.clear();
3345
- helpers.each(
3346
- this.segments,function (segment, index) {
3347
- segment.transition(
3348
- {
3349
- circumference : this.scale.getCircumference(),
3350
- outerRadius : this.scale.calculateCenterOffset(segment.value)
3351
- },easingDecimal
3352
- );
3353
-
3354
- segment.endAngle = segment.startAngle + segment.circumference;
3355
-
3356
- // If we've removed the first segment we need to set the first one to
3357
- // start at the top.
3358
- if (index === 0) {
3359
- segment.startAngle = Math.PI * 1.5;
3360
- }
3361
-
3362
- //Check to see if it's the last segment, if not get the next and update the start angle
3363
- if (index < this.segments.length - 1) {
3364
- this.segments[index+1].startAngle = segment.endAngle;
3365
- }
3366
- segment.draw();
3367
- }, this
3368
- );
3369
- this.scale.draw();
3370
- }
3371
  }
3372
- );
3373
-
3374
- }).call(this);
3375
- (function () {
3376
- "use strict";
3377
-
3378
- var root = this,
3379
- Chart = root.Chart,
3380
- helpers = Chart.helpers;
3381
-
3382
-
3383
-
3384
- Chart.Type.extend(
3385
- {
3386
- name: "Radar",
3387
- defaults:{
3388
- //Boolean - Whether to show lines for each scale point
3389
- scaleShowLine : true,
3390
-
3391
- //Boolean - Whether we show the angle lines out of the radar
3392
- angleShowLineOut : true,
3393
-
3394
- //Boolean - Whether to show labels on the scale
3395
- scaleShowLabels : false,
3396
-
3397
- // Boolean - Whether the scale should begin at zero
3398
- scaleBeginAtZero : true,
3399
-
3400
- //String - Colour of the angle line
3401
- angleLineColor : "rgba(0,0,0,.1)",
3402
-
3403
- //Number - Pixel width of the angle line
3404
- angleLineWidth : 1,
3405
-
3406
- //String - Point label font declaration
3407
- pointLabelFontFamily : "'Arial'",
3408
-
3409
- //String - Point label font weight
3410
- pointLabelFontStyle : "normal",
3411
-
3412
- //Number - Point label font size in pixels
3413
- pointLabelFontSize : 10,
3414
-
3415
- //String - Point label font colour
3416
- pointLabelFontColor : "#666",
3417
-
3418
- //Boolean - Whether to show a dot for each point
3419
- pointDot : true,
3420
-
3421
- //Number - Radius of each point dot in pixels
3422
- pointDotRadius : 3,
3423
-
3424
- //Number - Pixel width of point dot stroke
3425
- pointDotStrokeWidth : 1,
3426
-
3427
- //Number - amount extra to add to the radius to cater for hit detection outside the drawn point
3428
- pointHitDetectionRadius : 20,
3429
-
3430
- //Boolean - Whether to show a stroke for datasets
3431
- datasetStroke : true,
3432
-
3433
- //Number - Pixel width of dataset stroke
3434
- datasetStrokeWidth : 2,
3435
-
3436
- //Boolean - Whether to fill the dataset with a colour
3437
- datasetFill : true,
3438
-
3439
- //String - A legend template
3440
- legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
3441
-
3442
- },
3443
-
3444
- initialize: function (data) {
3445
- this.PointClass = Chart.Point.extend(
3446
- {
3447
- strokeWidth : this.options.pointDotStrokeWidth,
3448
- radius : this.options.pointDotRadius,
3449
- display: this.options.pointDot,
3450
- hitDetectionRadius : this.options.pointHitDetectionRadius,
3451
- ctx : this.chart.ctx
3452
- }
3453
- );
3454
-
3455
- this.datasets = [];
3456
-
3457
- this.buildScale(data);
3458
-
3459
- //Set up tooltip events on the chart
3460
- if (this.options.showTooltips) {
3461
- helpers.bindEvents(
3462
- this, this.options.tooltipEvents, function (evt) {
3463
- var activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
3464
-
3465
- this.eachPoints(
3466
- function (point) {
3467
- point.restore(['fillColor', 'strokeColor']);
3468
- }
3469
- );
3470
- helpers.each(
3471
- activePointsCollection, function (activePoint) {
3472
- activePoint.fillColor = activePoint.highlightFill;
3473
- activePoint.strokeColor = activePoint.highlightStroke;
3474
- }
3475
- );
3476
-
3477
- this.showTooltip(activePointsCollection);
3478
- }
3479
- );
3480
- }
3481
-
3482
- //Iterate through each of the datasets, and build this into a property of the chart
3483
- helpers.each(
3484
- data.datasets,function (dataset) {
3485
-
3486
- var datasetObject = {
3487
- label: dataset.label || null,
3488
- fillColor : dataset.fillColor,
3489
- strokeColor : dataset.strokeColor,
3490
- pointColor : dataset.pointColor,
3491
- pointStrokeColor : dataset.pointStrokeColor,
3492
- points : []
3493
- };
3494
-
3495
- this.datasets.push(datasetObject);
3496
-
3497
- helpers.each(
3498
- dataset.data,function (dataPoint,index) {
3499
- //Add a new point for each piece of data, passing any required data to draw.
3500
- var pointPosition;
3501
- if (!this.scale.animation) {
3502
- pointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint));
3503
- }
3504
- datasetObject.points.push(
3505
- new this.PointClass(
3506
- {
3507
- value : dataPoint,
3508
- label : data.labels[index],
3509
- datasetLabel: dataset.label,
3510
- x: (this.options.animation) ? this.scale.xCenter : pointPosition.x,
3511
- y: (this.options.animation) ? this.scale.yCenter : pointPosition.y,
3512
- strokeColor : dataset.pointStrokeColor,
3513
- fillColor : dataset.pointColor,
3514
- highlightFill : dataset.pointHighlightFill || dataset.pointColor,
3515
- highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
3516
- }
3517
- )
3518
- );
3519
- },this
3520
- );
3521
-
3522
- },this
3523
- );
3524
-
3525
- this.render();
3526
- },
3527
- eachPoints : function (callback) {
3528
- helpers.each(
3529
- this.datasets,function (dataset) {
3530
- helpers.each(dataset.points,callback,this);
3531
- },this
3532
- );
3533
- },
3534
-
3535
- getPointsAtEvent : function (evt) {
3536
- var mousePosition = helpers.getRelativePosition(evt),
3537
- fromCenter = helpers.getAngleFromPoint(
3538
- {
3539
- x: this.scale.xCenter,
3540
- y: this.scale.yCenter
3541
- }, mousePosition
3542
- );
3543
-
3544
- var anglePerIndex = (Math.PI * 2) /this.scale.valuesCount,
3545
- pointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex),
3546
- activePointsCollection = [];
3547
-
3548
- // If we're at the top, make the pointIndex 0 to get the first of the array.
3549
- if (pointIndex >= this.scale.valuesCount || pointIndex < 0) {
3550
- pointIndex = 0;
3551
- }
3552
-
3553
- if (fromCenter.distance <= this.scale.drawingArea) {
3554
- helpers.each(
3555
- this.datasets, function (dataset) {
3556
- activePointsCollection.push(dataset.points[pointIndex]);
3557
- }
3558
- );
3559
- }
3560
-
3561
- return activePointsCollection;
3562
- },
3563
-
3564
- buildScale : function (data) {
3565
- this.scale = new Chart.RadialScale(
3566
- {
3567
- display: this.options.showScale,
3568
- fontStyle: this.options.scaleFontStyle,
3569
- fontSize: this.options.scaleFontSize,
3570
- fontFamily: this.options.scaleFontFamily,
3571
- fontColor: this.options.scaleFontColor,
3572
- showLabels: this.options.scaleShowLabels,
3573
- showLabelBackdrop: this.options.scaleShowLabelBackdrop,
3574
- backdropColor: this.options.scaleBackdropColor,
3575
- backdropPaddingY : this.options.scaleBackdropPaddingY,
3576
- backdropPaddingX: this.options.scaleBackdropPaddingX,
3577
- lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
3578
- lineColor: this.options.scaleLineColor,
3579
- angleLineColor : this.options.angleLineColor,
3580
- angleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0,
3581
- // Point labels at the edge of each line
3582
- pointLabelFontColor : this.options.pointLabelFontColor,
3583
- pointLabelFontSize : this.options.pointLabelFontSize,
3584
- pointLabelFontFamily : this.options.pointLabelFontFamily,
3585
- pointLabelFontStyle : this.options.pointLabelFontStyle,
3586
- height : this.chart.height,
3587
- width: this.chart.width,
3588
- xCenter: this.chart.width/2,
3589
- yCenter: this.chart.height/2,
3590
- ctx : this.chart.ctx,
3591
- templateString: this.options.scaleLabel,
3592
- labels: data.labels,
3593
- valuesCount: data.datasets[0].data.length
3594
- }
3595
- );
3596
-
3597
- this.scale.setScaleSize();
3598
- this.updateScaleRange(data.datasets);
3599
- this.scale.buildYLabels();
3600
- },
3601
- updateScaleRange: function (datasets) {
3602
- var valuesArray = (function () {
3603
- var totalDataArray = [];
3604
- helpers.each(
3605
- datasets,function (dataset) {
3606
- if (dataset.data) {
3607
- totalDataArray = totalDataArray.concat(dataset.data);
3608
- }
3609
- else {
3610
- helpers.each(
3611
- dataset.points, function (point) {
3612
- totalDataArray.push(point.value);
3613
- }
3614
- );
3615
- }
3616
- }
3617
- );
3618
- return totalDataArray;
3619
- })();
3620
-
3621
-
3622
- var scaleSizes = (this.options.scaleOverride) ?
3623
- {
3624
- steps: this.options.scaleSteps,
3625
- stepValue: this.options.scaleStepWidth,
3626
- min: this.options.scaleStartValue,
3627
- max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
3628
- } :
3629
- helpers.calculateScaleRange(
3630
- valuesArray,
3631
- helpers.min([this.chart.width, this.chart.height])/2,
3632
- this.options.scaleFontSize,
3633
- this.options.scaleBeginAtZero,
3634
- this.options.scaleIntegersOnly
3635
- );
3636
-
3637
- helpers.extend(
3638
- this.scale,
3639
- scaleSizes
3640
- );
3641
-
3642
- },
3643
- addData : function (valuesArray,label) {
3644
- //Map the values array for each of the datasets
3645
- this.scale.valuesCount++;
3646
- helpers.each(
3647
- valuesArray,function (value,datasetIndex) {
3648
- var pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value));
3649
- this.datasets[datasetIndex].points.push(
3650
- new this.PointClass(
3651
- {
3652
- value : value,
3653
- label : label,
3654
- x: pointPosition.x,
3655
- y: pointPosition.y,
3656
- strokeColor : this.datasets[datasetIndex].pointStrokeColor,
3657
- fillColor : this.datasets[datasetIndex].pointColor
3658
- }
3659
- )
3660
- );
3661
- },this
3662
- );
3663
-
3664
- this.scale.labels.push(label);
3665
-
3666
- this.reflow();
3667
-
3668
- this.update();
3669
- },
3670
- removeData : function () {
3671
- this.scale.valuesCount--;
3672
- this.scale.labels.shift();
3673
- helpers.each(
3674
- this.datasets,function (dataset) {
3675
- dataset.points.shift();
3676
- },this
3677
- );
3678
- this.reflow();
3679
- this.update();
3680
- },
3681
- update : function () {
3682
- this.eachPoints(
3683
- function (point) {
3684
- point.save();
3685
- }
3686
- );
3687
- this.reflow();
3688
- this.render();
3689
- },
3690
- reflow: function () {
3691
- helpers.extend(
3692
- this.scale, {
3693
- width : this.chart.width,
3694
- height: this.chart.height,
3695
- size : helpers.min([this.chart.width, this.chart.height]),
3696
- xCenter: this.chart.width/2,
3697
- yCenter: this.chart.height/2
3698
- }
3699
- );
3700
- this.updateScaleRange(this.datasets);
3701
- this.scale.setScaleSize();
3702
- this.scale.buildYLabels();
3703
- },
3704
- draw : function (ease) {
3705
- var easeDecimal = ease || 1,
3706
- ctx = this.chart.ctx;
3707
- this.clear();
3708
- this.scale.draw();
3709
-
3710
- helpers.each(
3711
- this.datasets,function (dataset) {
3712
-
3713
- //Transition each point first so that the line and point drawing isn't out of sync
3714
- helpers.each(
3715
- dataset.points,function (point,index) {
3716
- if (point.hasValue()) {
3717
- point.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);
3718
- }
3719
- },this
3720
- );
3721
-
3722
-
3723
-
3724
- //Draw the line between all the points
3725
- ctx.lineWidth = this.options.datasetStrokeWidth;
3726
- ctx.strokeStyle = dataset.strokeColor;
3727
- ctx.beginPath();
3728
- helpers.each(
3729
- dataset.points,function (point,index) {
3730
- if (index === 0) {
3731
- ctx.moveTo(point.x,point.y);
3732
- }
3733
- else{
3734
- ctx.lineTo(point.x,point.y);
3735
- }
3736
- },this
3737
- );
3738
- ctx.closePath();
3739
- ctx.stroke();
3740
-
3741
- ctx.fillStyle = dataset.fillColor;
3742
- ctx.fill();
3743
-
3744
- //Now draw the points over the line
3745
- //A little inefficient double looping, but better than the line
3746
- //lagging behind the point positions
3747
- helpers.each(
3748
- dataset.points,function (point) {
3749
- if (point.hasValue()) {
3750
- point.draw();
3751
- }
3752
- }
3753
- );
3754
-
3755
- },this
3756
- );
3757
-
3758
  }
3759
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3760
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3761
  );
3762
-
3763
-
3764
-
3765
-
3766
-
3767
- }).call(this);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Chart.js v3.7.1
3
+ * https://www.chartjs.org
4
+ * (c) 2022 Chart.js Contributors
5
+ * Released under the MIT License
6
  */
7
+ (function (global, factory) {
8
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
9
+ typeof define === 'function' && define.amd ? define(factory) :
10
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Chart = factory());
11
+ })(this, (function () { 'use strict';
12
+
13
+ function fontString(pixelSize, fontStyle, fontFamily) {
14
+ return fontStyle + ' ' + pixelSize + 'px ' + fontFamily;
15
+ }
16
+ const requestAnimFrame = (function() {
17
+ if (typeof window === 'undefined') {
18
+ return function(callback) {
19
+ return callback();
 
 
 
 
 
 
 
 
 
 
20
  };
21
+ }
22
+ return window.requestAnimationFrame;
23
+ }());
24
+ function throttled(fn, thisArg, updateFn) {
25
+ const updateArgs = updateFn || ((args) => Array.prototype.slice.call(args));
26
+ let ticking = false;
27
+ let args = [];
28
+ return function(...rest) {
29
+ args = updateArgs(rest);
30
+ if (!ticking) {
31
+ ticking = true;
32
+ requestAnimFrame.call(window, () => {
33
+ ticking = false;
34
+ fn.apply(thisArg, args);
35
+ });
36
+ }
37
+ };
38
+ }
39
+ function debounce(fn, delay) {
40
+ let timeout;
41
+ return function(...args) {
42
+ if (delay) {
43
+ clearTimeout(timeout);
44
+ timeout = setTimeout(fn, delay, args);
45
+ } else {
46
+ fn.apply(this, args);
47
+ }
48
+ return delay;
49
+ };
50
+ }
51
+ const _toLeftRightCenter = (align) => align === 'start' ? 'left' : align === 'end' ? 'right' : 'center';
52
+ const _alignStartEnd = (align, start, end) => align === 'start' ? start : align === 'end' ? end : (start + end) / 2;
53
+ const _textX = (align, left, right, rtl) => {
54
+ const check = rtl ? 'left' : 'right';
55
+ return align === check ? right : align === 'center' ? (left + right) / 2 : left;
56
+ };
57
+
58
+ class Animator {
59
+ constructor() {
60
+ this._request = null;
61
+ this._charts = new Map();
62
+ this._running = false;
63
+ this._lastDate = undefined;
64
+ }
65
+ _notify(chart, anims, date, type) {
66
+ const callbacks = anims.listeners[type];
67
+ const numSteps = anims.duration;
68
+ callbacks.forEach(fn => fn({
69
+ chart,
70
+ initial: anims.initial,
71
+ numSteps,
72
+ currentStep: Math.min(date - anims.start, numSteps)
73
+ }));
74
+ }
75
+ _refresh() {
76
+ if (this._request) {
77
+ return;
78
+ }
79
+ this._running = true;
80
+ this._request = requestAnimFrame.call(window, () => {
81
+ this._update();
82
+ this._request = null;
83
+ if (this._running) {
84
+ this._refresh();
85
+ }
86
+ });
87
+ }
88
+ _update(date = Date.now()) {
89
+ let remaining = 0;
90
+ this._charts.forEach((anims, chart) => {
91
+ if (!anims.running || !anims.items.length) {
92
+ return;
93
+ }
94
+ const items = anims.items;
95
+ let i = items.length - 1;
96
+ let draw = false;
97
+ let item;
98
+ for (; i >= 0; --i) {
99
+ item = items[i];
100
+ if (item._active) {
101
+ if (item._total > anims.duration) {
102
+ anims.duration = item._total;
103
+ }
104
+ item.tick(date);
105
+ draw = true;
106
+ } else {
107
+ items[i] = items[items.length - 1];
108
+ items.pop();
109
+ }
110
+ }
111
+ if (draw) {
112
+ chart.draw();
113
+ this._notify(chart, anims, date, 'progress');
114
+ }
115
+ if (!items.length) {
116
+ anims.running = false;
117
+ this._notify(chart, anims, date, 'complete');
118
+ anims.initial = false;
119
+ }
120
+ remaining += items.length;
121
+ });
122
+ this._lastDate = date;
123
+ if (remaining === 0) {
124
+ this._running = false;
125
+ }
126
+ }
127
+ _getAnims(chart) {
128
+ const charts = this._charts;
129
+ let anims = charts.get(chart);
130
+ if (!anims) {
131
+ anims = {
132
+ running: false,
133
+ initial: true,
134
+ items: [],
135
+ listeners: {
136
+ complete: [],
137
+ progress: []
138
+ }
139
+ };
140
+ charts.set(chart, anims);
141
+ }
142
+ return anims;
143
+ }
144
+ listen(chart, event, cb) {
145
+ this._getAnims(chart).listeners[event].push(cb);
146
+ }
147
+ add(chart, items) {
148
+ if (!items || !items.length) {
149
+ return;
150
+ }
151
+ this._getAnims(chart).items.push(...items);
152
+ }
153
+ has(chart) {
154
+ return this._getAnims(chart).items.length > 0;
155
+ }
156
+ start(chart) {
157
+ const anims = this._charts.get(chart);
158
+ if (!anims) {
159
+ return;
160
+ }
161
+ anims.running = true;
162
+ anims.start = Date.now();
163
+ anims.duration = anims.items.reduce((acc, cur) => Math.max(acc, cur._duration), 0);
164
+ this._refresh();
165
+ }
166
+ running(chart) {
167
+ if (!this._running) {
168
+ return false;
169
+ }
170
+ const anims = this._charts.get(chart);
171
+ if (!anims || !anims.running || !anims.items.length) {
172
+ return false;
173
+ }
174
+ return true;
175
+ }
176
+ stop(chart) {
177
+ const anims = this._charts.get(chart);
178
+ if (!anims || !anims.items.length) {
179
+ return;
180
+ }
181
+ const items = anims.items;
182
+ let i = items.length - 1;
183
+ for (; i >= 0; --i) {
184
+ items[i].cancel();
185
+ }
186
+ anims.items = [];
187
+ this._notify(chart, anims, Date.now(), 'complete');
188
+ }
189
+ remove(chart) {
190
+ return this._charts.delete(chart);
191
+ }
192
+ }
193
+ var animator = new Animator();
194
+
195
+ /*!
196
+ * @kurkle/color v0.1.9
197
+ * https://github.com/kurkle/color#readme
198
+ * (c) 2020 Jukka Kurkela
199
+ * Released under the MIT License
200
+ */
201
+ const map$1 = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15};
202
+ const hex = '0123456789ABCDEF';
203
+ const h1 = (b) => hex[b & 0xF];
204
+ const h2 = (b) => hex[(b & 0xF0) >> 4] + hex[b & 0xF];
205
+ const eq = (b) => (((b & 0xF0) >> 4) === (b & 0xF));
206
+ function isShort(v) {
207
+ return eq(v.r) && eq(v.g) && eq(v.b) && eq(v.a);
208
+ }
209
+ function hexParse(str) {
210
+ var len = str.length;
211
+ var ret;
212
+ if (str[0] === '#') {
213
+ if (len === 4 || len === 5) {
214
+ ret = {
215
+ r: 255 & map$1[str[1]] * 17,
216
+ g: 255 & map$1[str[2]] * 17,
217
+ b: 255 & map$1[str[3]] * 17,
218
+ a: len === 5 ? map$1[str[4]] * 17 : 255
219
+ };
220
+ } else if (len === 7 || len === 9) {
221
+ ret = {
222
+ r: map$1[str[1]] << 4 | map$1[str[2]],
223
+ g: map$1[str[3]] << 4 | map$1[str[4]],
224
+ b: map$1[str[5]] << 4 | map$1[str[6]],
225
+ a: len === 9 ? (map$1[str[7]] << 4 | map$1[str[8]]) : 255
226
+ };
227
  }
228
+ }
229
+ return ret;
230
+ }
231
+ function hexString(v) {
232
+ var f = isShort(v) ? h1 : h2;
233
+ return v
234
+ ? '#' + f(v.r) + f(v.g) + f(v.b) + (v.a < 255 ? f(v.a) : '')
235
+ : v;
236
+ }
237
+ function round(v) {
238
+ return v + 0.5 | 0;
239
+ }
240
+ const lim = (v, l, h) => Math.max(Math.min(v, h), l);
241
+ function p2b(v) {
242
+ return lim(round(v * 2.55), 0, 255);
243
+ }
244
+ function n2b(v) {
245
+ return lim(round(v * 255), 0, 255);
246
+ }
247
+ function b2n(v) {
248
+ return lim(round(v / 2.55) / 100, 0, 1);
249
+ }
250
+ function n2p(v) {
251
+ return lim(round(v * 100), 0, 100);
252
+ }
253
+ const RGB_RE = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;
254
+ function rgbParse(str) {
255
+ const m = RGB_RE.exec(str);
256
+ let a = 255;
257
+ let r, g, b;
258
+ if (!m) {
259
+ return;
260
+ }
261
+ if (m[7] !== r) {
262
+ const v = +m[7];
263
+ a = 255 & (m[8] ? p2b(v) : v * 255);
264
+ }
265
+ r = +m[1];
266
+ g = +m[3];
267
+ b = +m[5];
268
+ r = 255 & (m[2] ? p2b(r) : r);
269
+ g = 255 & (m[4] ? p2b(g) : g);
270
+ b = 255 & (m[6] ? p2b(b) : b);
271
+ return {
272
+ r: r,
273
+ g: g,
274
+ b: b,
275
+ a: a
276
  };
277
+ }
278
+ function rgbString(v) {
279
+ return v && (
280
+ v.a < 255
281
+ ? `rgba(${v.r}, ${v.g}, ${v.b}, ${b2n(v.a)})`
282
+ : `rgb(${v.r}, ${v.g}, ${v.b})`
283
+ );
284
+ }
285
+ const HUE_RE = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;
286
+ function hsl2rgbn(h, s, l) {
287
+ const a = s * Math.min(l, 1 - l);
288
+ const f = (n, k = (n + h / 30) % 12) => l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
289
+ return [f(0), f(8), f(4)];
290
+ }
291
+ function hsv2rgbn(h, s, v) {
292
+ const f = (n, k = (n + h / 60) % 6) => v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
293
+ return [f(5), f(3), f(1)];
294
+ }
295
+ function hwb2rgbn(h, w, b) {
296
+ const rgb = hsl2rgbn(h, 1, 0.5);
297
+ let i;
298
+ if (w + b > 1) {
299
+ i = 1 / (w + b);
300
+ w *= i;
301
+ b *= i;
302
+ }
303
+ for (i = 0; i < 3; i++) {
304
+ rgb[i] *= 1 - w - b;
305
+ rgb[i] += w;
306
+ }
307
+ return rgb;
308
+ }
309
+ function rgb2hsl(v) {
310
+ const range = 255;
311
+ const r = v.r / range;
312
+ const g = v.g / range;
313
+ const b = v.b / range;
314
+ const max = Math.max(r, g, b);
315
+ const min = Math.min(r, g, b);
316
+ const l = (max + min) / 2;
317
+ let h, s, d;
318
+ if (max !== min) {
319
+ d = max - min;
320
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
321
+ h = max === r
322
+ ? ((g - b) / d) + (g < b ? 6 : 0)
323
+ : max === g
324
+ ? (b - r) / d + 2
325
+ : (r - g) / d + 4;
326
+ h = h * 60 + 0.5;
327
+ }
328
+ return [h | 0, s || 0, l];
329
+ }
330
+ function calln(f, a, b, c) {
331
+ return (
332
+ Array.isArray(a)
333
+ ? f(a[0], a[1], a[2])
334
+ : f(a, b, c)
335
+ ).map(n2b);
336
+ }
337
+ function hsl2rgb(h, s, l) {
338
+ return calln(hsl2rgbn, h, s, l);
339
+ }
340
+ function hwb2rgb(h, w, b) {
341
+ return calln(hwb2rgbn, h, w, b);
342
+ }
343
+ function hsv2rgb(h, s, v) {
344
+ return calln(hsv2rgbn, h, s, v);
345
+ }
346
+ function hue(h) {
347
+ return (h % 360 + 360) % 360;
348
+ }
349
+ function hueParse(str) {
350
+ const m = HUE_RE.exec(str);
351
+ let a = 255;
352
+ let v;
353
+ if (!m) {
354
+ return;
355
+ }
356
+ if (m[5] !== v) {
357
+ a = m[6] ? p2b(+m[5]) : n2b(+m[5]);
358
+ }
359
+ const h = hue(+m[2]);
360
+ const p1 = +m[3] / 100;
361
+ const p2 = +m[4] / 100;
362
+ if (m[1] === 'hwb') {
363
+ v = hwb2rgb(h, p1, p2);
364
+ } else if (m[1] === 'hsv') {
365
+ v = hsv2rgb(h, p1, p2);
366
+ } else {
367
+ v = hsl2rgb(h, p1, p2);
368
+ }
369
+ return {
370
+ r: v[0],
371
+ g: v[1],
372
+ b: v[2],
373
+ a: a
374
+ };
375
+ }
376
+ function rotate(v, deg) {
377
+ var h = rgb2hsl(v);
378
+ h[0] = hue(h[0] + deg);
379
+ h = hsl2rgb(h);
380
+ v.r = h[0];
381
+ v.g = h[1];
382
+ v.b = h[2];
383
+ }
384
+ function hslString(v) {
385
+ if (!v) {
386
+ return;
387
+ }
388
+ const a = rgb2hsl(v);
389
+ const h = a[0];
390
+ const s = n2p(a[1]);
391
+ const l = n2p(a[2]);
392
+ return v.a < 255
393
+ ? `hsla(${h}, ${s}%, ${l}%, ${b2n(v.a)})`
394
+ : `hsl(${h}, ${s}%, ${l}%)`;
395
+ }
396
+ const map$1$1 = {
397
+ x: 'dark',
398
+ Z: 'light',
399
+ Y: 're',
400
+ X: 'blu',
401
+ W: 'gr',
402
+ V: 'medium',
403
+ U: 'slate',
404
+ A: 'ee',
405
+ T: 'ol',
406
+ S: 'or',
407
+ B: 'ra',
408
+ C: 'lateg',
409
+ D: 'ights',
410
+ R: 'in',
411
+ Q: 'turquois',
412
+ E: 'hi',
413
+ P: 'ro',
414
+ O: 'al',
415
+ N: 'le',
416
+ M: 'de',
417
+ L: 'yello',
418
+ F: 'en',
419
+ K: 'ch',
420
+ G: 'arks',
421
+ H: 'ea',
422
+ I: 'ightg',
423
+ J: 'wh'
424
+ };
425
+ const names = {
426
+ OiceXe: 'f0f8ff',
427
+ antiquewEte: 'faebd7',
428
+ aqua: 'ffff',
429
+ aquamarRe: '7fffd4',
430
+ azuY: 'f0ffff',
431
+ beige: 'f5f5dc',
432
+ bisque: 'ffe4c4',
433
+ black: '0',
434
+ blanKedOmond: 'ffebcd',
435
+ Xe: 'ff',
436
+ XeviTet: '8a2be2',
437
+ bPwn: 'a52a2a',
438
+ burlywood: 'deb887',
439
+ caMtXe: '5f9ea0',
440
+ KartYuse: '7fff00',
441
+ KocTate: 'd2691e',
442
+ cSO: 'ff7f50',
443
+ cSnflowerXe: '6495ed',
444
+ cSnsilk: 'fff8dc',
445
+ crimson: 'dc143c',
446
+ cyan: 'ffff',
447
+ xXe: '8b',
448
+ xcyan: '8b8b',
449
+ xgTMnPd: 'b8860b',
450
+ xWay: 'a9a9a9',
451
+ xgYF: '6400',
452
+ xgYy: 'a9a9a9',
453
+ xkhaki: 'bdb76b',
454
+ xmagFta: '8b008b',
455
+ xTivegYF: '556b2f',
456
+ xSange: 'ff8c00',
457
+ xScEd: '9932cc',
458
+ xYd: '8b0000',
459
+ xsOmon: 'e9967a',
460
+ xsHgYF: '8fbc8f',
461
+ xUXe: '483d8b',
462
+ xUWay: '2f4f4f',
463
+ xUgYy: '2f4f4f',
464
+ xQe: 'ced1',
465
+ xviTet: '9400d3',
466
+ dAppRk: 'ff1493',
467
+ dApskyXe: 'bfff',
468
+ dimWay: '696969',
469
+ dimgYy: '696969',
470
+ dodgerXe: '1e90ff',
471
+ fiYbrick: 'b22222',
472
+ flSOwEte: 'fffaf0',
473
+ foYstWAn: '228b22',
474
+ fuKsia: 'ff00ff',
475
+ gaRsbSo: 'dcdcdc',
476
+ ghostwEte: 'f8f8ff',
477
+ gTd: 'ffd700',
478
+ gTMnPd: 'daa520',
479
+ Way: '808080',
480
+ gYF: '8000',
481
+ gYFLw: 'adff2f',
482
+ gYy: '808080',
483
+ honeyMw: 'f0fff0',
484
+ hotpRk: 'ff69b4',
485
+ RdianYd: 'cd5c5c',
486
+ Rdigo: '4b0082',
487
+ ivSy: 'fffff0',
488
+ khaki: 'f0e68c',
489
+ lavFMr: 'e6e6fa',
490
+ lavFMrXsh: 'fff0f5',
491
+ lawngYF: '7cfc00',
492
+ NmoncEffon: 'fffacd',
493
+ ZXe: 'add8e6',
494
+ ZcSO: 'f08080',
495
+ Zcyan: 'e0ffff',
496
+ ZgTMnPdLw: 'fafad2',
497
+ ZWay: 'd3d3d3',
498
+ ZgYF: '90ee90',
499
+ ZgYy: 'd3d3d3',
500
+ ZpRk: 'ffb6c1',
501
+ ZsOmon: 'ffa07a',
502
+ ZsHgYF: '20b2aa',
503
+ ZskyXe: '87cefa',
504
+ ZUWay: '778899',
505
+ ZUgYy: '778899',
506
+ ZstAlXe: 'b0c4de',
507
+ ZLw: 'ffffe0',
508
+ lime: 'ff00',
509
+ limegYF: '32cd32',
510
+ lRF: 'faf0e6',
511
+ magFta: 'ff00ff',
512
+ maPon: '800000',
513
+ VaquamarRe: '66cdaa',
514
+ VXe: 'cd',
515
+ VScEd: 'ba55d3',
516
+ VpurpN: '9370db',
517
+ VsHgYF: '3cb371',
518
+ VUXe: '7b68ee',
519
+ VsprRggYF: 'fa9a',
520
+ VQe: '48d1cc',
521
+ VviTetYd: 'c71585',
522
+ midnightXe: '191970',
523
+ mRtcYam: 'f5fffa',
524
+ mistyPse: 'ffe4e1',
525
+ moccasR: 'ffe4b5',
526
+ navajowEte: 'ffdead',
527
+ navy: '80',
528
+ Tdlace: 'fdf5e6',
529
+ Tive: '808000',
530
+ TivedBb: '6b8e23',
531
+ Sange: 'ffa500',
532
+ SangeYd: 'ff4500',
533
+ ScEd: 'da70d6',
534
+ pOegTMnPd: 'eee8aa',
535
+ pOegYF: '98fb98',
536
+ pOeQe: 'afeeee',
537
+ pOeviTetYd: 'db7093',
538
+ papayawEp: 'ffefd5',
539
+ pHKpuff: 'ffdab9',
540
+ peru: 'cd853f',
541
+ pRk: 'ffc0cb',
542
+ plum: 'dda0dd',
543
+ powMrXe: 'b0e0e6',
544
+ purpN: '800080',
545
+ YbeccapurpN: '663399',
546
+ Yd: 'ff0000',
547
+ Psybrown: 'bc8f8f',
548
+ PyOXe: '4169e1',
549
+ saddNbPwn: '8b4513',
550
+ sOmon: 'fa8072',
551
+ sandybPwn: 'f4a460',
552
+ sHgYF: '2e8b57',
553
+ sHshell: 'fff5ee',
554
+ siFna: 'a0522d',
555
+ silver: 'c0c0c0',
556
+ skyXe: '87ceeb',
557
+ UXe: '6a5acd',
558
+ UWay: '708090',
559
+ UgYy: '708090',
560
+ snow: 'fffafa',
561
+ sprRggYF: 'ff7f',
562
+ stAlXe: '4682b4',
563
+ tan: 'd2b48c',
564
+ teO: '8080',
565
+ tEstN: 'd8bfd8',
566
+ tomato: 'ff6347',
567
+ Qe: '40e0d0',
568
+ viTet: 'ee82ee',
569
+ JHt: 'f5deb3',
570
+ wEte: 'ffffff',
571
+ wEtesmoke: 'f5f5f5',
572
+ Lw: 'ffff00',
573
+ LwgYF: '9acd32'
574
+ };
575
+ function unpack() {
576
+ const unpacked = {};
577
+ const keys = Object.keys(names);
578
+ const tkeys = Object.keys(map$1$1);
579
+ let i, j, k, ok, nk;
580
+ for (i = 0; i < keys.length; i++) {
581
+ ok = nk = keys[i];
582
+ for (j = 0; j < tkeys.length; j++) {
583
+ k = tkeys[j];
584
+ nk = nk.replace(k, map$1$1[k]);
585
  }
586
+ k = parseInt(names[ok], 16);
587
+ unpacked[nk] = [k >> 16 & 0xFF, k >> 8 & 0xFF, k & 0xFF];
588
+ }
589
+ return unpacked;
590
+ }
591
+ let names$1;
592
+ function nameParse(str) {
593
+ if (!names$1) {
594
+ names$1 = unpack();
595
+ names$1.transparent = [0, 0, 0, 0];
596
+ }
597
+ const a = names$1[str.toLowerCase()];
598
+ return a && {
599
+ r: a[0],
600
+ g: a[1],
601
+ b: a[2],
602
+ a: a.length === 4 ? a[3] : 255
603
+ };
604
+ }
605
+ function modHSL(v, i, ratio) {
606
+ if (v) {
607
+ let tmp = rgb2hsl(v);
608
+ tmp[i] = Math.max(0, Math.min(tmp[i] + tmp[i] * ratio, i === 0 ? 360 : 1));
609
+ tmp = hsl2rgb(tmp);
610
+ v.r = tmp[0];
611
+ v.g = tmp[1];
612
+ v.b = tmp[2];
613
+ }
614
+ }
615
+ function clone$1(v, proto) {
616
+ return v ? Object.assign(proto || {}, v) : v;
617
+ }
618
+ function fromObject(input) {
619
+ var v = {r: 0, g: 0, b: 0, a: 255};
620
+ if (Array.isArray(input)) {
621
+ if (input.length >= 3) {
622
+ v = {r: input[0], g: input[1], b: input[2], a: 255};
623
+ if (input.length > 3) {
624
+ v.a = n2b(input[3]);
625
  }
 
 
 
 
 
 
 
 
 
 
 
 
626
  }
627
+ } else {
628
+ v = clone$1(input, {r: 0, g: 0, b: 0, a: 1});
629
+ v.a = n2b(v.a);
630
+ }
631
+ return v;
632
+ }
633
+ function functionParse(str) {
634
+ if (str.charAt(0) === 'r') {
635
+ return rgbParse(str);
636
+ }
637
+ return hueParse(str);
638
+ }
639
+ class Color {
640
+ constructor(input) {
641
+ if (input instanceof Color) {
642
+ return input;
643
  }
644
+ const type = typeof input;
645
+ let v;
646
+ if (type === 'object') {
647
+ v = fromObject(input);
648
+ } else if (type === 'string') {
649
+ v = hexParse(input) || nameParse(input) || functionParse(input);
 
 
 
 
 
 
 
 
 
 
 
 
650
  }
651
+ this._rgb = v;
652
+ this._valid = !!v;
653
+ }
654
+ get valid() {
655
+ return this._valid;
656
+ }
657
+ get rgb() {
658
+ var v = clone$1(this._rgb);
659
+ if (v) {
660
+ v.a = b2n(v.a);
661
  }
662
+ return v;
663
+ }
664
+ set rgb(obj) {
665
+ this._rgb = fromObject(obj);
666
+ }
667
+ rgbString() {
668
+ return this._valid ? rgbString(this._rgb) : this._rgb;
669
+ }
670
+ hexString() {
671
+ return this._valid ? hexString(this._rgb) : this._rgb;
672
+ }
673
+ hslString() {
674
+ return this._valid ? hslString(this._rgb) : this._rgb;
675
+ }
676
+ mix(color, weight) {
677
+ const me = this;
678
+ if (color) {
679
+ const c1 = me.rgb;
680
+ const c2 = color.rgb;
681
+ let w2;
682
+ const p = weight === w2 ? 0.5 : weight;
683
+ const w = 2 * p - 1;
684
+ const a = c1.a - c2.a;
685
+ const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
686
+ w2 = 1 - w1;
687
+ c1.r = 0xFF & w1 * c1.r + w2 * c2.r + 0.5;
688
+ c1.g = 0xFF & w1 * c1.g + w2 * c2.g + 0.5;
689
+ c1.b = 0xFF & w1 * c1.b + w2 * c2.b + 0.5;
690
+ c1.a = p * c1.a + (1 - p) * c2.a;
691
+ me.rgb = c1;
692
  }
693
+ return me;
694
+ }
695
+ clone() {
696
+ return new Color(this.rgb);
697
+ }
698
+ alpha(a) {
699
+ this._rgb.a = n2b(a);
700
+ return this;
701
+ }
702
+ clearer(ratio) {
703
+ const rgb = this._rgb;
704
+ rgb.a *= 1 - ratio;
705
+ return this;
706
+ }
707
+ greyscale() {
708
+ const rgb = this._rgb;
709
+ const val = round(rgb.r * 0.3 + rgb.g * 0.59 + rgb.b * 0.11);
710
+ rgb.r = rgb.g = rgb.b = val;
711
+ return this;
712
+ }
713
+ opaquer(ratio) {
714
+ const rgb = this._rgb;
715
+ rgb.a *= 1 + ratio;
716
+ return this;
717
+ }
718
+ negate() {
719
+ const v = this._rgb;
720
+ v.r = 255 - v.r;
721
+ v.g = 255 - v.g;
722
+ v.b = 255 - v.b;
723
+ return this;
724
+ }
725
+ lighten(ratio) {
726
+ modHSL(this._rgb, 2, ratio);
727
+ return this;
728
+ }
729
+ darken(ratio) {
730
+ modHSL(this._rgb, 2, -ratio);
731
+ return this;
732
+ }
733
+ saturate(ratio) {
734
+ modHSL(this._rgb, 1, ratio);
735
+ return this;
736
+ }
737
+ desaturate(ratio) {
738
+ modHSL(this._rgb, 1, -ratio);
739
+ return this;
740
+ }
741
+ rotate(deg) {
742
+ rotate(this._rgb, deg);
743
+ return this;
744
+ }
745
+ }
746
+ function index_esm(input) {
747
+ return new Color(input);
748
+ }
749
+
750
+ const isPatternOrGradient = (value) => value instanceof CanvasGradient || value instanceof CanvasPattern;
751
+ function color(value) {
752
+ return isPatternOrGradient(value) ? value : index_esm(value);
753
+ }
754
+ function getHoverColor(value) {
755
+ return isPatternOrGradient(value)
756
+ ? value
757
+ : index_esm(value).saturate(0.5).darken(0.1).hexString();
758
+ }
759
+
760
+ function noop() {}
761
+ const uid = (function() {
762
+ let id = 0;
763
+ return function() {
764
+ return id++;
765
+ };
766
+ }());
767
+ function isNullOrUndef(value) {
768
+ return value === null || typeof value === 'undefined';
769
+ }
770
+ function isArray(value) {
771
+ if (Array.isArray && Array.isArray(value)) {
772
+ return true;
773
+ }
774
+ const type = Object.prototype.toString.call(value);
775
+ if (type.substr(0, 7) === '[object' && type.substr(-6) === 'Array]') {
776
+ return true;
777
+ }
778
+ return false;
779
+ }
780
+ function isObject(value) {
781
+ return value !== null && Object.prototype.toString.call(value) === '[object Object]';
782
+ }
783
+ const isNumberFinite = (value) => (typeof value === 'number' || value instanceof Number) && isFinite(+value);
784
+ function finiteOrDefault(value, defaultValue) {
785
+ return isNumberFinite(value) ? value : defaultValue;
786
+ }
787
+ function valueOrDefault(value, defaultValue) {
788
+ return typeof value === 'undefined' ? defaultValue : value;
789
+ }
790
+ const toPercentage = (value, dimension) =>
791
+ typeof value === 'string' && value.endsWith('%') ?
792
+ parseFloat(value) / 100
793
+ : value / dimension;
794
+ const toDimension = (value, dimension) =>
795
+ typeof value === 'string' && value.endsWith('%') ?
796
+ parseFloat(value) / 100 * dimension
797
+ : +value;
798
+ function callback(fn, args, thisArg) {
799
+ if (fn && typeof fn.call === 'function') {
800
+ return fn.apply(thisArg, args);
801
+ }
802
+ }
803
+ function each(loopable, fn, thisArg, reverse) {
804
+ let i, len, keys;
805
+ if (isArray(loopable)) {
806
+ len = loopable.length;
807
+ if (reverse) {
808
+ for (i = len - 1; i >= 0; i--) {
809
+ fn.call(thisArg, loopable[i], i);
810
+ }
811
+ } else {
812
+ for (i = 0; i < len; i++) {
813
+ fn.call(thisArg, loopable[i], i);
814
+ }
815
+ }
816
+ } else if (isObject(loopable)) {
817
+ keys = Object.keys(loopable);
818
+ len = keys.length;
819
+ for (i = 0; i < len; i++) {
820
+ fn.call(thisArg, loopable[keys[i]], keys[i]);
821
+ }
822
+ }
823
+ }
824
+ function _elementsEqual(a0, a1) {
825
+ let i, ilen, v0, v1;
826
+ if (!a0 || !a1 || a0.length !== a1.length) {
827
+ return false;
828
+ }
829
+ for (i = 0, ilen = a0.length; i < ilen; ++i) {
830
+ v0 = a0[i];
831
+ v1 = a1[i];
832
+ if (v0.datasetIndex !== v1.datasetIndex || v0.index !== v1.index) {
833
+ return false;
834
+ }
835
+ }
836
+ return true;
837
+ }
838
+ function clone(source) {
839
+ if (isArray(source)) {
840
+ return source.map(clone);
841
+ }
842
+ if (isObject(source)) {
843
+ const target = Object.create(null);
844
+ const keys = Object.keys(source);
845
+ const klen = keys.length;
846
+ let k = 0;
847
+ for (; k < klen; ++k) {
848
+ target[keys[k]] = clone(source[keys[k]]);
849
+ }
850
+ return target;
851
+ }
852
+ return source;
853
+ }
854
+ function isValidKey(key) {
855
+ return ['__proto__', 'prototype', 'constructor'].indexOf(key) === -1;
856
+ }
857
+ function _merger(key, target, source, options) {
858
+ if (!isValidKey(key)) {
859
+ return;
860
+ }
861
+ const tval = target[key];
862
+ const sval = source[key];
863
+ if (isObject(tval) && isObject(sval)) {
864
+ merge(tval, sval, options);
865
+ } else {
866
+ target[key] = clone(sval);
867
+ }
868
+ }
869
+ function merge(target, source, options) {
870
+ const sources = isArray(source) ? source : [source];
871
+ const ilen = sources.length;
872
+ if (!isObject(target)) {
873
+ return target;
874
+ }
875
+ options = options || {};
876
+ const merger = options.merger || _merger;
877
+ for (let i = 0; i < ilen; ++i) {
878
+ source = sources[i];
879
+ if (!isObject(source)) {
880
+ continue;
881
+ }
882
+ const keys = Object.keys(source);
883
+ for (let k = 0, klen = keys.length; k < klen; ++k) {
884
+ merger(keys[k], target, source, options);
885
+ }
886
+ }
887
+ return target;
888
+ }
889
+ function mergeIf(target, source) {
890
+ return merge(target, source, {merger: _mergerIf});
891
+ }
892
+ function _mergerIf(key, target, source) {
893
+ if (!isValidKey(key)) {
894
+ return;
895
+ }
896
+ const tval = target[key];
897
+ const sval = source[key];
898
+ if (isObject(tval) && isObject(sval)) {
899
+ mergeIf(tval, sval);
900
+ } else if (!Object.prototype.hasOwnProperty.call(target, key)) {
901
+ target[key] = clone(sval);
902
+ }
903
+ }
904
+ function _deprecated(scope, value, previous, current) {
905
+ if (value !== undefined) {
906
+ console.warn(scope + ': "' + previous +
907
+ '" is deprecated. Please use "' + current + '" instead');
908
+ }
909
+ }
910
+ const emptyString = '';
911
+ const dot = '.';
912
+ function indexOfDotOrLength(key, start) {
913
+ const idx = key.indexOf(dot, start);
914
+ return idx === -1 ? key.length : idx;
915
+ }
916
+ function resolveObjectKey(obj, key) {
917
+ if (key === emptyString) {
918
+ return obj;
919
+ }
920
+ let pos = 0;
921
+ let idx = indexOfDotOrLength(key, pos);
922
+ while (obj && idx > pos) {
923
+ obj = obj[key.substr(pos, idx - pos)];
924
+ pos = idx + 1;
925
+ idx = indexOfDotOrLength(key, pos);
926
+ }
927
+ return obj;
928
+ }
929
+ function _capitalize(str) {
930
+ return str.charAt(0).toUpperCase() + str.slice(1);
931
+ }
932
+ const defined = (value) => typeof value !== 'undefined';
933
+ const isFunction = (value) => typeof value === 'function';
934
+ const setsEqual = (a, b) => {
935
+ if (a.size !== b.size) {
936
+ return false;
937
+ }
938
+ for (const item of a) {
939
+ if (!b.has(item)) {
940
+ return false;
941
+ }
942
+ }
943
+ return true;
944
+ };
945
+ function _isClickEvent(e) {
946
+ return e.type === 'mouseup' || e.type === 'click' || e.type === 'contextmenu';
947
+ }
948
+
949
+ const overrides = Object.create(null);
950
+ const descriptors = Object.create(null);
951
+ function getScope$1(node, key) {
952
+ if (!key) {
953
+ return node;
954
+ }
955
+ const keys = key.split('.');
956
+ for (let i = 0, n = keys.length; i < n; ++i) {
957
+ const k = keys[i];
958
+ node = node[k] || (node[k] = Object.create(null));
959
+ }
960
+ return node;
961
+ }
962
+ function set(root, scope, values) {
963
+ if (typeof scope === 'string') {
964
+ return merge(getScope$1(root, scope), values);
965
+ }
966
+ return merge(getScope$1(root, ''), scope);
967
+ }
968
+ class Defaults {
969
+ constructor(_descriptors) {
970
+ this.animation = undefined;
971
+ this.backgroundColor = 'rgba(0,0,0,0.1)';
972
+ this.borderColor = 'rgba(0,0,0,0.1)';
973
+ this.color = '#666';
974
+ this.datasets = {};
975
+ this.devicePixelRatio = (context) => context.chart.platform.getDevicePixelRatio();
976
+ this.elements = {};
977
+ this.events = [
978
+ 'mousemove',
979
+ 'mouseout',
980
+ 'click',
981
+ 'touchstart',
982
+ 'touchmove'
983
+ ];
984
+ this.font = {
985
+ family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
986
+ size: 12,
987
+ style: 'normal',
988
+ lineHeight: 1.2,
989
+ weight: null
990
+ };
991
+ this.hover = {};
992
+ this.hoverBackgroundColor = (ctx, options) => getHoverColor(options.backgroundColor);
993
+ this.hoverBorderColor = (ctx, options) => getHoverColor(options.borderColor);
994
+ this.hoverColor = (ctx, options) => getHoverColor(options.color);
995
+ this.indexAxis = 'x';
996
+ this.interaction = {
997
+ mode: 'nearest',
998
+ intersect: true
999
+ };
1000
+ this.maintainAspectRatio = true;
1001
+ this.onHover = null;
1002
+ this.onClick = null;
1003
+ this.parsing = true;
1004
+ this.plugins = {};
1005
+ this.responsive = true;
1006
+ this.scale = undefined;
1007
+ this.scales = {};
1008
+ this.showLine = true;
1009
+ this.drawActiveElementsOnTop = true;
1010
+ this.describe(_descriptors);
1011
+ }
1012
+ set(scope, values) {
1013
+ return set(this, scope, values);
1014
+ }
1015
+ get(scope) {
1016
+ return getScope$1(this, scope);
1017
+ }
1018
+ describe(scope, values) {
1019
+ return set(descriptors, scope, values);
1020
+ }
1021
+ override(scope, values) {
1022
+ return set(overrides, scope, values);
1023
+ }
1024
+ route(scope, name, targetScope, targetName) {
1025
+ const scopeObject = getScope$1(this, scope);
1026
+ const targetScopeObject = getScope$1(this, targetScope);
1027
+ const privateName = '_' + name;
1028
+ Object.defineProperties(scopeObject, {
1029
+ [privateName]: {
1030
+ value: scopeObject[name],
1031
+ writable: true
1032
+ },
1033
+ [name]: {
1034
+ enumerable: true,
1035
+ get() {
1036
+ const local = this[privateName];
1037
+ const target = targetScopeObject[targetName];
1038
+ if (isObject(local)) {
1039
+ return Object.assign({}, target, local);
1040
+ }
1041
+ return valueOrDefault(local, target);
1042
+ },
1043
+ set(value) {
1044
+ this[privateName] = value;
1045
  }
1046
+ }
1047
+ });
1048
+ }
1049
+ }
1050
+ var defaults = new Defaults({
1051
+ _scriptable: (name) => !name.startsWith('on'),
1052
+ _indexable: (name) => name !== 'events',
1053
+ hover: {
1054
+ _fallback: 'interaction'
1055
+ },
1056
+ interaction: {
1057
+ _scriptable: false,
1058
+ _indexable: false,
1059
+ }
1060
+ });
1061
+
1062
+ const PI = Math.PI;
1063
+ const TAU = 2 * PI;
1064
+ const PITAU = TAU + PI;
1065
+ const INFINITY = Number.POSITIVE_INFINITY;
1066
+ const RAD_PER_DEG = PI / 180;
1067
+ const HALF_PI = PI / 2;
1068
+ const QUARTER_PI = PI / 4;
1069
+ const TWO_THIRDS_PI = PI * 2 / 3;
1070
+ const log10 = Math.log10;
1071
+ const sign = Math.sign;
1072
+ function niceNum(range) {
1073
+ const roundedRange = Math.round(range);
1074
+ range = almostEquals(range, roundedRange, range / 1000) ? roundedRange : range;
1075
+ const niceRange = Math.pow(10, Math.floor(log10(range)));
1076
+ const fraction = range / niceRange;
1077
+ const niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10;
1078
+ return niceFraction * niceRange;
1079
+ }
1080
+ function _factorize(value) {
1081
+ const result = [];
1082
+ const sqrt = Math.sqrt(value);
1083
+ let i;
1084
+ for (i = 1; i < sqrt; i++) {
1085
+ if (value % i === 0) {
1086
+ result.push(i);
1087
+ result.push(value / i);
1088
+ }
1089
+ }
1090
+ if (sqrt === (sqrt | 0)) {
1091
+ result.push(sqrt);
1092
+ }
1093
+ result.sort((a, b) => a - b).pop();
1094
+ return result;
1095
+ }
1096
+ function isNumber(n) {
1097
+ return !isNaN(parseFloat(n)) && isFinite(n);
1098
+ }
1099
+ function almostEquals(x, y, epsilon) {
1100
+ return Math.abs(x - y) < epsilon;
1101
+ }
1102
+ function almostWhole(x, epsilon) {
1103
+ const rounded = Math.round(x);
1104
+ return ((rounded - epsilon) <= x) && ((rounded + epsilon) >= x);
1105
+ }
1106
+ function _setMinAndMaxByKey(array, target, property) {
1107
+ let i, ilen, value;
1108
+ for (i = 0, ilen = array.length; i < ilen; i++) {
1109
+ value = array[i][property];
1110
+ if (!isNaN(value)) {
1111
+ target.min = Math.min(target.min, value);
1112
+ target.max = Math.max(target.max, value);
1113
+ }
1114
+ }
1115
+ }
1116
+ function toRadians(degrees) {
1117
+ return degrees * (PI / 180);
1118
+ }
1119
+ function toDegrees(radians) {
1120
+ return radians * (180 / PI);
1121
+ }
1122
+ function _decimalPlaces(x) {
1123
+ if (!isNumberFinite(x)) {
1124
+ return;
1125
+ }
1126
+ let e = 1;
1127
+ let p = 0;
1128
+ while (Math.round(x * e) / e !== x) {
1129
+ e *= 10;
1130
+ p++;
1131
+ }
1132
+ return p;
1133
+ }
1134
+ function getAngleFromPoint(centrePoint, anglePoint) {
1135
+ const distanceFromXCenter = anglePoint.x - centrePoint.x;
1136
+ const distanceFromYCenter = anglePoint.y - centrePoint.y;
1137
+ const radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
1138
+ let angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
1139
+ if (angle < (-0.5 * PI)) {
1140
+ angle += TAU;
1141
+ }
1142
+ return {
1143
+ angle,
1144
+ distance: radialDistanceFromCenter
1145
+ };
1146
+ }
1147
+ function distanceBetweenPoints(pt1, pt2) {
1148
+ return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
1149
+ }
1150
+ function _angleDiff(a, b) {
1151
+ return (a - b + PITAU) % TAU - PI;
1152
+ }
1153
+ function _normalizeAngle(a) {
1154
+ return (a % TAU + TAU) % TAU;
1155
+ }
1156
+ function _angleBetween(angle, start, end, sameAngleIsFullCircle) {
1157
+ const a = _normalizeAngle(angle);
1158
+ const s = _normalizeAngle(start);
1159
+ const e = _normalizeAngle(end);
1160
+ const angleToStart = _normalizeAngle(s - a);
1161
+ const angleToEnd = _normalizeAngle(e - a);
1162
+ const startToAngle = _normalizeAngle(a - s);
1163
+ const endToAngle = _normalizeAngle(a - e);
1164
+ return a === s || a === e || (sameAngleIsFullCircle && s === e)
1165
+ || (angleToStart > angleToEnd && startToAngle < endToAngle);
1166
+ }
1167
+ function _limitValue(value, min, max) {
1168
+ return Math.max(min, Math.min(max, value));
1169
+ }
1170
+ function _int16Range(value) {
1171
+ return _limitValue(value, -32768, 32767);
1172
+ }
1173
+ function _isBetween(value, start, end, epsilon = 1e-6) {
1174
+ return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon;
1175
+ }
1176
+
1177
+ function toFontString(font) {
1178
+ if (!font || isNullOrUndef(font.size) || isNullOrUndef(font.family)) {
1179
+ return null;
1180
+ }
1181
+ return (font.style ? font.style + ' ' : '')
1182
+ + (font.weight ? font.weight + ' ' : '')
1183
+ + font.size + 'px '
1184
+ + font.family;
1185
+ }
1186
+ function _measureText(ctx, data, gc, longest, string) {
1187
+ let textWidth = data[string];
1188
+ if (!textWidth) {
1189
+ textWidth = data[string] = ctx.measureText(string).width;
1190
+ gc.push(string);
1191
+ }
1192
+ if (textWidth > longest) {
1193
+ longest = textWidth;
1194
+ }
1195
+ return longest;
1196
+ }
1197
+ function _longestText(ctx, font, arrayOfThings, cache) {
1198
+ cache = cache || {};
1199
+ let data = cache.data = cache.data || {};
1200
+ let gc = cache.garbageCollect = cache.garbageCollect || [];
1201
+ if (cache.font !== font) {
1202
+ data = cache.data = {};
1203
+ gc = cache.garbageCollect = [];
1204
+ cache.font = font;
1205
+ }
1206
+ ctx.save();
1207
+ ctx.font = font;
1208
+ let longest = 0;
1209
+ const ilen = arrayOfThings.length;
1210
+ let i, j, jlen, thing, nestedThing;
1211
+ for (i = 0; i < ilen; i++) {
1212
+ thing = arrayOfThings[i];
1213
+ if (thing !== undefined && thing !== null && isArray(thing) !== true) {
1214
+ longest = _measureText(ctx, data, gc, longest, thing);
1215
+ } else if (isArray(thing)) {
1216
+ for (j = 0, jlen = thing.length; j < jlen; j++) {
1217
+ nestedThing = thing[j];
1218
+ if (nestedThing !== undefined && nestedThing !== null && !isArray(nestedThing)) {
1219
+ longest = _measureText(ctx, data, gc, longest, nestedThing);
1220
  }
1221
+ }
1222
+ }
1223
+ }
1224
+ ctx.restore();
1225
+ const gcLen = gc.length / 2;
1226
+ if (gcLen > arrayOfThings.length) {
1227
+ for (i = 0; i < gcLen; i++) {
1228
+ delete data[gc[i]];
1229
+ }
1230
+ gc.splice(0, gcLen);
1231
+ }
1232
+ return longest;
1233
+ }
1234
+ function _alignPixel(chart, pixel, width) {
1235
+ const devicePixelRatio = chart.currentDevicePixelRatio;
1236
+ const halfWidth = width !== 0 ? Math.max(width / 2, 0.5) : 0;
1237
+ return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth;
1238
+ }
1239
+ function clearCanvas(canvas, ctx) {
1240
+ ctx = ctx || canvas.getContext('2d');
1241
+ ctx.save();
1242
+ ctx.resetTransform();
1243
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
1244
+ ctx.restore();
1245
+ }
1246
+ function drawPoint(ctx, options, x, y) {
1247
+ let type, xOffset, yOffset, size, cornerRadius;
1248
+ const style = options.pointStyle;
1249
+ const rotation = options.rotation;
1250
+ const radius = options.radius;
1251
+ let rad = (rotation || 0) * RAD_PER_DEG;
1252
+ if (style && typeof style === 'object') {
1253
+ type = style.toString();
1254
+ if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
1255
+ ctx.save();
1256
+ ctx.translate(x, y);
1257
+ ctx.rotate(rad);
1258
+ ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height);
1259
+ ctx.restore();
1260
+ return;
1261
+ }
1262
+ }
1263
+ if (isNaN(radius) || radius <= 0) {
1264
+ return;
1265
+ }
1266
+ ctx.beginPath();
1267
+ switch (style) {
1268
+ default:
1269
+ ctx.arc(x, y, radius, 0, TAU);
1270
+ ctx.closePath();
1271
+ break;
1272
+ case 'triangle':
1273
+ ctx.moveTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);
1274
+ rad += TWO_THIRDS_PI;
1275
+ ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);
1276
+ rad += TWO_THIRDS_PI;
1277
+ ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);
1278
+ ctx.closePath();
1279
+ break;
1280
+ case 'rectRounded':
1281
+ cornerRadius = radius * 0.516;
1282
+ size = radius - cornerRadius;
1283
+ xOffset = Math.cos(rad + QUARTER_PI) * size;
1284
+ yOffset = Math.sin(rad + QUARTER_PI) * size;
1285
+ ctx.arc(x - xOffset, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI);
1286
+ ctx.arc(x + yOffset, y - xOffset, cornerRadius, rad - HALF_PI, rad);
1287
+ ctx.arc(x + xOffset, y + yOffset, cornerRadius, rad, rad + HALF_PI);
1288
+ ctx.arc(x - yOffset, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI);
1289
+ ctx.closePath();
1290
+ break;
1291
+ case 'rect':
1292
+ if (!rotation) {
1293
+ size = Math.SQRT1_2 * radius;
1294
+ ctx.rect(x - size, y - size, 2 * size, 2 * size);
1295
+ break;
1296
+ }
1297
+ rad += QUARTER_PI;
1298
+ case 'rectRot':
1299
+ xOffset = Math.cos(rad) * radius;
1300
+ yOffset = Math.sin(rad) * radius;
1301
+ ctx.moveTo(x - xOffset, y - yOffset);
1302
+ ctx.lineTo(x + yOffset, y - xOffset);
1303
+ ctx.lineTo(x + xOffset, y + yOffset);
1304
+ ctx.lineTo(x - yOffset, y + xOffset);
1305
+ ctx.closePath();
1306
+ break;
1307
+ case 'crossRot':
1308
+ rad += QUARTER_PI;
1309
+ case 'cross':
1310
+ xOffset = Math.cos(rad) * radius;
1311
+ yOffset = Math.sin(rad) * radius;
1312
+ ctx.moveTo(x - xOffset, y - yOffset);
1313
+ ctx.lineTo(x + xOffset, y + yOffset);
1314
+ ctx.moveTo(x + yOffset, y - xOffset);
1315
+ ctx.lineTo(x - yOffset, y + xOffset);
1316
+ break;
1317
+ case 'star':
1318
+ xOffset = Math.cos(rad) * radius;
1319
+ yOffset = Math.sin(rad) * radius;
1320
+ ctx.moveTo(x - xOffset, y - yOffset);
1321
+ ctx.lineTo(x + xOffset, y + yOffset);
1322
+ ctx.moveTo(x + yOffset, y - xOffset);
1323
+ ctx.lineTo(x - yOffset, y + xOffset);
1324
+ rad += QUARTER_PI;
1325
+ xOffset = Math.cos(rad) * radius;
1326
+ yOffset = Math.sin(rad) * radius;
1327
+ ctx.moveTo(x - xOffset, y - yOffset);
1328
+ ctx.lineTo(x + xOffset, y + yOffset);
1329
+ ctx.moveTo(x + yOffset, y - xOffset);
1330
+ ctx.lineTo(x - yOffset, y + xOffset);
1331
+ break;
1332
+ case 'line':
1333
+ xOffset = Math.cos(rad) * radius;
1334
+ yOffset = Math.sin(rad) * radius;
1335
+ ctx.moveTo(x - xOffset, y - yOffset);
1336
+ ctx.lineTo(x + xOffset, y + yOffset);
1337
+ break;
1338
+ case 'dash':
1339
+ ctx.moveTo(x, y);
1340
+ ctx.lineTo(x + Math.cos(rad) * radius, y + Math.sin(rad) * radius);
1341
+ break;
1342
+ }
1343
+ ctx.fill();
1344
+ if (options.borderWidth > 0) {
1345
+ ctx.stroke();
1346
+ }
1347
+ }
1348
+ function _isPointInArea(point, area, margin) {
1349
+ margin = margin || 0.5;
1350
+ return !area || (point && point.x > area.left - margin && point.x < area.right + margin &&
1351
+ point.y > area.top - margin && point.y < area.bottom + margin);
1352
+ }
1353
+ function clipArea(ctx, area) {
1354
+ ctx.save();
1355
+ ctx.beginPath();
1356
+ ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);
1357
+ ctx.clip();
1358
+ }
1359
+ function unclipArea(ctx) {
1360
+ ctx.restore();
1361
+ }
1362
+ function _steppedLineTo(ctx, previous, target, flip, mode) {
1363
+ if (!previous) {
1364
+ return ctx.lineTo(target.x, target.y);
1365
+ }
1366
+ if (mode === 'middle') {
1367
+ const midpoint = (previous.x + target.x) / 2.0;
1368
+ ctx.lineTo(midpoint, previous.y);
1369
+ ctx.lineTo(midpoint, target.y);
1370
+ } else if (mode === 'after' !== !!flip) {
1371
+ ctx.lineTo(previous.x, target.y);
1372
+ } else {
1373
+ ctx.lineTo(target.x, previous.y);
1374
+ }
1375
+ ctx.lineTo(target.x, target.y);
1376
+ }
1377
+ function _bezierCurveTo(ctx, previous, target, flip) {
1378
+ if (!previous) {
1379
+ return ctx.lineTo(target.x, target.y);
1380
+ }
1381
+ ctx.bezierCurveTo(
1382
+ flip ? previous.cp1x : previous.cp2x,
1383
+ flip ? previous.cp1y : previous.cp2y,
1384
+ flip ? target.cp2x : target.cp1x,
1385
+ flip ? target.cp2y : target.cp1y,
1386
+ target.x,
1387
+ target.y);
1388
+ }
1389
+ function renderText(ctx, text, x, y, font, opts = {}) {
1390
+ const lines = isArray(text) ? text : [text];
1391
+ const stroke = opts.strokeWidth > 0 && opts.strokeColor !== '';
1392
+ let i, line;
1393
+ ctx.save();
1394
+ ctx.font = font.string;
1395
+ setRenderOpts(ctx, opts);
1396
+ for (i = 0; i < lines.length; ++i) {
1397
+ line = lines[i];
1398
+ if (stroke) {
1399
+ if (opts.strokeColor) {
1400
+ ctx.strokeStyle = opts.strokeColor;
1401
+ }
1402
+ if (!isNullOrUndef(opts.strokeWidth)) {
1403
+ ctx.lineWidth = opts.strokeWidth;
1404
+ }
1405
+ ctx.strokeText(line, x, y, opts.maxWidth);
1406
+ }
1407
+ ctx.fillText(line, x, y, opts.maxWidth);
1408
+ decorateText(ctx, x, y, line, opts);
1409
+ y += font.lineHeight;
1410
+ }
1411
+ ctx.restore();
1412
+ }
1413
+ function setRenderOpts(ctx, opts) {
1414
+ if (opts.translation) {
1415
+ ctx.translate(opts.translation[0], opts.translation[1]);
1416
+ }
1417
+ if (!isNullOrUndef(opts.rotation)) {
1418
+ ctx.rotate(opts.rotation);
1419
+ }
1420
+ if (opts.color) {
1421
+ ctx.fillStyle = opts.color;
1422
+ }
1423
+ if (opts.textAlign) {
1424
+ ctx.textAlign = opts.textAlign;
1425
+ }
1426
+ if (opts.textBaseline) {
1427
+ ctx.textBaseline = opts.textBaseline;
1428
+ }
1429
+ }
1430
+ function decorateText(ctx, x, y, line, opts) {
1431
+ if (opts.strikethrough || opts.underline) {
1432
+ const metrics = ctx.measureText(line);
1433
+ const left = x - metrics.actualBoundingBoxLeft;
1434
+ const right = x + metrics.actualBoundingBoxRight;
1435
+ const top = y - metrics.actualBoundingBoxAscent;
1436
+ const bottom = y + metrics.actualBoundingBoxDescent;
1437
+ const yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom;
1438
+ ctx.strokeStyle = ctx.fillStyle;
1439
+ ctx.beginPath();
1440
+ ctx.lineWidth = opts.decorationWidth || 2;
1441
+ ctx.moveTo(left, yDecoration);
1442
+ ctx.lineTo(right, yDecoration);
1443
+ ctx.stroke();
1444
+ }
1445
+ }
1446
+ function addRoundedRectPath(ctx, rect) {
1447
+ const {x, y, w, h, radius} = rect;
1448
+ ctx.arc(x + radius.topLeft, y + radius.topLeft, radius.topLeft, -HALF_PI, PI, true);
1449
+ ctx.lineTo(x, y + h - radius.bottomLeft);
1450
+ ctx.arc(x + radius.bottomLeft, y + h - radius.bottomLeft, radius.bottomLeft, PI, HALF_PI, true);
1451
+ ctx.lineTo(x + w - radius.bottomRight, y + h);
1452
+ ctx.arc(x + w - radius.bottomRight, y + h - radius.bottomRight, radius.bottomRight, HALF_PI, 0, true);
1453
+ ctx.lineTo(x + w, y + radius.topRight);
1454
+ ctx.arc(x + w - radius.topRight, y + radius.topRight, radius.topRight, 0, -HALF_PI, true);
1455
+ ctx.lineTo(x + radius.topLeft, y);
1456
+ }
1457
+
1458
+ function _lookup(table, value, cmp) {
1459
+ cmp = cmp || ((index) => table[index] < value);
1460
+ let hi = table.length - 1;
1461
+ let lo = 0;
1462
+ let mid;
1463
+ while (hi - lo > 1) {
1464
+ mid = (lo + hi) >> 1;
1465
+ if (cmp(mid)) {
1466
+ lo = mid;
1467
+ } else {
1468
+ hi = mid;
1469
+ }
1470
+ }
1471
+ return {lo, hi};
1472
+ }
1473
+ const _lookupByKey = (table, key, value) =>
1474
+ _lookup(table, value, index => table[index][key] < value);
1475
+ const _rlookupByKey = (table, key, value) =>
1476
+ _lookup(table, value, index => table[index][key] >= value);
1477
+ function _filterBetween(values, min, max) {
1478
+ let start = 0;
1479
+ let end = values.length;
1480
+ while (start < end && values[start] < min) {
1481
+ start++;
1482
+ }
1483
+ while (end > start && values[end - 1] > max) {
1484
+ end--;
1485
+ }
1486
+ return start > 0 || end < values.length
1487
+ ? values.slice(start, end)
1488
+ : values;
1489
+ }
1490
+ const arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
1491
+ function listenArrayEvents(array, listener) {
1492
+ if (array._chartjs) {
1493
+ array._chartjs.listeners.push(listener);
1494
+ return;
1495
+ }
1496
+ Object.defineProperty(array, '_chartjs', {
1497
+ configurable: true,
1498
+ enumerable: false,
1499
+ value: {
1500
+ listeners: [listener]
1501
+ }
1502
+ });
1503
+ arrayEvents.forEach((key) => {
1504
+ const method = '_onData' + _capitalize(key);
1505
+ const base = array[key];
1506
+ Object.defineProperty(array, key, {
1507
+ configurable: true,
1508
+ enumerable: false,
1509
+ value(...args) {
1510
+ const res = base.apply(this, args);
1511
+ array._chartjs.listeners.forEach((object) => {
1512
+ if (typeof object[method] === 'function') {
1513
+ object[method](...args);
1514
+ }
1515
+ });
1516
+ return res;
1517
+ }
1518
+ });
1519
+ });
1520
+ }
1521
+ function unlistenArrayEvents(array, listener) {
1522
+ const stub = array._chartjs;
1523
+ if (!stub) {
1524
+ return;
1525
+ }
1526
+ const listeners = stub.listeners;
1527
+ const index = listeners.indexOf(listener);
1528
+ if (index !== -1) {
1529
+ listeners.splice(index, 1);
1530
+ }
1531
+ if (listeners.length > 0) {
1532
+ return;
1533
+ }
1534
+ arrayEvents.forEach((key) => {
1535
+ delete array[key];
1536
+ });
1537
+ delete array._chartjs;
1538
+ }
1539
+ function _arrayUnique(items) {
1540
+ const set = new Set();
1541
+ let i, ilen;
1542
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
1543
+ set.add(items[i]);
1544
+ }
1545
+ if (set.size === ilen) {
1546
+ return items;
1547
+ }
1548
+ return Array.from(set);
1549
+ }
1550
+
1551
+ function _isDomSupported() {
1552
+ return typeof window !== 'undefined' && typeof document !== 'undefined';
1553
+ }
1554
+ function _getParentNode(domNode) {
1555
+ let parent = domNode.parentNode;
1556
+ if (parent && parent.toString() === '[object ShadowRoot]') {
1557
+ parent = parent.host;
1558
+ }
1559
+ return parent;
1560
+ }
1561
+ function parseMaxStyle(styleValue, node, parentProperty) {
1562
+ let valueInPixels;
1563
+ if (typeof styleValue === 'string') {
1564
+ valueInPixels = parseInt(styleValue, 10);
1565
+ if (styleValue.indexOf('%') !== -1) {
1566
+ valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];
1567
+ }
1568
+ } else {
1569
+ valueInPixels = styleValue;
1570
+ }
1571
+ return valueInPixels;
1572
+ }
1573
+ const getComputedStyle = (element) => window.getComputedStyle(element, null);
1574
+ function getStyle(el, property) {
1575
+ return getComputedStyle(el).getPropertyValue(property);
1576
+ }
1577
+ const positions = ['top', 'right', 'bottom', 'left'];
1578
+ function getPositionedStyle(styles, style, suffix) {
1579
+ const result = {};
1580
+ suffix = suffix ? '-' + suffix : '';
1581
+ for (let i = 0; i < 4; i++) {
1582
+ const pos = positions[i];
1583
+ result[pos] = parseFloat(styles[style + '-' + pos + suffix]) || 0;
1584
+ }
1585
+ result.width = result.left + result.right;
1586
+ result.height = result.top + result.bottom;
1587
+ return result;
1588
+ }
1589
+ const useOffsetPos = (x, y, target) => (x > 0 || y > 0) && (!target || !target.shadowRoot);
1590
+ function getCanvasPosition(evt, canvas) {
1591
+ const e = evt.native || evt;
1592
+ const touches = e.touches;
1593
+ const source = touches && touches.length ? touches[0] : e;
1594
+ const {offsetX, offsetY} = source;
1595
+ let box = false;
1596
+ let x, y;
1597
+ if (useOffsetPos(offsetX, offsetY, e.target)) {
1598
+ x = offsetX;
1599
+ y = offsetY;
1600
+ } else {
1601
+ const rect = canvas.getBoundingClientRect();
1602
+ x = source.clientX - rect.left;
1603
+ y = source.clientY - rect.top;
1604
+ box = true;
1605
+ }
1606
+ return {x, y, box};
1607
+ }
1608
+ function getRelativePosition$1(evt, chart) {
1609
+ const {canvas, currentDevicePixelRatio} = chart;
1610
+ const style = getComputedStyle(canvas);
1611
+ const borderBox = style.boxSizing === 'border-box';
1612
+ const paddings = getPositionedStyle(style, 'padding');
1613
+ const borders = getPositionedStyle(style, 'border', 'width');
1614
+ const {x, y, box} = getCanvasPosition(evt, canvas);
1615
+ const xOffset = paddings.left + (box && borders.left);
1616
+ const yOffset = paddings.top + (box && borders.top);
1617
+ let {width, height} = chart;
1618
+ if (borderBox) {
1619
+ width -= paddings.width + borders.width;
1620
+ height -= paddings.height + borders.height;
1621
+ }
1622
+ return {
1623
+ x: Math.round((x - xOffset) / width * canvas.width / currentDevicePixelRatio),
1624
+ y: Math.round((y - yOffset) / height * canvas.height / currentDevicePixelRatio)
1625
+ };
1626
+ }
1627
+ function getContainerSize(canvas, width, height) {
1628
+ let maxWidth, maxHeight;
1629
+ if (width === undefined || height === undefined) {
1630
+ const container = _getParentNode(canvas);
1631
+ if (!container) {
1632
+ width = canvas.clientWidth;
1633
+ height = canvas.clientHeight;
1634
+ } else {
1635
+ const rect = container.getBoundingClientRect();
1636
+ const containerStyle = getComputedStyle(container);
1637
+ const containerBorder = getPositionedStyle(containerStyle, 'border', 'width');
1638
+ const containerPadding = getPositionedStyle(containerStyle, 'padding');
1639
+ width = rect.width - containerPadding.width - containerBorder.width;
1640
+ height = rect.height - containerPadding.height - containerBorder.height;
1641
+ maxWidth = parseMaxStyle(containerStyle.maxWidth, container, 'clientWidth');
1642
+ maxHeight = parseMaxStyle(containerStyle.maxHeight, container, 'clientHeight');
1643
+ }
1644
+ }
1645
+ return {
1646
+ width,
1647
+ height,
1648
+ maxWidth: maxWidth || INFINITY,
1649
+ maxHeight: maxHeight || INFINITY
1650
+ };
1651
+ }
1652
+ const round1 = v => Math.round(v * 10) / 10;
1653
+ function getMaximumSize(canvas, bbWidth, bbHeight, aspectRatio) {
1654
+ const style = getComputedStyle(canvas);
1655
+ const margins = getPositionedStyle(style, 'margin');
1656
+ const maxWidth = parseMaxStyle(style.maxWidth, canvas, 'clientWidth') || INFINITY;
1657
+ const maxHeight = parseMaxStyle(style.maxHeight, canvas, 'clientHeight') || INFINITY;
1658
+ const containerSize = getContainerSize(canvas, bbWidth, bbHeight);
1659
+ let {width, height} = containerSize;
1660
+ if (style.boxSizing === 'content-box') {
1661
+ const borders = getPositionedStyle(style, 'border', 'width');
1662
+ const paddings = getPositionedStyle(style, 'padding');
1663
+ width -= paddings.width + borders.width;
1664
+ height -= paddings.height + borders.height;
1665
+ }
1666
+ width = Math.max(0, width - margins.width);
1667
+ height = Math.max(0, aspectRatio ? Math.floor(width / aspectRatio) : height - margins.height);
1668
+ width = round1(Math.min(width, maxWidth, containerSize.maxWidth));
1669
+ height = round1(Math.min(height, maxHeight, containerSize.maxHeight));
1670
+ if (width && !height) {
1671
+ height = round1(width / 2);
1672
+ }
1673
+ return {
1674
+ width,
1675
+ height
1676
+ };
1677
+ }
1678
+ function retinaScale(chart, forceRatio, forceStyle) {
1679
+ const pixelRatio = forceRatio || 1;
1680
+ const deviceHeight = Math.floor(chart.height * pixelRatio);
1681
+ const deviceWidth = Math.floor(chart.width * pixelRatio);
1682
+ chart.height = deviceHeight / pixelRatio;
1683
+ chart.width = deviceWidth / pixelRatio;
1684
+ const canvas = chart.canvas;
1685
+ if (canvas.style && (forceStyle || (!canvas.style.height && !canvas.style.width))) {
1686
+ canvas.style.height = `${chart.height}px`;
1687
+ canvas.style.width = `${chart.width}px`;
1688
+ }
1689
+ if (chart.currentDevicePixelRatio !== pixelRatio
1690
+ || canvas.height !== deviceHeight
1691
+ || canvas.width !== deviceWidth) {
1692
+ chart.currentDevicePixelRatio = pixelRatio;
1693
+ canvas.height = deviceHeight;
1694
+ canvas.width = deviceWidth;
1695
+ chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
1696
+ return true;
1697
+ }
1698
+ return false;
1699
+ }
1700
+ const supportsEventListenerOptions = (function() {
1701
+ let passiveSupported = false;
1702
+ try {
1703
+ const options = {
1704
+ get passive() {
1705
+ passiveSupported = true;
1706
+ return false;
1707
+ }
1708
+ };
1709
+ window.addEventListener('test', null, options);
1710
+ window.removeEventListener('test', null, options);
1711
+ } catch (e) {
1712
+ }
1713
+ return passiveSupported;
1714
+ }());
1715
+ function readUsedSize(element, property) {
1716
+ const value = getStyle(element, property);
1717
+ const matches = value && value.match(/^(\d+)(\.\d+)?px$/);
1718
+ return matches ? +matches[1] : undefined;
1719
+ }
1720
+
1721
+ function getRelativePosition(e, chart) {
1722
+ if ('native' in e) {
1723
+ return {
1724
+ x: e.x,
1725
+ y: e.y
1726
+ };
1727
+ }
1728
+ return getRelativePosition$1(e, chart);
1729
+ }
1730
+ function evaluateAllVisibleItems(chart, handler) {
1731
+ const metasets = chart.getSortedVisibleDatasetMetas();
1732
+ let index, data, element;
1733
+ for (let i = 0, ilen = metasets.length; i < ilen; ++i) {
1734
+ ({index, data} = metasets[i]);
1735
+ for (let j = 0, jlen = data.length; j < jlen; ++j) {
1736
+ element = data[j];
1737
+ if (!element.skip) {
1738
+ handler(element, index, j);
1739
+ }
1740
+ }
1741
+ }
1742
+ }
1743
+ function binarySearch(metaset, axis, value, intersect) {
1744
+ const {controller, data, _sorted} = metaset;
1745
+ const iScale = controller._cachedMeta.iScale;
1746
+ if (iScale && axis === iScale.axis && axis !== 'r' && _sorted && data.length) {
1747
+ const lookupMethod = iScale._reversePixels ? _rlookupByKey : _lookupByKey;
1748
+ if (!intersect) {
1749
+ return lookupMethod(data, axis, value);
1750
+ } else if (controller._sharedOptions) {
1751
+ const el = data[0];
1752
+ const range = typeof el.getRange === 'function' && el.getRange(axis);
1753
+ if (range) {
1754
+ const start = lookupMethod(data, axis, value - range);
1755
+ const end = lookupMethod(data, axis, value + range);
1756
+ return {lo: start.lo, hi: end.hi};
1757
+ }
1758
+ }
1759
+ }
1760
+ return {lo: 0, hi: data.length - 1};
1761
+ }
1762
+ function optimizedEvaluateItems(chart, axis, position, handler, intersect) {
1763
+ const metasets = chart.getSortedVisibleDatasetMetas();
1764
+ const value = position[axis];
1765
+ for (let i = 0, ilen = metasets.length; i < ilen; ++i) {
1766
+ const {index, data} = metasets[i];
1767
+ const {lo, hi} = binarySearch(metasets[i], axis, value, intersect);
1768
+ for (let j = lo; j <= hi; ++j) {
1769
+ const element = data[j];
1770
+ if (!element.skip) {
1771
+ handler(element, index, j);
1772
+ }
1773
+ }
1774
+ }
1775
+ }
1776
+ function getDistanceMetricForAxis(axis) {
1777
+ const useX = axis.indexOf('x') !== -1;
1778
+ const useY = axis.indexOf('y') !== -1;
1779
+ return function(pt1, pt2) {
1780
+ const deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0;
1781
+ const deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0;
1782
+ return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
1783
+ };
1784
+ }
1785
+ function getIntersectItems(chart, position, axis, useFinalPosition) {
1786
+ const items = [];
1787
+ if (!_isPointInArea(position, chart.chartArea, chart._minPadding)) {
1788
+ return items;
1789
+ }
1790
+ const evaluationFunc = function(element, datasetIndex, index) {
1791
+ if (element.inRange(position.x, position.y, useFinalPosition)) {
1792
+ items.push({element, datasetIndex, index});
1793
+ }
1794
+ };
1795
+ optimizedEvaluateItems(chart, axis, position, evaluationFunc, true);
1796
+ return items;
1797
+ }
1798
+ function getNearestRadialItems(chart, position, axis, useFinalPosition) {
1799
+ let items = [];
1800
+ function evaluationFunc(element, datasetIndex, index) {
1801
+ const {startAngle, endAngle} = element.getProps(['startAngle', 'endAngle'], useFinalPosition);
1802
+ const {angle} = getAngleFromPoint(element, {x: position.x, y: position.y});
1803
+ if (_angleBetween(angle, startAngle, endAngle)) {
1804
+ items.push({element, datasetIndex, index});
1805
+ }
1806
+ }
1807
+ optimizedEvaluateItems(chart, axis, position, evaluationFunc);
1808
+ return items;
1809
+ }
1810
+ function getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition) {
1811
+ let items = [];
1812
+ const distanceMetric = getDistanceMetricForAxis(axis);
1813
+ let minDistance = Number.POSITIVE_INFINITY;
1814
+ function evaluationFunc(element, datasetIndex, index) {
1815
+ const inRange = element.inRange(position.x, position.y, useFinalPosition);
1816
+ if (intersect && !inRange) {
1817
+ return;
1818
+ }
1819
+ const center = element.getCenterPoint(useFinalPosition);
1820
+ const pointInArea = _isPointInArea(center, chart.chartArea, chart._minPadding);
1821
+ if (!pointInArea && !inRange) {
1822
+ return;
1823
+ }
1824
+ const distance = distanceMetric(position, center);
1825
+ if (distance < minDistance) {
1826
+ items = [{element, datasetIndex, index}];
1827
+ minDistance = distance;
1828
+ } else if (distance === minDistance) {
1829
+ items.push({element, datasetIndex, index});
1830
+ }
1831
+ }
1832
+ optimizedEvaluateItems(chart, axis, position, evaluationFunc);
1833
+ return items;
1834
+ }
1835
+ function getNearestItems(chart, position, axis, intersect, useFinalPosition) {
1836
+ if (!_isPointInArea(position, chart.chartArea, chart._minPadding)) {
1837
+ return [];
1838
+ }
1839
+ return axis === 'r' && !intersect
1840
+ ? getNearestRadialItems(chart, position, axis, useFinalPosition)
1841
+ : getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition);
1842
+ }
1843
+ function getAxisItems(chart, e, options, useFinalPosition) {
1844
+ const position = getRelativePosition(e, chart);
1845
+ const items = [];
1846
+ const axis = options.axis;
1847
+ const rangeMethod = axis === 'x' ? 'inXRange' : 'inYRange';
1848
+ let intersectsItem = false;
1849
+ evaluateAllVisibleItems(chart, (element, datasetIndex, index) => {
1850
+ if (element[rangeMethod](position[axis], useFinalPosition)) {
1851
+ items.push({element, datasetIndex, index});
1852
+ }
1853
+ if (element.inRange(position.x, position.y, useFinalPosition)) {
1854
+ intersectsItem = true;
1855
+ }
1856
+ });
1857
+ if (options.intersect && !intersectsItem) {
1858
+ return [];
1859
+ }
1860
+ return items;
1861
+ }
1862
+ var Interaction = {
1863
+ modes: {
1864
+ index(chart, e, options, useFinalPosition) {
1865
+ const position = getRelativePosition(e, chart);
1866
+ const axis = options.axis || 'x';
1867
+ const items = options.intersect
1868
+ ? getIntersectItems(chart, position, axis, useFinalPosition)
1869
+ : getNearestItems(chart, position, axis, false, useFinalPosition);
1870
+ const elements = [];
1871
+ if (!items.length) {
1872
+ return [];
1873
+ }
1874
+ chart.getSortedVisibleDatasetMetas().forEach((meta) => {
1875
+ const index = items[0].index;
1876
+ const element = meta.data[index];
1877
+ if (element && !element.skip) {
1878
+ elements.push({element, datasetIndex: meta.index, index});
1879
+ }
1880
+ });
1881
+ return elements;
1882
  },
1883
+ dataset(chart, e, options, useFinalPosition) {
1884
+ const position = getRelativePosition(e, chart);
1885
+ const axis = options.axis || 'xy';
1886
+ let items = options.intersect
1887
+ ? getIntersectItems(chart, position, axis, useFinalPosition) :
1888
+ getNearestItems(chart, position, axis, false, useFinalPosition);
1889
+ if (items.length > 0) {
1890
+ const datasetIndex = items[0].datasetIndex;
1891
+ const data = chart.getDatasetMeta(datasetIndex).data;
1892
+ items = [];
1893
+ for (let i = 0; i < data.length; ++i) {
1894
+ items.push({element: data[i], datasetIndex, index: i});
1895
  }
1896
+ }
1897
+ return items;
1898
  },
1899
+ point(chart, e, options, useFinalPosition) {
1900
+ const position = getRelativePosition(e, chart);
1901
+ const axis = options.axis || 'xy';
1902
+ return getIntersectItems(chart, position, axis, useFinalPosition);
1903
  },
1904
+ nearest(chart, e, options, useFinalPosition) {
1905
+ const position = getRelativePosition(e, chart);
1906
+ const axis = options.axis || 'xy';
1907
+ return getNearestItems(chart, position, axis, options.intersect, useFinalPosition);
1908
  },
1909
+ x(chart, e, options, useFinalPosition) {
1910
+ return getAxisItems(chart, e, {axis: 'x', intersect: options.intersect}, useFinalPosition);
1911
  },
1912
+ y(chart, e, options, useFinalPosition) {
1913
+ return getAxisItems(chart, e, {axis: 'y', intersect: options.intersect}, useFinalPosition);
1914
+ }
1915
+ }
1916
+ };
1917
+
1918
+ const LINE_HEIGHT = new RegExp(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);
1919
+ const FONT_STYLE = new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/);
1920
+ function toLineHeight(value, size) {
1921
+ const matches = ('' + value).match(LINE_HEIGHT);
1922
+ if (!matches || matches[1] === 'normal') {
1923
+ return size * 1.2;
1924
+ }
1925
+ value = +matches[2];
1926
+ switch (matches[3]) {
1927
+ case 'px':
1928
+ return value;
1929
+ case '%':
1930
+ value /= 100;
1931
+ break;
1932
+ }
1933
+ return size * value;
1934
+ }
1935
+ const numberOrZero = v => +v || 0;
1936
+ function _readValueToProps(value, props) {
1937
+ const ret = {};
1938
+ const objProps = isObject(props);
1939
+ const keys = objProps ? Object.keys(props) : props;
1940
+ const read = isObject(value)
1941
+ ? objProps
1942
+ ? prop => valueOrDefault(value[prop], value[props[prop]])
1943
+ : prop => value[prop]
1944
+ : () => value;
1945
+ for (const prop of keys) {
1946
+ ret[prop] = numberOrZero(read(prop));
1947
+ }
1948
+ return ret;
1949
+ }
1950
+ function toTRBL(value) {
1951
+ return _readValueToProps(value, {top: 'y', right: 'x', bottom: 'y', left: 'x'});
1952
+ }
1953
+ function toTRBLCorners(value) {
1954
+ return _readValueToProps(value, ['topLeft', 'topRight', 'bottomLeft', 'bottomRight']);
1955
+ }
1956
+ function toPadding(value) {
1957
+ const obj = toTRBL(value);
1958
+ obj.width = obj.left + obj.right;
1959
+ obj.height = obj.top + obj.bottom;
1960
+ return obj;
1961
+ }
1962
+ function toFont(options, fallback) {
1963
+ options = options || {};
1964
+ fallback = fallback || defaults.font;
1965
+ let size = valueOrDefault(options.size, fallback.size);
1966
+ if (typeof size === 'string') {
1967
+ size = parseInt(size, 10);
1968
+ }
1969
+ let style = valueOrDefault(options.style, fallback.style);
1970
+ if (style && !('' + style).match(FONT_STYLE)) {
1971
+ console.warn('Invalid font style specified: "' + style + '"');
1972
+ style = '';
1973
+ }
1974
+ const font = {
1975
+ family: valueOrDefault(options.family, fallback.family),
1976
+ lineHeight: toLineHeight(valueOrDefault(options.lineHeight, fallback.lineHeight), size),
1977
+ size,
1978
+ style,
1979
+ weight: valueOrDefault(options.weight, fallback.weight),
1980
+ string: ''
1981
+ };
1982
+ font.string = toFontString(font);
1983
+ return font;
1984
+ }
1985
+ function resolve(inputs, context, index, info) {
1986
+ let cacheable = true;
1987
+ let i, ilen, value;
1988
+ for (i = 0, ilen = inputs.length; i < ilen; ++i) {
1989
+ value = inputs[i];
1990
+ if (value === undefined) {
1991
+ continue;
1992
+ }
1993
+ if (context !== undefined && typeof value === 'function') {
1994
+ value = value(context);
1995
+ cacheable = false;
1996
+ }
1997
+ if (index !== undefined && isArray(value)) {
1998
+ value = value[index % value.length];
1999
+ cacheable = false;
2000
+ }
2001
+ if (value !== undefined) {
2002
+ if (info && !cacheable) {
2003
+ info.cacheable = false;
2004
+ }
2005
+ return value;
2006
+ }
2007
+ }
2008
+ }
2009
+ function _addGrace(minmax, grace, beginAtZero) {
2010
+ const {min, max} = minmax;
2011
+ const change = toDimension(grace, (max - min) / 2);
2012
+ const keepZero = (value, add) => beginAtZero && value === 0 ? 0 : value + add;
2013
+ return {
2014
+ min: keepZero(min, -Math.abs(change)),
2015
+ max: keepZero(max, change)
2016
+ };
2017
+ }
2018
+ function createContext(parentContext, context) {
2019
+ return Object.assign(Object.create(parentContext), context);
2020
+ }
2021
+
2022
+ const STATIC_POSITIONS = ['left', 'top', 'right', 'bottom'];
2023
+ function filterByPosition(array, position) {
2024
+ return array.filter(v => v.pos === position);
2025
+ }
2026
+ function filterDynamicPositionByAxis(array, axis) {
2027
+ return array.filter(v => STATIC_POSITIONS.indexOf(v.pos) === -1 && v.box.axis === axis);
2028
+ }
2029
+ function sortByWeight(array, reverse) {
2030
+ return array.sort((a, b) => {
2031
+ const v0 = reverse ? b : a;
2032
+ const v1 = reverse ? a : b;
2033
+ return v0.weight === v1.weight ?
2034
+ v0.index - v1.index :
2035
+ v0.weight - v1.weight;
2036
+ });
2037
+ }
2038
+ function wrapBoxes(boxes) {
2039
+ const layoutBoxes = [];
2040
+ let i, ilen, box, pos, stack, stackWeight;
2041
+ for (i = 0, ilen = (boxes || []).length; i < ilen; ++i) {
2042
+ box = boxes[i];
2043
+ ({position: pos, options: {stack, stackWeight = 1}} = box);
2044
+ layoutBoxes.push({
2045
+ index: i,
2046
+ box,
2047
+ pos,
2048
+ horizontal: box.isHorizontal(),
2049
+ weight: box.weight,
2050
+ stack: stack && (pos + stack),
2051
+ stackWeight
2052
+ });
2053
+ }
2054
+ return layoutBoxes;
2055
+ }
2056
+ function buildStacks(layouts) {
2057
+ const stacks = {};
2058
+ for (const wrap of layouts) {
2059
+ const {stack, pos, stackWeight} = wrap;
2060
+ if (!stack || !STATIC_POSITIONS.includes(pos)) {
2061
+ continue;
2062
+ }
2063
+ const _stack = stacks[stack] || (stacks[stack] = {count: 0, placed: 0, weight: 0, size: 0});
2064
+ _stack.count++;
2065
+ _stack.weight += stackWeight;
2066
+ }
2067
+ return stacks;
2068
+ }
2069
+ function setLayoutDims(layouts, params) {
2070
+ const stacks = buildStacks(layouts);
2071
+ const {vBoxMaxWidth, hBoxMaxHeight} = params;
2072
+ let i, ilen, layout;
2073
+ for (i = 0, ilen = layouts.length; i < ilen; ++i) {
2074
+ layout = layouts[i];
2075
+ const {fullSize} = layout.box;
2076
+ const stack = stacks[layout.stack];
2077
+ const factor = stack && layout.stackWeight / stack.weight;
2078
+ if (layout.horizontal) {
2079
+ layout.width = factor ? factor * vBoxMaxWidth : fullSize && params.availableWidth;
2080
+ layout.height = hBoxMaxHeight;
2081
+ } else {
2082
+ layout.width = vBoxMaxWidth;
2083
+ layout.height = factor ? factor * hBoxMaxHeight : fullSize && params.availableHeight;
2084
+ }
2085
+ }
2086
+ return stacks;
2087
+ }
2088
+ function buildLayoutBoxes(boxes) {
2089
+ const layoutBoxes = wrapBoxes(boxes);
2090
+ const fullSize = sortByWeight(layoutBoxes.filter(wrap => wrap.box.fullSize), true);
2091
+ const left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true);
2092
+ const right = sortByWeight(filterByPosition(layoutBoxes, 'right'));
2093
+ const top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true);
2094
+ const bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom'));
2095
+ const centerHorizontal = filterDynamicPositionByAxis(layoutBoxes, 'x');
2096
+ const centerVertical = filterDynamicPositionByAxis(layoutBoxes, 'y');
2097
+ return {
2098
+ fullSize,
2099
+ leftAndTop: left.concat(top),
2100
+ rightAndBottom: right.concat(centerVertical).concat(bottom).concat(centerHorizontal),
2101
+ chartArea: filterByPosition(layoutBoxes, 'chartArea'),
2102
+ vertical: left.concat(right).concat(centerVertical),
2103
+ horizontal: top.concat(bottom).concat(centerHorizontal)
2104
+ };
2105
+ }
2106
+ function getCombinedMax(maxPadding, chartArea, a, b) {
2107
+ return Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]);
2108
+ }
2109
+ function updateMaxPadding(maxPadding, boxPadding) {
2110
+ maxPadding.top = Math.max(maxPadding.top, boxPadding.top);
2111
+ maxPadding.left = Math.max(maxPadding.left, boxPadding.left);
2112
+ maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom);
2113
+ maxPadding.right = Math.max(maxPadding.right, boxPadding.right);
2114
+ }
2115
+ function updateDims(chartArea, params, layout, stacks) {
2116
+ const {pos, box} = layout;
2117
+ const maxPadding = chartArea.maxPadding;
2118
+ if (!isObject(pos)) {
2119
+ if (layout.size) {
2120
+ chartArea[pos] -= layout.size;
2121
+ }
2122
+ const stack = stacks[layout.stack] || {size: 0, count: 1};
2123
+ stack.size = Math.max(stack.size, layout.horizontal ? box.height : box.width);
2124
+ layout.size = stack.size / stack.count;
2125
+ chartArea[pos] += layout.size;
2126
+ }
2127
+ if (box.getPadding) {
2128
+ updateMaxPadding(maxPadding, box.getPadding());
2129
+ }
2130
+ const newWidth = Math.max(0, params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right'));
2131
+ const newHeight = Math.max(0, params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom'));
2132
+ const widthChanged = newWidth !== chartArea.w;
2133
+ const heightChanged = newHeight !== chartArea.h;
2134
+ chartArea.w = newWidth;
2135
+ chartArea.h = newHeight;
2136
+ return layout.horizontal
2137
+ ? {same: widthChanged, other: heightChanged}
2138
+ : {same: heightChanged, other: widthChanged};
2139
+ }
2140
+ function handleMaxPadding(chartArea) {
2141
+ const maxPadding = chartArea.maxPadding;
2142
+ function updatePos(pos) {
2143
+ const change = Math.max(maxPadding[pos] - chartArea[pos], 0);
2144
+ chartArea[pos] += change;
2145
+ return change;
2146
+ }
2147
+ chartArea.y += updatePos('top');
2148
+ chartArea.x += updatePos('left');
2149
+ updatePos('right');
2150
+ updatePos('bottom');
2151
+ }
2152
+ function getMargins(horizontal, chartArea) {
2153
+ const maxPadding = chartArea.maxPadding;
2154
+ function marginForPositions(positions) {
2155
+ const margin = {left: 0, top: 0, right: 0, bottom: 0};
2156
+ positions.forEach((pos) => {
2157
+ margin[pos] = Math.max(chartArea[pos], maxPadding[pos]);
2158
+ });
2159
+ return margin;
2160
+ }
2161
+ return horizontal
2162
+ ? marginForPositions(['left', 'right'])
2163
+ : marginForPositions(['top', 'bottom']);
2164
+ }
2165
+ function fitBoxes(boxes, chartArea, params, stacks) {
2166
+ const refitBoxes = [];
2167
+ let i, ilen, layout, box, refit, changed;
2168
+ for (i = 0, ilen = boxes.length, refit = 0; i < ilen; ++i) {
2169
+ layout = boxes[i];
2170
+ box = layout.box;
2171
+ box.update(
2172
+ layout.width || chartArea.w,
2173
+ layout.height || chartArea.h,
2174
+ getMargins(layout.horizontal, chartArea)
2175
+ );
2176
+ const {same, other} = updateDims(chartArea, params, layout, stacks);
2177
+ refit |= same && refitBoxes.length;
2178
+ changed = changed || other;
2179
+ if (!box.fullSize) {
2180
+ refitBoxes.push(layout);
2181
+ }
2182
+ }
2183
+ return refit && fitBoxes(refitBoxes, chartArea, params, stacks) || changed;
2184
+ }
2185
+ function setBoxDims(box, left, top, width, height) {
2186
+ box.top = top;
2187
+ box.left = left;
2188
+ box.right = left + width;
2189
+ box.bottom = top + height;
2190
+ box.width = width;
2191
+ box.height = height;
2192
+ }
2193
+ function placeBoxes(boxes, chartArea, params, stacks) {
2194
+ const userPadding = params.padding;
2195
+ let {x, y} = chartArea;
2196
+ for (const layout of boxes) {
2197
+ const box = layout.box;
2198
+ const stack = stacks[layout.stack] || {count: 1, placed: 0, weight: 1};
2199
+ const weight = (layout.stackWeight / stack.weight) || 1;
2200
+ if (layout.horizontal) {
2201
+ const width = chartArea.w * weight;
2202
+ const height = stack.size || box.height;
2203
+ if (defined(stack.start)) {
2204
+ y = stack.start;
2205
+ }
2206
+ if (box.fullSize) {
2207
+ setBoxDims(box, userPadding.left, y, params.outerWidth - userPadding.right - userPadding.left, height);
2208
+ } else {
2209
+ setBoxDims(box, chartArea.left + stack.placed, y, width, height);
2210
+ }
2211
+ stack.start = y;
2212
+ stack.placed += width;
2213
+ y = box.bottom;
2214
+ } else {
2215
+ const height = chartArea.h * weight;
2216
+ const width = stack.size || box.width;
2217
+ if (defined(stack.start)) {
2218
+ x = stack.start;
2219
+ }
2220
+ if (box.fullSize) {
2221
+ setBoxDims(box, x, userPadding.top, width, params.outerHeight - userPadding.bottom - userPadding.top);
2222
+ } else {
2223
+ setBoxDims(box, x, chartArea.top + stack.placed, width, height);
2224
+ }
2225
+ stack.start = x;
2226
+ stack.placed += height;
2227
+ x = box.right;
2228
+ }
2229
+ }
2230
+ chartArea.x = x;
2231
+ chartArea.y = y;
2232
+ }
2233
+ defaults.set('layout', {
2234
+ autoPadding: true,
2235
+ padding: {
2236
+ top: 0,
2237
+ right: 0,
2238
+ bottom: 0,
2239
+ left: 0
2240
+ }
2241
+ });
2242
+ var layouts = {
2243
+ addBox(chart, item) {
2244
+ if (!chart.boxes) {
2245
+ chart.boxes = [];
2246
+ }
2247
+ item.fullSize = item.fullSize || false;
2248
+ item.position = item.position || 'top';
2249
+ item.weight = item.weight || 0;
2250
+ item._layers = item._layers || function() {
2251
+ return [{
2252
+ z: 0,
2253
+ draw(chartArea) {
2254
+ item.draw(chartArea);
2255
  }
2256
+ }];
2257
+ };
2258
+ chart.boxes.push(item);
2259
+ },
2260
+ removeBox(chart, layoutItem) {
2261
+ const index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1;
2262
+ if (index !== -1) {
2263
+ chart.boxes.splice(index, 1);
2264
+ }
2265
+ },
2266
+ configure(chart, item, options) {
2267
+ item.fullSize = options.fullSize;
2268
+ item.position = options.position;
2269
+ item.weight = options.weight;
2270
+ },
2271
+ update(chart, width, height, minPadding) {
2272
+ if (!chart) {
2273
+ return;
2274
+ }
2275
+ const padding = toPadding(chart.options.layout.padding);
2276
+ const availableWidth = Math.max(width - padding.width, 0);
2277
+ const availableHeight = Math.max(height - padding.height, 0);
2278
+ const boxes = buildLayoutBoxes(chart.boxes);
2279
+ const verticalBoxes = boxes.vertical;
2280
+ const horizontalBoxes = boxes.horizontal;
2281
+ each(chart.boxes, box => {
2282
+ if (typeof box.beforeLayout === 'function') {
2283
+ box.beforeLayout();
2284
+ }
2285
+ });
2286
+ const visibleVerticalBoxCount = verticalBoxes.reduce((total, wrap) =>
2287
+ wrap.box.options && wrap.box.options.display === false ? total : total + 1, 0) || 1;
2288
+ const params = Object.freeze({
2289
+ outerWidth: width,
2290
+ outerHeight: height,
2291
+ padding,
2292
+ availableWidth,
2293
+ availableHeight,
2294
+ vBoxMaxWidth: availableWidth / 2 / visibleVerticalBoxCount,
2295
+ hBoxMaxHeight: availableHeight / 2
2296
+ });
2297
+ const maxPadding = Object.assign({}, padding);
2298
+ updateMaxPadding(maxPadding, toPadding(minPadding));
2299
+ const chartArea = Object.assign({
2300
+ maxPadding,
2301
+ w: availableWidth,
2302
+ h: availableHeight,
2303
+ x: padding.left,
2304
+ y: padding.top
2305
+ }, padding);
2306
+ const stacks = setLayoutDims(verticalBoxes.concat(horizontalBoxes), params);
2307
+ fitBoxes(boxes.fullSize, chartArea, params, stacks);
2308
+ fitBoxes(verticalBoxes, chartArea, params, stacks);
2309
+ if (fitBoxes(horizontalBoxes, chartArea, params, stacks)) {
2310
+ fitBoxes(verticalBoxes, chartArea, params, stacks);
2311
+ }
2312
+ handleMaxPadding(chartArea);
2313
+ placeBoxes(boxes.leftAndTop, chartArea, params, stacks);
2314
+ chartArea.x += chartArea.w;
2315
+ chartArea.y += chartArea.h;
2316
+ placeBoxes(boxes.rightAndBottom, chartArea, params, stacks);
2317
+ chart.chartArea = {
2318
+ left: chartArea.left,
2319
+ top: chartArea.top,
2320
+ right: chartArea.left + chartArea.w,
2321
+ bottom: chartArea.top + chartArea.h,
2322
+ height: chartArea.h,
2323
+ width: chartArea.w,
2324
+ };
2325
+ each(boxes.chartArea, (layout) => {
2326
+ const box = layout.box;
2327
+ Object.assign(box, chart.chartArea);
2328
+ box.update(chartArea.w, chartArea.h, {left: 0, top: 0, right: 0, bottom: 0});
2329
+ });
2330
+ }
2331
+ };
2332
+
2333
+ function _createResolver(scopes, prefixes = [''], rootScopes = scopes, fallback, getTarget = () => scopes[0]) {
2334
+ if (!defined(fallback)) {
2335
+ fallback = _resolve('_fallback', scopes);
2336
+ }
2337
+ const cache = {
2338
+ [Symbol.toStringTag]: 'Object',
2339
+ _cacheable: true,
2340
+ _scopes: scopes,
2341
+ _rootScopes: rootScopes,
2342
+ _fallback: fallback,
2343
+ _getTarget: getTarget,
2344
+ override: (scope) => _createResolver([scope, ...scopes], prefixes, rootScopes, fallback),
2345
+ };
2346
+ return new Proxy(cache, {
2347
+ deleteProperty(target, prop) {
2348
+ delete target[prop];
2349
+ delete target._keys;
2350
+ delete scopes[0][prop];
2351
+ return true;
2352
  },
2353
+ get(target, prop) {
2354
+ return _cached(target, prop,
2355
+ () => _resolveWithPrefixes(prop, prefixes, scopes, target));
 
 
 
 
2356
  },
2357
+ getOwnPropertyDescriptor(target, prop) {
2358
+ return Reflect.getOwnPropertyDescriptor(target._scopes[0], prop);
2359
  },
2360
+ getPrototypeOf() {
2361
+ return Reflect.getPrototypeOf(scopes[0]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2362
  },
2363
+ has(target, prop) {
2364
+ return getKeysFromAllScopes(target).includes(prop);
2365
  },
2366
+ ownKeys(target) {
2367
+ return getKeysFromAllScopes(target);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2368
  },
2369
+ set(target, prop, value) {
2370
+ const storage = target._storage || (target._storage = getTarget());
2371
+ target[prop] = storage[prop] = value;
2372
+ delete target._keys;
2373
+ return true;
2374
+ }
2375
+ });
2376
+ }
2377
+ function _attachContext(proxy, context, subProxy, descriptorDefaults) {
2378
+ const cache = {
2379
+ _cacheable: false,
2380
+ _proxy: proxy,
2381
+ _context: context,
2382
+ _subProxy: subProxy,
2383
+ _stack: new Set(),
2384
+ _descriptors: _descriptors(proxy, descriptorDefaults),
2385
+ setContext: (ctx) => _attachContext(proxy, ctx, subProxy, descriptorDefaults),
2386
+ override: (scope) => _attachContext(proxy.override(scope), context, subProxy, descriptorDefaults)
2387
+ };
2388
+ return new Proxy(cache, {
2389
+ deleteProperty(target, prop) {
2390
+ delete target[prop];
2391
+ delete proxy[prop];
2392
+ return true;
2393
  },
2394
+ get(target, prop, receiver) {
2395
+ return _cached(target, prop,
2396
+ () => _resolveWithContext(target, prop, receiver));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2397
  },
2398
+ getOwnPropertyDescriptor(target, prop) {
2399
+ return target._descriptors.allKeys
2400
+ ? Reflect.has(proxy, prop) ? {enumerable: true, configurable: true} : undefined
2401
+ : Reflect.getOwnPropertyDescriptor(proxy, prop);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2402
  },
2403
+ getPrototypeOf() {
2404
+ return Reflect.getPrototypeOf(proxy);
 
 
 
 
 
 
 
 
 
2405
  },
2406
+ has(target, prop) {
2407
+ return Reflect.has(proxy, prop);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2408
  },
2409
+ ownKeys() {
2410
+ return Reflect.ownKeys(proxy);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2411
  },
2412
+ set(target, prop, value) {
2413
+ proxy[prop] = value;
2414
+ delete target[prop];
2415
+ return true;
2416
+ }
2417
+ });
2418
+ }
2419
+ function _descriptors(proxy, defaults = {scriptable: true, indexable: true}) {
2420
+ const {_scriptable = defaults.scriptable, _indexable = defaults.indexable, _allKeys = defaults.allKeys} = proxy;
2421
+ return {
2422
+ allKeys: _allKeys,
2423
+ scriptable: _scriptable,
2424
+ indexable: _indexable,
2425
+ isScriptable: isFunction(_scriptable) ? _scriptable : () => _scriptable,
2426
+ isIndexable: isFunction(_indexable) ? _indexable : () => _indexable
2427
+ };
2428
+ }
2429
+ const readKey = (prefix, name) => prefix ? prefix + _capitalize(name) : name;
2430
+ const needsSubResolver = (prop, value) => isObject(value) && prop !== 'adapters' &&
2431
+ (Object.getPrototypeOf(value) === null || value.constructor === Object);
2432
+ function _cached(target, prop, resolve) {
2433
+ if (Object.prototype.hasOwnProperty.call(target, prop)) {
2434
+ return target[prop];
2435
+ }
2436
+ const value = resolve();
2437
+ target[prop] = value;
2438
+ return value;
2439
+ }
2440
+ function _resolveWithContext(target, prop, receiver) {
2441
+ const {_proxy, _context, _subProxy, _descriptors: descriptors} = target;
2442
+ let value = _proxy[prop];
2443
+ if (isFunction(value) && descriptors.isScriptable(prop)) {
2444
+ value = _resolveScriptable(prop, value, target, receiver);
2445
+ }
2446
+ if (isArray(value) && value.length) {
2447
+ value = _resolveArray(prop, value, target, descriptors.isIndexable);
2448
+ }
2449
+ if (needsSubResolver(prop, value)) {
2450
+ value = _attachContext(value, _context, _subProxy && _subProxy[prop], descriptors);
2451
+ }
2452
+ return value;
2453
+ }
2454
+ function _resolveScriptable(prop, value, target, receiver) {
2455
+ const {_proxy, _context, _subProxy, _stack} = target;
2456
+ if (_stack.has(prop)) {
2457
+ throw new Error('Recursion detected: ' + Array.from(_stack).join('->') + '->' + prop);
2458
+ }
2459
+ _stack.add(prop);
2460
+ value = value(_context, _subProxy || receiver);
2461
+ _stack.delete(prop);
2462
+ if (needsSubResolver(prop, value)) {
2463
+ value = createSubResolver(_proxy._scopes, _proxy, prop, value);
2464
+ }
2465
+ return value;
2466
+ }
2467
+ function _resolveArray(prop, value, target, isIndexable) {
2468
+ const {_proxy, _context, _subProxy, _descriptors: descriptors} = target;
2469
+ if (defined(_context.index) && isIndexable(prop)) {
2470
+ value = value[_context.index % value.length];
2471
+ } else if (isObject(value[0])) {
2472
+ const arr = value;
2473
+ const scopes = _proxy._scopes.filter(s => s !== arr);
2474
+ value = [];
2475
+ for (const item of arr) {
2476
+ const resolver = createSubResolver(scopes, _proxy, prop, item);
2477
+ value.push(_attachContext(resolver, _context, _subProxy && _subProxy[prop], descriptors));
2478
+ }
2479
+ }
2480
+ return value;
2481
+ }
2482
+ function resolveFallback(fallback, prop, value) {
2483
+ return isFunction(fallback) ? fallback(prop, value) : fallback;
2484
+ }
2485
+ const getScope = (key, parent) => key === true ? parent
2486
+ : typeof key === 'string' ? resolveObjectKey(parent, key) : undefined;
2487
+ function addScopes(set, parentScopes, key, parentFallback, value) {
2488
+ for (const parent of parentScopes) {
2489
+ const scope = getScope(key, parent);
2490
+ if (scope) {
2491
+ set.add(scope);
2492
+ const fallback = resolveFallback(scope._fallback, key, value);
2493
+ if (defined(fallback) && fallback !== key && fallback !== parentFallback) {
2494
+ return fallback;
2495
+ }
2496
+ } else if (scope === false && defined(parentFallback) && key !== parentFallback) {
2497
+ return null;
2498
+ }
2499
+ }
2500
+ return false;
2501
+ }
2502
+ function createSubResolver(parentScopes, resolver, prop, value) {
2503
+ const rootScopes = resolver._rootScopes;
2504
+ const fallback = resolveFallback(resolver._fallback, prop, value);
2505
+ const allScopes = [...parentScopes, ...rootScopes];
2506
+ const set = new Set();
2507
+ set.add(value);
2508
+ let key = addScopesFromKey(set, allScopes, prop, fallback || prop, value);
2509
+ if (key === null) {
2510
+ return false;
2511
+ }
2512
+ if (defined(fallback) && fallback !== prop) {
2513
+ key = addScopesFromKey(set, allScopes, fallback, key, value);
2514
+ if (key === null) {
2515
+ return false;
2516
+ }
2517
+ }
2518
+ return _createResolver(Array.from(set), [''], rootScopes, fallback,
2519
+ () => subGetTarget(resolver, prop, value));
2520
+ }
2521
+ function addScopesFromKey(set, allScopes, key, fallback, item) {
2522
+ while (key) {
2523
+ key = addScopes(set, allScopes, key, fallback, item);
2524
+ }
2525
+ return key;
2526
+ }
2527
+ function subGetTarget(resolver, prop, value) {
2528
+ const parent = resolver._getTarget();
2529
+ if (!(prop in parent)) {
2530
+ parent[prop] = {};
2531
+ }
2532
+ const target = parent[prop];
2533
+ if (isArray(target) && isObject(value)) {
2534
+ return value;
2535
+ }
2536
+ return target;
2537
+ }
2538
+ function _resolveWithPrefixes(prop, prefixes, scopes, proxy) {
2539
+ let value;
2540
+ for (const prefix of prefixes) {
2541
+ value = _resolve(readKey(prefix, prop), scopes);
2542
+ if (defined(value)) {
2543
+ return needsSubResolver(prop, value)
2544
+ ? createSubResolver(scopes, proxy, prop, value)
2545
+ : value;
2546
+ }
2547
+ }
2548
+ }
2549
+ function _resolve(key, scopes) {
2550
+ for (const scope of scopes) {
2551
+ if (!scope) {
2552
+ continue;
2553
+ }
2554
+ const value = scope[key];
2555
+ if (defined(value)) {
2556
+ return value;
2557
+ }
2558
+ }
2559
+ }
2560
+ function getKeysFromAllScopes(target) {
2561
+ let keys = target._keys;
2562
+ if (!keys) {
2563
+ keys = target._keys = resolveKeysFromAllScopes(target._scopes);
2564
+ }
2565
+ return keys;
2566
+ }
2567
+ function resolveKeysFromAllScopes(scopes) {
2568
+ const set = new Set();
2569
+ for (const scope of scopes) {
2570
+ for (const key of Object.keys(scope).filter(k => !k.startsWith('_'))) {
2571
+ set.add(key);
2572
+ }
2573
+ }
2574
+ return Array.from(set);
2575
+ }
2576
+
2577
+ const EPSILON = Number.EPSILON || 1e-14;
2578
+ const getPoint = (points, i) => i < points.length && !points[i].skip && points[i];
2579
+ const getValueAxis = (indexAxis) => indexAxis === 'x' ? 'y' : 'x';
2580
+ function splineCurve(firstPoint, middlePoint, afterPoint, t) {
2581
+ const previous = firstPoint.skip ? middlePoint : firstPoint;
2582
+ const current = middlePoint;
2583
+ const next = afterPoint.skip ? middlePoint : afterPoint;
2584
+ const d01 = distanceBetweenPoints(current, previous);
2585
+ const d12 = distanceBetweenPoints(next, current);
2586
+ let s01 = d01 / (d01 + d12);
2587
+ let s12 = d12 / (d01 + d12);
2588
+ s01 = isNaN(s01) ? 0 : s01;
2589
+ s12 = isNaN(s12) ? 0 : s12;
2590
+ const fa = t * s01;
2591
+ const fb = t * s12;
2592
+ return {
2593
+ previous: {
2594
+ x: current.x - fa * (next.x - previous.x),
2595
+ y: current.y - fa * (next.y - previous.y)
2596
  },
2597
+ next: {
2598
+ x: current.x + fb * (next.x - previous.x),
2599
+ y: current.y + fb * (next.y - previous.y)
2600
+ }
2601
+ };
2602
+ }
2603
+ function monotoneAdjust(points, deltaK, mK) {
2604
+ const pointsLen = points.length;
2605
+ let alphaK, betaK, tauK, squaredMagnitude, pointCurrent;
2606
+ let pointAfter = getPoint(points, 0);
2607
+ for (let i = 0; i < pointsLen - 1; ++i) {
2608
+ pointCurrent = pointAfter;
2609
+ pointAfter = getPoint(points, i + 1);
2610
+ if (!pointCurrent || !pointAfter) {
2611
+ continue;
2612
+ }
2613
+ if (almostEquals(deltaK[i], 0, EPSILON)) {
2614
+ mK[i] = mK[i + 1] = 0;
2615
+ continue;
2616
+ }
2617
+ alphaK = mK[i] / deltaK[i];
2618
+ betaK = mK[i + 1] / deltaK[i];
2619
+ squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);
2620
+ if (squaredMagnitude <= 9) {
2621
+ continue;
2622
+ }
2623
+ tauK = 3 / Math.sqrt(squaredMagnitude);
2624
+ mK[i] = alphaK * tauK * deltaK[i];
2625
+ mK[i + 1] = betaK * tauK * deltaK[i];
2626
+ }
2627
+ }
2628
+ function monotoneCompute(points, mK, indexAxis = 'x') {
2629
+ const valueAxis = getValueAxis(indexAxis);
2630
+ const pointsLen = points.length;
2631
+ let delta, pointBefore, pointCurrent;
2632
+ let pointAfter = getPoint(points, 0);
2633
+ for (let i = 0; i < pointsLen; ++i) {
2634
+ pointBefore = pointCurrent;
2635
+ pointCurrent = pointAfter;
2636
+ pointAfter = getPoint(points, i + 1);
2637
+ if (!pointCurrent) {
2638
+ continue;
2639
+ }
2640
+ const iPixel = pointCurrent[indexAxis];
2641
+ const vPixel = pointCurrent[valueAxis];
2642
+ if (pointBefore) {
2643
+ delta = (iPixel - pointBefore[indexAxis]) / 3;
2644
+ pointCurrent[`cp1${indexAxis}`] = iPixel - delta;
2645
+ pointCurrent[`cp1${valueAxis}`] = vPixel - delta * mK[i];
2646
+ }
2647
+ if (pointAfter) {
2648
+ delta = (pointAfter[indexAxis] - iPixel) / 3;
2649
+ pointCurrent[`cp2${indexAxis}`] = iPixel + delta;
2650
+ pointCurrent[`cp2${valueAxis}`] = vPixel + delta * mK[i];
2651
+ }
2652
+ }
2653
+ }
2654
+ function splineCurveMonotone(points, indexAxis = 'x') {
2655
+ const valueAxis = getValueAxis(indexAxis);
2656
+ const pointsLen = points.length;
2657
+ const deltaK = Array(pointsLen).fill(0);
2658
+ const mK = Array(pointsLen);
2659
+ let i, pointBefore, pointCurrent;
2660
+ let pointAfter = getPoint(points, 0);
2661
+ for (i = 0; i < pointsLen; ++i) {
2662
+ pointBefore = pointCurrent;
2663
+ pointCurrent = pointAfter;
2664
+ pointAfter = getPoint(points, i + 1);
2665
+ if (!pointCurrent) {
2666
+ continue;
2667
+ }
2668
+ if (pointAfter) {
2669
+ const slopeDelta = pointAfter[indexAxis] - pointCurrent[indexAxis];
2670
+ deltaK[i] = slopeDelta !== 0 ? (pointAfter[valueAxis] - pointCurrent[valueAxis]) / slopeDelta : 0;
2671
+ }
2672
+ mK[i] = !pointBefore ? deltaK[i]
2673
+ : !pointAfter ? deltaK[i - 1]
2674
+ : (sign(deltaK[i - 1]) !== sign(deltaK[i])) ? 0
2675
+ : (deltaK[i - 1] + deltaK[i]) / 2;
2676
+ }
2677
+ monotoneAdjust(points, deltaK, mK);
2678
+ monotoneCompute(points, mK, indexAxis);
2679
+ }
2680
+ function capControlPoint(pt, min, max) {
2681
+ return Math.max(Math.min(pt, max), min);
2682
+ }
2683
+ function capBezierPoints(points, area) {
2684
+ let i, ilen, point, inArea, inAreaPrev;
2685
+ let inAreaNext = _isPointInArea(points[0], area);
2686
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
2687
+ inAreaPrev = inArea;
2688
+ inArea = inAreaNext;
2689
+ inAreaNext = i < ilen - 1 && _isPointInArea(points[i + 1], area);
2690
+ if (!inArea) {
2691
+ continue;
2692
+ }
2693
+ point = points[i];
2694
+ if (inAreaPrev) {
2695
+ point.cp1x = capControlPoint(point.cp1x, area.left, area.right);
2696
+ point.cp1y = capControlPoint(point.cp1y, area.top, area.bottom);
2697
+ }
2698
+ if (inAreaNext) {
2699
+ point.cp2x = capControlPoint(point.cp2x, area.left, area.right);
2700
+ point.cp2y = capControlPoint(point.cp2y, area.top, area.bottom);
2701
+ }
2702
+ }
2703
+ }
2704
+ function _updateBezierControlPoints(points, options, area, loop, indexAxis) {
2705
+ let i, ilen, point, controlPoints;
2706
+ if (options.spanGaps) {
2707
+ points = points.filter((pt) => !pt.skip);
2708
+ }
2709
+ if (options.cubicInterpolationMode === 'monotone') {
2710
+ splineCurveMonotone(points, indexAxis);
2711
+ } else {
2712
+ let prev = loop ? points[points.length - 1] : points[0];
2713
+ for (i = 0, ilen = points.length; i < ilen; ++i) {
2714
+ point = points[i];
2715
+ controlPoints = splineCurve(
2716
+ prev,
2717
+ point,
2718
+ points[Math.min(i + 1, ilen - (loop ? 0 : 1)) % ilen],
2719
+ options.tension
2720
+ );
2721
+ point.cp1x = controlPoints.previous.x;
2722
+ point.cp1y = controlPoints.previous.y;
2723
+ point.cp2x = controlPoints.next.x;
2724
+ point.cp2y = controlPoints.next.y;
2725
+ prev = point;
2726
+ }
2727
+ }
2728
+ if (options.capBezierPoints) {
2729
+ capBezierPoints(points, area);
2730
+ }
2731
+ }
2732
+
2733
+ const atEdge = (t) => t === 0 || t === 1;
2734
+ const elasticIn = (t, s, p) => -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * TAU / p));
2735
+ const elasticOut = (t, s, p) => Math.pow(2, -10 * t) * Math.sin((t - s) * TAU / p) + 1;
2736
+ const effects = {
2737
+ linear: t => t,
2738
+ easeInQuad: t => t * t,
2739
+ easeOutQuad: t => -t * (t - 2),
2740
+ easeInOutQuad: t => ((t /= 0.5) < 1)
2741
+ ? 0.5 * t * t
2742
+ : -0.5 * ((--t) * (t - 2) - 1),
2743
+ easeInCubic: t => t * t * t,
2744
+ easeOutCubic: t => (t -= 1) * t * t + 1,
2745
+ easeInOutCubic: t => ((t /= 0.5) < 1)
2746
+ ? 0.5 * t * t * t
2747
+ : 0.5 * ((t -= 2) * t * t + 2),
2748
+ easeInQuart: t => t * t * t * t,
2749
+ easeOutQuart: t => -((t -= 1) * t * t * t - 1),
2750
+ easeInOutQuart: t => ((t /= 0.5) < 1)
2751
+ ? 0.5 * t * t * t * t
2752
+ : -0.5 * ((t -= 2) * t * t * t - 2),
2753
+ easeInQuint: t => t * t * t * t * t,
2754
+ easeOutQuint: t => (t -= 1) * t * t * t * t + 1,
2755
+ easeInOutQuint: t => ((t /= 0.5) < 1)
2756
+ ? 0.5 * t * t * t * t * t
2757
+ : 0.5 * ((t -= 2) * t * t * t * t + 2),
2758
+ easeInSine: t => -Math.cos(t * HALF_PI) + 1,
2759
+ easeOutSine: t => Math.sin(t * HALF_PI),
2760
+ easeInOutSine: t => -0.5 * (Math.cos(PI * t) - 1),
2761
+ easeInExpo: t => (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)),
2762
+ easeOutExpo: t => (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1,
2763
+ easeInOutExpo: t => atEdge(t) ? t : t < 0.5
2764
+ ? 0.5 * Math.pow(2, 10 * (t * 2 - 1))
2765
+ : 0.5 * (-Math.pow(2, -10 * (t * 2 - 1)) + 2),
2766
+ easeInCirc: t => (t >= 1) ? t : -(Math.sqrt(1 - t * t) - 1),
2767
+ easeOutCirc: t => Math.sqrt(1 - (t -= 1) * t),
2768
+ easeInOutCirc: t => ((t /= 0.5) < 1)
2769
+ ? -0.5 * (Math.sqrt(1 - t * t) - 1)
2770
+ : 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1),
2771
+ easeInElastic: t => atEdge(t) ? t : elasticIn(t, 0.075, 0.3),
2772
+ easeOutElastic: t => atEdge(t) ? t : elasticOut(t, 0.075, 0.3),
2773
+ easeInOutElastic(t) {
2774
+ const s = 0.1125;
2775
+ const p = 0.45;
2776
+ return atEdge(t) ? t :
2777
+ t < 0.5
2778
+ ? 0.5 * elasticIn(t * 2, s, p)
2779
+ : 0.5 + 0.5 * elasticOut(t * 2 - 1, s, p);
2780
+ },
2781
+ easeInBack(t) {
2782
+ const s = 1.70158;
2783
+ return t * t * ((s + 1) * t - s);
2784
+ },
2785
+ easeOutBack(t) {
2786
+ const s = 1.70158;
2787
+ return (t -= 1) * t * ((s + 1) * t + s) + 1;
2788
+ },
2789
+ easeInOutBack(t) {
2790
+ let s = 1.70158;
2791
+ if ((t /= 0.5) < 1) {
2792
+ return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s));
2793
+ }
2794
+ return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
2795
+ },
2796
+ easeInBounce: t => 1 - effects.easeOutBounce(1 - t),
2797
+ easeOutBounce(t) {
2798
+ const m = 7.5625;
2799
+ const d = 2.75;
2800
+ if (t < (1 / d)) {
2801
+ return m * t * t;
2802
+ }
2803
+ if (t < (2 / d)) {
2804
+ return m * (t -= (1.5 / d)) * t + 0.75;
2805
+ }
2806
+ if (t < (2.5 / d)) {
2807
+ return m * (t -= (2.25 / d)) * t + 0.9375;
2808
+ }
2809
+ return m * (t -= (2.625 / d)) * t + 0.984375;
2810
+ },
2811
+ easeInOutBounce: t => (t < 0.5)
2812
+ ? effects.easeInBounce(t * 2) * 0.5
2813
+ : effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5,
2814
+ };
2815
+
2816
+ function _pointInLine(p1, p2, t, mode) {
2817
+ return {
2818
+ x: p1.x + t * (p2.x - p1.x),
2819
+ y: p1.y + t * (p2.y - p1.y)
2820
+ };
2821
+ }
2822
+ function _steppedInterpolation(p1, p2, t, mode) {
2823
+ return {
2824
+ x: p1.x + t * (p2.x - p1.x),
2825
+ y: mode === 'middle' ? t < 0.5 ? p1.y : p2.y
2826
+ : mode === 'after' ? t < 1 ? p1.y : p2.y
2827
+ : t > 0 ? p2.y : p1.y
2828
+ };
2829
+ }
2830
+ function _bezierInterpolation(p1, p2, t, mode) {
2831
+ const cp1 = {x: p1.cp2x, y: p1.cp2y};
2832
+ const cp2 = {x: p2.cp1x, y: p2.cp1y};
2833
+ const a = _pointInLine(p1, cp1, t);
2834
+ const b = _pointInLine(cp1, cp2, t);
2835
+ const c = _pointInLine(cp2, p2, t);
2836
+ const d = _pointInLine(a, b, t);
2837
+ const e = _pointInLine(b, c, t);
2838
+ return _pointInLine(d, e, t);
2839
+ }
2840
+
2841
+ const intlCache = new Map();
2842
+ function getNumberFormat(locale, options) {
2843
+ options = options || {};
2844
+ const cacheKey = locale + JSON.stringify(options);
2845
+ let formatter = intlCache.get(cacheKey);
2846
+ if (!formatter) {
2847
+ formatter = new Intl.NumberFormat(locale, options);
2848
+ intlCache.set(cacheKey, formatter);
2849
+ }
2850
+ return formatter;
2851
+ }
2852
+ function formatNumber(num, locale, options) {
2853
+ return getNumberFormat(locale, options).format(num);
2854
+ }
2855
+
2856
+ const getRightToLeftAdapter = function(rectX, width) {
2857
+ return {
2858
+ x(x) {
2859
+ return rectX + rectX + width - x;
2860
  },
2861
+ setWidth(w) {
2862
+ width = w;
 
 
 
 
 
 
2863
  },
2864
+ textAlign(align) {
2865
+ if (align === 'center') {
2866
+ return align;
2867
+ }
2868
+ return align === 'right' ? 'left' : 'right';
 
 
 
 
 
 
 
 
2869
  },
2870
+ xPlus(x, value) {
2871
+ return x - value;
 
 
 
 
2872
  },
2873
+ leftForLtr(x, itemWidth) {
2874
+ return x - itemWidth;
 
 
2875
  },
2876
+ };
2877
+ };
2878
+ const getLeftToRightAdapter = function() {
2879
+ return {
2880
+ x(x) {
2881
+ return x;
2882
  },
2883
+ setWidth(w) {
 
 
 
 
 
 
 
 
 
 
 
 
2884
  },
2885
+ textAlign(align) {
2886
+ return align;
 
2887
  },
2888
+ xPlus(x, value) {
2889
+ return x + value;
2890
  },
2891
+ leftForLtr(x, _itemWidth) {
2892
+ return x;
 
 
 
 
 
 
 
 
2893
  },
2894
+ };
2895
+ };
2896
+ function getRtlAdapter(rtl, rectX, width) {
2897
+ return rtl ? getRightToLeftAdapter(rectX, width) : getLeftToRightAdapter();
2898
+ }
2899
+ function overrideTextDirection(ctx, direction) {
2900
+ let style, original;
2901
+ if (direction === 'ltr' || direction === 'rtl') {
2902
+ style = ctx.canvas.style;
2903
+ original = [
2904
+ style.getPropertyValue('direction'),
2905
+ style.getPropertyPriority('direction'),
2906
+ ];
2907
+ style.setProperty('direction', direction, 'important');
2908
+ ctx.prevTextDirection = original;
2909
+ }
2910
+ }
2911
+ function restoreTextDirection(ctx, original) {
2912
+ if (original !== undefined) {
2913
+ delete ctx.prevTextDirection;
2914
+ ctx.canvas.style.setProperty('direction', original[0], original[1]);
2915
+ }
2916
+ }
2917
+
2918
+ function propertyFn(property) {
2919
+ if (property === 'angle') {
2920
+ return {
2921
+ between: _angleBetween,
2922
+ compare: _angleDiff,
2923
+ normalize: _normalizeAngle,
2924
  };
2925
+ }
2926
+ return {
2927
+ between: _isBetween,
2928
+ compare: (a, b) => a - b,
2929
+ normalize: x => x
2930
+ };
2931
+ }
2932
+ function normalizeSegment({start, end, count, loop, style}) {
2933
+ return {
2934
+ start: start % count,
2935
+ end: end % count,
2936
+ loop: loop && (end - start + 1) % count === 0,
2937
+ style
2938
+ };
2939
+ }
2940
+ function getSegment(segment, points, bounds) {
2941
+ const {property, start: startBound, end: endBound} = bounds;
2942
+ const {between, normalize} = propertyFn(property);
2943
+ const count = points.length;
2944
+ let {start, end, loop} = segment;
2945
+ let i, ilen;
2946
+ if (loop) {
2947
+ start += count;
2948
+ end += count;
2949
+ for (i = 0, ilen = count; i < ilen; ++i) {
2950
+ if (!between(normalize(points[start % count][property]), startBound, endBound)) {
2951
+ break;
2952
+ }
2953
+ start--;
2954
+ end--;
2955
+ }
2956
+ start %= count;
2957
+ end %= count;
2958
+ }
2959
+ if (end < start) {
2960
+ end += count;
2961
+ }
2962
+ return {start, end, loop, style: segment.style};
2963
+ }
2964
+ function _boundSegment(segment, points, bounds) {
2965
+ if (!bounds) {
2966
+ return [segment];
2967
+ }
2968
+ const {property, start: startBound, end: endBound} = bounds;
2969
+ const count = points.length;
2970
+ const {compare, between, normalize} = propertyFn(property);
2971
+ const {start, end, loop, style} = getSegment(segment, points, bounds);
2972
+ const result = [];
2973
+ let inside = false;
2974
+ let subStart = null;
2975
+ let value, point, prevValue;
2976
+ const startIsBefore = () => between(startBound, prevValue, value) && compare(startBound, prevValue) !== 0;
2977
+ const endIsBefore = () => compare(endBound, value) === 0 || between(endBound, prevValue, value);
2978
+ const shouldStart = () => inside || startIsBefore();
2979
+ const shouldStop = () => !inside || endIsBefore();
2980
+ for (let i = start, prev = start; i <= end; ++i) {
2981
+ point = points[i % count];
2982
+ if (point.skip) {
2983
+ continue;
2984
+ }
2985
+ value = normalize(point[property]);
2986
+ if (value === prevValue) {
2987
+ continue;
2988
+ }
2989
+ inside = between(value, startBound, endBound);
2990
+ if (subStart === null && shouldStart()) {
2991
+ subStart = compare(value, startBound) === 0 ? i : prev;
2992
+ }
2993
+ if (subStart !== null && shouldStop()) {
2994
+ result.push(normalizeSegment({start: subStart, end: i, loop, count, style}));
2995
+ subStart = null;
2996
+ }
2997
+ prev = i;
2998
+ prevValue = value;
2999
+ }
3000
+ if (subStart !== null) {
3001
+ result.push(normalizeSegment({start: subStart, end, loop, count, style}));
3002
+ }
3003
+ return result;
3004
+ }
3005
+ function _boundSegments(line, bounds) {
3006
+ const result = [];
3007
+ const segments = line.segments;
3008
+ for (let i = 0; i < segments.length; i++) {
3009
+ const sub = _boundSegment(segments[i], line.points, bounds);
3010
+ if (sub.length) {
3011
+ result.push(...sub);
3012
+ }
3013
+ }
3014
+ return result;
3015
+ }
3016
+ function findStartAndEnd(points, count, loop, spanGaps) {
3017
+ let start = 0;
3018
+ let end = count - 1;
3019
+ if (loop && !spanGaps) {
3020
+ while (start < count && !points[start].skip) {
3021
+ start++;
3022
+ }
3023
+ }
3024
+ while (start < count && points[start].skip) {
3025
+ start++;
3026
+ }
3027
+ start %= count;
3028
+ if (loop) {
3029
+ end += start;
3030
+ }
3031
+ while (end > start && points[end % count].skip) {
3032
+ end--;
3033
+ }
3034
+ end %= count;
3035
+ return {start, end};
3036
+ }
3037
+ function solidSegments(points, start, max, loop) {
3038
+ const count = points.length;
3039
+ const result = [];
3040
+ let last = start;
3041
+ let prev = points[start];
3042
+ let end;
3043
+ for (end = start + 1; end <= max; ++end) {
3044
+ const cur = points[end % count];
3045
+ if (cur.skip || cur.stop) {
3046
+ if (!prev.skip) {
3047
+ loop = false;
3048
+ result.push({start: start % count, end: (end - 1) % count, loop});
3049
+ start = last = cur.stop ? end : null;
3050
+ }
3051
+ } else {
3052
+ last = end;
3053
+ if (prev.skip) {
3054
+ start = end;
3055
+ }
3056
+ }
3057
+ prev = cur;
3058
+ }
3059
+ if (last !== null) {
3060
+ result.push({start: start % count, end: last % count, loop});
3061
+ }
3062
+ return result;
3063
+ }
3064
+ function _computeSegments(line, segmentOptions) {
3065
+ const points = line.points;
3066
+ const spanGaps = line.options.spanGaps;
3067
+ const count = points.length;
3068
+ if (!count) {
3069
+ return [];
3070
+ }
3071
+ const loop = !!line._loop;
3072
+ const {start, end} = findStartAndEnd(points, count, loop, spanGaps);
3073
+ if (spanGaps === true) {
3074
+ return splitByStyles(line, [{start, end, loop}], points, segmentOptions);
3075
+ }
3076
+ const max = end < start ? end + count : end;
3077
+ const completeLoop = !!line._fullLoop && start === 0 && end === count - 1;
3078
+ return splitByStyles(line, solidSegments(points, start, max, completeLoop), points, segmentOptions);
3079
+ }
3080
+ function splitByStyles(line, segments, points, segmentOptions) {
3081
+ if (!segmentOptions || !segmentOptions.setContext || !points) {
3082
+ return segments;
3083
+ }
3084
+ return doSplitByStyles(line, segments, points, segmentOptions);
3085
+ }
3086
+ function doSplitByStyles(line, segments, points, segmentOptions) {
3087
+ const chartContext = line._chart.getContext();
3088
+ const baseStyle = readStyle(line.options);
3089
+ const {_datasetIndex: datasetIndex, options: {spanGaps}} = line;
3090
+ const count = points.length;
3091
+ const result = [];
3092
+ let prevStyle = baseStyle;
3093
+ let start = segments[0].start;
3094
+ let i = start;
3095
+ function addStyle(s, e, l, st) {
3096
+ const dir = spanGaps ? -1 : 1;
3097
+ if (s === e) {
3098
+ return;
3099
+ }
3100
+ s += count;
3101
+ while (points[s % count].skip) {
3102
+ s -= dir;
3103
+ }
3104
+ while (points[e % count].skip) {
3105
+ e += dir;
3106
+ }
3107
+ if (s % count !== e % count) {
3108
+ result.push({start: s % count, end: e % count, loop: l, style: st});
3109
+ prevStyle = st;
3110
+ start = e % count;
3111
+ }
3112
+ }
3113
+ for (const segment of segments) {
3114
+ start = spanGaps ? start : segment.start;
3115
+ let prev = points[start % count];
3116
+ let style;
3117
+ for (i = start + 1; i <= segment.end; i++) {
3118
+ const pt = points[i % count];
3119
+ style = readStyle(segmentOptions.setContext(createContext(chartContext, {
3120
+ type: 'segment',
3121
+ p0: prev,
3122
+ p1: pt,
3123
+ p0DataIndex: (i - 1) % count,
3124
+ p1DataIndex: i % count,
3125
+ datasetIndex
3126
+ })));
3127
+ if (styleChanged(style, prevStyle)) {
3128
+ addStyle(start, i - 1, segment.loop, prevStyle);
3129
+ }
3130
+ prev = pt;
3131
+ prevStyle = style;
3132
+ }
3133
+ if (start < i - 1) {
3134
+ addStyle(start, i - 1, segment.loop, prevStyle);
3135
+ }
3136
+ }
3137
+ return result;
3138
+ }
3139
+ function readStyle(options) {
3140
+ return {
3141
+ backgroundColor: options.backgroundColor,
3142
+ borderCapStyle: options.borderCapStyle,
3143
+ borderDash: options.borderDash,
3144
+ borderDashOffset: options.borderDashOffset,
3145
+ borderJoinStyle: options.borderJoinStyle,
3146
+ borderWidth: options.borderWidth,
3147
+ borderColor: options.borderColor
3148
+ };
3149
+ }
3150
+ function styleChanged(style, prevStyle) {
3151
+ return prevStyle && JSON.stringify(style) !== JSON.stringify(prevStyle);
3152
+ }
3153
+
3154
+ var helpers = /*#__PURE__*/Object.freeze({
3155
+ __proto__: null,
3156
+ easingEffects: effects,
3157
+ color: color,
3158
+ getHoverColor: getHoverColor,
3159
+ noop: noop,
3160
+ uid: uid,
3161
+ isNullOrUndef: isNullOrUndef,
3162
+ isArray: isArray,
3163
+ isObject: isObject,
3164
+ isFinite: isNumberFinite,
3165
+ finiteOrDefault: finiteOrDefault,
3166
+ valueOrDefault: valueOrDefault,
3167
+ toPercentage: toPercentage,
3168
+ toDimension: toDimension,
3169
+ callback: callback,
3170
+ each: each,
3171
+ _elementsEqual: _elementsEqual,
3172
+ clone: clone,
3173
+ _merger: _merger,
3174
+ merge: merge,
3175
+ mergeIf: mergeIf,
3176
+ _mergerIf: _mergerIf,
3177
+ _deprecated: _deprecated,
3178
+ resolveObjectKey: resolveObjectKey,
3179
+ _capitalize: _capitalize,
3180
+ defined: defined,
3181
+ isFunction: isFunction,
3182
+ setsEqual: setsEqual,
3183
+ _isClickEvent: _isClickEvent,
3184
+ toFontString: toFontString,
3185
+ _measureText: _measureText,
3186
+ _longestText: _longestText,
3187
+ _alignPixel: _alignPixel,
3188
+ clearCanvas: clearCanvas,
3189
+ drawPoint: drawPoint,
3190
+ _isPointInArea: _isPointInArea,
3191
+ clipArea: clipArea,
3192
+ unclipArea: unclipArea,
3193
+ _steppedLineTo: _steppedLineTo,
3194
+ _bezierCurveTo: _bezierCurveTo,
3195
+ renderText: renderText,
3196
+ addRoundedRectPath: addRoundedRectPath,
3197
+ _lookup: _lookup,
3198
+ _lookupByKey: _lookupByKey,
3199
+ _rlookupByKey: _rlookupByKey,
3200
+ _filterBetween: _filterBetween,
3201
+ listenArrayEvents: listenArrayEvents,
3202
+ unlistenArrayEvents: unlistenArrayEvents,
3203
+ _arrayUnique: _arrayUnique,
3204
+ _createResolver: _createResolver,
3205
+ _attachContext: _attachContext,
3206
+ _descriptors: _descriptors,
3207
+ splineCurve: splineCurve,
3208
+ splineCurveMonotone: splineCurveMonotone,
3209
+ _updateBezierControlPoints: _updateBezierControlPoints,
3210
+ _isDomSupported: _isDomSupported,
3211
+ _getParentNode: _getParentNode,
3212
+ getStyle: getStyle,
3213
+ getRelativePosition: getRelativePosition$1,
3214
+ getMaximumSize: getMaximumSize,
3215
+ retinaScale: retinaScale,
3216
+ supportsEventListenerOptions: supportsEventListenerOptions,
3217
+ readUsedSize: readUsedSize,
3218
+ fontString: fontString,
3219
+ requestAnimFrame: requestAnimFrame,
3220
+ throttled: throttled,
3221
+ debounce: debounce,
3222
+ _toLeftRightCenter: _toLeftRightCenter,
3223
+ _alignStartEnd: _alignStartEnd,
3224
+ _textX: _textX,
3225
+ _pointInLine: _pointInLine,
3226
+ _steppedInterpolation: _steppedInterpolation,
3227
+ _bezierInterpolation: _bezierInterpolation,
3228
+ formatNumber: formatNumber,
3229
+ toLineHeight: toLineHeight,
3230
+ _readValueToProps: _readValueToProps,
3231
+ toTRBL: toTRBL,
3232
+ toTRBLCorners: toTRBLCorners,
3233
+ toPadding: toPadding,
3234
+ toFont: toFont,
3235
+ resolve: resolve,
3236
+ _addGrace: _addGrace,
3237
+ createContext: createContext,
3238
+ PI: PI,
3239
+ TAU: TAU,
3240
+ PITAU: PITAU,
3241
+ INFINITY: INFINITY,
3242
+ RAD_PER_DEG: RAD_PER_DEG,
3243
+ HALF_PI: HALF_PI,
3244
+ QUARTER_PI: QUARTER_PI,
3245
+ TWO_THIRDS_PI: TWO_THIRDS_PI,
3246
+ log10: log10,
3247
+ sign: sign,
3248
+ niceNum: niceNum,
3249
+ _factorize: _factorize,
3250
+ isNumber: isNumber,
3251
+ almostEquals: almostEquals,
3252
+ almostWhole: almostWhole,
3253
+ _setMinAndMaxByKey: _setMinAndMaxByKey,
3254
+ toRadians: toRadians,
3255
+ toDegrees: toDegrees,
3256
+ _decimalPlaces: _decimalPlaces,
3257
+ getAngleFromPoint: getAngleFromPoint,
3258
+ distanceBetweenPoints: distanceBetweenPoints,
3259
+ _angleDiff: _angleDiff,
3260
+ _normalizeAngle: _normalizeAngle,
3261
+ _angleBetween: _angleBetween,
3262
+ _limitValue: _limitValue,
3263
+ _int16Range: _int16Range,
3264
+ _isBetween: _isBetween,
3265
+ getRtlAdapter: getRtlAdapter,
3266
+ overrideTextDirection: overrideTextDirection,
3267
+ restoreTextDirection: restoreTextDirection,
3268
+ _boundSegment: _boundSegment,
3269
+ _boundSegments: _boundSegments,
3270
+ _computeSegments: _computeSegments
3271
+ });
3272
+
3273
+ class BasePlatform {
3274
+ acquireContext(canvas, aspectRatio) {}
3275
+ releaseContext(context) {
3276
+ return false;
3277
+ }
3278
+ addEventListener(chart, type, listener) {}
3279
+ removeEventListener(chart, type, listener) {}
3280
+ getDevicePixelRatio() {
3281
+ return 1;
3282
+ }
3283
+ getMaximumSize(element, width, height, aspectRatio) {
3284
+ width = Math.max(0, width || element.width);
3285
+ height = height || element.height;
3286
+ return {
3287
+ width,
3288
+ height: Math.max(0, aspectRatio ? Math.floor(width / aspectRatio) : height)
3289
+ };
3290
+ }
3291
+ isAttached(canvas) {
3292
+ return true;
3293
+ }
3294
+ updateConfig(config) {
3295
+ }
3296
+ }
3297
+
3298
+ class BasicPlatform extends BasePlatform {
3299
+ acquireContext(item) {
3300
+ return item && item.getContext && item.getContext('2d') || null;
3301
+ }
3302
+ updateConfig(config) {
3303
+ config.options.animation = false;
3304
+ }
3305
+ }
3306
+
3307
+ const EXPANDO_KEY = '$chartjs';
3308
+ const EVENT_TYPES = {
3309
+ touchstart: 'mousedown',
3310
+ touchmove: 'mousemove',
3311
+ touchend: 'mouseup',
3312
+ pointerenter: 'mouseenter',
3313
+ pointerdown: 'mousedown',
3314
+ pointermove: 'mousemove',
3315
+ pointerup: 'mouseup',
3316
+ pointerleave: 'mouseout',
3317
+ pointerout: 'mouseout'
3318
+ };
3319
+ const isNullOrEmpty = value => value === null || value === '';
3320
+ function initCanvas(canvas, aspectRatio) {
3321
+ const style = canvas.style;
3322
+ const renderHeight = canvas.getAttribute('height');
3323
+ const renderWidth = canvas.getAttribute('width');
3324
+ canvas[EXPANDO_KEY] = {
3325
+ initial: {
3326
+ height: renderHeight,
3327
+ width: renderWidth,
3328
+ style: {
3329
+ display: style.display,
3330
+ height: style.height,
3331
+ width: style.width
3332
+ }
3333
+ }
3334
+ };
3335
+ style.display = style.display || 'block';
3336
+ style.boxSizing = style.boxSizing || 'border-box';
3337
+ if (isNullOrEmpty(renderWidth)) {
3338
+ const displayWidth = readUsedSize(canvas, 'width');
3339
+ if (displayWidth !== undefined) {
3340
+ canvas.width = displayWidth;
3341
+ }
3342
+ }
3343
+ if (isNullOrEmpty(renderHeight)) {
3344
+ if (canvas.style.height === '') {
3345
+ canvas.height = canvas.width / (aspectRatio || 2);
3346
+ } else {
3347
+ const displayHeight = readUsedSize(canvas, 'height');
3348
+ if (displayHeight !== undefined) {
3349
+ canvas.height = displayHeight;
3350
+ }
3351
+ }
3352
+ }
3353
+ return canvas;
3354
+ }
3355
+ const eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false;
3356
+ function addListener(node, type, listener) {
3357
+ node.addEventListener(type, listener, eventListenerOptions);
3358
+ }
3359
+ function removeListener(chart, type, listener) {
3360
+ chart.canvas.removeEventListener(type, listener, eventListenerOptions);
3361
+ }
3362
+ function fromNativeEvent(event, chart) {
3363
+ const type = EVENT_TYPES[event.type] || event.type;
3364
+ const {x, y} = getRelativePosition$1(event, chart);
3365
+ return {
3366
+ type,
3367
+ chart,
3368
+ native: event,
3369
+ x: x !== undefined ? x : null,
3370
+ y: y !== undefined ? y : null,
3371
+ };
3372
+ }
3373
+ function nodeListContains(nodeList, canvas) {
3374
+ for (const node of nodeList) {
3375
+ if (node === canvas || node.contains(canvas)) {
3376
+ return true;
3377
+ }
3378
+ }
3379
+ }
3380
+ function createAttachObserver(chart, type, listener) {
3381
+ const canvas = chart.canvas;
3382
+ const observer = new MutationObserver(entries => {
3383
+ let trigger = false;
3384
+ for (const entry of entries) {
3385
+ trigger = trigger || nodeListContains(entry.addedNodes, canvas);
3386
+ trigger = trigger && !nodeListContains(entry.removedNodes, canvas);
3387
+ }
3388
+ if (trigger) {
3389
+ listener();
3390
+ }
3391
+ });
3392
+ observer.observe(document, {childList: true, subtree: true});
3393
+ return observer;
3394
+ }
3395
+ function createDetachObserver(chart, type, listener) {
3396
+ const canvas = chart.canvas;
3397
+ const observer = new MutationObserver(entries => {
3398
+ let trigger = false;
3399
+ for (const entry of entries) {
3400
+ trigger = trigger || nodeListContains(entry.removedNodes, canvas);
3401
+ trigger = trigger && !nodeListContains(entry.addedNodes, canvas);
3402
+ }
3403
+ if (trigger) {
3404
+ listener();
3405
+ }
3406
+ });
3407
+ observer.observe(document, {childList: true, subtree: true});
3408
+ return observer;
3409
+ }
3410
+ const drpListeningCharts = new Map();
3411
+ let oldDevicePixelRatio = 0;
3412
+ function onWindowResize() {
3413
+ const dpr = window.devicePixelRatio;
3414
+ if (dpr === oldDevicePixelRatio) {
3415
+ return;
3416
+ }
3417
+ oldDevicePixelRatio = dpr;
3418
+ drpListeningCharts.forEach((resize, chart) => {
3419
+ if (chart.currentDevicePixelRatio !== dpr) {
3420
+ resize();
3421
+ }
3422
+ });
3423
+ }
3424
+ function listenDevicePixelRatioChanges(chart, resize) {
3425
+ if (!drpListeningCharts.size) {
3426
+ window.addEventListener('resize', onWindowResize);
3427
+ }
3428
+ drpListeningCharts.set(chart, resize);
3429
+ }
3430
+ function unlistenDevicePixelRatioChanges(chart) {
3431
+ drpListeningCharts.delete(chart);
3432
+ if (!drpListeningCharts.size) {
3433
+ window.removeEventListener('resize', onWindowResize);
3434
+ }
3435
+ }
3436
+ function createResizeObserver(chart, type, listener) {
3437
+ const canvas = chart.canvas;
3438
+ const container = canvas && _getParentNode(canvas);
3439
+ if (!container) {
3440
+ return;
3441
+ }
3442
+ const resize = throttled((width, height) => {
3443
+ const w = container.clientWidth;
3444
+ listener(width, height);
3445
+ if (w < container.clientWidth) {
3446
+ listener();
3447
+ }
3448
+ }, window);
3449
+ const observer = new ResizeObserver(entries => {
3450
+ const entry = entries[0];
3451
+ const width = entry.contentRect.width;
3452
+ const height = entry.contentRect.height;
3453
+ if (width === 0 && height === 0) {
3454
+ return;
3455
+ }
3456
+ resize(width, height);
3457
+ });
3458
+ observer.observe(container);
3459
+ listenDevicePixelRatioChanges(chart, resize);
3460
+ return observer;
3461
+ }
3462
+ function releaseObserver(chart, type, observer) {
3463
+ if (observer) {
3464
+ observer.disconnect();
3465
+ }
3466
+ if (type === 'resize') {
3467
+ unlistenDevicePixelRatioChanges(chart);
3468
+ }
3469
+ }
3470
+ function createProxyAndListen(chart, type, listener) {
3471
+ const canvas = chart.canvas;
3472
+ const proxy = throttled((event) => {
3473
+ if (chart.ctx !== null) {
3474
+ listener(fromNativeEvent(event, chart));
3475
+ }
3476
+ }, chart, (args) => {
3477
+ const event = args[0];
3478
+ return [event, event.offsetX, event.offsetY];
3479
+ });
3480
+ addListener(canvas, type, proxy);
3481
+ return proxy;
3482
+ }
3483
+ class DomPlatform extends BasePlatform {
3484
+ acquireContext(canvas, aspectRatio) {
3485
+ const context = canvas && canvas.getContext && canvas.getContext('2d');
3486
+ if (context && context.canvas === canvas) {
3487
+ initCanvas(canvas, aspectRatio);
3488
+ return context;
3489
+ }
3490
+ return null;
3491
+ }
3492
+ releaseContext(context) {
3493
+ const canvas = context.canvas;
3494
+ if (!canvas[EXPANDO_KEY]) {
3495
+ return false;
3496
+ }
3497
+ const initial = canvas[EXPANDO_KEY].initial;
3498
+ ['height', 'width'].forEach((prop) => {
3499
+ const value = initial[prop];
3500
+ if (isNullOrUndef(value)) {
3501
+ canvas.removeAttribute(prop);
3502
+ } else {
3503
+ canvas.setAttribute(prop, value);
3504
+ }
3505
+ });
3506
+ const style = initial.style || {};
3507
+ Object.keys(style).forEach((key) => {
3508
+ canvas.style[key] = style[key];
3509
+ });
3510
+ canvas.width = canvas.width;
3511
+ delete canvas[EXPANDO_KEY];
3512
+ return true;
3513
+ }
3514
+ addEventListener(chart, type, listener) {
3515
+ this.removeEventListener(chart, type);
3516
+ const proxies = chart.$proxies || (chart.$proxies = {});
3517
+ const handlers = {
3518
+ attach: createAttachObserver,
3519
+ detach: createDetachObserver,
3520
+ resize: createResizeObserver
3521
+ };
3522
+ const handler = handlers[type] || createProxyAndListen;
3523
+ proxies[type] = handler(chart, type, listener);
3524
+ }
3525
+ removeEventListener(chart, type) {
3526
+ const proxies = chart.$proxies || (chart.$proxies = {});
3527
+ const proxy = proxies[type];
3528
+ if (!proxy) {
3529
+ return;
3530
+ }
3531
+ const handlers = {
3532
+ attach: releaseObserver,
3533
+ detach: releaseObserver,
3534
+ resize: releaseObserver
3535
+ };
3536
+ const handler = handlers[type] || removeListener;
3537
+ handler(chart, type, proxy);
3538
+ proxies[type] = undefined;
3539
+ }
3540
+ getDevicePixelRatio() {
3541
+ return window.devicePixelRatio;
3542
+ }
3543
+ getMaximumSize(canvas, width, height, aspectRatio) {
3544
+ return getMaximumSize(canvas, width, height, aspectRatio);
3545
+ }
3546
+ isAttached(canvas) {
3547
+ const container = _getParentNode(canvas);
3548
+ return !!(container && container.isConnected);
3549
+ }
3550
+ }
3551
+
3552
+ function _detectPlatform(canvas) {
3553
+ if (!_isDomSupported() || (typeof OffscreenCanvas !== 'undefined' && canvas instanceof OffscreenCanvas)) {
3554
+ return BasicPlatform;
3555
+ }
3556
+ return DomPlatform;
3557
+ }
3558
+
3559
+ var platforms = /*#__PURE__*/Object.freeze({
3560
+ __proto__: null,
3561
+ _detectPlatform: _detectPlatform,
3562
+ BasePlatform: BasePlatform,
3563
+ BasicPlatform: BasicPlatform,
3564
+ DomPlatform: DomPlatform
3565
+ });
3566
+
3567
+ const transparent = 'transparent';
3568
+ const interpolators = {
3569
+ boolean(from, to, factor) {
3570
+ return factor > 0.5 ? to : from;
3571
+ },
3572
+ color(from, to, factor) {
3573
+ const c0 = color(from || transparent);
3574
+ const c1 = c0.valid && color(to || transparent);
3575
+ return c1 && c1.valid
3576
+ ? c1.mix(c0, factor).hexString()
3577
+ : to;
3578
+ },
3579
+ number(from, to, factor) {
3580
+ return from + (to - from) * factor;
3581
+ }
3582
+ };
3583
+ class Animation {
3584
+ constructor(cfg, target, prop, to) {
3585
+ const currentValue = target[prop];
3586
+ to = resolve([cfg.to, to, currentValue, cfg.from]);
3587
+ const from = resolve([cfg.from, currentValue, to]);
3588
+ this._active = true;
3589
+ this._fn = cfg.fn || interpolators[cfg.type || typeof from];
3590
+ this._easing = effects[cfg.easing] || effects.linear;
3591
+ this._start = Math.floor(Date.now() + (cfg.delay || 0));
3592
+ this._duration = this._total = Math.floor(cfg.duration);
3593
+ this._loop = !!cfg.loop;
3594
+ this._target = target;
3595
+ this._prop = prop;
3596
+ this._from = from;
3597
+ this._to = to;
3598
+ this._promises = undefined;
3599
+ }
3600
+ active() {
3601
+ return this._active;
3602
+ }
3603
+ update(cfg, to, date) {
3604
+ if (this._active) {
3605
+ this._notify(false);
3606
+ const currentValue = this._target[this._prop];
3607
+ const elapsed = date - this._start;
3608
+ const remain = this._duration - elapsed;
3609
+ this._start = date;
3610
+ this._duration = Math.floor(Math.max(remain, cfg.duration));
3611
+ this._total += elapsed;
3612
+ this._loop = !!cfg.loop;
3613
+ this._to = resolve([cfg.to, to, currentValue, cfg.from]);
3614
+ this._from = resolve([cfg.from, currentValue, to]);
3615
+ }
3616
+ }
3617
+ cancel() {
3618
+ if (this._active) {
3619
+ this.tick(Date.now());
3620
+ this._active = false;
3621
+ this._notify(false);
3622
+ }
3623
+ }
3624
+ tick(date) {
3625
+ const elapsed = date - this._start;
3626
+ const duration = this._duration;
3627
+ const prop = this._prop;
3628
+ const from = this._from;
3629
+ const loop = this._loop;
3630
+ const to = this._to;
3631
+ let factor;
3632
+ this._active = from !== to && (loop || (elapsed < duration));
3633
+ if (!this._active) {
3634
+ this._target[prop] = to;
3635
+ this._notify(true);
3636
+ return;
3637
+ }
3638
+ if (elapsed < 0) {
3639
+ this._target[prop] = from;
3640
+ return;
3641
+ }
3642
+ factor = (elapsed / duration) % 2;
3643
+ factor = loop && factor > 1 ? 2 - factor : factor;
3644
+ factor = this._easing(Math.min(1, Math.max(0, factor)));
3645
+ this._target[prop] = this._fn(from, to, factor);
3646
+ }
3647
+ wait() {
3648
+ const promises = this._promises || (this._promises = []);
3649
+ return new Promise((res, rej) => {
3650
+ promises.push({res, rej});
3651
+ });
3652
+ }
3653
+ _notify(resolved) {
3654
+ const method = resolved ? 'res' : 'rej';
3655
+ const promises = this._promises || [];
3656
+ for (let i = 0; i < promises.length; i++) {
3657
+ promises[i][method]();
3658
+ }
3659
+ }
3660
+ }
3661
+
3662
+ const numbers = ['x', 'y', 'borderWidth', 'radius', 'tension'];
3663
+ const colors = ['color', 'borderColor', 'backgroundColor'];
3664
+ defaults.set('animation', {
3665
+ delay: undefined,
3666
+ duration: 1000,
3667
+ easing: 'easeOutQuart',
3668
+ fn: undefined,
3669
+ from: undefined,
3670
+ loop: undefined,
3671
+ to: undefined,
3672
+ type: undefined,
3673
+ });
3674
+ const animationOptions = Object.keys(defaults.animation);
3675
+ defaults.describe('animation', {
3676
+ _fallback: false,
3677
+ _indexable: false,
3678
+ _scriptable: (name) => name !== 'onProgress' && name !== 'onComplete' && name !== 'fn',
3679
+ });
3680
+ defaults.set('animations', {
3681
+ colors: {
3682
+ type: 'color',
3683
+ properties: colors
3684
+ },
3685
+ numbers: {
3686
+ type: 'number',
3687
+ properties: numbers
3688
+ },
3689
+ });
3690
+ defaults.describe('animations', {
3691
+ _fallback: 'animation',
3692
+ });
3693
+ defaults.set('transitions', {
3694
+ active: {
3695
+ animation: {
3696
+ duration: 400
3697
+ }
3698
+ },
3699
+ resize: {
3700
+ animation: {
3701
+ duration: 0
3702
+ }
3703
+ },
3704
+ show: {
3705
+ animations: {
3706
+ colors: {
3707
+ from: 'transparent'
3708
+ },
3709
+ visible: {
3710
+ type: 'boolean',
3711
+ duration: 0
3712
+ },
3713
+ }
3714
+ },
3715
+ hide: {
3716
+ animations: {
3717
+ colors: {
3718
+ to: 'transparent'
3719
+ },
3720
+ visible: {
3721
+ type: 'boolean',
3722
+ easing: 'linear',
3723
+ fn: v => v | 0
3724
+ },
3725
+ }
3726
+ }
3727
+ });
3728
+ class Animations {
3729
+ constructor(chart, config) {
3730
+ this._chart = chart;
3731
+ this._properties = new Map();
3732
+ this.configure(config);
3733
+ }
3734
+ configure(config) {
3735
+ if (!isObject(config)) {
3736
+ return;
3737
+ }
3738
+ const animatedProps = this._properties;
3739
+ Object.getOwnPropertyNames(config).forEach(key => {
3740
+ const cfg = config[key];
3741
+ if (!isObject(cfg)) {
3742
+ return;
3743
+ }
3744
+ const resolved = {};
3745
+ for (const option of animationOptions) {
3746
+ resolved[option] = cfg[option];
3747
+ }
3748
+ (isArray(cfg.properties) && cfg.properties || [key]).forEach((prop) => {
3749
+ if (prop === key || !animatedProps.has(prop)) {
3750
+ animatedProps.set(prop, resolved);
3751
  }
3752
+ });
3753
+ });
3754
+ }
3755
+ _animateOptions(target, values) {
3756
+ const newOptions = values.options;
3757
+ const options = resolveTargetOptions(target, newOptions);
3758
+ if (!options) {
3759
+ return [];
3760
+ }
3761
+ const animations = this._createAnimations(options, newOptions);
3762
+ if (newOptions.$shared) {
3763
+ awaitAll(target.options.$animations, newOptions).then(() => {
3764
+ target.options = newOptions;
3765
+ }, () => {
3766
+ });
3767
+ }
3768
+ return animations;
3769
+ }
3770
+ _createAnimations(target, values) {
3771
+ const animatedProps = this._properties;
3772
+ const animations = [];
3773
+ const running = target.$animations || (target.$animations = {});
3774
+ const props = Object.keys(values);
3775
+ const date = Date.now();
3776
+ let i;
3777
+ for (i = props.length - 1; i >= 0; --i) {
3778
+ const prop = props[i];
3779
+ if (prop.charAt(0) === '$') {
3780
+ continue;
3781
+ }
3782
+ if (prop === 'options') {
3783
+ animations.push(...this._animateOptions(target, values));
3784
+ continue;
3785
+ }
3786
+ const value = values[prop];
3787
+ let animation = running[prop];
3788
+ const cfg = animatedProps.get(prop);
3789
+ if (animation) {
3790
+ if (cfg && animation.active()) {
3791
+ animation.update(cfg, value, date);
3792
+ continue;
3793
+ } else {
3794
+ animation.cancel();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3795
  }
3796
+ }
3797
+ if (!cfg || !cfg.duration) {
3798
+ target[prop] = value;
3799
+ continue;
3800
+ }
3801
+ running[prop] = animation = new Animation(cfg, target, prop, value);
3802
+ animations.push(animation);
3803
+ }
3804
+ return animations;
3805
+ }
3806
+ update(target, values) {
3807
+ if (this._properties.size === 0) {
3808
+ Object.assign(target, values);
3809
+ return;
3810
+ }
3811
+ const animations = this._createAnimations(target, values);
3812
+ if (animations.length) {
3813
+ animator.add(this._chart, animations);
3814
+ return true;
3815
+ }
3816
+ }
3817
+ }
3818
+ function awaitAll(animations, properties) {
3819
+ const running = [];
3820
+ const keys = Object.keys(properties);
3821
+ for (let i = 0; i < keys.length; i++) {
3822
+ const anim = animations[keys[i]];
3823
+ if (anim && anim.active()) {
3824
+ running.push(anim.wait());
3825
+ }
3826
+ }
3827
+ return Promise.all(running);
3828
+ }
3829
+ function resolveTargetOptions(target, newOptions) {
3830
+ if (!newOptions) {
3831
+ return;
3832
+ }
3833
+ let options = target.options;
3834
+ if (!options) {
3835
+ target.options = newOptions;
3836
+ return;
3837
+ }
3838
+ if (options.$shared) {
3839
+ target.options = options = Object.assign({}, options, {$shared: false, $animations: {}});
3840
+ }
3841
+ return options;
3842
+ }
3843
+
3844
+ function scaleClip(scale, allowedOverflow) {
3845
+ const opts = scale && scale.options || {};
3846
+ const reverse = opts.reverse;
3847
+ const min = opts.min === undefined ? allowedOverflow : 0;
3848
+ const max = opts.max === undefined ? allowedOverflow : 0;
3849
+ return {
3850
+ start: reverse ? max : min,
3851
+ end: reverse ? min : max
3852
+ };
3853
+ }
3854
+ function defaultClip(xScale, yScale, allowedOverflow) {
3855
+ if (allowedOverflow === false) {
3856
+ return false;
3857
+ }
3858
+ const x = scaleClip(xScale, allowedOverflow);
3859
+ const y = scaleClip(yScale, allowedOverflow);
3860
+ return {
3861
+ top: y.end,
3862
+ right: x.end,
3863
+ bottom: y.start,
3864
+ left: x.start
3865
+ };
3866
+ }
3867
+ function toClip(value) {
3868
+ let t, r, b, l;
3869
+ if (isObject(value)) {
3870
+ t = value.top;
3871
+ r = value.right;
3872
+ b = value.bottom;
3873
+ l = value.left;
3874
+ } else {
3875
+ t = r = b = l = value;
3876
+ }
3877
+ return {
3878
+ top: t,
3879
+ right: r,
3880
+ bottom: b,
3881
+ left: l,
3882
+ disabled: value === false
3883
+ };
3884
+ }
3885
+ function getSortedDatasetIndices(chart, filterVisible) {
3886
+ const keys = [];
3887
+ const metasets = chart._getSortedDatasetMetas(filterVisible);
3888
+ let i, ilen;
3889
+ for (i = 0, ilen = metasets.length; i < ilen; ++i) {
3890
+ keys.push(metasets[i].index);
3891
+ }
3892
+ return keys;
3893
+ }
3894
+ function applyStack(stack, value, dsIndex, options = {}) {
3895
+ const keys = stack.keys;
3896
+ const singleMode = options.mode === 'single';
3897
+ let i, ilen, datasetIndex, otherValue;
3898
+ if (value === null) {
3899
+ return;
3900
+ }
3901
+ for (i = 0, ilen = keys.length; i < ilen; ++i) {
3902
+ datasetIndex = +keys[i];
3903
+ if (datasetIndex === dsIndex) {
3904
+ if (options.all) {
3905
+ continue;
3906
+ }
3907
+ break;
3908
+ }
3909
+ otherValue = stack.values[datasetIndex];
3910
+ if (isNumberFinite(otherValue) && (singleMode || (value === 0 || sign(value) === sign(otherValue)))) {
3911
+ value += otherValue;
3912
+ }
3913
+ }
3914
+ return value;
3915
+ }
3916
+ function convertObjectDataToArray(data) {
3917
+ const keys = Object.keys(data);
3918
+ const adata = new Array(keys.length);
3919
+ let i, ilen, key;
3920
+ for (i = 0, ilen = keys.length; i < ilen; ++i) {
3921
+ key = keys[i];
3922
+ adata[i] = {
3923
+ x: key,
3924
+ y: data[key]
3925
+ };
3926
+ }
3927
+ return adata;
3928
+ }
3929
+ function isStacked(scale, meta) {
3930
+ const stacked = scale && scale.options.stacked;
3931
+ return stacked || (stacked === undefined && meta.stack !== undefined);
3932
+ }
3933
+ function getStackKey(indexScale, valueScale, meta) {
3934
+ return `${indexScale.id}.${valueScale.id}.${meta.stack || meta.type}`;
3935
+ }
3936
+ function getUserBounds(scale) {
3937
+ const {min, max, minDefined, maxDefined} = scale.getUserBounds();
3938
+ return {
3939
+ min: minDefined ? min : Number.NEGATIVE_INFINITY,
3940
+ max: maxDefined ? max : Number.POSITIVE_INFINITY
3941
+ };
3942
+ }
3943
+ function getOrCreateStack(stacks, stackKey, indexValue) {
3944
+ const subStack = stacks[stackKey] || (stacks[stackKey] = {});
3945
+ return subStack[indexValue] || (subStack[indexValue] = {});
3946
+ }
3947
+ function getLastIndexInStack(stack, vScale, positive, type) {
3948
+ for (const meta of vScale.getMatchingVisibleMetas(type).reverse()) {
3949
+ const value = stack[meta.index];
3950
+ if ((positive && value > 0) || (!positive && value < 0)) {
3951
+ return meta.index;
3952
+ }
3953
+ }
3954
+ return null;
3955
+ }
3956
+ function updateStacks(controller, parsed) {
3957
+ const {chart, _cachedMeta: meta} = controller;
3958
+ const stacks = chart._stacks || (chart._stacks = {});
3959
+ const {iScale, vScale, index: datasetIndex} = meta;
3960
+ const iAxis = iScale.axis;
3961
+ const vAxis = vScale.axis;
3962
+ const key = getStackKey(iScale, vScale, meta);
3963
+ const ilen = parsed.length;
3964
+ let stack;
3965
+ for (let i = 0; i < ilen; ++i) {
3966
+ const item = parsed[i];
3967
+ const {[iAxis]: index, [vAxis]: value} = item;
3968
+ const itemStacks = item._stacks || (item._stacks = {});
3969
+ stack = itemStacks[vAxis] = getOrCreateStack(stacks, key, index);
3970
+ stack[datasetIndex] = value;
3971
+ stack._top = getLastIndexInStack(stack, vScale, true, meta.type);
3972
+ stack._bottom = getLastIndexInStack(stack, vScale, false, meta.type);
3973
+ }
3974
+ }
3975
+ function getFirstScaleId(chart, axis) {
3976
+ const scales = chart.scales;
3977
+ return Object.keys(scales).filter(key => scales[key].axis === axis).shift();
3978
+ }
3979
+ function createDatasetContext(parent, index) {
3980
+ return createContext(parent,
3981
+ {
3982
+ active: false,
3983
+ dataset: undefined,
3984
+ datasetIndex: index,
3985
+ index,
3986
+ mode: 'default',
3987
+ type: 'dataset'
3988
+ }
3989
+ );
3990
+ }
3991
+ function createDataContext(parent, index, element) {
3992
+ return createContext(parent, {
3993
+ active: false,
3994
+ dataIndex: index,
3995
+ parsed: undefined,
3996
+ raw: undefined,
3997
+ element,
3998
+ index,
3999
+ mode: 'default',
4000
+ type: 'data'
4001
+ });
4002
+ }
4003
+ function clearStacks(meta, items) {
4004
+ const datasetIndex = meta.controller.index;
4005
+ const axis = meta.vScale && meta.vScale.axis;
4006
+ if (!axis) {
4007
+ return;
4008
+ }
4009
+ items = items || meta._parsed;
4010
+ for (const parsed of items) {
4011
+ const stacks = parsed._stacks;
4012
+ if (!stacks || stacks[axis] === undefined || stacks[axis][datasetIndex] === undefined) {
4013
+ return;
4014
+ }
4015
+ delete stacks[axis][datasetIndex];
4016
+ }
4017
+ }
4018
+ const isDirectUpdateMode = (mode) => mode === 'reset' || mode === 'none';
4019
+ const cloneIfNotShared = (cached, shared) => shared ? cached : Object.assign({}, cached);
4020
+ const createStack = (canStack, meta, chart) => canStack && !meta.hidden && meta._stacked
4021
+ && {keys: getSortedDatasetIndices(chart, true), values: null};
4022
+ class DatasetController {
4023
+ constructor(chart, datasetIndex) {
4024
+ this.chart = chart;
4025
+ this._ctx = chart.ctx;
4026
+ this.index = datasetIndex;
4027
+ this._cachedDataOpts = {};
4028
+ this._cachedMeta = this.getMeta();
4029
+ this._type = this._cachedMeta.type;
4030
+ this.options = undefined;
4031
+ this._parsing = false;
4032
+ this._data = undefined;
4033
+ this._objectData = undefined;
4034
+ this._sharedOptions = undefined;
4035
+ this._drawStart = undefined;
4036
+ this._drawCount = undefined;
4037
+ this.enableOptionSharing = false;
4038
+ this.$context = undefined;
4039
+ this._syncList = [];
4040
+ this.initialize();
4041
+ }
4042
+ initialize() {
4043
+ const meta = this._cachedMeta;
4044
+ this.configure();
4045
+ this.linkScales();
4046
+ meta._stacked = isStacked(meta.vScale, meta);
4047
+ this.addElements();
4048
+ }
4049
+ updateIndex(datasetIndex) {
4050
+ if (this.index !== datasetIndex) {
4051
+ clearStacks(this._cachedMeta);
4052
+ }
4053
+ this.index = datasetIndex;
4054
+ }
4055
+ linkScales() {
4056
+ const chart = this.chart;
4057
+ const meta = this._cachedMeta;
4058
+ const dataset = this.getDataset();
4059
+ const chooseId = (axis, x, y, r) => axis === 'x' ? x : axis === 'r' ? r : y;
4060
+ const xid = meta.xAxisID = valueOrDefault(dataset.xAxisID, getFirstScaleId(chart, 'x'));
4061
+ const yid = meta.yAxisID = valueOrDefault(dataset.yAxisID, getFirstScaleId(chart, 'y'));
4062
+ const rid = meta.rAxisID = valueOrDefault(dataset.rAxisID, getFirstScaleId(chart, 'r'));
4063
+ const indexAxis = meta.indexAxis;
4064
+ const iid = meta.iAxisID = chooseId(indexAxis, xid, yid, rid);
4065
+ const vid = meta.vAxisID = chooseId(indexAxis, yid, xid, rid);
4066
+ meta.xScale = this.getScaleForId(xid);
4067
+ meta.yScale = this.getScaleForId(yid);
4068
+ meta.rScale = this.getScaleForId(rid);
4069
+ meta.iScale = this.getScaleForId(iid);
4070
+ meta.vScale = this.getScaleForId(vid);
4071
+ }
4072
+ getDataset() {
4073
+ return this.chart.data.datasets[this.index];
4074
+ }
4075
+ getMeta() {
4076
+ return this.chart.getDatasetMeta(this.index);
4077
+ }
4078
+ getScaleForId(scaleID) {
4079
+ return this.chart.scales[scaleID];
4080
+ }
4081
+ _getOtherScale(scale) {
4082
+ const meta = this._cachedMeta;
4083
+ return scale === meta.iScale
4084
+ ? meta.vScale
4085
+ : meta.iScale;
4086
+ }
4087
+ reset() {
4088
+ this._update('reset');
4089
+ }
4090
+ _destroy() {
4091
+ const meta = this._cachedMeta;
4092
+ if (this._data) {
4093
+ unlistenArrayEvents(this._data, this);
4094
+ }
4095
+ if (meta._stacked) {
4096
+ clearStacks(meta);
4097
+ }
4098
+ }
4099
+ _dataCheck() {
4100
+ const dataset = this.getDataset();
4101
+ const data = dataset.data || (dataset.data = []);
4102
+ const _data = this._data;
4103
+ if (isObject(data)) {
4104
+ this._data = convertObjectDataToArray(data);
4105
+ } else if (_data !== data) {
4106
+ if (_data) {
4107
+ unlistenArrayEvents(_data, this);
4108
+ const meta = this._cachedMeta;
4109
+ clearStacks(meta);
4110
+ meta._parsed = [];
4111
+ }
4112
+ if (data && Object.isExtensible(data)) {
4113
+ listenArrayEvents(data, this);
4114
+ }
4115
+ this._syncList = [];
4116
+ this._data = data;
4117
+ }
4118
+ }
4119
+ addElements() {
4120
+ const meta = this._cachedMeta;
4121
+ this._dataCheck();
4122
+ if (this.datasetElementType) {
4123
+ meta.dataset = new this.datasetElementType();
4124
+ }
4125
+ }
4126
+ buildOrUpdateElements(resetNewElements) {
4127
+ const meta = this._cachedMeta;
4128
+ const dataset = this.getDataset();
4129
+ let stackChanged = false;
4130
+ this._dataCheck();
4131
+ const oldStacked = meta._stacked;
4132
+ meta._stacked = isStacked(meta.vScale, meta);
4133
+ if (meta.stack !== dataset.stack) {
4134
+ stackChanged = true;
4135
+ clearStacks(meta);
4136
+ meta.stack = dataset.stack;
4137
+ }
4138
+ this._resyncElements(resetNewElements);
4139
+ if (stackChanged || oldStacked !== meta._stacked) {
4140
+ updateStacks(this, meta._parsed);
4141
+ }
4142
+ }
4143
+ configure() {
4144
+ const config = this.chart.config;
4145
+ const scopeKeys = config.datasetScopeKeys(this._type);
4146
+ const scopes = config.getOptionScopes(this.getDataset(), scopeKeys, true);
4147
+ this.options = config.createResolver(scopes, this.getContext());
4148
+ this._parsing = this.options.parsing;
4149
+ this._cachedDataOpts = {};
4150
+ }
4151
+ parse(start, count) {
4152
+ const {_cachedMeta: meta, _data: data} = this;
4153
+ const {iScale, _stacked} = meta;
4154
+ const iAxis = iScale.axis;
4155
+ let sorted = start === 0 && count === data.length ? true : meta._sorted;
4156
+ let prev = start > 0 && meta._parsed[start - 1];
4157
+ let i, cur, parsed;
4158
+ if (this._parsing === false) {
4159
+ meta._parsed = data;
4160
+ meta._sorted = true;
4161
+ parsed = data;
4162
+ } else {
4163
+ if (isArray(data[start])) {
4164
+ parsed = this.parseArrayData(meta, data, start, count);
4165
+ } else if (isObject(data[start])) {
4166
+ parsed = this.parseObjectData(meta, data, start, count);
4167
+ } else {
4168
+ parsed = this.parsePrimitiveData(meta, data, start, count);
4169
+ }
4170
+ const isNotInOrderComparedToPrev = () => cur[iAxis] === null || (prev && cur[iAxis] < prev[iAxis]);
4171
+ for (i = 0; i < count; ++i) {
4172
+ meta._parsed[i + start] = cur = parsed[i];
4173
+ if (sorted) {
4174
+ if (isNotInOrderComparedToPrev()) {
4175
+ sorted = false;
4176
+ }
4177
+ prev = cur;
4178
  }
4179
+ }
4180
+ meta._sorted = sorted;
4181
+ }
4182
+ if (_stacked) {
4183
+ updateStacks(this, parsed);
4184
+ }
4185
+ }
4186
+ parsePrimitiveData(meta, data, start, count) {
4187
+ const {iScale, vScale} = meta;
4188
+ const iAxis = iScale.axis;
4189
+ const vAxis = vScale.axis;
4190
+ const labels = iScale.getLabels();
4191
+ const singleScale = iScale === vScale;
4192
+ const parsed = new Array(count);
4193
+ let i, ilen, index;
4194
+ for (i = 0, ilen = count; i < ilen; ++i) {
4195
+ index = i + start;
4196
+ parsed[i] = {
4197
+ [iAxis]: singleScale || iScale.parse(labels[index], index),
4198
+ [vAxis]: vScale.parse(data[index], index)
4199
+ };
4200
+ }
4201
+ return parsed;
4202
+ }
4203
+ parseArrayData(meta, data, start, count) {
4204
+ const {xScale, yScale} = meta;
4205
+ const parsed = new Array(count);
4206
+ let i, ilen, index, item;
4207
+ for (i = 0, ilen = count; i < ilen; ++i) {
4208
+ index = i + start;
4209
+ item = data[index];
4210
+ parsed[i] = {
4211
+ x: xScale.parse(item[0], index),
4212
+ y: yScale.parse(item[1], index)
4213
+ };
4214
+ }
4215
+ return parsed;
4216
+ }
4217
+ parseObjectData(meta, data, start, count) {
4218
+ const {xScale, yScale} = meta;
4219
+ const {xAxisKey = 'x', yAxisKey = 'y'} = this._parsing;
4220
+ const parsed = new Array(count);
4221
+ let i, ilen, index, item;
4222
+ for (i = 0, ilen = count; i < ilen; ++i) {
4223
+ index = i + start;
4224
+ item = data[index];
4225
+ parsed[i] = {
4226
+ x: xScale.parse(resolveObjectKey(item, xAxisKey), index),
4227
+ y: yScale.parse(resolveObjectKey(item, yAxisKey), index)
4228
+ };
4229
+ }
4230
+ return parsed;
4231
+ }
4232
+ getParsed(index) {
4233
+ return this._cachedMeta._parsed[index];
4234
+ }
4235
+ getDataElement(index) {
4236
+ return this._cachedMeta.data[index];
4237
+ }
4238
+ applyStack(scale, parsed, mode) {
4239
+ const chart = this.chart;
4240
+ const meta = this._cachedMeta;
4241
+ const value = parsed[scale.axis];
4242
+ const stack = {
4243
+ keys: getSortedDatasetIndices(chart, true),
4244
+ values: parsed._stacks[scale.axis]
4245
+ };
4246
+ return applyStack(stack, value, meta.index, {mode});
4247
+ }
4248
+ updateRangeFromParsed(range, scale, parsed, stack) {
4249
+ const parsedValue = parsed[scale.axis];
4250
+ let value = parsedValue === null ? NaN : parsedValue;
4251
+ const values = stack && parsed._stacks[scale.axis];
4252
+ if (stack && values) {
4253
+ stack.values = values;
4254
+ value = applyStack(stack, parsedValue, this._cachedMeta.index);
4255
+ }
4256
+ range.min = Math.min(range.min, value);
4257
+ range.max = Math.max(range.max, value);
4258
+ }
4259
+ getMinMax(scale, canStack) {
4260
+ const meta = this._cachedMeta;
4261
+ const _parsed = meta._parsed;
4262
+ const sorted = meta._sorted && scale === meta.iScale;
4263
+ const ilen = _parsed.length;
4264
+ const otherScale = this._getOtherScale(scale);
4265
+ const stack = createStack(canStack, meta, this.chart);
4266
+ const range = {min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY};
4267
+ const {min: otherMin, max: otherMax} = getUserBounds(otherScale);
4268
+ let i, parsed;
4269
+ function _skip() {
4270
+ parsed = _parsed[i];
4271
+ const otherValue = parsed[otherScale.axis];
4272
+ return !isNumberFinite(parsed[scale.axis]) || otherMin > otherValue || otherMax < otherValue;
4273
+ }
4274
+ for (i = 0; i < ilen; ++i) {
4275
+ if (_skip()) {
4276
+ continue;
4277
+ }
4278
+ this.updateRangeFromParsed(range, scale, parsed, stack);
4279
+ if (sorted) {
4280
+ break;
4281
+ }
4282
+ }
4283
+ if (sorted) {
4284
+ for (i = ilen - 1; i >= 0; --i) {
4285
+ if (_skip()) {
4286
+ continue;
4287
  }
4288
+ this.updateRangeFromParsed(range, scale, parsed, stack);
4289
+ break;
4290
+ }
4291
+ }
4292
+ return range;
4293
+ }
4294
+ getAllParsedValues(scale) {
4295
+ const parsed = this._cachedMeta._parsed;
4296
+ const values = [];
4297
+ let i, ilen, value;
4298
+ for (i = 0, ilen = parsed.length; i < ilen; ++i) {
4299
+ value = parsed[i][scale.axis];
4300
+ if (isNumberFinite(value)) {
4301
+ values.push(value);
4302
+ }
4303
+ }
4304
+ return values;
4305
+ }
4306
+ getMaxOverflow() {
4307
+ return false;
4308
+ }
4309
+ getLabelAndValue(index) {
4310
+ const meta = this._cachedMeta;
4311
+ const iScale = meta.iScale;
4312
+ const vScale = meta.vScale;
4313
+ const parsed = this.getParsed(index);
4314
+ return {
4315
+ label: iScale ? '' + iScale.getLabelForValue(parsed[iScale.axis]) : '',
4316
+ value: vScale ? '' + vScale.getLabelForValue(parsed[vScale.axis]) : ''
4317
+ };
4318
+ }
4319
+ _update(mode) {
4320
+ const meta = this._cachedMeta;
4321
+ this.update(mode || 'default');
4322
+ meta._clip = toClip(valueOrDefault(this.options.clip, defaultClip(meta.xScale, meta.yScale, this.getMaxOverflow())));
4323
+ }
4324
+ update(mode) {}
4325
+ draw() {
4326
+ const ctx = this._ctx;
4327
+ const chart = this.chart;
4328
+ const meta = this._cachedMeta;
4329
+ const elements = meta.data || [];
4330
+ const area = chart.chartArea;
4331
+ const active = [];
4332
+ const start = this._drawStart || 0;
4333
+ const count = this._drawCount || (elements.length - start);
4334
+ const drawActiveElementsOnTop = this.options.drawActiveElementsOnTop;
4335
+ let i;
4336
+ if (meta.dataset) {
4337
+ meta.dataset.draw(ctx, area, start, count);
4338
+ }
4339
+ for (i = start; i < start + count; ++i) {
4340
+ const element = elements[i];
4341
+ if (element.hidden) {
4342
+ continue;
4343
+ }
4344
+ if (element.active && drawActiveElementsOnTop) {
4345
+ active.push(element);
4346
+ } else {
4347
+ element.draw(ctx, area);
4348
+ }
4349
+ }
4350
+ for (i = 0; i < active.length; ++i) {
4351
+ active[i].draw(ctx, area);
4352
+ }
4353
+ }
4354
+ getStyle(index, active) {
4355
+ const mode = active ? 'active' : 'default';
4356
+ return index === undefined && this._cachedMeta.dataset
4357
+ ? this.resolveDatasetElementOptions(mode)
4358
+ : this.resolveDataElementOptions(index || 0, mode);
4359
+ }
4360
+ getContext(index, active, mode) {
4361
+ const dataset = this.getDataset();
4362
+ let context;
4363
+ if (index >= 0 && index < this._cachedMeta.data.length) {
4364
+ const element = this._cachedMeta.data[index];
4365
+ context = element.$context ||
4366
+ (element.$context = createDataContext(this.getContext(), index, element));
4367
+ context.parsed = this.getParsed(index);
4368
+ context.raw = dataset.data[index];
4369
+ context.index = context.dataIndex = index;
4370
+ } else {
4371
+ context = this.$context ||
4372
+ (this.$context = createDatasetContext(this.chart.getContext(), this.index));
4373
+ context.dataset = dataset;
4374
+ context.index = context.datasetIndex = this.index;
4375
+ }
4376
+ context.active = !!active;
4377
+ context.mode = mode;
4378
+ return context;
4379
+ }
4380
+ resolveDatasetElementOptions(mode) {
4381
+ return this._resolveElementOptions(this.datasetElementType.id, mode);
4382
+ }
4383
+ resolveDataElementOptions(index, mode) {
4384
+ return this._resolveElementOptions(this.dataElementType.id, mode, index);
4385
+ }
4386
+ _resolveElementOptions(elementType, mode = 'default', index) {
4387
+ const active = mode === 'active';
4388
+ const cache = this._cachedDataOpts;
4389
+ const cacheKey = elementType + '-' + mode;
4390
+ const cached = cache[cacheKey];
4391
+ const sharing = this.enableOptionSharing && defined(index);
4392
+ if (cached) {
4393
+ return cloneIfNotShared(cached, sharing);
4394
+ }
4395
+ const config = this.chart.config;
4396
+ const scopeKeys = config.datasetElementScopeKeys(this._type, elementType);
4397
+ const prefixes = active ? [`${elementType}Hover`, 'hover', elementType, ''] : [elementType, ''];
4398
+ const scopes = config.getOptionScopes(this.getDataset(), scopeKeys);
4399
+ const names = Object.keys(defaults.elements[elementType]);
4400
+ const context = () => this.getContext(index, active);
4401
+ const values = config.resolveNamedOptions(scopes, names, context, prefixes);
4402
+ if (values.$shared) {
4403
+ values.$shared = sharing;
4404
+ cache[cacheKey] = Object.freeze(cloneIfNotShared(values, sharing));
4405
+ }
4406
+ return values;
4407
+ }
4408
+ _resolveAnimations(index, transition, active) {
4409
+ const chart = this.chart;
4410
+ const cache = this._cachedDataOpts;
4411
+ const cacheKey = `animation-${transition}`;
4412
+ const cached = cache[cacheKey];
4413
+ if (cached) {
4414
+ return cached;
4415
+ }
4416
+ let options;
4417
+ if (chart.options.animation !== false) {
4418
+ const config = this.chart.config;
4419
+ const scopeKeys = config.datasetAnimationScopeKeys(this._type, transition);
4420
+ const scopes = config.getOptionScopes(this.getDataset(), scopeKeys);
4421
+ options = config.createResolver(scopes, this.getContext(index, active, transition));
4422
+ }
4423
+ const animations = new Animations(chart, options && options.animations);
4424
+ if (options && options._cacheable) {
4425
+ cache[cacheKey] = Object.freeze(animations);
4426
+ }
4427
+ return animations;
4428
+ }
4429
+ getSharedOptions(options) {
4430
+ if (!options.$shared) {
4431
+ return;
4432
+ }
4433
+ return this._sharedOptions || (this._sharedOptions = Object.assign({}, options));
4434
+ }
4435
+ includeOptions(mode, sharedOptions) {
4436
+ return !sharedOptions || isDirectUpdateMode(mode) || this.chart._animationsDisabled;
4437
+ }
4438
+ updateElement(element, index, properties, mode) {
4439
+ if (isDirectUpdateMode(mode)) {
4440
+ Object.assign(element, properties);
4441
+ } else {
4442
+ this._resolveAnimations(index, mode).update(element, properties);
4443
+ }
4444
+ }
4445
+ updateSharedOptions(sharedOptions, mode, newOptions) {
4446
+ if (sharedOptions && !isDirectUpdateMode(mode)) {
4447
+ this._resolveAnimations(undefined, mode).update(sharedOptions, newOptions);
4448
+ }
4449
+ }
4450
+ _setStyle(element, index, mode, active) {
4451
+ element.active = active;
4452
+ const options = this.getStyle(index, active);
4453
+ this._resolveAnimations(index, mode, active).update(element, {
4454
+ options: (!active && this.getSharedOptions(options)) || options
4455
+ });
4456
+ }
4457
+ removeHoverStyle(element, datasetIndex, index) {
4458
+ this._setStyle(element, index, 'active', false);
4459
+ }
4460
+ setHoverStyle(element, datasetIndex, index) {
4461
+ this._setStyle(element, index, 'active', true);
4462
+ }
4463
+ _removeDatasetHoverStyle() {
4464
+ const element = this._cachedMeta.dataset;
4465
+ if (element) {
4466
+ this._setStyle(element, undefined, 'active', false);
4467
+ }
4468
+ }
4469
+ _setDatasetHoverStyle() {
4470
+ const element = this._cachedMeta.dataset;
4471
+ if (element) {
4472
+ this._setStyle(element, undefined, 'active', true);
4473
+ }
4474
+ }
4475
+ _resyncElements(resetNewElements) {
4476
+ const data = this._data;
4477
+ const elements = this._cachedMeta.data;
4478
+ for (const [method, arg1, arg2] of this._syncList) {
4479
+ this[method](arg1, arg2);
4480
+ }
4481
+ this._syncList = [];
4482
+ const numMeta = elements.length;
4483
+ const numData = data.length;
4484
+ const count = Math.min(numData, numMeta);
4485
+ if (count) {
4486
+ this.parse(0, count);
4487
+ }
4488
+ if (numData > numMeta) {
4489
+ this._insertElements(numMeta, numData - numMeta, resetNewElements);
4490
+ } else if (numData < numMeta) {
4491
+ this._removeElements(numData, numMeta - numData);
4492
+ }
4493
+ }
4494
+ _insertElements(start, count, resetNewElements = true) {
4495
+ const meta = this._cachedMeta;
4496
+ const data = meta.data;
4497
+ const end = start + count;
4498
+ let i;
4499
+ const move = (arr) => {
4500
+ arr.length += count;
4501
+ for (i = arr.length - 1; i >= end; i--) {
4502
+ arr[i] = arr[i - count];
4503
+ }
4504
+ };
4505
+ move(data);
4506
+ for (i = start; i < end; ++i) {
4507
+ data[i] = new this.dataElementType();
4508
+ }
4509
+ if (this._parsing) {
4510
+ move(meta._parsed);
4511
+ }
4512
+ this.parse(start, count);
4513
+ if (resetNewElements) {
4514
+ this.updateElements(data, start, count, 'reset');
4515
+ }
4516
+ }
4517
+ updateElements(element, start, count, mode) {}
4518
+ _removeElements(start, count) {
4519
+ const meta = this._cachedMeta;
4520
+ if (this._parsing) {
4521
+ const removed = meta._parsed.splice(start, count);
4522
+ if (meta._stacked) {
4523
+ clearStacks(meta, removed);
4524
+ }
4525
+ }
4526
+ meta.data.splice(start, count);
4527
+ }
4528
+ _sync(args) {
4529
+ if (this._parsing) {
4530
+ this._syncList.push(args);
4531
+ } else {
4532
+ const [method, arg1, arg2] = args;
4533
+ this[method](arg1, arg2);
4534
+ }
4535
+ this.chart._dataChanges.push([this.index, ...args]);
4536
+ }
4537
+ _onDataPush() {
4538
+ const count = arguments.length;
4539
+ this._sync(['_insertElements', this.getDataset().data.length - count, count]);
4540
+ }
4541
+ _onDataPop() {
4542
+ this._sync(['_removeElements', this._cachedMeta.data.length - 1, 1]);
4543
+ }
4544
+ _onDataShift() {
4545
+ this._sync(['_removeElements', 0, 1]);
4546
+ }
4547
+ _onDataSplice(start, count) {
4548
+ if (count) {
4549
+ this._sync(['_removeElements', start, count]);
4550
+ }
4551
+ const newCount = arguments.length - 2;
4552
+ if (newCount) {
4553
+ this._sync(['_insertElements', start, newCount]);
4554
+ }
4555
+ }
4556
+ _onDataUnshift() {
4557
+ this._sync(['_insertElements', 0, arguments.length]);
4558
+ }
4559
+ }
4560
+ DatasetController.defaults = {};
4561
+ DatasetController.prototype.datasetElementType = null;
4562
+ DatasetController.prototype.dataElementType = null;
4563
+
4564
+ class Element {
4565
+ constructor() {
4566
+ this.x = undefined;
4567
+ this.y = undefined;
4568
+ this.active = false;
4569
+ this.options = undefined;
4570
+ this.$animations = undefined;
4571
+ }
4572
+ tooltipPosition(useFinalPosition) {
4573
+ const {x, y} = this.getProps(['x', 'y'], useFinalPosition);
4574
+ return {x, y};
4575
+ }
4576
+ hasValue() {
4577
+ return isNumber(this.x) && isNumber(this.y);
4578
+ }
4579
+ getProps(props, final) {
4580
+ const anims = this.$animations;
4581
+ if (!final || !anims) {
4582
+ return this;
4583
+ }
4584
+ const ret = {};
4585
+ props.forEach(prop => {
4586
+ ret[prop] = anims[prop] && anims[prop].active() ? anims[prop]._to : this[prop];
4587
+ });
4588
+ return ret;
4589
+ }
4590
+ }
4591
+ Element.defaults = {};
4592
+ Element.defaultRoutes = undefined;
4593
+
4594
+ const formatters = {
4595
+ values(value) {
4596
+ return isArray(value) ? value : '' + value;
4597
+ },
4598
+ numeric(tickValue, index, ticks) {
4599
+ if (tickValue === 0) {
4600
+ return '0';
4601
+ }
4602
+ const locale = this.chart.options.locale;
4603
+ let notation;
4604
+ let delta = tickValue;
4605
+ if (ticks.length > 1) {
4606
+ const maxTick = Math.max(Math.abs(ticks[0].value), Math.abs(ticks[ticks.length - 1].value));
4607
+ if (maxTick < 1e-4 || maxTick > 1e+15) {
4608
+ notation = 'scientific';
4609
+ }
4610
+ delta = calculateDelta(tickValue, ticks);
4611
+ }
4612
+ const logDelta = log10(Math.abs(delta));
4613
+ const numDecimal = Math.max(Math.min(-1 * Math.floor(logDelta), 20), 0);
4614
+ const options = {notation, minimumFractionDigits: numDecimal, maximumFractionDigits: numDecimal};
4615
+ Object.assign(options, this.options.ticks.format);
4616
+ return formatNumber(tickValue, locale, options);
4617
+ },
4618
+ logarithmic(tickValue, index, ticks) {
4619
+ if (tickValue === 0) {
4620
+ return '0';
4621
+ }
4622
+ const remain = tickValue / (Math.pow(10, Math.floor(log10(tickValue))));
4623
+ if (remain === 1 || remain === 2 || remain === 5) {
4624
+ return formatters.numeric.call(this, tickValue, index, ticks);
4625
+ }
4626
+ return '';
4627
+ }
4628
+ };
4629
+ function calculateDelta(tickValue, ticks) {
4630
+ let delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value;
4631
+ if (Math.abs(delta) >= 1 && tickValue !== Math.floor(tickValue)) {
4632
+ delta = tickValue - Math.floor(tickValue);
4633
+ }
4634
+ return delta;
4635
+ }
4636
+ var Ticks = {formatters};
4637
+
4638
+ defaults.set('scale', {
4639
+ display: true,
4640
+ offset: false,
4641
+ reverse: false,
4642
+ beginAtZero: false,
4643
+ bounds: 'ticks',
4644
+ grace: 0,
4645
+ grid: {
4646
+ display: true,
4647
+ lineWidth: 1,
4648
+ drawBorder: true,
4649
+ drawOnChartArea: true,
4650
+ drawTicks: true,
4651
+ tickLength: 8,
4652
+ tickWidth: (_ctx, options) => options.lineWidth,
4653
+ tickColor: (_ctx, options) => options.color,
4654
+ offset: false,
4655
+ borderDash: [],
4656
+ borderDashOffset: 0.0,
4657
+ borderWidth: 1
4658
+ },
4659
+ title: {
4660
+ display: false,
4661
+ text: '',
4662
+ padding: {
4663
+ top: 4,
4664
+ bottom: 4
4665
+ }
4666
+ },
4667
+ ticks: {
4668
+ minRotation: 0,
4669
+ maxRotation: 50,
4670
+ mirror: false,
4671
+ textStrokeWidth: 0,
4672
+ textStrokeColor: '',
4673
+ padding: 3,
4674
+ display: true,
4675
+ autoSkip: true,
4676
+ autoSkipPadding: 3,
4677
+ labelOffset: 0,
4678
+ callback: Ticks.formatters.values,
4679
+ minor: {},
4680
+ major: {},
4681
+ align: 'center',
4682
+ crossAlign: 'near',
4683
+ showLabelBackdrop: false,
4684
+ backdropColor: 'rgba(255, 255, 255, 0.75)',
4685
+ backdropPadding: 2,
4686
+ }
4687
+ });
4688
+ defaults.route('scale.ticks', 'color', '', 'color');
4689
+ defaults.route('scale.grid', 'color', '', 'borderColor');
4690
+ defaults.route('scale.grid', 'borderColor', '', 'borderColor');
4691
+ defaults.route('scale.title', 'color', '', 'color');
4692
+ defaults.describe('scale', {
4693
+ _fallback: false,
4694
+ _scriptable: (name) => !name.startsWith('before') && !name.startsWith('after') && name !== 'callback' && name !== 'parser',
4695
+ _indexable: (name) => name !== 'borderDash' && name !== 'tickBorderDash',
4696
+ });
4697
+ defaults.describe('scales', {
4698
+ _fallback: 'scale',
4699
+ });
4700
+ defaults.describe('scale.ticks', {
4701
+ _scriptable: (name) => name !== 'backdropPadding' && name !== 'callback',
4702
+ _indexable: (name) => name !== 'backdropPadding',
4703
+ });
4704
+
4705
+ function autoSkip(scale, ticks) {
4706
+ const tickOpts = scale.options.ticks;
4707
+ const ticksLimit = tickOpts.maxTicksLimit || determineMaxTicks(scale);
4708
+ const majorIndices = tickOpts.major.enabled ? getMajorIndices(ticks) : [];
4709
+ const numMajorIndices = majorIndices.length;
4710
+ const first = majorIndices[0];
4711
+ const last = majorIndices[numMajorIndices - 1];
4712
+ const newTicks = [];
4713
+ if (numMajorIndices > ticksLimit) {
4714
+ skipMajors(ticks, newTicks, majorIndices, numMajorIndices / ticksLimit);
4715
+ return newTicks;
4716
+ }
4717
+ const spacing = calculateSpacing(majorIndices, ticks, ticksLimit);
4718
+ if (numMajorIndices > 0) {
4719
+ let i, ilen;
4720
+ const avgMajorSpacing = numMajorIndices > 1 ? Math.round((last - first) / (numMajorIndices - 1)) : null;
4721
+ skip(ticks, newTicks, spacing, isNullOrUndef(avgMajorSpacing) ? 0 : first - avgMajorSpacing, first);
4722
+ for (i = 0, ilen = numMajorIndices - 1; i < ilen; i++) {
4723
+ skip(ticks, newTicks, spacing, majorIndices[i], majorIndices[i + 1]);
4724
+ }
4725
+ skip(ticks, newTicks, spacing, last, isNullOrUndef(avgMajorSpacing) ? ticks.length : last + avgMajorSpacing);
4726
+ return newTicks;
4727
+ }
4728
+ skip(ticks, newTicks, spacing);
4729
+ return newTicks;
4730
+ }
4731
+ function determineMaxTicks(scale) {
4732
+ const offset = scale.options.offset;
4733
+ const tickLength = scale._tickSize();
4734
+ const maxScale = scale._length / tickLength + (offset ? 0 : 1);
4735
+ const maxChart = scale._maxLength / tickLength;
4736
+ return Math.floor(Math.min(maxScale, maxChart));
4737
+ }
4738
+ function calculateSpacing(majorIndices, ticks, ticksLimit) {
4739
+ const evenMajorSpacing = getEvenSpacing(majorIndices);
4740
+ const spacing = ticks.length / ticksLimit;
4741
+ if (!evenMajorSpacing) {
4742
+ return Math.max(spacing, 1);
4743
+ }
4744
+ const factors = _factorize(evenMajorSpacing);
4745
+ for (let i = 0, ilen = factors.length - 1; i < ilen; i++) {
4746
+ const factor = factors[i];
4747
+ if (factor > spacing) {
4748
+ return factor;
4749
+ }
4750
+ }
4751
+ return Math.max(spacing, 1);
4752
+ }
4753
+ function getMajorIndices(ticks) {
4754
+ const result = [];
4755
+ let i, ilen;
4756
+ for (i = 0, ilen = ticks.length; i < ilen; i++) {
4757
+ if (ticks[i].major) {
4758
+ result.push(i);
4759
+ }
4760
+ }
4761
+ return result;
4762
+ }
4763
+ function skipMajors(ticks, newTicks, majorIndices, spacing) {
4764
+ let count = 0;
4765
+ let next = majorIndices[0];
4766
+ let i;
4767
+ spacing = Math.ceil(spacing);
4768
+ for (i = 0; i < ticks.length; i++) {
4769
+ if (i === next) {
4770
+ newTicks.push(ticks[i]);
4771
+ count++;
4772
+ next = majorIndices[count * spacing];
4773
+ }
4774
+ }
4775
+ }
4776
+ function skip(ticks, newTicks, spacing, majorStart, majorEnd) {
4777
+ const start = valueOrDefault(majorStart, 0);
4778
+ const end = Math.min(valueOrDefault(majorEnd, ticks.length), ticks.length);
4779
+ let count = 0;
4780
+ let length, i, next;
4781
+ spacing = Math.ceil(spacing);
4782
+ if (majorEnd) {
4783
+ length = majorEnd - majorStart;
4784
+ spacing = length / Math.floor(length / spacing);
4785
+ }
4786
+ next = start;
4787
+ while (next < 0) {
4788
+ count++;
4789
+ next = Math.round(start + count * spacing);
4790
+ }
4791
+ for (i = Math.max(start, 0); i < end; i++) {
4792
+ if (i === next) {
4793
+ newTicks.push(ticks[i]);
4794
+ count++;
4795
+ next = Math.round(start + count * spacing);
4796
+ }
4797
+ }
4798
+ }
4799
+ function getEvenSpacing(arr) {
4800
+ const len = arr.length;
4801
+ let i, diff;
4802
+ if (len < 2) {
4803
+ return false;
4804
+ }
4805
+ for (diff = arr[0], i = 1; i < len; ++i) {
4806
+ if (arr[i] - arr[i - 1] !== diff) {
4807
+ return false;
4808
+ }
4809
+ }
4810
+ return diff;
4811
+ }
4812
+
4813
+ const reverseAlign = (align) => align === 'left' ? 'right' : align === 'right' ? 'left' : align;
4814
+ const offsetFromEdge = (scale, edge, offset) => edge === 'top' || edge === 'left' ? scale[edge] + offset : scale[edge] - offset;
4815
+ function sample(arr, numItems) {
4816
+ const result = [];
4817
+ const increment = arr.length / numItems;
4818
+ const len = arr.length;
4819
+ let i = 0;
4820
+ for (; i < len; i += increment) {
4821
+ result.push(arr[Math.floor(i)]);
4822
+ }
4823
+ return result;
4824
+ }
4825
+ function getPixelForGridLine(scale, index, offsetGridLines) {
4826
+ const length = scale.ticks.length;
4827
+ const validIndex = Math.min(index, length - 1);
4828
+ const start = scale._startPixel;
4829
+ const end = scale._endPixel;
4830
+ const epsilon = 1e-6;
4831
+ let lineValue = scale.getPixelForTick(validIndex);
4832
+ let offset;
4833
+ if (offsetGridLines) {
4834
+ if (length === 1) {
4835
+ offset = Math.max(lineValue - start, end - lineValue);
4836
+ } else if (index === 0) {
4837
+ offset = (scale.getPixelForTick(1) - lineValue) / 2;
4838
+ } else {
4839
+ offset = (lineValue - scale.getPixelForTick(validIndex - 1)) / 2;
4840
+ }
4841
+ lineValue += validIndex < index ? offset : -offset;
4842
+ if (lineValue < start - epsilon || lineValue > end + epsilon) {
4843
+ return;
4844
+ }
4845
+ }
4846
+ return lineValue;
4847
+ }
4848
+ function garbageCollect(caches, length) {
4849
+ each(caches, (cache) => {
4850
+ const gc = cache.gc;
4851
+ const gcLen = gc.length / 2;
4852
+ let i;
4853
+ if (gcLen > length) {
4854
+ for (i = 0; i < gcLen; ++i) {
4855
+ delete cache.data[gc[i]];
4856
+ }
4857
+ gc.splice(0, gcLen);
4858
+ }
4859
+ });
4860
+ }
4861
+ function getTickMarkLength(options) {
4862
+ return options.drawTicks ? options.tickLength : 0;
4863
+ }
4864
+ function getTitleHeight(options, fallback) {
4865
+ if (!options.display) {
4866
+ return 0;
4867
+ }
4868
+ const font = toFont(options.font, fallback);
4869
+ const padding = toPadding(options.padding);
4870
+ const lines = isArray(options.text) ? options.text.length : 1;
4871
+ return (lines * font.lineHeight) + padding.height;
4872
+ }
4873
+ function createScaleContext(parent, scale) {
4874
+ return createContext(parent, {
4875
+ scale,
4876
+ type: 'scale'
4877
+ });
4878
+ }
4879
+ function createTickContext(parent, index, tick) {
4880
+ return createContext(parent, {
4881
+ tick,
4882
+ index,
4883
+ type: 'tick'
4884
+ });
4885
+ }
4886
+ function titleAlign(align, position, reverse) {
4887
+ let ret = _toLeftRightCenter(align);
4888
+ if ((reverse && position !== 'right') || (!reverse && position === 'right')) {
4889
+ ret = reverseAlign(ret);
4890
+ }
4891
+ return ret;
4892
+ }
4893
+ function titleArgs(scale, offset, position, align) {
4894
+ const {top, left, bottom, right, chart} = scale;
4895
+ const {chartArea, scales} = chart;
4896
+ let rotation = 0;
4897
+ let maxWidth, titleX, titleY;
4898
+ const height = bottom - top;
4899
+ const width = right - left;
4900
+ if (scale.isHorizontal()) {
4901
+ titleX = _alignStartEnd(align, left, right);
4902
+ if (isObject(position)) {
4903
+ const positionAxisID = Object.keys(position)[0];
4904
+ const value = position[positionAxisID];
4905
+ titleY = scales[positionAxisID].getPixelForValue(value) + height - offset;
4906
+ } else if (position === 'center') {
4907
+ titleY = (chartArea.bottom + chartArea.top) / 2 + height - offset;
4908
+ } else {
4909
+ titleY = offsetFromEdge(scale, position, offset);
4910
+ }
4911
+ maxWidth = right - left;
4912
+ } else {
4913
+ if (isObject(position)) {
4914
+ const positionAxisID = Object.keys(position)[0];
4915
+ const value = position[positionAxisID];
4916
+ titleX = scales[positionAxisID].getPixelForValue(value) - width + offset;
4917
+ } else if (position === 'center') {
4918
+ titleX = (chartArea.left + chartArea.right) / 2 - width + offset;
4919
+ } else {
4920
+ titleX = offsetFromEdge(scale, position, offset);
4921
+ }
4922
+ titleY = _alignStartEnd(align, bottom, top);
4923
+ rotation = position === 'left' ? -HALF_PI : HALF_PI;
4924
+ }
4925
+ return {titleX, titleY, maxWidth, rotation};
4926
+ }
4927
+ class Scale extends Element {
4928
+ constructor(cfg) {
4929
+ super();
4930
+ this.id = cfg.id;
4931
+ this.type = cfg.type;
4932
+ this.options = undefined;
4933
+ this.ctx = cfg.ctx;
4934
+ this.chart = cfg.chart;
4935
+ this.top = undefined;
4936
+ this.bottom = undefined;
4937
+ this.left = undefined;
4938
+ this.right = undefined;
4939
+ this.width = undefined;
4940
+ this.height = undefined;
4941
+ this._margins = {
4942
+ left: 0,
4943
+ right: 0,
4944
+ top: 0,
4945
+ bottom: 0
4946
+ };
4947
+ this.maxWidth = undefined;
4948
+ this.maxHeight = undefined;
4949
+ this.paddingTop = undefined;
4950
+ this.paddingBottom = undefined;
4951
+ this.paddingLeft = undefined;
4952
+ this.paddingRight = undefined;
4953
+ this.axis = undefined;
4954
+ this.labelRotation = undefined;
4955
+ this.min = undefined;
4956
+ this.max = undefined;
4957
+ this._range = undefined;
4958
+ this.ticks = [];
4959
+ this._gridLineItems = null;
4960
+ this._labelItems = null;
4961
+ this._labelSizes = null;
4962
+ this._length = 0;
4963
+ this._maxLength = 0;
4964
+ this._longestTextCache = {};
4965
+ this._startPixel = undefined;
4966
+ this._endPixel = undefined;
4967
+ this._reversePixels = false;
4968
+ this._userMax = undefined;
4969
+ this._userMin = undefined;
4970
+ this._suggestedMax = undefined;
4971
+ this._suggestedMin = undefined;
4972
+ this._ticksLength = 0;
4973
+ this._borderValue = 0;
4974
+ this._cache = {};
4975
+ this._dataLimitsCached = false;
4976
+ this.$context = undefined;
4977
+ }
4978
+ init(options) {
4979
+ this.options = options.setContext(this.getContext());
4980
+ this.axis = options.axis;
4981
+ this._userMin = this.parse(options.min);
4982
+ this._userMax = this.parse(options.max);
4983
+ this._suggestedMin = this.parse(options.suggestedMin);
4984
+ this._suggestedMax = this.parse(options.suggestedMax);
4985
+ }
4986
+ parse(raw, index) {
4987
+ return raw;
4988
+ }
4989
+ getUserBounds() {
4990
+ let {_userMin, _userMax, _suggestedMin, _suggestedMax} = this;
4991
+ _userMin = finiteOrDefault(_userMin, Number.POSITIVE_INFINITY);
4992
+ _userMax = finiteOrDefault(_userMax, Number.NEGATIVE_INFINITY);
4993
+ _suggestedMin = finiteOrDefault(_suggestedMin, Number.POSITIVE_INFINITY);
4994
+ _suggestedMax = finiteOrDefault(_suggestedMax, Number.NEGATIVE_INFINITY);
4995
+ return {
4996
+ min: finiteOrDefault(_userMin, _suggestedMin),
4997
+ max: finiteOrDefault(_userMax, _suggestedMax),
4998
+ minDefined: isNumberFinite(_userMin),
4999
+ maxDefined: isNumberFinite(_userMax)
5000
+ };
5001
+ }
5002
+ getMinMax(canStack) {
5003
+ let {min, max, minDefined, maxDefined} = this.getUserBounds();
5004
+ let range;
5005
+ if (minDefined && maxDefined) {
5006
+ return {min, max};
5007
+ }
5008
+ const metas = this.getMatchingVisibleMetas();
5009
+ for (let i = 0, ilen = metas.length; i < ilen; ++i) {
5010
+ range = metas[i].controller.getMinMax(this, canStack);
5011
+ if (!minDefined) {
5012
+ min = Math.min(min, range.min);
5013
+ }
5014
+ if (!maxDefined) {
5015
+ max = Math.max(max, range.max);
5016
+ }
5017
+ }
5018
+ min = maxDefined && min > max ? max : min;
5019
+ max = minDefined && min > max ? min : max;
5020
+ return {
5021
+ min: finiteOrDefault(min, finiteOrDefault(max, min)),
5022
+ max: finiteOrDefault(max, finiteOrDefault(min, max))
5023
+ };
5024
+ }
5025
+ getPadding() {
5026
+ return {
5027
+ left: this.paddingLeft || 0,
5028
+ top: this.paddingTop || 0,
5029
+ right: this.paddingRight || 0,
5030
+ bottom: this.paddingBottom || 0
5031
+ };
5032
+ }
5033
+ getTicks() {
5034
+ return this.ticks;
5035
+ }
5036
+ getLabels() {
5037
+ const data = this.chart.data;
5038
+ return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels || [];
5039
+ }
5040
+ beforeLayout() {
5041
+ this._cache = {};
5042
+ this._dataLimitsCached = false;
5043
+ }
5044
+ beforeUpdate() {
5045
+ callback(this.options.beforeUpdate, [this]);
5046
+ }
5047
+ update(maxWidth, maxHeight, margins) {
5048
+ const {beginAtZero, grace, ticks: tickOpts} = this.options;
5049
+ const sampleSize = tickOpts.sampleSize;
5050
+ this.beforeUpdate();
5051
+ this.maxWidth = maxWidth;
5052
+ this.maxHeight = maxHeight;
5053
+ this._margins = margins = Object.assign({
5054
+ left: 0,
5055
+ right: 0,
5056
+ top: 0,
5057
+ bottom: 0
5058
+ }, margins);
5059
+ this.ticks = null;
5060
+ this._labelSizes = null;
5061
+ this._gridLineItems = null;
5062
+ this._labelItems = null;
5063
+ this.beforeSetDimensions();
5064
+ this.setDimensions();
5065
+ this.afterSetDimensions();
5066
+ this._maxLength = this.isHorizontal()
5067
+ ? this.width + margins.left + margins.right
5068
+ : this.height + margins.top + margins.bottom;
5069
+ if (!this._dataLimitsCached) {
5070
+ this.beforeDataLimits();
5071
+ this.determineDataLimits();
5072
+ this.afterDataLimits();
5073
+ this._range = _addGrace(this, grace, beginAtZero);
5074
+ this._dataLimitsCached = true;
5075
+ }
5076
+ this.beforeBuildTicks();
5077
+ this.ticks = this.buildTicks() || [];
5078
+ this.afterBuildTicks();
5079
+ const samplingEnabled = sampleSize < this.ticks.length;
5080
+ this._convertTicksToLabels(samplingEnabled ? sample(this.ticks, sampleSize) : this.ticks);
5081
+ this.configure();
5082
+ this.beforeCalculateLabelRotation();
5083
+ this.calculateLabelRotation();
5084
+ this.afterCalculateLabelRotation();
5085
+ if (tickOpts.display && (tickOpts.autoSkip || tickOpts.source === 'auto')) {
5086
+ this.ticks = autoSkip(this, this.ticks);
5087
+ this._labelSizes = null;
5088
+ }
5089
+ if (samplingEnabled) {
5090
+ this._convertTicksToLabels(this.ticks);
5091
+ }
5092
+ this.beforeFit();
5093
+ this.fit();
5094
+ this.afterFit();
5095
+ this.afterUpdate();
5096
+ }
5097
+ configure() {
5098
+ let reversePixels = this.options.reverse;
5099
+ let startPixel, endPixel;
5100
+ if (this.isHorizontal()) {
5101
+ startPixel = this.left;
5102
+ endPixel = this.right;
5103
+ } else {
5104
+ startPixel = this.top;
5105
+ endPixel = this.bottom;
5106
+ reversePixels = !reversePixels;
5107
+ }
5108
+ this._startPixel = startPixel;
5109
+ this._endPixel = endPixel;
5110
+ this._reversePixels = reversePixels;
5111
+ this._length = endPixel - startPixel;
5112
+ this._alignToPixels = this.options.alignToPixels;
5113
+ }
5114
+ afterUpdate() {
5115
+ callback(this.options.afterUpdate, [this]);
5116
+ }
5117
+ beforeSetDimensions() {
5118
+ callback(this.options.beforeSetDimensions, [this]);
5119
+ }
5120
+ setDimensions() {
5121
+ if (this.isHorizontal()) {
5122
+ this.width = this.maxWidth;
5123
+ this.left = 0;
5124
+ this.right = this.width;
5125
+ } else {
5126
+ this.height = this.maxHeight;
5127
+ this.top = 0;
5128
+ this.bottom = this.height;
5129
+ }
5130
+ this.paddingLeft = 0;
5131
+ this.paddingTop = 0;
5132
+ this.paddingRight = 0;
5133
+ this.paddingBottom = 0;
5134
+ }
5135
+ afterSetDimensions() {
5136
+ callback(this.options.afterSetDimensions, [this]);
5137
+ }
5138
+ _callHooks(name) {
5139
+ this.chart.notifyPlugins(name, this.getContext());
5140
+ callback(this.options[name], [this]);
5141
+ }
5142
+ beforeDataLimits() {
5143
+ this._callHooks('beforeDataLimits');
5144
+ }
5145
+ determineDataLimits() {}
5146
+ afterDataLimits() {
5147
+ this._callHooks('afterDataLimits');
5148
+ }
5149
+ beforeBuildTicks() {
5150
+ this._callHooks('beforeBuildTicks');
5151
+ }
5152
+ buildTicks() {
5153
+ return [];
5154
+ }
5155
+ afterBuildTicks() {
5156
+ this._callHooks('afterBuildTicks');
5157
+ }
5158
+ beforeTickToLabelConversion() {
5159
+ callback(this.options.beforeTickToLabelConversion, [this]);
5160
+ }
5161
+ generateTickLabels(ticks) {
5162
+ const tickOpts = this.options.ticks;
5163
+ let i, ilen, tick;
5164
+ for (i = 0, ilen = ticks.length; i < ilen; i++) {
5165
+ tick = ticks[i];
5166
+ tick.label = callback(tickOpts.callback, [tick.value, i, ticks], this);
5167
+ }
5168
+ }
5169
+ afterTickToLabelConversion() {
5170
+ callback(this.options.afterTickToLabelConversion, [this]);
5171
+ }
5172
+ beforeCalculateLabelRotation() {
5173
+ callback(this.options.beforeCalculateLabelRotation, [this]);
5174
+ }
5175
+ calculateLabelRotation() {
5176
+ const options = this.options;
5177
+ const tickOpts = options.ticks;
5178
+ const numTicks = this.ticks.length;
5179
+ const minRotation = tickOpts.minRotation || 0;
5180
+ const maxRotation = tickOpts.maxRotation;
5181
+ let labelRotation = minRotation;
5182
+ let tickWidth, maxHeight, maxLabelDiagonal;
5183
+ if (!this._isVisible() || !tickOpts.display || minRotation >= maxRotation || numTicks <= 1 || !this.isHorizontal()) {
5184
+ this.labelRotation = minRotation;
5185
+ return;
5186
+ }
5187
+ const labelSizes = this._getLabelSizes();
5188
+ const maxLabelWidth = labelSizes.widest.width;
5189
+ const maxLabelHeight = labelSizes.highest.height;
5190
+ const maxWidth = _limitValue(this.chart.width - maxLabelWidth, 0, this.maxWidth);
5191
+ tickWidth = options.offset ? this.maxWidth / numTicks : maxWidth / (numTicks - 1);
5192
+ if (maxLabelWidth + 6 > tickWidth) {
5193
+ tickWidth = maxWidth / (numTicks - (options.offset ? 0.5 : 1));
5194
+ maxHeight = this.maxHeight - getTickMarkLength(options.grid)
5195
+ - tickOpts.padding - getTitleHeight(options.title, this.chart.options.font);
5196
+ maxLabelDiagonal = Math.sqrt(maxLabelWidth * maxLabelWidth + maxLabelHeight * maxLabelHeight);
5197
+ labelRotation = toDegrees(Math.min(
5198
+ Math.asin(_limitValue((labelSizes.highest.height + 6) / tickWidth, -1, 1)),
5199
+ Math.asin(_limitValue(maxHeight / maxLabelDiagonal, -1, 1)) - Math.asin(_limitValue(maxLabelHeight / maxLabelDiagonal, -1, 1))
5200
+ ));
5201
+ labelRotation = Math.max(minRotation, Math.min(maxRotation, labelRotation));
5202
+ }
5203
+ this.labelRotation = labelRotation;
5204
+ }
5205
+ afterCalculateLabelRotation() {
5206
+ callback(this.options.afterCalculateLabelRotation, [this]);
5207
+ }
5208
+ beforeFit() {
5209
+ callback(this.options.beforeFit, [this]);
5210
+ }
5211
+ fit() {
5212
+ const minSize = {
5213
+ width: 0,
5214
+ height: 0
5215
+ };
5216
+ const {chart, options: {ticks: tickOpts, title: titleOpts, grid: gridOpts}} = this;
5217
+ const display = this._isVisible();
5218
+ const isHorizontal = this.isHorizontal();
5219
+ if (display) {
5220
+ const titleHeight = getTitleHeight(titleOpts, chart.options.font);
5221
+ if (isHorizontal) {
5222
+ minSize.width = this.maxWidth;
5223
+ minSize.height = getTickMarkLength(gridOpts) + titleHeight;
5224
+ } else {
5225
+ minSize.height = this.maxHeight;
5226
+ minSize.width = getTickMarkLength(gridOpts) + titleHeight;
5227
+ }
5228
+ if (tickOpts.display && this.ticks.length) {
5229
+ const {first, last, widest, highest} = this._getLabelSizes();
5230
+ const tickPadding = tickOpts.padding * 2;
5231
+ const angleRadians = toRadians(this.labelRotation);
5232
+ const cos = Math.cos(angleRadians);
5233
+ const sin = Math.sin(angleRadians);
5234
+ if (isHorizontal) {
5235
+ const labelHeight = tickOpts.mirror ? 0 : sin * widest.width + cos * highest.height;
5236
+ minSize.height = Math.min(this.maxHeight, minSize.height + labelHeight + tickPadding);
5237
+ } else {
5238
+ const labelWidth = tickOpts.mirror ? 0 : cos * widest.width + sin * highest.height;
5239
+ minSize.width = Math.min(this.maxWidth, minSize.width + labelWidth + tickPadding);
5240
  }
5241
+ this._calculatePadding(first, last, sin, cos);
5242
+ }
5243
+ }
5244
+ this._handleMargins();
5245
+ if (isHorizontal) {
5246
+ this.width = this._length = chart.width - this._margins.left - this._margins.right;
5247
+ this.height = minSize.height;
5248
+ } else {
5249
+ this.width = minSize.width;
5250
+ this.height = this._length = chart.height - this._margins.top - this._margins.bottom;
5251
+ }
5252
+ }
5253
+ _calculatePadding(first, last, sin, cos) {
5254
+ const {ticks: {align, padding}, position} = this.options;
5255
+ const isRotated = this.labelRotation !== 0;
5256
+ const labelsBelowTicks = position !== 'top' && this.axis === 'x';
5257
+ if (this.isHorizontal()) {
5258
+ const offsetLeft = this.getPixelForTick(0) - this.left;
5259
+ const offsetRight = this.right - this.getPixelForTick(this.ticks.length - 1);
5260
+ let paddingLeft = 0;
5261
+ let paddingRight = 0;
5262
+ if (isRotated) {
5263
+ if (labelsBelowTicks) {
5264
+ paddingLeft = cos * first.width;
5265
+ paddingRight = sin * last.height;
5266
+ } else {
5267
+ paddingLeft = sin * first.height;
5268
+ paddingRight = cos * last.width;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5269
  }
5270
+ } else if (align === 'start') {
5271
+ paddingRight = last.width;
5272
+ } else if (align === 'end') {
5273
+ paddingLeft = first.width;
5274
+ } else {
5275
+ paddingLeft = first.width / 2;
5276
+ paddingRight = last.width / 2;
5277
+ }
5278
+ this.paddingLeft = Math.max((paddingLeft - offsetLeft + padding) * this.width / (this.width - offsetLeft), 0);
5279
+ this.paddingRight = Math.max((paddingRight - offsetRight + padding) * this.width / (this.width - offsetRight), 0);
5280
+ } else {
5281
+ let paddingTop = last.height / 2;
5282
+ let paddingBottom = first.height / 2;
5283
+ if (align === 'start') {
5284
+ paddingTop = 0;
5285
+ paddingBottom = first.height;
5286
+ } else if (align === 'end') {
5287
+ paddingTop = last.height;
5288
+ paddingBottom = 0;
5289
+ }
5290
+ this.paddingTop = paddingTop + padding;
5291
+ this.paddingBottom = paddingBottom + padding;
5292
+ }
5293
+ }
5294
+ _handleMargins() {
5295
+ if (this._margins) {
5296
+ this._margins.left = Math.max(this.paddingLeft, this._margins.left);
5297
+ this._margins.top = Math.max(this.paddingTop, this._margins.top);
5298
+ this._margins.right = Math.max(this.paddingRight, this._margins.right);
5299
+ this._margins.bottom = Math.max(this.paddingBottom, this._margins.bottom);
5300
+ }
5301
+ }
5302
+ afterFit() {
5303
+ callback(this.options.afterFit, [this]);
5304
+ }
5305
+ isHorizontal() {
5306
+ const {axis, position} = this.options;
5307
+ return position === 'top' || position === 'bottom' || axis === 'x';
5308
+ }
5309
+ isFullSize() {
5310
+ return this.options.fullSize;
5311
+ }
5312
+ _convertTicksToLabels(ticks) {
5313
+ this.beforeTickToLabelConversion();
5314
+ this.generateTickLabels(ticks);
5315
+ let i, ilen;
5316
+ for (i = 0, ilen = ticks.length; i < ilen; i++) {
5317
+ if (isNullOrUndef(ticks[i].label)) {
5318
+ ticks.splice(i, 1);
5319
+ ilen--;
5320
+ i--;
5321
+ }
5322
+ }
5323
+ this.afterTickToLabelConversion();
5324
+ }
5325
+ _getLabelSizes() {
5326
+ let labelSizes = this._labelSizes;
5327
+ if (!labelSizes) {
5328
+ const sampleSize = this.options.ticks.sampleSize;
5329
+ let ticks = this.ticks;
5330
+ if (sampleSize < ticks.length) {
5331
+ ticks = sample(ticks, sampleSize);
5332
+ }
5333
+ this._labelSizes = labelSizes = this._computeLabelSizes(ticks, ticks.length);
5334
+ }
5335
+ return labelSizes;
5336
+ }
5337
+ _computeLabelSizes(ticks, length) {
5338
+ const {ctx, _longestTextCache: caches} = this;
5339
+ const widths = [];
5340
+ const heights = [];
5341
+ let widestLabelSize = 0;
5342
+ let highestLabelSize = 0;
5343
+ let i, j, jlen, label, tickFont, fontString, cache, lineHeight, width, height, nestedLabel;
5344
+ for (i = 0; i < length; ++i) {
5345
+ label = ticks[i].label;
5346
+ tickFont = this._resolveTickFontOptions(i);
5347
+ ctx.font = fontString = tickFont.string;
5348
+ cache = caches[fontString] = caches[fontString] || {data: {}, gc: []};
5349
+ lineHeight = tickFont.lineHeight;
5350
+ width = height = 0;
5351
+ if (!isNullOrUndef(label) && !isArray(label)) {
5352
+ width = _measureText(ctx, cache.data, cache.gc, width, label);
5353
+ height = lineHeight;
5354
+ } else if (isArray(label)) {
5355
+ for (j = 0, jlen = label.length; j < jlen; ++j) {
5356
+ nestedLabel = label[j];
5357
+ if (!isNullOrUndef(nestedLabel) && !isArray(nestedLabel)) {
5358
+ width = _measureText(ctx, cache.data, cache.gc, width, nestedLabel);
5359
+ height += lineHeight;
5360
+ }
5361
  }
5362
+ }
5363
+ widths.push(width);
5364
+ heights.push(height);
5365
+ widestLabelSize = Math.max(width, widestLabelSize);
5366
+ highestLabelSize = Math.max(height, highestLabelSize);
5367
+ }
5368
+ garbageCollect(caches, length);
5369
+ const widest = widths.indexOf(widestLabelSize);
5370
+ const highest = heights.indexOf(highestLabelSize);
5371
+ const valueAt = (idx) => ({width: widths[idx] || 0, height: heights[idx] || 0});
5372
+ return {
5373
+ first: valueAt(0),
5374
+ last: valueAt(length - 1),
5375
+ widest: valueAt(widest),
5376
+ highest: valueAt(highest),
5377
+ widths,
5378
+ heights,
5379
+ };
5380
+ }
5381
+ getLabelForValue(value) {
5382
+ return value;
5383
+ }
5384
+ getPixelForValue(value, index) {
5385
+ return NaN;
5386
+ }
5387
+ getValueForPixel(pixel) {}
5388
+ getPixelForTick(index) {
5389
+ const ticks = this.ticks;
5390
+ if (index < 0 || index > ticks.length - 1) {
5391
+ return null;
5392
+ }
5393
+ return this.getPixelForValue(ticks[index].value);
5394
+ }
5395
+ getPixelForDecimal(decimal) {
5396
+ if (this._reversePixels) {
5397
+ decimal = 1 - decimal;
5398
+ }
5399
+ const pixel = this._startPixel + decimal * this._length;
5400
+ return _int16Range(this._alignToPixels ? _alignPixel(this.chart, pixel, 0) : pixel);
5401
+ }
5402
+ getDecimalForPixel(pixel) {
5403
+ const decimal = (pixel - this._startPixel) / this._length;
5404
+ return this._reversePixels ? 1 - decimal : decimal;
5405
+ }
5406
+ getBasePixel() {
5407
+ return this.getPixelForValue(this.getBaseValue());
5408
+ }
5409
+ getBaseValue() {
5410
+ const {min, max} = this;
5411
+ return min < 0 && max < 0 ? max :
5412
+ min > 0 && max > 0 ? min :
5413
+ 0;
5414
+ }
5415
+ getContext(index) {
5416
+ const ticks = this.ticks || [];
5417
+ if (index >= 0 && index < ticks.length) {
5418
+ const tick = ticks[index];
5419
+ return tick.$context ||
5420
+ (tick.$context = createTickContext(this.getContext(), index, tick));
5421
+ }
5422
+ return this.$context ||
5423
+ (this.$context = createScaleContext(this.chart.getContext(), this));
5424
+ }
5425
+ _tickSize() {
5426
+ const optionTicks = this.options.ticks;
5427
+ const rot = toRadians(this.labelRotation);
5428
+ const cos = Math.abs(Math.cos(rot));
5429
+ const sin = Math.abs(Math.sin(rot));
5430
+ const labelSizes = this._getLabelSizes();
5431
+ const padding = optionTicks.autoSkipPadding || 0;
5432
+ const w = labelSizes ? labelSizes.widest.width + padding : 0;
5433
+ const h = labelSizes ? labelSizes.highest.height + padding : 0;
5434
+ return this.isHorizontal()
5435
+ ? h * cos > w * sin ? w / cos : h / sin
5436
+ : h * sin < w * cos ? h / cos : w / sin;
5437
+ }
5438
+ _isVisible() {
5439
+ const display = this.options.display;
5440
+ if (display !== 'auto') {
5441
+ return !!display;
5442
+ }
5443
+ return this.getMatchingVisibleMetas().length > 0;
5444
+ }
5445
+ _computeGridLineItems(chartArea) {
5446
+ const axis = this.axis;
5447
+ const chart = this.chart;
5448
+ const options = this.options;
5449
+ const {grid, position} = options;
5450
+ const offset = grid.offset;
5451
+ const isHorizontal = this.isHorizontal();
5452
+ const ticks = this.ticks;
5453
+ const ticksLength = ticks.length + (offset ? 1 : 0);
5454
+ const tl = getTickMarkLength(grid);
5455
+ const items = [];
5456
+ const borderOpts = grid.setContext(this.getContext());
5457
+ const axisWidth = borderOpts.drawBorder ? borderOpts.borderWidth : 0;
5458
+ const axisHalfWidth = axisWidth / 2;
5459
+ const alignBorderValue = function(pixel) {
5460
+ return _alignPixel(chart, pixel, axisWidth);
5461
+ };
5462
+ let borderValue, i, lineValue, alignedLineValue;
5463
+ let tx1, ty1, tx2, ty2, x1, y1, x2, y2;
5464
+ if (position === 'top') {
5465
+ borderValue = alignBorderValue(this.bottom);
5466
+ ty1 = this.bottom - tl;
5467
+ ty2 = borderValue - axisHalfWidth;
5468
+ y1 = alignBorderValue(chartArea.top) + axisHalfWidth;
5469
+ y2 = chartArea.bottom;
5470
+ } else if (position === 'bottom') {
5471
+ borderValue = alignBorderValue(this.top);
5472
+ y1 = chartArea.top;
5473
+ y2 = alignBorderValue(chartArea.bottom) - axisHalfWidth;
5474
+ ty1 = borderValue + axisHalfWidth;
5475
+ ty2 = this.top + tl;
5476
+ } else if (position === 'left') {
5477
+ borderValue = alignBorderValue(this.right);
5478
+ tx1 = this.right - tl;
5479
+ tx2 = borderValue - axisHalfWidth;
5480
+ x1 = alignBorderValue(chartArea.left) + axisHalfWidth;
5481
+ x2 = chartArea.right;
5482
+ } else if (position === 'right') {
5483
+ borderValue = alignBorderValue(this.left);
5484
+ x1 = chartArea.left;
5485
+ x2 = alignBorderValue(chartArea.right) - axisHalfWidth;
5486
+ tx1 = borderValue + axisHalfWidth;
5487
+ tx2 = this.left + tl;
5488
+ } else if (axis === 'x') {
5489
+ if (position === 'center') {
5490
+ borderValue = alignBorderValue((chartArea.top + chartArea.bottom) / 2 + 0.5);
5491
+ } else if (isObject(position)) {
5492
+ const positionAxisID = Object.keys(position)[0];
5493
+ const value = position[positionAxisID];
5494
+ borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value));
5495
+ }
5496
+ y1 = chartArea.top;
5497
+ y2 = chartArea.bottom;
5498
+ ty1 = borderValue + axisHalfWidth;
5499
+ ty2 = ty1 + tl;
5500
+ } else if (axis === 'y') {
5501
+ if (position === 'center') {
5502
+ borderValue = alignBorderValue((chartArea.left + chartArea.right) / 2);
5503
+ } else if (isObject(position)) {
5504
+ const positionAxisID = Object.keys(position)[0];
5505
+ const value = position[positionAxisID];
5506
+ borderValue = alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value));
5507
+ }
5508
+ tx1 = borderValue - axisHalfWidth;
5509
+ tx2 = tx1 - tl;
5510
+ x1 = chartArea.left;
5511
+ x2 = chartArea.right;
5512
+ }
5513
+ const limit = valueOrDefault(options.ticks.maxTicksLimit, ticksLength);
5514
+ const step = Math.max(1, Math.ceil(ticksLength / limit));
5515
+ for (i = 0; i < ticksLength; i += step) {
5516
+ const optsAtIndex = grid.setContext(this.getContext(i));
5517
+ const lineWidth = optsAtIndex.lineWidth;
5518
+ const lineColor = optsAtIndex.color;
5519
+ const borderDash = grid.borderDash || [];
5520
+ const borderDashOffset = optsAtIndex.borderDashOffset;
5521
+ const tickWidth = optsAtIndex.tickWidth;
5522
+ const tickColor = optsAtIndex.tickColor;
5523
+ const tickBorderDash = optsAtIndex.tickBorderDash || [];
5524
+ const tickBorderDashOffset = optsAtIndex.tickBorderDashOffset;
5525
+ lineValue = getPixelForGridLine(this, i, offset);
5526
+ if (lineValue === undefined) {
5527
+ continue;
5528
+ }
5529
+ alignedLineValue = _alignPixel(chart, lineValue, lineWidth);
5530
+ if (isHorizontal) {
5531
+ tx1 = tx2 = x1 = x2 = alignedLineValue;
5532
+ } else {
5533
+ ty1 = ty2 = y1 = y2 = alignedLineValue;
5534
+ }
5535
+ items.push({
5536
+ tx1,
5537
+ ty1,
5538
+ tx2,
5539
+ ty2,
5540
+ x1,
5541
+ y1,
5542
+ x2,
5543
+ y2,
5544
+ width: lineWidth,
5545
+ color: lineColor,
5546
+ borderDash,
5547
+ borderDashOffset,
5548
+ tickWidth,
5549
+ tickColor,
5550
+ tickBorderDash,
5551
+ tickBorderDashOffset,
5552
+ });
5553
+ }
5554
+ this._ticksLength = ticksLength;
5555
+ this._borderValue = borderValue;
5556
+ return items;
5557
+ }
5558
+ _computeLabelItems(chartArea) {
5559
+ const axis = this.axis;
5560
+ const options = this.options;
5561
+ const {position, ticks: optionTicks} = options;
5562
+ const isHorizontal = this.isHorizontal();
5563
+ const ticks = this.ticks;
5564
+ const {align, crossAlign, padding, mirror} = optionTicks;
5565
+ const tl = getTickMarkLength(options.grid);
5566
+ const tickAndPadding = tl + padding;
5567
+ const hTickAndPadding = mirror ? -padding : tickAndPadding;
5568
+ const rotation = -toRadians(this.labelRotation);
5569
+ const items = [];
5570
+ let i, ilen, tick, label, x, y, textAlign, pixel, font, lineHeight, lineCount, textOffset;
5571
+ let textBaseline = 'middle';
5572
+ if (position === 'top') {
5573
+ y = this.bottom - hTickAndPadding;
5574
+ textAlign = this._getXAxisLabelAlignment();
5575
+ } else if (position === 'bottom') {
5576
+ y = this.top + hTickAndPadding;
5577
+ textAlign = this._getXAxisLabelAlignment();
5578
+ } else if (position === 'left') {
5579
+ const ret = this._getYAxisLabelAlignment(tl);
5580
+ textAlign = ret.textAlign;
5581
+ x = ret.x;
5582
+ } else if (position === 'right') {
5583
+ const ret = this._getYAxisLabelAlignment(tl);
5584
+ textAlign = ret.textAlign;
5585
+ x = ret.x;
5586
+ } else if (axis === 'x') {
5587
+ if (position === 'center') {
5588
+ y = ((chartArea.top + chartArea.bottom) / 2) + tickAndPadding;
5589
+ } else if (isObject(position)) {
5590
+ const positionAxisID = Object.keys(position)[0];
5591
+ const value = position[positionAxisID];
5592
+ y = this.chart.scales[positionAxisID].getPixelForValue(value) + tickAndPadding;
5593
+ }
5594
+ textAlign = this._getXAxisLabelAlignment();
5595
+ } else if (axis === 'y') {
5596
+ if (position === 'center') {
5597
+ x = ((chartArea.left + chartArea.right) / 2) - tickAndPadding;
5598
+ } else if (isObject(position)) {
5599
+ const positionAxisID = Object.keys(position)[0];
5600
+ const value = position[positionAxisID];
5601
+ x = this.chart.scales[positionAxisID].getPixelForValue(value);
5602
+ }
5603
+ textAlign = this._getYAxisLabelAlignment(tl).textAlign;
5604
+ }
5605
+ if (axis === 'y') {
5606
+ if (align === 'start') {
5607
+ textBaseline = 'top';
5608
+ } else if (align === 'end') {
5609
+ textBaseline = 'bottom';
5610
+ }
5611
+ }
5612
+ const labelSizes = this._getLabelSizes();
5613
+ for (i = 0, ilen = ticks.length; i < ilen; ++i) {
5614
+ tick = ticks[i];
5615
+ label = tick.label;
5616
+ const optsAtIndex = optionTicks.setContext(this.getContext(i));
5617
+ pixel = this.getPixelForTick(i) + optionTicks.labelOffset;
5618
+ font = this._resolveTickFontOptions(i);
5619
+ lineHeight = font.lineHeight;
5620
+ lineCount = isArray(label) ? label.length : 1;
5621
+ const halfCount = lineCount / 2;
5622
+ const color = optsAtIndex.color;
5623
+ const strokeColor = optsAtIndex.textStrokeColor;
5624
+ const strokeWidth = optsAtIndex.textStrokeWidth;
5625
+ if (isHorizontal) {
5626
+ x = pixel;
5627
+ if (position === 'top') {
5628
+ if (crossAlign === 'near' || rotation !== 0) {
5629
+ textOffset = -lineCount * lineHeight + lineHeight / 2;
5630
+ } else if (crossAlign === 'center') {
5631
+ textOffset = -labelSizes.highest.height / 2 - halfCount * lineHeight + lineHeight;
5632
+ } else {
5633
+ textOffset = -labelSizes.highest.height + lineHeight / 2;
5634
+ }
5635
+ } else {
5636
+ if (crossAlign === 'near' || rotation !== 0) {
5637
+ textOffset = lineHeight / 2;
5638
+ } else if (crossAlign === 'center') {
5639
+ textOffset = labelSizes.highest.height / 2 - halfCount * lineHeight;
5640
+ } else {
5641
+ textOffset = labelSizes.highest.height - lineCount * lineHeight;
5642
+ }
5643
  }
5644
+ if (mirror) {
5645
+ textOffset *= -1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5646
  }
5647
+ } else {
5648
+ y = pixel;
5649
+ textOffset = (1 - lineCount) * lineHeight / 2;
5650
+ }
5651
+ let backdrop;
5652
+ if (optsAtIndex.showLabelBackdrop) {
5653
+ const labelPadding = toPadding(optsAtIndex.backdropPadding);
5654
+ const height = labelSizes.heights[i];
5655
+ const width = labelSizes.widths[i];
5656
+ let top = y + textOffset - labelPadding.top;
5657
+ let left = x - labelPadding.left;
5658
+ switch (textBaseline) {
5659
+ case 'middle':
5660
+ top -= height / 2;
5661
+ break;
5662
+ case 'bottom':
5663
+ top -= height;
5664
+ break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5665
  }
5666
+ switch (textAlign) {
5667
+ case 'center':
5668
+ left -= width / 2;
5669
+ break;
5670
+ case 'right':
5671
+ left -= width;
5672
+ break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5673
  }
5674
+ backdrop = {
5675
+ left,
5676
+ top,
5677
+ width: width + labelPadding.width,
5678
+ height: height + labelPadding.height,
5679
+ color: optsAtIndex.backdropColor,
5680
+ };
5681
+ }
5682
+ items.push({
5683
+ rotation,
5684
+ label,
5685
+ font,
5686
+ color,
5687
+ strokeColor,
5688
+ strokeWidth,
5689
+ textOffset,
5690
+ textAlign,
5691
+ textBaseline,
5692
+ translation: [x, y],
5693
+ backdrop,
5694
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5695
  }
5696
+ return items;
5697
+ }
5698
+ _getXAxisLabelAlignment() {
5699
+ const {position, ticks} = this.options;
5700
+ const rotation = -toRadians(this.labelRotation);
5701
+ if (rotation) {
5702
+ return position === 'top' ? 'left' : 'right';
5703
+ }
5704
+ let align = 'center';
5705
+ if (ticks.align === 'start') {
5706
+ align = 'left';
5707
+ } else if (ticks.align === 'end') {
5708
+ align = 'right';
5709
+ }
5710
+ return align;
5711
+ }
5712
+ _getYAxisLabelAlignment(tl) {
5713
+ const {position, ticks: {crossAlign, mirror, padding}} = this.options;
5714
+ const labelSizes = this._getLabelSizes();
5715
+ const tickAndPadding = tl + padding;
5716
+ const widest = labelSizes.widest.width;
5717
+ let textAlign;
5718
+ let x;
5719
+ if (position === 'left') {
5720
+ if (mirror) {
5721
+ x = this.right + padding;
5722
+ if (crossAlign === 'near') {
5723
+ textAlign = 'left';
5724
+ } else if (crossAlign === 'center') {
5725
+ textAlign = 'center';
5726
+ x += (widest / 2);
5727
+ } else {
5728
+ textAlign = 'right';
5729
+ x += widest;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5730
  }
5731
+ } else {
5732
+ x = this.right - tickAndPadding;
5733
+ if (crossAlign === 'near') {
5734
+ textAlign = 'right';
5735
+ } else if (crossAlign === 'center') {
5736
+ textAlign = 'center';
5737
+ x -= (widest / 2);
5738
+ } else {
5739
+ textAlign = 'left';
5740
+ x = this.left;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5741
  }
5742
+ }
5743
+ } else if (position === 'right') {
5744
+ if (mirror) {
5745
+ x = this.left + padding;
5746
+ if (crossAlign === 'near') {
5747
+ textAlign = 'right';
5748
+ } else if (crossAlign === 'center') {
5749
+ textAlign = 'center';
5750
+ x -= (widest / 2);
5751
+ } else {
5752
+ textAlign = 'left';
5753
+ x -= widest;
5754
  }
5755
+ } else {
5756
+ x = this.left + tickAndPadding;
5757
+ if (crossAlign === 'near') {
5758
+ textAlign = 'left';
5759
+ } else if (crossAlign === 'center') {
5760
+ textAlign = 'center';
5761
+ x += widest / 2;
5762
+ } else {
5763
+ textAlign = 'right';
5764
+ x = this.right;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5765
  }
5766
+ }
5767
+ } else {
5768
+ textAlign = 'right';
5769
+ }
5770
+ return {textAlign, x};
5771
+ }
5772
+ _computeLabelArea() {
5773
+ if (this.options.ticks.mirror) {
5774
+ return;
5775
+ }
5776
+ const chart = this.chart;
5777
+ const position = this.options.position;
5778
+ if (position === 'left' || position === 'right') {
5779
+ return {top: 0, left: this.left, bottom: chart.height, right: this.right};
5780
+ } if (position === 'top' || position === 'bottom') {
5781
+ return {top: this.top, left: 0, bottom: this.bottom, right: chart.width};
5782
+ }
5783
+ }
5784
+ drawBackground() {
5785
+ const {ctx, options: {backgroundColor}, left, top, width, height} = this;
5786
+ if (backgroundColor) {
5787
+ ctx.save();
5788
+ ctx.fillStyle = backgroundColor;
5789
+ ctx.fillRect(left, top, width, height);
5790
+ ctx.restore();
5791
+ }
5792
+ }
5793
+ getLineWidthForValue(value) {
5794
+ const grid = this.options.grid;
5795
+ if (!this._isVisible() || !grid.display) {
5796
+ return 0;
5797
+ }
5798
+ const ticks = this.ticks;
5799
+ const index = ticks.findIndex(t => t.value === value);
5800
+ if (index >= 0) {
5801
+ const opts = grid.setContext(this.getContext(index));
5802
+ return opts.lineWidth;
5803
+ }
5804
+ return 0;
5805
+ }
5806
+ drawGrid(chartArea) {
5807
+ const grid = this.options.grid;
5808
+ const ctx = this.ctx;
5809
+ const items = this._gridLineItems || (this._gridLineItems = this._computeGridLineItems(chartArea));
5810
+ let i, ilen;
5811
+ const drawLine = (p1, p2, style) => {
5812
+ if (!style.width || !style.color) {
5813
+ return;
5814
+ }
5815
+ ctx.save();
5816
+ ctx.lineWidth = style.width;
5817
+ ctx.strokeStyle = style.color;
5818
+ ctx.setLineDash(style.borderDash || []);
5819
+ ctx.lineDashOffset = style.borderDashOffset;
5820
+ ctx.beginPath();
5821
+ ctx.moveTo(p1.x, p1.y);
5822
+ ctx.lineTo(p2.x, p2.y);
5823
+ ctx.stroke();
5824
+ ctx.restore();
5825
+ };
5826
+ if (grid.display) {
5827
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
5828
+ const item = items[i];
5829
+ if (grid.drawOnChartArea) {
5830
+ drawLine(
5831
+ {x: item.x1, y: item.y1},
5832
+ {x: item.x2, y: item.y2},
5833
+ item
5834
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5835
  }
5836
+ if (grid.drawTicks) {
5837
+ drawLine(
5838
+ {x: item.tx1, y: item.ty1},
5839
+ {x: item.tx2, y: item.ty2},
5840
+ {
5841
+ color: item.tickColor,
5842
+ width: item.tickWidth,
5843
+ borderDash: item.tickBorderDash,
5844
+ borderDashOffset: item.tickBorderDashOffset
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5845
  }
5846
+ );
5847
+ }
5848
+ }
5849
+ }
5850
+ }
5851
+ drawBorder() {
5852
+ const {chart, ctx, options: {grid}} = this;
5853
+ const borderOpts = grid.setContext(this.getContext());
5854
+ const axisWidth = grid.drawBorder ? borderOpts.borderWidth : 0;
5855
+ if (!axisWidth) {
5856
+ return;
5857
+ }
5858
+ const lastLineWidth = grid.setContext(this.getContext(0)).lineWidth;
5859
+ const borderValue = this._borderValue;
5860
+ let x1, x2, y1, y2;
5861
+ if (this.isHorizontal()) {
5862
+ x1 = _alignPixel(chart, this.left, axisWidth) - axisWidth / 2;
5863
+ x2 = _alignPixel(chart, this.right, lastLineWidth) + lastLineWidth / 2;
5864
+ y1 = y2 = borderValue;
5865
+ } else {
5866
+ y1 = _alignPixel(chart, this.top, axisWidth) - axisWidth / 2;
5867
+ y2 = _alignPixel(chart, this.bottom, lastLineWidth) + lastLineWidth / 2;
5868
+ x1 = x2 = borderValue;
5869
+ }
5870
+ ctx.save();
5871
+ ctx.lineWidth = borderOpts.borderWidth;
5872
+ ctx.strokeStyle = borderOpts.borderColor;
5873
+ ctx.beginPath();
5874
+ ctx.moveTo(x1, y1);
5875
+ ctx.lineTo(x2, y2);
5876
+ ctx.stroke();
5877
+ ctx.restore();
5878
+ }
5879
+ drawLabels(chartArea) {
5880
+ const optionTicks = this.options.ticks;
5881
+ if (!optionTicks.display) {
5882
+ return;
5883
+ }
5884
+ const ctx = this.ctx;
5885
+ const area = this._computeLabelArea();
5886
+ if (area) {
5887
+ clipArea(ctx, area);
5888
+ }
5889
+ const items = this._labelItems || (this._labelItems = this._computeLabelItems(chartArea));
5890
+ let i, ilen;
5891
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
5892
+ const item = items[i];
5893
+ const tickFont = item.font;
5894
+ const label = item.label;
5895
+ if (item.backdrop) {
5896
+ ctx.fillStyle = item.backdrop.color;
5897
+ ctx.fillRect(item.backdrop.left, item.backdrop.top, item.backdrop.width, item.backdrop.height);
5898
+ }
5899
+ let y = item.textOffset;
5900
+ renderText(ctx, label, 0, y, tickFont, item);
5901
+ }
5902
+ if (area) {
5903
+ unclipArea(ctx);
5904
+ }
5905
+ }
5906
+ drawTitle() {
5907
+ const {ctx, options: {position, title, reverse}} = this;
5908
+ if (!title.display) {
5909
+ return;
5910
+ }
5911
+ const font = toFont(title.font);
5912
+ const padding = toPadding(title.padding);
5913
+ const align = title.align;
5914
+ let offset = font.lineHeight / 2;
5915
+ if (position === 'bottom' || position === 'center' || isObject(position)) {
5916
+ offset += padding.bottom;
5917
+ if (isArray(title.text)) {
5918
+ offset += font.lineHeight * (title.text.length - 1);
5919
+ }
5920
+ } else {
5921
+ offset += padding.top;
5922
+ }
5923
+ const {titleX, titleY, maxWidth, rotation} = titleArgs(this, offset, position, align);
5924
+ renderText(ctx, title.text, 0, 0, font, {
5925
+ color: title.color,
5926
+ maxWidth,
5927
+ rotation,
5928
+ textAlign: titleAlign(align, position, reverse),
5929
+ textBaseline: 'middle',
5930
+ translation: [titleX, titleY],
5931
+ });
5932
+ }
5933
+ draw(chartArea) {
5934
+ if (!this._isVisible()) {
5935
+ return;
5936
+ }
5937
+ this.drawBackground();
5938
+ this.drawGrid(chartArea);
5939
+ this.drawBorder();
5940
+ this.drawTitle();
5941
+ this.drawLabels(chartArea);
5942
+ }
5943
+ _layers() {
5944
+ const opts = this.options;
5945
+ const tz = opts.ticks && opts.ticks.z || 0;
5946
+ const gz = valueOrDefault(opts.grid && opts.grid.z, -1);
5947
+ if (!this._isVisible() || this.draw !== Scale.prototype.draw) {
5948
+ return [{
5949
+ z: tz,
5950
+ draw: (chartArea) => {
5951
+ this.draw(chartArea);
5952
  }
5953
+ }];
5954
+ }
5955
+ return [{
5956
+ z: gz,
5957
+ draw: (chartArea) => {
5958
+ this.drawBackground();
5959
+ this.drawGrid(chartArea);
5960
+ this.drawTitle();
5961
+ }
5962
+ }, {
5963
+ z: gz + 1,
5964
+ draw: () => {
5965
+ this.drawBorder();
5966
+ }
5967
+ }, {
5968
+ z: tz,
5969
+ draw: (chartArea) => {
5970
+ this.drawLabels(chartArea);
5971
+ }
5972
+ }];
5973
+ }
5974
+ getMatchingVisibleMetas(type) {
5975
+ const metas = this.chart.getSortedVisibleDatasetMetas();
5976
+ const axisID = this.axis + 'AxisID';
5977
+ const result = [];
5978
+ let i, ilen;
5979
+ for (i = 0, ilen = metas.length; i < ilen; ++i) {
5980
+ const meta = metas[i];
5981
+ if (meta[axisID] === this.id && (!type || meta.type === type)) {
5982
+ result.push(meta);
5983
+ }
5984
+ }
5985
+ return result;
5986
+ }
5987
+ _resolveTickFontOptions(index) {
5988
+ const opts = this.options.ticks.setContext(this.getContext(index));
5989
+ return toFont(opts.font);
5990
+ }
5991
+ _maxDigits() {
5992
+ const fontSize = this._resolveTickFontOptions(0).lineHeight;
5993
+ return (this.isHorizontal() ? this.width : this.height) / fontSize;
5994
+ }
5995
+ }
5996
+
5997
+ class TypedRegistry {
5998
+ constructor(type, scope, override) {
5999
+ this.type = type;
6000
+ this.scope = scope;
6001
+ this.override = override;
6002
+ this.items = Object.create(null);
6003
+ }
6004
+ isForType(type) {
6005
+ return Object.prototype.isPrototypeOf.call(this.type.prototype, type.prototype);
6006
+ }
6007
+ register(item) {
6008
+ const proto = Object.getPrototypeOf(item);
6009
+ let parentScope;
6010
+ if (isIChartComponent(proto)) {
6011
+ parentScope = this.register(proto);
6012
+ }
6013
+ const items = this.items;
6014
+ const id = item.id;
6015
+ const scope = this.scope + '.' + id;
6016
+ if (!id) {
6017
+ throw new Error('class does not have id: ' + item);
6018
+ }
6019
+ if (id in items) {
6020
+ return scope;
6021
+ }
6022
+ items[id] = item;
6023
+ registerDefaults(item, scope, parentScope);
6024
+ if (this.override) {
6025
+ defaults.override(item.id, item.overrides);
6026
+ }
6027
+ return scope;
6028
+ }
6029
+ get(id) {
6030
+ return this.items[id];
6031
+ }
6032
+ unregister(item) {
6033
+ const items = this.items;
6034
+ const id = item.id;
6035
+ const scope = this.scope;
6036
+ if (id in items) {
6037
+ delete items[id];
6038
+ }
6039
+ if (scope && id in defaults[scope]) {
6040
+ delete defaults[scope][id];
6041
+ if (this.override) {
6042
+ delete overrides[id];
6043
+ }
6044
+ }
6045
+ }
6046
+ }
6047
+ function registerDefaults(item, scope, parentScope) {
6048
+ const itemDefaults = merge(Object.create(null), [
6049
+ parentScope ? defaults.get(parentScope) : {},
6050
+ defaults.get(scope),
6051
+ item.defaults
6052
+ ]);
6053
+ defaults.set(scope, itemDefaults);
6054
+ if (item.defaultRoutes) {
6055
+ routeDefaults(scope, item.defaultRoutes);
6056
+ }
6057
+ if (item.descriptors) {
6058
+ defaults.describe(scope, item.descriptors);
6059
+ }
6060
+ }
6061
+ function routeDefaults(scope, routes) {
6062
+ Object.keys(routes).forEach(property => {
6063
+ const propertyParts = property.split('.');
6064
+ const sourceName = propertyParts.pop();
6065
+ const sourceScope = [scope].concat(propertyParts).join('.');
6066
+ const parts = routes[property].split('.');
6067
+ const targetName = parts.pop();
6068
+ const targetScope = parts.join('.');
6069
+ defaults.route(sourceScope, sourceName, targetScope, targetName);
6070
+ });
6071
+ }
6072
+ function isIChartComponent(proto) {
6073
+ return 'id' in proto && 'defaults' in proto;
6074
+ }
6075
+
6076
+ class Registry {
6077
+ constructor() {
6078
+ this.controllers = new TypedRegistry(DatasetController, 'datasets', true);
6079
+ this.elements = new TypedRegistry(Element, 'elements');
6080
+ this.plugins = new TypedRegistry(Object, 'plugins');
6081
+ this.scales = new TypedRegistry(Scale, 'scales');
6082
+ this._typedRegistries = [this.controllers, this.scales, this.elements];
6083
+ }
6084
+ add(...args) {
6085
+ this._each('register', args);
6086
+ }
6087
+ remove(...args) {
6088
+ this._each('unregister', args);
6089
+ }
6090
+ addControllers(...args) {
6091
+ this._each('register', args, this.controllers);
6092
+ }
6093
+ addElements(...args) {
6094
+ this._each('register', args, this.elements);
6095
+ }
6096
+ addPlugins(...args) {
6097
+ this._each('register', args, this.plugins);
6098
+ }
6099
+ addScales(...args) {
6100
+ this._each('register', args, this.scales);
6101
+ }
6102
+ getController(id) {
6103
+ return this._get(id, this.controllers, 'controller');
6104
+ }
6105
+ getElement(id) {
6106
+ return this._get(id, this.elements, 'element');
6107
+ }
6108
+ getPlugin(id) {
6109
+ return this._get(id, this.plugins, 'plugin');
6110
+ }
6111
+ getScale(id) {
6112
+ return this._get(id, this.scales, 'scale');
6113
+ }
6114
+ removeControllers(...args) {
6115
+ this._each('unregister', args, this.controllers);
6116
+ }
6117
+ removeElements(...args) {
6118
+ this._each('unregister', args, this.elements);
6119
+ }
6120
+ removePlugins(...args) {
6121
+ this._each('unregister', args, this.plugins);
6122
+ }
6123
+ removeScales(...args) {
6124
+ this._each('unregister', args, this.scales);
6125
+ }
6126
+ _each(method, args, typedRegistry) {
6127
+ [...args].forEach(arg => {
6128
+ const reg = typedRegistry || this._getRegistryForType(arg);
6129
+ if (typedRegistry || reg.isForType(arg) || (reg === this.plugins && arg.id)) {
6130
+ this._exec(method, reg, arg);
6131
+ } else {
6132
+ each(arg, item => {
6133
+ const itemReg = typedRegistry || this._getRegistryForType(item);
6134
+ this._exec(method, itemReg, item);
6135
+ });
6136
+ }
6137
+ });
6138
+ }
6139
+ _exec(method, registry, component) {
6140
+ const camelMethod = _capitalize(method);
6141
+ callback(component['before' + camelMethod], [], component);
6142
+ registry[method](component);
6143
+ callback(component['after' + camelMethod], [], component);
6144
+ }
6145
+ _getRegistryForType(type) {
6146
+ for (let i = 0; i < this._typedRegistries.length; i++) {
6147
+ const reg = this._typedRegistries[i];
6148
+ if (reg.isForType(type)) {
6149
+ return reg;
6150
+ }
6151
+ }
6152
+ return this.plugins;
6153
+ }
6154
+ _get(id, typedRegistry, type) {
6155
+ const item = typedRegistry.get(id);
6156
+ if (item === undefined) {
6157
+ throw new Error('"' + id + '" is not a registered ' + type + '.');
6158
+ }
6159
+ return item;
6160
+ }
6161
+ }
6162
+ var registry = new Registry();
6163
+
6164
+ class PluginService {
6165
+ constructor() {
6166
+ this._init = [];
6167
+ }
6168
+ notify(chart, hook, args, filter) {
6169
+ if (hook === 'beforeInit') {
6170
+ this._init = this._createDescriptors(chart, true);
6171
+ this._notify(this._init, chart, 'install');
6172
+ }
6173
+ const descriptors = filter ? this._descriptors(chart).filter(filter) : this._descriptors(chart);
6174
+ const result = this._notify(descriptors, chart, hook, args);
6175
+ if (hook === 'afterDestroy') {
6176
+ this._notify(descriptors, chart, 'stop');
6177
+ this._notify(this._init, chart, 'uninstall');
6178
+ }
6179
+ return result;
6180
+ }
6181
+ _notify(descriptors, chart, hook, args) {
6182
+ args = args || {};
6183
+ for (const descriptor of descriptors) {
6184
+ const plugin = descriptor.plugin;
6185
+ const method = plugin[hook];
6186
+ const params = [chart, args, descriptor.options];
6187
+ if (callback(method, params, plugin) === false && args.cancelable) {
6188
+ return false;
6189
+ }
6190
+ }
6191
+ return true;
6192
+ }
6193
+ invalidate() {
6194
+ if (!isNullOrUndef(this._cache)) {
6195
+ this._oldCache = this._cache;
6196
+ this._cache = undefined;
6197
+ }
6198
+ }
6199
+ _descriptors(chart) {
6200
+ if (this._cache) {
6201
+ return this._cache;
6202
+ }
6203
+ const descriptors = this._cache = this._createDescriptors(chart);
6204
+ this._notifyStateChanges(chart);
6205
+ return descriptors;
6206
+ }
6207
+ _createDescriptors(chart, all) {
6208
+ const config = chart && chart.config;
6209
+ const options = valueOrDefault(config.options && config.options.plugins, {});
6210
+ const plugins = allPlugins(config);
6211
+ return options === false && !all ? [] : createDescriptors(chart, plugins, options, all);
6212
+ }
6213
+ _notifyStateChanges(chart) {
6214
+ const previousDescriptors = this._oldCache || [];
6215
+ const descriptors = this._cache;
6216
+ const diff = (a, b) => a.filter(x => !b.some(y => x.plugin.id === y.plugin.id));
6217
+ this._notify(diff(previousDescriptors, descriptors), chart, 'stop');
6218
+ this._notify(diff(descriptors, previousDescriptors), chart, 'start');
6219
+ }
6220
+ }
6221
+ function allPlugins(config) {
6222
+ const plugins = [];
6223
+ const keys = Object.keys(registry.plugins.items);
6224
+ for (let i = 0; i < keys.length; i++) {
6225
+ plugins.push(registry.getPlugin(keys[i]));
6226
+ }
6227
+ const local = config.plugins || [];
6228
+ for (let i = 0; i < local.length; i++) {
6229
+ const plugin = local[i];
6230
+ if (plugins.indexOf(plugin) === -1) {
6231
+ plugins.push(plugin);
6232
+ }
6233
+ }
6234
+ return plugins;
6235
+ }
6236
+ function getOpts(options, all) {
6237
+ if (!all && options === false) {
6238
+ return null;
6239
+ }
6240
+ if (options === true) {
6241
+ return {};
6242
+ }
6243
+ return options;
6244
+ }
6245
+ function createDescriptors(chart, plugins, options, all) {
6246
+ const result = [];
6247
+ const context = chart.getContext();
6248
+ for (let i = 0; i < plugins.length; i++) {
6249
+ const plugin = plugins[i];
6250
+ const id = plugin.id;
6251
+ const opts = getOpts(options[id], all);
6252
+ if (opts === null) {
6253
+ continue;
6254
+ }
6255
+ result.push({
6256
+ plugin,
6257
+ options: pluginOpts(chart.config, plugin, opts, context)
6258
+ });
6259
+ }
6260
+ return result;
6261
+ }
6262
+ function pluginOpts(config, plugin, opts, context) {
6263
+ const keys = config.pluginScopeKeys(plugin);
6264
+ const scopes = config.getOptionScopes(opts, keys);
6265
+ return config.createResolver(scopes, context, [''], {scriptable: false, indexable: false, allKeys: true});
6266
+ }
6267
+
6268
+ function getIndexAxis(type, options) {
6269
+ const datasetDefaults = defaults.datasets[type] || {};
6270
+ const datasetOptions = (options.datasets || {})[type] || {};
6271
+ return datasetOptions.indexAxis || options.indexAxis || datasetDefaults.indexAxis || 'x';
6272
+ }
6273
+ function getAxisFromDefaultScaleID(id, indexAxis) {
6274
+ let axis = id;
6275
+ if (id === '_index_') {
6276
+ axis = indexAxis;
6277
+ } else if (id === '_value_') {
6278
+ axis = indexAxis === 'x' ? 'y' : 'x';
6279
+ }
6280
+ return axis;
6281
+ }
6282
+ function getDefaultScaleIDFromAxis(axis, indexAxis) {
6283
+ return axis === indexAxis ? '_index_' : '_value_';
6284
+ }
6285
+ function axisFromPosition(position) {
6286
+ if (position === 'top' || position === 'bottom') {
6287
+ return 'x';
6288
+ }
6289
+ if (position === 'left' || position === 'right') {
6290
+ return 'y';
6291
+ }
6292
+ }
6293
+ function determineAxis(id, scaleOptions) {
6294
+ if (id === 'x' || id === 'y') {
6295
+ return id;
6296
+ }
6297
+ return scaleOptions.axis || axisFromPosition(scaleOptions.position) || id.charAt(0).toLowerCase();
6298
+ }
6299
+ function mergeScaleConfig(config, options) {
6300
+ const chartDefaults = overrides[config.type] || {scales: {}};
6301
+ const configScales = options.scales || {};
6302
+ const chartIndexAxis = getIndexAxis(config.type, options);
6303
+ const firstIDs = Object.create(null);
6304
+ const scales = Object.create(null);
6305
+ Object.keys(configScales).forEach(id => {
6306
+ const scaleConf = configScales[id];
6307
+ if (!isObject(scaleConf)) {
6308
+ return console.error(`Invalid scale configuration for scale: ${id}`);
6309
+ }
6310
+ if (scaleConf._proxy) {
6311
+ return console.warn(`Ignoring resolver passed as options for scale: ${id}`);
6312
+ }
6313
+ const axis = determineAxis(id, scaleConf);
6314
+ const defaultId = getDefaultScaleIDFromAxis(axis, chartIndexAxis);
6315
+ const defaultScaleOptions = chartDefaults.scales || {};
6316
+ firstIDs[axis] = firstIDs[axis] || id;
6317
+ scales[id] = mergeIf(Object.create(null), [{axis}, scaleConf, defaultScaleOptions[axis], defaultScaleOptions[defaultId]]);
6318
+ });
6319
+ config.data.datasets.forEach(dataset => {
6320
+ const type = dataset.type || config.type;
6321
+ const indexAxis = dataset.indexAxis || getIndexAxis(type, options);
6322
+ const datasetDefaults = overrides[type] || {};
6323
+ const defaultScaleOptions = datasetDefaults.scales || {};
6324
+ Object.keys(defaultScaleOptions).forEach(defaultID => {
6325
+ const axis = getAxisFromDefaultScaleID(defaultID, indexAxis);
6326
+ const id = dataset[axis + 'AxisID'] || firstIDs[axis] || axis;
6327
+ scales[id] = scales[id] || Object.create(null);
6328
+ mergeIf(scales[id], [{axis}, configScales[id], defaultScaleOptions[defaultID]]);
6329
+ });
6330
+ });
6331
+ Object.keys(scales).forEach(key => {
6332
+ const scale = scales[key];
6333
+ mergeIf(scale, [defaults.scales[scale.type], defaults.scale]);
6334
+ });
6335
+ return scales;
6336
+ }
6337
+ function initOptions(config) {
6338
+ const options = config.options || (config.options = {});
6339
+ options.plugins = valueOrDefault(options.plugins, {});
6340
+ options.scales = mergeScaleConfig(config, options);
6341
+ }
6342
+ function initData(data) {
6343
+ data = data || {};
6344
+ data.datasets = data.datasets || [];
6345
+ data.labels = data.labels || [];
6346
+ return data;
6347
+ }
6348
+ function initConfig(config) {
6349
+ config = config || {};
6350
+ config.data = initData(config.data);
6351
+ initOptions(config);
6352
+ return config;
6353
+ }
6354
+ const keyCache = new Map();
6355
+ const keysCached = new Set();
6356
+ function cachedKeys(cacheKey, generate) {
6357
+ let keys = keyCache.get(cacheKey);
6358
+ if (!keys) {
6359
+ keys = generate();
6360
+ keyCache.set(cacheKey, keys);
6361
+ keysCached.add(keys);
6362
+ }
6363
+ return keys;
6364
+ }
6365
+ const addIfFound = (set, obj, key) => {
6366
+ const opts = resolveObjectKey(obj, key);
6367
+ if (opts !== undefined) {
6368
+ set.add(opts);
6369
+ }
6370
+ };
6371
+ class Config {
6372
+ constructor(config) {
6373
+ this._config = initConfig(config);
6374
+ this._scopeCache = new Map();
6375
+ this._resolverCache = new Map();
6376
+ }
6377
+ get platform() {
6378
+ return this._config.platform;
6379
+ }
6380
+ get type() {
6381
+ return this._config.type;
6382
+ }
6383
+ set type(type) {
6384
+ this._config.type = type;
6385
+ }
6386
+ get data() {
6387
+ return this._config.data;
6388
+ }
6389
+ set data(data) {
6390
+ this._config.data = initData(data);
6391
+ }
6392
+ get options() {
6393
+ return this._config.options;
6394
+ }
6395
+ set options(options) {
6396
+ this._config.options = options;
6397
+ }
6398
+ get plugins() {
6399
+ return this._config.plugins;
6400
+ }
6401
+ update() {
6402
+ const config = this._config;
6403
+ this.clearCache();
6404
+ initOptions(config);
6405
+ }
6406
+ clearCache() {
6407
+ this._scopeCache.clear();
6408
+ this._resolverCache.clear();
6409
+ }
6410
+ datasetScopeKeys(datasetType) {
6411
+ return cachedKeys(datasetType,
6412
+ () => [[
6413
+ `datasets.${datasetType}`,
6414
+ ''
6415
+ ]]);
6416
+ }
6417
+ datasetAnimationScopeKeys(datasetType, transition) {
6418
+ return cachedKeys(`${datasetType}.transition.${transition}`,
6419
+ () => [
6420
+ [
6421
+ `datasets.${datasetType}.transitions.${transition}`,
6422
+ `transitions.${transition}`,
6423
+ ],
6424
+ [
6425
+ `datasets.${datasetType}`,
6426
+ ''
6427
+ ]
6428
+ ]);
6429
+ }
6430
+ datasetElementScopeKeys(datasetType, elementType) {
6431
+ return cachedKeys(`${datasetType}-${elementType}`,
6432
+ () => [[
6433
+ `datasets.${datasetType}.elements.${elementType}`,
6434
+ `datasets.${datasetType}`,
6435
+ `elements.${elementType}`,
6436
+ ''
6437
+ ]]);
6438
+ }
6439
+ pluginScopeKeys(plugin) {
6440
+ const id = plugin.id;
6441
+ const type = this.type;
6442
+ return cachedKeys(`${type}-plugin-${id}`,
6443
+ () => [[
6444
+ `plugins.${id}`,
6445
+ ...plugin.additionalOptionScopes || [],
6446
+ ]]);
6447
+ }
6448
+ _cachedScopes(mainScope, resetCache) {
6449
+ const _scopeCache = this._scopeCache;
6450
+ let cache = _scopeCache.get(mainScope);
6451
+ if (!cache || resetCache) {
6452
+ cache = new Map();
6453
+ _scopeCache.set(mainScope, cache);
6454
+ }
6455
+ return cache;
6456
+ }
6457
+ getOptionScopes(mainScope, keyLists, resetCache) {
6458
+ const {options, type} = this;
6459
+ const cache = this._cachedScopes(mainScope, resetCache);
6460
+ const cached = cache.get(keyLists);
6461
+ if (cached) {
6462
+ return cached;
6463
+ }
6464
+ const scopes = new Set();
6465
+ keyLists.forEach(keys => {
6466
+ if (mainScope) {
6467
+ scopes.add(mainScope);
6468
+ keys.forEach(key => addIfFound(scopes, mainScope, key));
6469
+ }
6470
+ keys.forEach(key => addIfFound(scopes, options, key));
6471
+ keys.forEach(key => addIfFound(scopes, overrides[type] || {}, key));
6472
+ keys.forEach(key => addIfFound(scopes, defaults, key));
6473
+ keys.forEach(key => addIfFound(scopes, descriptors, key));
6474
+ });
6475
+ const array = Array.from(scopes);
6476
+ if (array.length === 0) {
6477
+ array.push(Object.create(null));
6478
+ }
6479
+ if (keysCached.has(keyLists)) {
6480
+ cache.set(keyLists, array);
6481
+ }
6482
+ return array;
6483
+ }
6484
+ chartOptionScopes() {
6485
+ const {options, type} = this;
6486
+ return [
6487
+ options,
6488
+ overrides[type] || {},
6489
+ defaults.datasets[type] || {},
6490
+ {type},
6491
+ defaults,
6492
+ descriptors
6493
+ ];
6494
+ }
6495
+ resolveNamedOptions(scopes, names, context, prefixes = ['']) {
6496
+ const result = {$shared: true};
6497
+ const {resolver, subPrefixes} = getResolver(this._resolverCache, scopes, prefixes);
6498
+ let options = resolver;
6499
+ if (needContext(resolver, names)) {
6500
+ result.$shared = false;
6501
+ context = isFunction(context) ? context() : context;
6502
+ const subResolver = this.createResolver(scopes, context, subPrefixes);
6503
+ options = _attachContext(resolver, context, subResolver);
6504
+ }
6505
+ for (const prop of names) {
6506
+ result[prop] = options[prop];
6507
+ }
6508
+ return result;
6509
+ }
6510
+ createResolver(scopes, context, prefixes = [''], descriptorDefaults) {
6511
+ const {resolver} = getResolver(this._resolverCache, scopes, prefixes);
6512
+ return isObject(context)
6513
+ ? _attachContext(resolver, context, undefined, descriptorDefaults)
6514
+ : resolver;
6515
+ }
6516
+ }
6517
+ function getResolver(resolverCache, scopes, prefixes) {
6518
+ let cache = resolverCache.get(scopes);
6519
+ if (!cache) {
6520
+ cache = new Map();
6521
+ resolverCache.set(scopes, cache);
6522
+ }
6523
+ const cacheKey = prefixes.join();
6524
+ let cached = cache.get(cacheKey);
6525
+ if (!cached) {
6526
+ const resolver = _createResolver(scopes, prefixes);
6527
+ cached = {
6528
+ resolver,
6529
+ subPrefixes: prefixes.filter(p => !p.toLowerCase().includes('hover'))
6530
+ };
6531
+ cache.set(cacheKey, cached);
6532
+ }
6533
+ return cached;
6534
+ }
6535
+ const hasFunction = value => isObject(value)
6536
+ && Object.getOwnPropertyNames(value).reduce((acc, key) => acc || isFunction(value[key]), false);
6537
+ function needContext(proxy, names) {
6538
+ const {isScriptable, isIndexable} = _descriptors(proxy);
6539
+ for (const prop of names) {
6540
+ const scriptable = isScriptable(prop);
6541
+ const indexable = isIndexable(prop);
6542
+ const value = (indexable || scriptable) && proxy[prop];
6543
+ if ((scriptable && (isFunction(value) || hasFunction(value)))
6544
+ || (indexable && isArray(value))) {
6545
+ return true;
6546
+ }
6547
+ }
6548
+ return false;
6549
+ }
6550
+
6551
+ var version = "3.7.1";
6552
+
6553
+ const KNOWN_POSITIONS = ['top', 'bottom', 'left', 'right', 'chartArea'];
6554
+ function positionIsHorizontal(position, axis) {
6555
+ return position === 'top' || position === 'bottom' || (KNOWN_POSITIONS.indexOf(position) === -1 && axis === 'x');
6556
+ }
6557
+ function compare2Level(l1, l2) {
6558
+ return function(a, b) {
6559
+ return a[l1] === b[l1]
6560
+ ? a[l2] - b[l2]
6561
+ : a[l1] - b[l1];
6562
+ };
6563
+ }
6564
+ function onAnimationsComplete(context) {
6565
+ const chart = context.chart;
6566
+ const animationOptions = chart.options.animation;
6567
+ chart.notifyPlugins('afterRender');
6568
+ callback(animationOptions && animationOptions.onComplete, [context], chart);
6569
+ }
6570
+ function onAnimationProgress(context) {
6571
+ const chart = context.chart;
6572
+ const animationOptions = chart.options.animation;
6573
+ callback(animationOptions && animationOptions.onProgress, [context], chart);
6574
+ }
6575
+ function getCanvas(item) {
6576
+ if (_isDomSupported() && typeof item === 'string') {
6577
+ item = document.getElementById(item);
6578
+ } else if (item && item.length) {
6579
+ item = item[0];
6580
+ }
6581
+ if (item && item.canvas) {
6582
+ item = item.canvas;
6583
+ }
6584
+ return item;
6585
+ }
6586
+ const instances = {};
6587
+ const getChart = (key) => {
6588
+ const canvas = getCanvas(key);
6589
+ return Object.values(instances).filter((c) => c.canvas === canvas).pop();
6590
+ };
6591
+ function moveNumericKeys(obj, start, move) {
6592
+ const keys = Object.keys(obj);
6593
+ for (const key of keys) {
6594
+ const intKey = +key;
6595
+ if (intKey >= start) {
6596
+ const value = obj[key];
6597
+ delete obj[key];
6598
+ if (move > 0 || intKey > start) {
6599
+ obj[intKey + move] = value;
6600
+ }
6601
+ }
6602
+ }
6603
+ }
6604
+ function determineLastEvent(e, lastEvent, inChartArea, isClick) {
6605
+ if (!inChartArea || e.type === 'mouseout') {
6606
+ return null;
6607
+ }
6608
+ if (isClick) {
6609
+ return lastEvent;
6610
+ }
6611
+ return e;
6612
+ }
6613
+ class Chart {
6614
+ constructor(item, userConfig) {
6615
+ const config = this.config = new Config(userConfig);
6616
+ const initialCanvas = getCanvas(item);
6617
+ const existingChart = getChart(initialCanvas);
6618
+ if (existingChart) {
6619
+ throw new Error(
6620
+ 'Canvas is already in use. Chart with ID \'' + existingChart.id + '\'' +
6621
+ ' must be destroyed before the canvas can be reused.'
6622
+ );
6623
+ }
6624
+ const options = config.createResolver(config.chartOptionScopes(), this.getContext());
6625
+ this.platform = new (config.platform || _detectPlatform(initialCanvas))();
6626
+ this.platform.updateConfig(config);
6627
+ const context = this.platform.acquireContext(initialCanvas, options.aspectRatio);
6628
+ const canvas = context && context.canvas;
6629
+ const height = canvas && canvas.height;
6630
+ const width = canvas && canvas.width;
6631
+ this.id = uid();
6632
+ this.ctx = context;
6633
+ this.canvas = canvas;
6634
+ this.width = width;
6635
+ this.height = height;
6636
+ this._options = options;
6637
+ this._aspectRatio = this.aspectRatio;
6638
+ this._layers = [];
6639
+ this._metasets = [];
6640
+ this._stacks = undefined;
6641
+ this.boxes = [];
6642
+ this.currentDevicePixelRatio = undefined;
6643
+ this.chartArea = undefined;
6644
+ this._active = [];
6645
+ this._lastEvent = undefined;
6646
+ this._listeners = {};
6647
+ this._responsiveListeners = undefined;
6648
+ this._sortedMetasets = [];
6649
+ this.scales = {};
6650
+ this._plugins = new PluginService();
6651
+ this.$proxies = {};
6652
+ this._hiddenIndices = {};
6653
+ this.attached = false;
6654
+ this._animationsDisabled = undefined;
6655
+ this.$context = undefined;
6656
+ this._doResize = debounce(mode => this.update(mode), options.resizeDelay || 0);
6657
+ this._dataChanges = [];
6658
+ instances[this.id] = this;
6659
+ if (!context || !canvas) {
6660
+ console.error("Failed to create chart: can't acquire context from the given item");
6661
+ return;
6662
+ }
6663
+ animator.listen(this, 'complete', onAnimationsComplete);
6664
+ animator.listen(this, 'progress', onAnimationProgress);
6665
+ this._initialize();
6666
+ if (this.attached) {
6667
+ this.update();
6668
+ }
6669
+ }
6670
+ get aspectRatio() {
6671
+ const {options: {aspectRatio, maintainAspectRatio}, width, height, _aspectRatio} = this;
6672
+ if (!isNullOrUndef(aspectRatio)) {
6673
+ return aspectRatio;
6674
+ }
6675
+ if (maintainAspectRatio && _aspectRatio) {
6676
+ return _aspectRatio;
6677
+ }
6678
+ return height ? width / height : null;
6679
+ }
6680
+ get data() {
6681
+ return this.config.data;
6682
+ }
6683
+ set data(data) {
6684
+ this.config.data = data;
6685
+ }
6686
+ get options() {
6687
+ return this._options;
6688
+ }
6689
+ set options(options) {
6690
+ this.config.options = options;
6691
+ }
6692
+ _initialize() {
6693
+ this.notifyPlugins('beforeInit');
6694
+ if (this.options.responsive) {
6695
+ this.resize();
6696
+ } else {
6697
+ retinaScale(this, this.options.devicePixelRatio);
6698
+ }
6699
+ this.bindEvents();
6700
+ this.notifyPlugins('afterInit');
6701
+ return this;
6702
+ }
6703
+ clear() {
6704
+ clearCanvas(this.canvas, this.ctx);
6705
+ return this;
6706
+ }
6707
+ stop() {
6708
+ animator.stop(this);
6709
+ return this;
6710
+ }
6711
+ resize(width, height) {
6712
+ if (!animator.running(this)) {
6713
+ this._resize(width, height);
6714
+ } else {
6715
+ this._resizeBeforeDraw = {width, height};
6716
+ }
6717
+ }
6718
+ _resize(width, height) {
6719
+ const options = this.options;
6720
+ const canvas = this.canvas;
6721
+ const aspectRatio = options.maintainAspectRatio && this.aspectRatio;
6722
+ const newSize = this.platform.getMaximumSize(canvas, width, height, aspectRatio);
6723
+ const newRatio = options.devicePixelRatio || this.platform.getDevicePixelRatio();
6724
+ const mode = this.width ? 'resize' : 'attach';
6725
+ this.width = newSize.width;
6726
+ this.height = newSize.height;
6727
+ this._aspectRatio = this.aspectRatio;
6728
+ if (!retinaScale(this, newRatio, true)) {
6729
+ return;
6730
+ }
6731
+ this.notifyPlugins('resize', {size: newSize});
6732
+ callback(options.onResize, [this, newSize], this);
6733
+ if (this.attached) {
6734
+ if (this._doResize(mode)) {
6735
+ this.render();
6736
+ }
6737
+ }
6738
+ }
6739
+ ensureScalesHaveIDs() {
6740
+ const options = this.options;
6741
+ const scalesOptions = options.scales || {};
6742
+ each(scalesOptions, (axisOptions, axisID) => {
6743
+ axisOptions.id = axisID;
6744
+ });
6745
+ }
6746
+ buildOrUpdateScales() {
6747
+ const options = this.options;
6748
+ const scaleOpts = options.scales;
6749
+ const scales = this.scales;
6750
+ const updated = Object.keys(scales).reduce((obj, id) => {
6751
+ obj[id] = false;
6752
+ return obj;
6753
+ }, {});
6754
+ let items = [];
6755
+ if (scaleOpts) {
6756
+ items = items.concat(
6757
+ Object.keys(scaleOpts).map((id) => {
6758
+ const scaleOptions = scaleOpts[id];
6759
+ const axis = determineAxis(id, scaleOptions);
6760
+ const isRadial = axis === 'r';
6761
+ const isHorizontal = axis === 'x';
6762
+ return {
6763
+ options: scaleOptions,
6764
+ dposition: isRadial ? 'chartArea' : isHorizontal ? 'bottom' : 'left',
6765
+ dtype: isRadial ? 'radialLinear' : isHorizontal ? 'category' : 'linear'
6766
+ };
6767
+ })
6768
+ );
6769
+ }
6770
+ each(items, (item) => {
6771
+ const scaleOptions = item.options;
6772
+ const id = scaleOptions.id;
6773
+ const axis = determineAxis(id, scaleOptions);
6774
+ const scaleType = valueOrDefault(scaleOptions.type, item.dtype);
6775
+ if (scaleOptions.position === undefined || positionIsHorizontal(scaleOptions.position, axis) !== positionIsHorizontal(item.dposition)) {
6776
+ scaleOptions.position = item.dposition;
6777
+ }
6778
+ updated[id] = true;
6779
+ let scale = null;
6780
+ if (id in scales && scales[id].type === scaleType) {
6781
+ scale = scales[id];
6782
+ } else {
6783
+ const scaleClass = registry.getScale(scaleType);
6784
+ scale = new scaleClass({
6785
+ id,
6786
+ type: scaleType,
6787
+ ctx: this.ctx,
6788
+ chart: this
6789
+ });
6790
+ scales[scale.id] = scale;
6791
+ }
6792
+ scale.init(scaleOptions, options);
6793
+ });
6794
+ each(updated, (hasUpdated, id) => {
6795
+ if (!hasUpdated) {
6796
+ delete scales[id];
6797
+ }
6798
+ });
6799
+ each(scales, (scale) => {
6800
+ layouts.configure(this, scale, scale.options);
6801
+ layouts.addBox(this, scale);
6802
+ });
6803
+ }
6804
+ _updateMetasets() {
6805
+ const metasets = this._metasets;
6806
+ const numData = this.data.datasets.length;
6807
+ const numMeta = metasets.length;
6808
+ metasets.sort((a, b) => a.index - b.index);
6809
+ if (numMeta > numData) {
6810
+ for (let i = numData; i < numMeta; ++i) {
6811
+ this._destroyDatasetMeta(i);
6812
+ }
6813
+ metasets.splice(numData, numMeta - numData);
6814
+ }
6815
+ this._sortedMetasets = metasets.slice(0).sort(compare2Level('order', 'index'));
6816
+ }
6817
+ _removeUnreferencedMetasets() {
6818
+ const {_metasets: metasets, data: {datasets}} = this;
6819
+ if (metasets.length > datasets.length) {
6820
+ delete this._stacks;
6821
+ }
6822
+ metasets.forEach((meta, index) => {
6823
+ if (datasets.filter(x => x === meta._dataset).length === 0) {
6824
+ this._destroyDatasetMeta(index);
6825
+ }
6826
+ });
6827
+ }
6828
+ buildOrUpdateControllers() {
6829
+ const newControllers = [];
6830
+ const datasets = this.data.datasets;
6831
+ let i, ilen;
6832
+ this._removeUnreferencedMetasets();
6833
+ for (i = 0, ilen = datasets.length; i < ilen; i++) {
6834
+ const dataset = datasets[i];
6835
+ let meta = this.getDatasetMeta(i);
6836
+ const type = dataset.type || this.config.type;
6837
+ if (meta.type && meta.type !== type) {
6838
+ this._destroyDatasetMeta(i);
6839
+ meta = this.getDatasetMeta(i);
6840
+ }
6841
+ meta.type = type;
6842
+ meta.indexAxis = dataset.indexAxis || getIndexAxis(type, this.options);
6843
+ meta.order = dataset.order || 0;
6844
+ meta.index = i;
6845
+ meta.label = '' + dataset.label;
6846
+ meta.visible = this.isDatasetVisible(i);
6847
+ if (meta.controller) {
6848
+ meta.controller.updateIndex(i);
6849
+ meta.controller.linkScales();
6850
+ } else {
6851
+ const ControllerClass = registry.getController(type);
6852
+ const {datasetElementType, dataElementType} = defaults.datasets[type];
6853
+ Object.assign(ControllerClass.prototype, {
6854
+ dataElementType: registry.getElement(dataElementType),
6855
+ datasetElementType: datasetElementType && registry.getElement(datasetElementType)
6856
+ });
6857
+ meta.controller = new ControllerClass(this, i);
6858
+ newControllers.push(meta.controller);
6859
+ }
6860
+ }
6861
+ this._updateMetasets();
6862
+ return newControllers;
6863
+ }
6864
+ _resetElements() {
6865
+ each(this.data.datasets, (dataset, datasetIndex) => {
6866
+ this.getDatasetMeta(datasetIndex).controller.reset();
6867
+ }, this);
6868
+ }
6869
+ reset() {
6870
+ this._resetElements();
6871
+ this.notifyPlugins('reset');
6872
+ }
6873
+ update(mode) {
6874
+ const config = this.config;
6875
+ config.update();
6876
+ const options = this._options = config.createResolver(config.chartOptionScopes(), this.getContext());
6877
+ const animsDisabled = this._animationsDisabled = !options.animation;
6878
+ this._updateScales();
6879
+ this._checkEventBindings();
6880
+ this._updateHiddenIndices();
6881
+ this._plugins.invalidate();
6882
+ if (this.notifyPlugins('beforeUpdate', {mode, cancelable: true}) === false) {
6883
+ return;
6884
+ }
6885
+ const newControllers = this.buildOrUpdateControllers();
6886
+ this.notifyPlugins('beforeElementsUpdate');
6887
+ let minPadding = 0;
6888
+ for (let i = 0, ilen = this.data.datasets.length; i < ilen; i++) {
6889
+ const {controller} = this.getDatasetMeta(i);
6890
+ const reset = !animsDisabled && newControllers.indexOf(controller) === -1;
6891
+ controller.buildOrUpdateElements(reset);
6892
+ minPadding = Math.max(+controller.getMaxOverflow(), minPadding);
6893
+ }
6894
+ minPadding = this._minPadding = options.layout.autoPadding ? minPadding : 0;
6895
+ this._updateLayout(minPadding);
6896
+ if (!animsDisabled) {
6897
+ each(newControllers, (controller) => {
6898
+ controller.reset();
6899
+ });
6900
+ }
6901
+ this._updateDatasets(mode);
6902
+ this.notifyPlugins('afterUpdate', {mode});
6903
+ this._layers.sort(compare2Level('z', '_idx'));
6904
+ const {_active, _lastEvent} = this;
6905
+ if (_lastEvent) {
6906
+ this._eventHandler(_lastEvent, true);
6907
+ } else if (_active.length) {
6908
+ this._updateHoverStyles(_active, _active, true);
6909
+ }
6910
+ this.render();
6911
+ }
6912
+ _updateScales() {
6913
+ each(this.scales, (scale) => {
6914
+ layouts.removeBox(this, scale);
6915
+ });
6916
+ this.ensureScalesHaveIDs();
6917
+ this.buildOrUpdateScales();
6918
+ }
6919
+ _checkEventBindings() {
6920
+ const options = this.options;
6921
+ const existingEvents = new Set(Object.keys(this._listeners));
6922
+ const newEvents = new Set(options.events);
6923
+ if (!setsEqual(existingEvents, newEvents) || !!this._responsiveListeners !== options.responsive) {
6924
+ this.unbindEvents();
6925
+ this.bindEvents();
6926
+ }
6927
+ }
6928
+ _updateHiddenIndices() {
6929
+ const {_hiddenIndices} = this;
6930
+ const changes = this._getUniformDataChanges() || [];
6931
+ for (const {method, start, count} of changes) {
6932
+ const move = method === '_removeElements' ? -count : count;
6933
+ moveNumericKeys(_hiddenIndices, start, move);
6934
+ }
6935
+ }
6936
+ _getUniformDataChanges() {
6937
+ const _dataChanges = this._dataChanges;
6938
+ if (!_dataChanges || !_dataChanges.length) {
6939
+ return;
6940
+ }
6941
+ this._dataChanges = [];
6942
+ const datasetCount = this.data.datasets.length;
6943
+ const makeSet = (idx) => new Set(
6944
+ _dataChanges
6945
+ .filter(c => c[0] === idx)
6946
+ .map((c, i) => i + ',' + c.splice(1).join(','))
6947
  );
6948
+ const changeSet = makeSet(0);
6949
+ for (let i = 1; i < datasetCount; i++) {
6950
+ if (!setsEqual(changeSet, makeSet(i))) {
6951
+ return;
6952
+ }
6953
+ }
6954
+ return Array.from(changeSet)
6955
+ .map(c => c.split(','))
6956
+ .map(a => ({method: a[1], start: +a[2], count: +a[3]}));
6957
+ }
6958
+ _updateLayout(minPadding) {
6959
+ if (this.notifyPlugins('beforeLayout', {cancelable: true}) === false) {
6960
+ return;
6961
+ }
6962
+ layouts.update(this, this.width, this.height, minPadding);
6963
+ const area = this.chartArea;
6964
+ const noArea = area.width <= 0 || area.height <= 0;
6965
+ this._layers = [];
6966
+ each(this.boxes, (box) => {
6967
+ if (noArea && box.position === 'chartArea') {
6968
+ return;
6969
+ }
6970
+ if (box.configure) {
6971
+ box.configure();
6972
+ }
6973
+ this._layers.push(...box._layers());
6974
+ }, this);
6975
+ this._layers.forEach((item, index) => {
6976
+ item._idx = index;
6977
+ });
6978
+ this.notifyPlugins('afterLayout');
6979
+ }
6980
+ _updateDatasets(mode) {
6981
+ if (this.notifyPlugins('beforeDatasetsUpdate', {mode, cancelable: true}) === false) {
6982
+ return;
6983
+ }
6984
+ for (let i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
6985
+ this.getDatasetMeta(i).controller.configure();
6986
+ }
6987
+ for (let i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
6988
+ this._updateDataset(i, isFunction(mode) ? mode({datasetIndex: i}) : mode);
6989
+ }
6990
+ this.notifyPlugins('afterDatasetsUpdate', {mode});
6991
+ }
6992
+ _updateDataset(index, mode) {
6993
+ const meta = this.getDatasetMeta(index);
6994
+ const args = {meta, index, mode, cancelable: true};
6995
+ if (this.notifyPlugins('beforeDatasetUpdate', args) === false) {
6996
+ return;
6997
+ }
6998
+ meta.controller._update(mode);
6999
+ args.cancelable = false;
7000
+ this.notifyPlugins('afterDatasetUpdate', args);
7001
+ }
7002
+ render() {
7003
+ if (this.notifyPlugins('beforeRender', {cancelable: true}) === false) {
7004
+ return;
7005
+ }
7006
+ if (animator.has(this)) {
7007
+ if (this.attached && !animator.running(this)) {
7008
+ animator.start(this);
7009
+ }
7010
+ } else {
7011
+ this.draw();
7012
+ onAnimationsComplete({chart: this});
7013
+ }
7014
+ }
7015
+ draw() {
7016
+ let i;
7017
+ if (this._resizeBeforeDraw) {
7018
+ const {width, height} = this._resizeBeforeDraw;
7019
+ this._resize(width, height);
7020
+ this._resizeBeforeDraw = null;
7021
+ }
7022
+ this.clear();
7023
+ if (this.width <= 0 || this.height <= 0) {
7024
+ return;
7025
+ }
7026
+ if (this.notifyPlugins('beforeDraw', {cancelable: true}) === false) {
7027
+ return;
7028
+ }
7029
+ const layers = this._layers;
7030
+ for (i = 0; i < layers.length && layers[i].z <= 0; ++i) {
7031
+ layers[i].draw(this.chartArea);
7032
+ }
7033
+ this._drawDatasets();
7034
+ for (; i < layers.length; ++i) {
7035
+ layers[i].draw(this.chartArea);
7036
+ }
7037
+ this.notifyPlugins('afterDraw');
7038
+ }
7039
+ _getSortedDatasetMetas(filterVisible) {
7040
+ const metasets = this._sortedMetasets;
7041
+ const result = [];
7042
+ let i, ilen;
7043
+ for (i = 0, ilen = metasets.length; i < ilen; ++i) {
7044
+ const meta = metasets[i];
7045
+ if (!filterVisible || meta.visible) {
7046
+ result.push(meta);
7047
+ }
7048
+ }
7049
+ return result;
7050
+ }
7051
+ getSortedVisibleDatasetMetas() {
7052
+ return this._getSortedDatasetMetas(true);
7053
+ }
7054
+ _drawDatasets() {
7055
+ if (this.notifyPlugins('beforeDatasetsDraw', {cancelable: true}) === false) {
7056
+ return;
7057
+ }
7058
+ const metasets = this.getSortedVisibleDatasetMetas();
7059
+ for (let i = metasets.length - 1; i >= 0; --i) {
7060
+ this._drawDataset(metasets[i]);
7061
+ }
7062
+ this.notifyPlugins('afterDatasetsDraw');
7063
+ }
7064
+ _drawDataset(meta) {
7065
+ const ctx = this.ctx;
7066
+ const clip = meta._clip;
7067
+ const useClip = !clip.disabled;
7068
+ const area = this.chartArea;
7069
+ const args = {
7070
+ meta,
7071
+ index: meta.index,
7072
+ cancelable: true
7073
+ };
7074
+ if (this.notifyPlugins('beforeDatasetDraw', args) === false) {
7075
+ return;
7076
+ }
7077
+ if (useClip) {
7078
+ clipArea(ctx, {
7079
+ left: clip.left === false ? 0 : area.left - clip.left,
7080
+ right: clip.right === false ? this.width : area.right + clip.right,
7081
+ top: clip.top === false ? 0 : area.top - clip.top,
7082
+ bottom: clip.bottom === false ? this.height : area.bottom + clip.bottom
7083
+ });
7084
+ }
7085
+ meta.controller.draw();
7086
+ if (useClip) {
7087
+ unclipArea(ctx);
7088
+ }
7089
+ args.cancelable = false;
7090
+ this.notifyPlugins('afterDatasetDraw', args);
7091
+ }
7092
+ getElementsAtEventForMode(e, mode, options, useFinalPosition) {
7093
+ const method = Interaction.modes[mode];
7094
+ if (typeof method === 'function') {
7095
+ return method(this, e, options, useFinalPosition);
7096
+ }
7097
+ return [];
7098
+ }
7099
+ getDatasetMeta(datasetIndex) {
7100
+ const dataset = this.data.datasets[datasetIndex];
7101
+ const metasets = this._metasets;
7102
+ let meta = metasets.filter(x => x && x._dataset === dataset).pop();
7103
+ if (!meta) {
7104
+ meta = {
7105
+ type: null,
7106
+ data: [],
7107
+ dataset: null,
7108
+ controller: null,
7109
+ hidden: null,
7110
+ xAxisID: null,
7111
+ yAxisID: null,
7112
+ order: dataset && dataset.order || 0,
7113
+ index: datasetIndex,
7114
+ _dataset: dataset,
7115
+ _parsed: [],
7116
+ _sorted: false
7117
+ };
7118
+ metasets.push(meta);
7119
+ }
7120
+ return meta;
7121
+ }
7122
+ getContext() {
7123
+ return this.$context || (this.$context = createContext(null, {chart: this, type: 'chart'}));
7124
+ }
7125
+ getVisibleDatasetCount() {
7126
+ return this.getSortedVisibleDatasetMetas().length;
7127
+ }
7128
+ isDatasetVisible(datasetIndex) {
7129
+ const dataset = this.data.datasets[datasetIndex];
7130
+ if (!dataset) {
7131
+ return false;
7132
+ }
7133
+ const meta = this.getDatasetMeta(datasetIndex);
7134
+ return typeof meta.hidden === 'boolean' ? !meta.hidden : !dataset.hidden;
7135
+ }
7136
+ setDatasetVisibility(datasetIndex, visible) {
7137
+ const meta = this.getDatasetMeta(datasetIndex);
7138
+ meta.hidden = !visible;
7139
+ }
7140
+ toggleDataVisibility(index) {
7141
+ this._hiddenIndices[index] = !this._hiddenIndices[index];
7142
+ }
7143
+ getDataVisibility(index) {
7144
+ return !this._hiddenIndices[index];
7145
+ }
7146
+ _updateVisibility(datasetIndex, dataIndex, visible) {
7147
+ const mode = visible ? 'show' : 'hide';
7148
+ const meta = this.getDatasetMeta(datasetIndex);
7149
+ const anims = meta.controller._resolveAnimations(undefined, mode);
7150
+ if (defined(dataIndex)) {
7151
+ meta.data[dataIndex].hidden = !visible;
7152
+ this.update();
7153
+ } else {
7154
+ this.setDatasetVisibility(datasetIndex, visible);
7155
+ anims.update(meta, {visible});
7156
+ this.update((ctx) => ctx.datasetIndex === datasetIndex ? mode : undefined);
7157
+ }
7158
+ }
7159
+ hide(datasetIndex, dataIndex) {
7160
+ this._updateVisibility(datasetIndex, dataIndex, false);
7161
+ }
7162
+ show(datasetIndex, dataIndex) {
7163
+ this._updateVisibility(datasetIndex, dataIndex, true);
7164
+ }
7165
+ _destroyDatasetMeta(datasetIndex) {
7166
+ const meta = this._metasets[datasetIndex];
7167
+ if (meta && meta.controller) {
7168
+ meta.controller._destroy();
7169
+ }
7170
+ delete this._metasets[datasetIndex];
7171
+ }
7172
+ _stop() {
7173
+ let i, ilen;
7174
+ this.stop();
7175
+ animator.remove(this);
7176
+ for (i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
7177
+ this._destroyDatasetMeta(i);
7178
+ }
7179
+ }
7180
+ destroy() {
7181
+ this.notifyPlugins('beforeDestroy');
7182
+ const {canvas, ctx} = this;
7183
+ this._stop();
7184
+ this.config.clearCache();
7185
+ if (canvas) {
7186
+ this.unbindEvents();
7187
+ clearCanvas(canvas, ctx);
7188
+ this.platform.releaseContext(ctx);
7189
+ this.canvas = null;
7190
+ this.ctx = null;
7191
+ }
7192
+ this.notifyPlugins('destroy');
7193
+ delete instances[this.id];
7194
+ this.notifyPlugins('afterDestroy');
7195
+ }
7196
+ toBase64Image(...args) {
7197
+ return this.canvas.toDataURL(...args);
7198
+ }
7199
+ bindEvents() {
7200
+ this.bindUserEvents();
7201
+ if (this.options.responsive) {
7202
+ this.bindResponsiveEvents();
7203
+ } else {
7204
+ this.attached = true;
7205
+ }
7206
+ }
7207
+ bindUserEvents() {
7208
+ const listeners = this._listeners;
7209
+ const platform = this.platform;
7210
+ const _add = (type, listener) => {
7211
+ platform.addEventListener(this, type, listener);
7212
+ listeners[type] = listener;
7213
+ };
7214
+ const listener = (e, x, y) => {
7215
+ e.offsetX = x;
7216
+ e.offsetY = y;
7217
+ this._eventHandler(e);
7218
+ };
7219
+ each(this.options.events, (type) => _add(type, listener));
7220
+ }
7221
+ bindResponsiveEvents() {
7222
+ if (!this._responsiveListeners) {
7223
+ this._responsiveListeners = {};
7224
+ }
7225
+ const listeners = this._responsiveListeners;
7226
+ const platform = this.platform;
7227
+ const _add = (type, listener) => {
7228
+ platform.addEventListener(this, type, listener);
7229
+ listeners[type] = listener;
7230
+ };
7231
+ const _remove = (type, listener) => {
7232
+ if (listeners[type]) {
7233
+ platform.removeEventListener(this, type, listener);
7234
+ delete listeners[type];
7235
+ }
7236
+ };
7237
+ const listener = (width, height) => {
7238
+ if (this.canvas) {
7239
+ this.resize(width, height);
7240
+ }
7241
+ };
7242
+ let detached;
7243
+ const attached = () => {
7244
+ _remove('attach', attached);
7245
+ this.attached = true;
7246
+ this.resize();
7247
+ _add('resize', listener);
7248
+ _add('detach', detached);
7249
+ };
7250
+ detached = () => {
7251
+ this.attached = false;
7252
+ _remove('resize', listener);
7253
+ this._stop();
7254
+ this._resize(0, 0);
7255
+ _add('attach', attached);
7256
+ };
7257
+ if (platform.isAttached(this.canvas)) {
7258
+ attached();
7259
+ } else {
7260
+ detached();
7261
+ }
7262
+ }
7263
+ unbindEvents() {
7264
+ each(this._listeners, (listener, type) => {
7265
+ this.platform.removeEventListener(this, type, listener);
7266
+ });
7267
+ this._listeners = {};
7268
+ each(this._responsiveListeners, (listener, type) => {
7269
+ this.platform.removeEventListener(this, type, listener);
7270
+ });
7271
+ this._responsiveListeners = undefined;
7272
+ }
7273
+ updateHoverStyle(items, mode, enabled) {
7274
+ const prefix = enabled ? 'set' : 'remove';
7275
+ let meta, item, i, ilen;
7276
+ if (mode === 'dataset') {
7277
+ meta = this.getDatasetMeta(items[0].datasetIndex);
7278
+ meta.controller['_' + prefix + 'DatasetHoverStyle']();
7279
+ }
7280
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
7281
+ item = items[i];
7282
+ const controller = item && this.getDatasetMeta(item.datasetIndex).controller;
7283
+ if (controller) {
7284
+ controller[prefix + 'HoverStyle'](item.element, item.datasetIndex, item.index);
7285
+ }
7286
+ }
7287
+ }
7288
+ getActiveElements() {
7289
+ return this._active || [];
7290
+ }
7291
+ setActiveElements(activeElements) {
7292
+ const lastActive = this._active || [];
7293
+ const active = activeElements.map(({datasetIndex, index}) => {
7294
+ const meta = this.getDatasetMeta(datasetIndex);
7295
+ if (!meta) {
7296
+ throw new Error('No dataset found at index ' + datasetIndex);
7297
+ }
7298
+ return {
7299
+ datasetIndex,
7300
+ element: meta.data[index],
7301
+ index,
7302
+ };
7303
+ });
7304
+ const changed = !_elementsEqual(active, lastActive);
7305
+ if (changed) {
7306
+ this._active = active;
7307
+ this._lastEvent = null;
7308
+ this._updateHoverStyles(active, lastActive);
7309
+ }
7310
+ }
7311
+ notifyPlugins(hook, args, filter) {
7312
+ return this._plugins.notify(this, hook, args, filter);
7313
+ }
7314
+ _updateHoverStyles(active, lastActive, replay) {
7315
+ const hoverOptions = this.options.hover;
7316
+ const diff = (a, b) => a.filter(x => !b.some(y => x.datasetIndex === y.datasetIndex && x.index === y.index));
7317
+ const deactivated = diff(lastActive, active);
7318
+ const activated = replay ? active : diff(active, lastActive);
7319
+ if (deactivated.length) {
7320
+ this.updateHoverStyle(deactivated, hoverOptions.mode, false);
7321
+ }
7322
+ if (activated.length && hoverOptions.mode) {
7323
+ this.updateHoverStyle(activated, hoverOptions.mode, true);
7324
+ }
7325
+ }
7326
+ _eventHandler(e, replay) {
7327
+ const args = {
7328
+ event: e,
7329
+ replay,
7330
+ cancelable: true,
7331
+ inChartArea: _isPointInArea(e, this.chartArea, this._minPadding)
7332
+ };
7333
+ const eventFilter = (plugin) => (plugin.options.events || this.options.events).includes(e.native.type);
7334
+ if (this.notifyPlugins('beforeEvent', args, eventFilter) === false) {
7335
+ return;
7336
+ }
7337
+ const changed = this._handleEvent(e, replay, args.inChartArea);
7338
+ args.cancelable = false;
7339
+ this.notifyPlugins('afterEvent', args, eventFilter);
7340
+ if (changed || args.changed) {
7341
+ this.render();
7342
+ }
7343
+ return this;
7344
+ }
7345
+ _handleEvent(e, replay, inChartArea) {
7346
+ const {_active: lastActive = [], options} = this;
7347
+ const useFinalPosition = replay;
7348
+ const active = this._getActiveElements(e, lastActive, inChartArea, useFinalPosition);
7349
+ const isClick = _isClickEvent(e);
7350
+ const lastEvent = determineLastEvent(e, this._lastEvent, inChartArea, isClick);
7351
+ if (inChartArea) {
7352
+ this._lastEvent = null;
7353
+ callback(options.onHover, [e, active, this], this);
7354
+ if (isClick) {
7355
+ callback(options.onClick, [e, active, this], this);
7356
+ }
7357
+ }
7358
+ const changed = !_elementsEqual(active, lastActive);
7359
+ if (changed || replay) {
7360
+ this._active = active;
7361
+ this._updateHoverStyles(active, lastActive, replay);
7362
+ }
7363
+ this._lastEvent = lastEvent;
7364
+ return changed;
7365
+ }
7366
+ _getActiveElements(e, lastActive, inChartArea, useFinalPosition) {
7367
+ if (e.type === 'mouseout') {
7368
+ return [];
7369
+ }
7370
+ if (!inChartArea) {
7371
+ return lastActive;
7372
+ }
7373
+ const hoverOptions = this.options.hover;
7374
+ return this.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions, useFinalPosition);
7375
+ }
7376
+ }
7377
+ const invalidatePlugins = () => each(Chart.instances, (chart) => chart._plugins.invalidate());
7378
+ const enumerable = true;
7379
+ Object.defineProperties(Chart, {
7380
+ defaults: {
7381
+ enumerable,
7382
+ value: defaults
7383
+ },
7384
+ instances: {
7385
+ enumerable,
7386
+ value: instances
7387
+ },
7388
+ overrides: {
7389
+ enumerable,
7390
+ value: overrides
7391
+ },
7392
+ registry: {
7393
+ enumerable,
7394
+ value: registry
7395
+ },
7396
+ version: {
7397
+ enumerable,
7398
+ value: version
7399
+ },
7400
+ getChart: {
7401
+ enumerable,
7402
+ value: getChart
7403
+ },
7404
+ register: {
7405
+ enumerable,
7406
+ value: (...items) => {
7407
+ registry.add(...items);
7408
+ invalidatePlugins();
7409
+ }
7410
+ },
7411
+ unregister: {
7412
+ enumerable,
7413
+ value: (...items) => {
7414
+ registry.remove(...items);
7415
+ invalidatePlugins();
7416
+ }
7417
+ }
7418
+ });
7419
+
7420
+ function abstract() {
7421
+ throw new Error('This method is not implemented: Check that a complete date adapter is provided.');
7422
+ }
7423
+ class DateAdapter {
7424
+ constructor(options) {
7425
+ this.options = options || {};
7426
+ }
7427
+ formats() {
7428
+ return abstract();
7429
+ }
7430
+ parse(value, format) {
7431
+ return abstract();
7432
+ }
7433
+ format(timestamp, format) {
7434
+ return abstract();
7435
+ }
7436
+ add(timestamp, amount, unit) {
7437
+ return abstract();
7438
+ }
7439
+ diff(a, b, unit) {
7440
+ return abstract();
7441
+ }
7442
+ startOf(timestamp, unit, weekday) {
7443
+ return abstract();
7444
+ }
7445
+ endOf(timestamp, unit) {
7446
+ return abstract();
7447
+ }
7448
+ }
7449
+ DateAdapter.override = function(members) {
7450
+ Object.assign(DateAdapter.prototype, members);
7451
+ };
7452
+ var _adapters = {
7453
+ _date: DateAdapter
7454
+ };
7455
+
7456
+ function getAllScaleValues(scale, type) {
7457
+ if (!scale._cache.$bar) {
7458
+ const visibleMetas = scale.getMatchingVisibleMetas(type);
7459
+ let values = [];
7460
+ for (let i = 0, ilen = visibleMetas.length; i < ilen; i++) {
7461
+ values = values.concat(visibleMetas[i].controller.getAllParsedValues(scale));
7462
+ }
7463
+ scale._cache.$bar = _arrayUnique(values.sort((a, b) => a - b));
7464
+ }
7465
+ return scale._cache.$bar;
7466
+ }
7467
+ function computeMinSampleSize(meta) {
7468
+ const scale = meta.iScale;
7469
+ const values = getAllScaleValues(scale, meta.type);
7470
+ let min = scale._length;
7471
+ let i, ilen, curr, prev;
7472
+ const updateMinAndPrev = () => {
7473
+ if (curr === 32767 || curr === -32768) {
7474
+ return;
7475
+ }
7476
+ if (defined(prev)) {
7477
+ min = Math.min(min, Math.abs(curr - prev) || min);
7478
+ }
7479
+ prev = curr;
7480
+ };
7481
+ for (i = 0, ilen = values.length; i < ilen; ++i) {
7482
+ curr = scale.getPixelForValue(values[i]);
7483
+ updateMinAndPrev();
7484
+ }
7485
+ prev = undefined;
7486
+ for (i = 0, ilen = scale.ticks.length; i < ilen; ++i) {
7487
+ curr = scale.getPixelForTick(i);
7488
+ updateMinAndPrev();
7489
+ }
7490
+ return min;
7491
+ }
7492
+ function computeFitCategoryTraits(index, ruler, options, stackCount) {
7493
+ const thickness = options.barThickness;
7494
+ let size, ratio;
7495
+ if (isNullOrUndef(thickness)) {
7496
+ size = ruler.min * options.categoryPercentage;
7497
+ ratio = options.barPercentage;
7498
+ } else {
7499
+ size = thickness * stackCount;
7500
+ ratio = 1;
7501
+ }
7502
+ return {
7503
+ chunk: size / stackCount,
7504
+ ratio,
7505
+ start: ruler.pixels[index] - (size / 2)
7506
+ };
7507
+ }
7508
+ function computeFlexCategoryTraits(index, ruler, options, stackCount) {
7509
+ const pixels = ruler.pixels;
7510
+ const curr = pixels[index];
7511
+ let prev = index > 0 ? pixels[index - 1] : null;
7512
+ let next = index < pixels.length - 1 ? pixels[index + 1] : null;
7513
+ const percent = options.categoryPercentage;
7514
+ if (prev === null) {
7515
+ prev = curr - (next === null ? ruler.end - ruler.start : next - curr);
7516
+ }
7517
+ if (next === null) {
7518
+ next = curr + curr - prev;
7519
+ }
7520
+ const start = curr - (curr - Math.min(prev, next)) / 2 * percent;
7521
+ const size = Math.abs(next - prev) / 2 * percent;
7522
+ return {
7523
+ chunk: size / stackCount,
7524
+ ratio: options.barPercentage,
7525
+ start
7526
+ };
7527
+ }
7528
+ function parseFloatBar(entry, item, vScale, i) {
7529
+ const startValue = vScale.parse(entry[0], i);
7530
+ const endValue = vScale.parse(entry[1], i);
7531
+ const min = Math.min(startValue, endValue);
7532
+ const max = Math.max(startValue, endValue);
7533
+ let barStart = min;
7534
+ let barEnd = max;
7535
+ if (Math.abs(min) > Math.abs(max)) {
7536
+ barStart = max;
7537
+ barEnd = min;
7538
+ }
7539
+ item[vScale.axis] = barEnd;
7540
+ item._custom = {
7541
+ barStart,
7542
+ barEnd,
7543
+ start: startValue,
7544
+ end: endValue,
7545
+ min,
7546
+ max
7547
+ };
7548
+ }
7549
+ function parseValue(entry, item, vScale, i) {
7550
+ if (isArray(entry)) {
7551
+ parseFloatBar(entry, item, vScale, i);
7552
+ } else {
7553
+ item[vScale.axis] = vScale.parse(entry, i);
7554
+ }
7555
+ return item;
7556
+ }
7557
+ function parseArrayOrPrimitive(meta, data, start, count) {
7558
+ const iScale = meta.iScale;
7559
+ const vScale = meta.vScale;
7560
+ const labels = iScale.getLabels();
7561
+ const singleScale = iScale === vScale;
7562
+ const parsed = [];
7563
+ let i, ilen, item, entry;
7564
+ for (i = start, ilen = start + count; i < ilen; ++i) {
7565
+ entry = data[i];
7566
+ item = {};
7567
+ item[iScale.axis] = singleScale || iScale.parse(labels[i], i);
7568
+ parsed.push(parseValue(entry, item, vScale, i));
7569
+ }
7570
+ return parsed;
7571
+ }
7572
+ function isFloatBar(custom) {
7573
+ return custom && custom.barStart !== undefined && custom.barEnd !== undefined;
7574
+ }
7575
+ function barSign(size, vScale, actualBase) {
7576
+ if (size !== 0) {
7577
+ return sign(size);
7578
+ }
7579
+ return (vScale.isHorizontal() ? 1 : -1) * (vScale.min >= actualBase ? 1 : -1);
7580
+ }
7581
+ function borderProps(properties) {
7582
+ let reverse, start, end, top, bottom;
7583
+ if (properties.horizontal) {
7584
+ reverse = properties.base > properties.x;
7585
+ start = 'left';
7586
+ end = 'right';
7587
+ } else {
7588
+ reverse = properties.base < properties.y;
7589
+ start = 'bottom';
7590
+ end = 'top';
7591
+ }
7592
+ if (reverse) {
7593
+ top = 'end';
7594
+ bottom = 'start';
7595
+ } else {
7596
+ top = 'start';
7597
+ bottom = 'end';
7598
+ }
7599
+ return {start, end, reverse, top, bottom};
7600
+ }
7601
+ function setBorderSkipped(properties, options, stack, index) {
7602
+ let edge = options.borderSkipped;
7603
+ const res = {};
7604
+ if (!edge) {
7605
+ properties.borderSkipped = res;
7606
+ return;
7607
+ }
7608
+ const {start, end, reverse, top, bottom} = borderProps(properties);
7609
+ if (edge === 'middle' && stack) {
7610
+ properties.enableBorderRadius = true;
7611
+ if ((stack._top || 0) === index) {
7612
+ edge = top;
7613
+ } else if ((stack._bottom || 0) === index) {
7614
+ edge = bottom;
7615
+ } else {
7616
+ res[parseEdge(bottom, start, end, reverse)] = true;
7617
+ edge = top;
7618
+ }
7619
+ }
7620
+ res[parseEdge(edge, start, end, reverse)] = true;
7621
+ properties.borderSkipped = res;
7622
+ }
7623
+ function parseEdge(edge, a, b, reverse) {
7624
+ if (reverse) {
7625
+ edge = swap(edge, a, b);
7626
+ edge = startEnd(edge, b, a);
7627
+ } else {
7628
+ edge = startEnd(edge, a, b);
7629
+ }
7630
+ return edge;
7631
+ }
7632
+ function swap(orig, v1, v2) {
7633
+ return orig === v1 ? v2 : orig === v2 ? v1 : orig;
7634
+ }
7635
+ function startEnd(v, start, end) {
7636
+ return v === 'start' ? start : v === 'end' ? end : v;
7637
+ }
7638
+ function setInflateAmount(properties, {inflateAmount}, ratio) {
7639
+ properties.inflateAmount = inflateAmount === 'auto'
7640
+ ? ratio === 1 ? 0.33 : 0
7641
+ : inflateAmount;
7642
+ }
7643
+ class BarController extends DatasetController {
7644
+ parsePrimitiveData(meta, data, start, count) {
7645
+ return parseArrayOrPrimitive(meta, data, start, count);
7646
+ }
7647
+ parseArrayData(meta, data, start, count) {
7648
+ return parseArrayOrPrimitive(meta, data, start, count);
7649
+ }
7650
+ parseObjectData(meta, data, start, count) {
7651
+ const {iScale, vScale} = meta;
7652
+ const {xAxisKey = 'x', yAxisKey = 'y'} = this._parsing;
7653
+ const iAxisKey = iScale.axis === 'x' ? xAxisKey : yAxisKey;
7654
+ const vAxisKey = vScale.axis === 'x' ? xAxisKey : yAxisKey;
7655
+ const parsed = [];
7656
+ let i, ilen, item, obj;
7657
+ for (i = start, ilen = start + count; i < ilen; ++i) {
7658
+ obj = data[i];
7659
+ item = {};
7660
+ item[iScale.axis] = iScale.parse(resolveObjectKey(obj, iAxisKey), i);
7661
+ parsed.push(parseValue(resolveObjectKey(obj, vAxisKey), item, vScale, i));
7662
+ }
7663
+ return parsed;
7664
+ }
7665
+ updateRangeFromParsed(range, scale, parsed, stack) {
7666
+ super.updateRangeFromParsed(range, scale, parsed, stack);
7667
+ const custom = parsed._custom;
7668
+ if (custom && scale === this._cachedMeta.vScale) {
7669
+ range.min = Math.min(range.min, custom.min);
7670
+ range.max = Math.max(range.max, custom.max);
7671
+ }
7672
+ }
7673
+ getMaxOverflow() {
7674
+ return 0;
7675
+ }
7676
+ getLabelAndValue(index) {
7677
+ const meta = this._cachedMeta;
7678
+ const {iScale, vScale} = meta;
7679
+ const parsed = this.getParsed(index);
7680
+ const custom = parsed._custom;
7681
+ const value = isFloatBar(custom)
7682
+ ? '[' + custom.start + ', ' + custom.end + ']'
7683
+ : '' + vScale.getLabelForValue(parsed[vScale.axis]);
7684
+ return {
7685
+ label: '' + iScale.getLabelForValue(parsed[iScale.axis]),
7686
+ value
7687
+ };
7688
+ }
7689
+ initialize() {
7690
+ this.enableOptionSharing = true;
7691
+ super.initialize();
7692
+ const meta = this._cachedMeta;
7693
+ meta.stack = this.getDataset().stack;
7694
+ }
7695
+ update(mode) {
7696
+ const meta = this._cachedMeta;
7697
+ this.updateElements(meta.data, 0, meta.data.length, mode);
7698
+ }
7699
+ updateElements(bars, start, count, mode) {
7700
+ const reset = mode === 'reset';
7701
+ const {index, _cachedMeta: {vScale}} = this;
7702
+ const base = vScale.getBasePixel();
7703
+ const horizontal = vScale.isHorizontal();
7704
+ const ruler = this._getRuler();
7705
+ const firstOpts = this.resolveDataElementOptions(start, mode);
7706
+ const sharedOptions = this.getSharedOptions(firstOpts);
7707
+ const includeOptions = this.includeOptions(mode, sharedOptions);
7708
+ this.updateSharedOptions(sharedOptions, mode, firstOpts);
7709
+ for (let i = start; i < start + count; i++) {
7710
+ const parsed = this.getParsed(i);
7711
+ const vpixels = reset || isNullOrUndef(parsed[vScale.axis]) ? {base, head: base} : this._calculateBarValuePixels(i);
7712
+ const ipixels = this._calculateBarIndexPixels(i, ruler);
7713
+ const stack = (parsed._stacks || {})[vScale.axis];
7714
+ const properties = {
7715
+ horizontal,
7716
+ base: vpixels.base,
7717
+ enableBorderRadius: !stack || isFloatBar(parsed._custom) || (index === stack._top || index === stack._bottom),
7718
+ x: horizontal ? vpixels.head : ipixels.center,
7719
+ y: horizontal ? ipixels.center : vpixels.head,
7720
+ height: horizontal ? ipixels.size : Math.abs(vpixels.size),
7721
+ width: horizontal ? Math.abs(vpixels.size) : ipixels.size
7722
+ };
7723
+ if (includeOptions) {
7724
+ properties.options = sharedOptions || this.resolveDataElementOptions(i, bars[i].active ? 'active' : mode);
7725
+ }
7726
+ const options = properties.options || bars[i].options;
7727
+ setBorderSkipped(properties, options, stack, index);
7728
+ setInflateAmount(properties, options, ruler.ratio);
7729
+ this.updateElement(bars[i], i, properties, mode);
7730
+ }
7731
+ }
7732
+ _getStacks(last, dataIndex) {
7733
+ const meta = this._cachedMeta;
7734
+ const iScale = meta.iScale;
7735
+ const metasets = iScale.getMatchingVisibleMetas(this._type);
7736
+ const stacked = iScale.options.stacked;
7737
+ const ilen = metasets.length;
7738
+ const stacks = [];
7739
+ let i, item;
7740
+ for (i = 0; i < ilen; ++i) {
7741
+ item = metasets[i];
7742
+ if (!item.controller.options.grouped) {
7743
+ continue;
7744
+ }
7745
+ if (typeof dataIndex !== 'undefined') {
7746
+ const val = item.controller.getParsed(dataIndex)[
7747
+ item.controller._cachedMeta.vScale.axis
7748
+ ];
7749
+ if (isNullOrUndef(val) || isNaN(val)) {
7750
+ continue;
7751
+ }
7752
+ }
7753
+ if (stacked === false || stacks.indexOf(item.stack) === -1 ||
7754
+ (stacked === undefined && item.stack === undefined)) {
7755
+ stacks.push(item.stack);
7756
+ }
7757
+ if (item.index === last) {
7758
+ break;
7759
+ }
7760
+ }
7761
+ if (!stacks.length) {
7762
+ stacks.push(undefined);
7763
+ }
7764
+ return stacks;
7765
+ }
7766
+ _getStackCount(index) {
7767
+ return this._getStacks(undefined, index).length;
7768
+ }
7769
+ _getStackIndex(datasetIndex, name, dataIndex) {
7770
+ const stacks = this._getStacks(datasetIndex, dataIndex);
7771
+ const index = (name !== undefined)
7772
+ ? stacks.indexOf(name)
7773
+ : -1;
7774
+ return (index === -1)
7775
+ ? stacks.length - 1
7776
+ : index;
7777
+ }
7778
+ _getRuler() {
7779
+ const opts = this.options;
7780
+ const meta = this._cachedMeta;
7781
+ const iScale = meta.iScale;
7782
+ const pixels = [];
7783
+ let i, ilen;
7784
+ for (i = 0, ilen = meta.data.length; i < ilen; ++i) {
7785
+ pixels.push(iScale.getPixelForValue(this.getParsed(i)[iScale.axis], i));
7786
+ }
7787
+ const barThickness = opts.barThickness;
7788
+ const min = barThickness || computeMinSampleSize(meta);
7789
+ return {
7790
+ min,
7791
+ pixels,
7792
+ start: iScale._startPixel,
7793
+ end: iScale._endPixel,
7794
+ stackCount: this._getStackCount(),
7795
+ scale: iScale,
7796
+ grouped: opts.grouped,
7797
+ ratio: barThickness ? 1 : opts.categoryPercentage * opts.barPercentage
7798
+ };
7799
+ }
7800
+ _calculateBarValuePixels(index) {
7801
+ const {_cachedMeta: {vScale, _stacked}, options: {base: baseValue, minBarLength}} = this;
7802
+ const actualBase = baseValue || 0;
7803
+ const parsed = this.getParsed(index);
7804
+ const custom = parsed._custom;
7805
+ const floating = isFloatBar(custom);
7806
+ let value = parsed[vScale.axis];
7807
+ let start = 0;
7808
+ let length = _stacked ? this.applyStack(vScale, parsed, _stacked) : value;
7809
+ let head, size;
7810
+ if (length !== value) {
7811
+ start = length - value;
7812
+ length = value;
7813
+ }
7814
+ if (floating) {
7815
+ value = custom.barStart;
7816
+ length = custom.barEnd - custom.barStart;
7817
+ if (value !== 0 && sign(value) !== sign(custom.barEnd)) {
7818
+ start = 0;
7819
+ }
7820
+ start += value;
7821
+ }
7822
+ const startValue = !isNullOrUndef(baseValue) && !floating ? baseValue : start;
7823
+ let base = vScale.getPixelForValue(startValue);
7824
+ if (this.chart.getDataVisibility(index)) {
7825
+ head = vScale.getPixelForValue(start + length);
7826
+ } else {
7827
+ head = base;
7828
+ }
7829
+ size = head - base;
7830
+ if (Math.abs(size) < minBarLength) {
7831
+ size = barSign(size, vScale, actualBase) * minBarLength;
7832
+ if (value === actualBase) {
7833
+ base -= size / 2;
7834
+ }
7835
+ head = base + size;
7836
+ }
7837
+ if (base === vScale.getPixelForValue(actualBase)) {
7838
+ const halfGrid = sign(size) * vScale.getLineWidthForValue(actualBase) / 2;
7839
+ base += halfGrid;
7840
+ size -= halfGrid;
7841
+ }
7842
+ return {
7843
+ size,
7844
+ base,
7845
+ head,
7846
+ center: head + size / 2
7847
+ };
7848
+ }
7849
+ _calculateBarIndexPixels(index, ruler) {
7850
+ const scale = ruler.scale;
7851
+ const options = this.options;
7852
+ const skipNull = options.skipNull;
7853
+ const maxBarThickness = valueOrDefault(options.maxBarThickness, Infinity);
7854
+ let center, size;
7855
+ if (ruler.grouped) {
7856
+ const stackCount = skipNull ? this._getStackCount(index) : ruler.stackCount;
7857
+ const range = options.barThickness === 'flex'
7858
+ ? computeFlexCategoryTraits(index, ruler, options, stackCount)
7859
+ : computeFitCategoryTraits(index, ruler, options, stackCount);
7860
+ const stackIndex = this._getStackIndex(this.index, this._cachedMeta.stack, skipNull ? index : undefined);
7861
+ center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);
7862
+ size = Math.min(maxBarThickness, range.chunk * range.ratio);
7863
+ } else {
7864
+ center = scale.getPixelForValue(this.getParsed(index)[scale.axis], index);
7865
+ size = Math.min(maxBarThickness, ruler.min * ruler.ratio);
7866
+ }
7867
+ return {
7868
+ base: center - size / 2,
7869
+ head: center + size / 2,
7870
+ center,
7871
+ size
7872
+ };
7873
+ }
7874
+ draw() {
7875
+ const meta = this._cachedMeta;
7876
+ const vScale = meta.vScale;
7877
+ const rects = meta.data;
7878
+ const ilen = rects.length;
7879
+ let i = 0;
7880
+ for (; i < ilen; ++i) {
7881
+ if (this.getParsed(i)[vScale.axis] !== null) {
7882
+ rects[i].draw(this._ctx);
7883
+ }
7884
+ }
7885
+ }
7886
+ }
7887
+ BarController.id = 'bar';
7888
+ BarController.defaults = {
7889
+ datasetElementType: false,
7890
+ dataElementType: 'bar',
7891
+ categoryPercentage: 0.8,
7892
+ barPercentage: 0.9,
7893
+ grouped: true,
7894
+ animations: {
7895
+ numbers: {
7896
+ type: 'number',
7897
+ properties: ['x', 'y', 'base', 'width', 'height']
7898
+ }
7899
+ }
7900
+ };
7901
+ BarController.overrides = {
7902
+ scales: {
7903
+ _index_: {
7904
+ type: 'category',
7905
+ offset: true,
7906
+ grid: {
7907
+ offset: true
7908
+ }
7909
+ },
7910
+ _value_: {
7911
+ type: 'linear',
7912
+ beginAtZero: true,
7913
+ }
7914
+ }
7915
+ };
7916
+
7917
+ class BubbleController extends DatasetController {
7918
+ initialize() {
7919
+ this.enableOptionSharing = true;
7920
+ super.initialize();
7921
+ }
7922
+ parsePrimitiveData(meta, data, start, count) {
7923
+ const parsed = super.parsePrimitiveData(meta, data, start, count);
7924
+ for (let i = 0; i < parsed.length; i++) {
7925
+ parsed[i]._custom = this.resolveDataElementOptions(i + start).radius;
7926
+ }
7927
+ return parsed;
7928
+ }
7929
+ parseArrayData(meta, data, start, count) {
7930
+ const parsed = super.parseArrayData(meta, data, start, count);
7931
+ for (let i = 0; i < parsed.length; i++) {
7932
+ const item = data[start + i];
7933
+ parsed[i]._custom = valueOrDefault(item[2], this.resolveDataElementOptions(i + start).radius);
7934
+ }
7935
+ return parsed;
7936
+ }
7937
+ parseObjectData(meta, data, start, count) {
7938
+ const parsed = super.parseObjectData(meta, data, start, count);
7939
+ for (let i = 0; i < parsed.length; i++) {
7940
+ const item = data[start + i];
7941
+ parsed[i]._custom = valueOrDefault(item && item.r && +item.r, this.resolveDataElementOptions(i + start).radius);
7942
+ }
7943
+ return parsed;
7944
+ }
7945
+ getMaxOverflow() {
7946
+ const data = this._cachedMeta.data;
7947
+ let max = 0;
7948
+ for (let i = data.length - 1; i >= 0; --i) {
7949
+ max = Math.max(max, data[i].size(this.resolveDataElementOptions(i)) / 2);
7950
+ }
7951
+ return max > 0 && max;
7952
+ }
7953
+ getLabelAndValue(index) {
7954
+ const meta = this._cachedMeta;
7955
+ const {xScale, yScale} = meta;
7956
+ const parsed = this.getParsed(index);
7957
+ const x = xScale.getLabelForValue(parsed.x);
7958
+ const y = yScale.getLabelForValue(parsed.y);
7959
+ const r = parsed._custom;
7960
+ return {
7961
+ label: meta.label,
7962
+ value: '(' + x + ', ' + y + (r ? ', ' + r : '') + ')'
7963
+ };
7964
+ }
7965
+ update(mode) {
7966
+ const points = this._cachedMeta.data;
7967
+ this.updateElements(points, 0, points.length, mode);
7968
+ }
7969
+ updateElements(points, start, count, mode) {
7970
+ const reset = mode === 'reset';
7971
+ const {iScale, vScale} = this._cachedMeta;
7972
+ const firstOpts = this.resolveDataElementOptions(start, mode);
7973
+ const sharedOptions = this.getSharedOptions(firstOpts);
7974
+ const includeOptions = this.includeOptions(mode, sharedOptions);
7975
+ const iAxis = iScale.axis;
7976
+ const vAxis = vScale.axis;
7977
+ for (let i = start; i < start + count; i++) {
7978
+ const point = points[i];
7979
+ const parsed = !reset && this.getParsed(i);
7980
+ const properties = {};
7981
+ const iPixel = properties[iAxis] = reset ? iScale.getPixelForDecimal(0.5) : iScale.getPixelForValue(parsed[iAxis]);
7982
+ const vPixel = properties[vAxis] = reset ? vScale.getBasePixel() : vScale.getPixelForValue(parsed[vAxis]);
7983
+ properties.skip = isNaN(iPixel) || isNaN(vPixel);
7984
+ if (includeOptions) {
7985
+ properties.options = this.resolveDataElementOptions(i, point.active ? 'active' : mode);
7986
+ if (reset) {
7987
+ properties.options.radius = 0;
7988
+ }
7989
+ }
7990
+ this.updateElement(point, i, properties, mode);
7991
+ }
7992
+ this.updateSharedOptions(sharedOptions, mode, firstOpts);
7993
+ }
7994
+ resolveDataElementOptions(index, mode) {
7995
+ const parsed = this.getParsed(index);
7996
+ let values = super.resolveDataElementOptions(index, mode);
7997
+ if (values.$shared) {
7998
+ values = Object.assign({}, values, {$shared: false});
7999
+ }
8000
+ const radius = values.radius;
8001
+ if (mode !== 'active') {
8002
+ values.radius = 0;
8003
+ }
8004
+ values.radius += valueOrDefault(parsed && parsed._custom, radius);
8005
+ return values;
8006
+ }
8007
+ }
8008
+ BubbleController.id = 'bubble';
8009
+ BubbleController.defaults = {
8010
+ datasetElementType: false,
8011
+ dataElementType: 'point',
8012
+ animations: {
8013
+ numbers: {
8014
+ type: 'number',
8015
+ properties: ['x', 'y', 'borderWidth', 'radius']
8016
+ }
8017
+ }
8018
+ };
8019
+ BubbleController.overrides = {
8020
+ scales: {
8021
+ x: {
8022
+ type: 'linear'
8023
+ },
8024
+ y: {
8025
+ type: 'linear'
8026
+ }
8027
+ },
8028
+ plugins: {
8029
+ tooltip: {
8030
+ callbacks: {
8031
+ title() {
8032
+ return '';
8033
+ }
8034
+ }
8035
+ }
8036
+ }
8037
+ };
8038
+
8039
+ function getRatioAndOffset(rotation, circumference, cutout) {
8040
+ let ratioX = 1;
8041
+ let ratioY = 1;
8042
+ let offsetX = 0;
8043
+ let offsetY = 0;
8044
+ if (circumference < TAU) {
8045
+ const startAngle = rotation;
8046
+ const endAngle = startAngle + circumference;
8047
+ const startX = Math.cos(startAngle);
8048
+ const startY = Math.sin(startAngle);
8049
+ const endX = Math.cos(endAngle);
8050
+ const endY = Math.sin(endAngle);
8051
+ const calcMax = (angle, a, b) => _angleBetween(angle, startAngle, endAngle, true) ? 1 : Math.max(a, a * cutout, b, b * cutout);
8052
+ const calcMin = (angle, a, b) => _angleBetween(angle, startAngle, endAngle, true) ? -1 : Math.min(a, a * cutout, b, b * cutout);
8053
+ const maxX = calcMax(0, startX, endX);
8054
+ const maxY = calcMax(HALF_PI, startY, endY);
8055
+ const minX = calcMin(PI, startX, endX);
8056
+ const minY = calcMin(PI + HALF_PI, startY, endY);
8057
+ ratioX = (maxX - minX) / 2;
8058
+ ratioY = (maxY - minY) / 2;
8059
+ offsetX = -(maxX + minX) / 2;
8060
+ offsetY = -(maxY + minY) / 2;
8061
+ }
8062
+ return {ratioX, ratioY, offsetX, offsetY};
8063
+ }
8064
+ class DoughnutController extends DatasetController {
8065
+ constructor(chart, datasetIndex) {
8066
+ super(chart, datasetIndex);
8067
+ this.enableOptionSharing = true;
8068
+ this.innerRadius = undefined;
8069
+ this.outerRadius = undefined;
8070
+ this.offsetX = undefined;
8071
+ this.offsetY = undefined;
8072
+ }
8073
+ linkScales() {}
8074
+ parse(start, count) {
8075
+ const data = this.getDataset().data;
8076
+ const meta = this._cachedMeta;
8077
+ if (this._parsing === false) {
8078
+ meta._parsed = data;
8079
+ } else {
8080
+ let getter = (i) => +data[i];
8081
+ if (isObject(data[start])) {
8082
+ const {key = 'value'} = this._parsing;
8083
+ getter = (i) => +resolveObjectKey(data[i], key);
8084
+ }
8085
+ let i, ilen;
8086
+ for (i = start, ilen = start + count; i < ilen; ++i) {
8087
+ meta._parsed[i] = getter(i);
8088
+ }
8089
+ }
8090
+ }
8091
+ _getRotation() {
8092
+ return toRadians(this.options.rotation - 90);
8093
+ }
8094
+ _getCircumference() {
8095
+ return toRadians(this.options.circumference);
8096
+ }
8097
+ _getRotationExtents() {
8098
+ let min = TAU;
8099
+ let max = -TAU;
8100
+ for (let i = 0; i < this.chart.data.datasets.length; ++i) {
8101
+ if (this.chart.isDatasetVisible(i)) {
8102
+ const controller = this.chart.getDatasetMeta(i).controller;
8103
+ const rotation = controller._getRotation();
8104
+ const circumference = controller._getCircumference();
8105
+ min = Math.min(min, rotation);
8106
+ max = Math.max(max, rotation + circumference);
8107
+ }
8108
+ }
8109
+ return {
8110
+ rotation: min,
8111
+ circumference: max - min,
8112
+ };
8113
+ }
8114
+ update(mode) {
8115
+ const chart = this.chart;
8116
+ const {chartArea} = chart;
8117
+ const meta = this._cachedMeta;
8118
+ const arcs = meta.data;
8119
+ const spacing = this.getMaxBorderWidth() + this.getMaxOffset(arcs) + this.options.spacing;
8120
+ const maxSize = Math.max((Math.min(chartArea.width, chartArea.height) - spacing) / 2, 0);
8121
+ const cutout = Math.min(toPercentage(this.options.cutout, maxSize), 1);
8122
+ const chartWeight = this._getRingWeight(this.index);
8123
+ const {circumference, rotation} = this._getRotationExtents();
8124
+ const {ratioX, ratioY, offsetX, offsetY} = getRatioAndOffset(rotation, circumference, cutout);
8125
+ const maxWidth = (chartArea.width - spacing) / ratioX;
8126
+ const maxHeight = (chartArea.height - spacing) / ratioY;
8127
+ const maxRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0);
8128
+ const outerRadius = toDimension(this.options.radius, maxRadius);
8129
+ const innerRadius = Math.max(outerRadius * cutout, 0);
8130
+ const radiusLength = (outerRadius - innerRadius) / this._getVisibleDatasetWeightTotal();
8131
+ this.offsetX = offsetX * outerRadius;
8132
+ this.offsetY = offsetY * outerRadius;
8133
+ meta.total = this.calculateTotal();
8134
+ this.outerRadius = outerRadius - radiusLength * this._getRingWeightOffset(this.index);
8135
+ this.innerRadius = Math.max(this.outerRadius - radiusLength * chartWeight, 0);
8136
+ this.updateElements(arcs, 0, arcs.length, mode);
8137
+ }
8138
+ _circumference(i, reset) {
8139
+ const opts = this.options;
8140
+ const meta = this._cachedMeta;
8141
+ const circumference = this._getCircumference();
8142
+ if ((reset && opts.animation.animateRotate) || !this.chart.getDataVisibility(i) || meta._parsed[i] === null || meta.data[i].hidden) {
8143
+ return 0;
8144
+ }
8145
+ return this.calculateCircumference(meta._parsed[i] * circumference / TAU);
8146
+ }
8147
+ updateElements(arcs, start, count, mode) {
8148
+ const reset = mode === 'reset';
8149
+ const chart = this.chart;
8150
+ const chartArea = chart.chartArea;
8151
+ const opts = chart.options;
8152
+ const animationOpts = opts.animation;
8153
+ const centerX = (chartArea.left + chartArea.right) / 2;
8154
+ const centerY = (chartArea.top + chartArea.bottom) / 2;
8155
+ const animateScale = reset && animationOpts.animateScale;
8156
+ const innerRadius = animateScale ? 0 : this.innerRadius;
8157
+ const outerRadius = animateScale ? 0 : this.outerRadius;
8158
+ const firstOpts = this.resolveDataElementOptions(start, mode);
8159
+ const sharedOptions = this.getSharedOptions(firstOpts);
8160
+ const includeOptions = this.includeOptions(mode, sharedOptions);
8161
+ let startAngle = this._getRotation();
8162
+ let i;
8163
+ for (i = 0; i < start; ++i) {
8164
+ startAngle += this._circumference(i, reset);
8165
+ }
8166
+ for (i = start; i < start + count; ++i) {
8167
+ const circumference = this._circumference(i, reset);
8168
+ const arc = arcs[i];
8169
+ const properties = {
8170
+ x: centerX + this.offsetX,
8171
+ y: centerY + this.offsetY,
8172
+ startAngle,
8173
+ endAngle: startAngle + circumference,
8174
+ circumference,
8175
+ outerRadius,
8176
+ innerRadius
8177
+ };
8178
+ if (includeOptions) {
8179
+ properties.options = sharedOptions || this.resolveDataElementOptions(i, arc.active ? 'active' : mode);
8180
+ }
8181
+ startAngle += circumference;
8182
+ this.updateElement(arc, i, properties, mode);
8183
+ }
8184
+ this.updateSharedOptions(sharedOptions, mode, firstOpts);
8185
+ }
8186
+ calculateTotal() {
8187
+ const meta = this._cachedMeta;
8188
+ const metaData = meta.data;
8189
+ let total = 0;
8190
+ let i;
8191
+ for (i = 0; i < metaData.length; i++) {
8192
+ const value = meta._parsed[i];
8193
+ if (value !== null && !isNaN(value) && this.chart.getDataVisibility(i) && !metaData[i].hidden) {
8194
+ total += Math.abs(value);
8195
+ }
8196
+ }
8197
+ return total;
8198
+ }
8199
+ calculateCircumference(value) {
8200
+ const total = this._cachedMeta.total;
8201
+ if (total > 0 && !isNaN(value)) {
8202
+ return TAU * (Math.abs(value) / total);
8203
+ }
8204
+ return 0;
8205
+ }
8206
+ getLabelAndValue(index) {
8207
+ const meta = this._cachedMeta;
8208
+ const chart = this.chart;
8209
+ const labels = chart.data.labels || [];
8210
+ const value = formatNumber(meta._parsed[index], chart.options.locale);
8211
+ return {
8212
+ label: labels[index] || '',
8213
+ value,
8214
+ };
8215
+ }
8216
+ getMaxBorderWidth(arcs) {
8217
+ let max = 0;
8218
+ const chart = this.chart;
8219
+ let i, ilen, meta, controller, options;
8220
+ if (!arcs) {
8221
+ for (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) {
8222
+ if (chart.isDatasetVisible(i)) {
8223
+ meta = chart.getDatasetMeta(i);
8224
+ arcs = meta.data;
8225
+ controller = meta.controller;
8226
+ break;
8227
+ }
8228
+ }
8229
+ }
8230
+ if (!arcs) {
8231
+ return 0;
8232
+ }
8233
+ for (i = 0, ilen = arcs.length; i < ilen; ++i) {
8234
+ options = controller.resolveDataElementOptions(i);
8235
+ if (options.borderAlign !== 'inner') {
8236
+ max = Math.max(max, options.borderWidth || 0, options.hoverBorderWidth || 0);
8237
+ }
8238
+ }
8239
+ return max;
8240
+ }
8241
+ getMaxOffset(arcs) {
8242
+ let max = 0;
8243
+ for (let i = 0, ilen = arcs.length; i < ilen; ++i) {
8244
+ const options = this.resolveDataElementOptions(i);
8245
+ max = Math.max(max, options.offset || 0, options.hoverOffset || 0);
8246
+ }
8247
+ return max;
8248
+ }
8249
+ _getRingWeightOffset(datasetIndex) {
8250
+ let ringWeightOffset = 0;
8251
+ for (let i = 0; i < datasetIndex; ++i) {
8252
+ if (this.chart.isDatasetVisible(i)) {
8253
+ ringWeightOffset += this._getRingWeight(i);
8254
+ }
8255
+ }
8256
+ return ringWeightOffset;
8257
+ }
8258
+ _getRingWeight(datasetIndex) {
8259
+ return Math.max(valueOrDefault(this.chart.data.datasets[datasetIndex].weight, 1), 0);
8260
+ }
8261
+ _getVisibleDatasetWeightTotal() {
8262
+ return this._getRingWeightOffset(this.chart.data.datasets.length) || 1;
8263
+ }
8264
+ }
8265
+ DoughnutController.id = 'doughnut';
8266
+ DoughnutController.defaults = {
8267
+ datasetElementType: false,
8268
+ dataElementType: 'arc',
8269
+ animation: {
8270
+ animateRotate: true,
8271
+ animateScale: false
8272
+ },
8273
+ animations: {
8274
+ numbers: {
8275
+ type: 'number',
8276
+ properties: ['circumference', 'endAngle', 'innerRadius', 'outerRadius', 'startAngle', 'x', 'y', 'offset', 'borderWidth', 'spacing']
8277
+ },
8278
+ },
8279
+ cutout: '50%',
8280
+ rotation: 0,
8281
+ circumference: 360,
8282
+ radius: '100%',
8283
+ spacing: 0,
8284
+ indexAxis: 'r',
8285
+ };
8286
+ DoughnutController.descriptors = {
8287
+ _scriptable: (name) => name !== 'spacing',
8288
+ _indexable: (name) => name !== 'spacing',
8289
+ };
8290
+ DoughnutController.overrides = {
8291
+ aspectRatio: 1,
8292
+ plugins: {
8293
+ legend: {
8294
+ labels: {
8295
+ generateLabels(chart) {
8296
+ const data = chart.data;
8297
+ if (data.labels.length && data.datasets.length) {
8298
+ const {labels: {pointStyle}} = chart.legend.options;
8299
+ return data.labels.map((label, i) => {
8300
+ const meta = chart.getDatasetMeta(0);
8301
+ const style = meta.controller.getStyle(i);
8302
+ return {
8303
+ text: label,
8304
+ fillStyle: style.backgroundColor,
8305
+ strokeStyle: style.borderColor,
8306
+ lineWidth: style.borderWidth,
8307
+ pointStyle: pointStyle,
8308
+ hidden: !chart.getDataVisibility(i),
8309
+ index: i
8310
+ };
8311
+ });
8312
+ }
8313
+ return [];
8314
+ }
8315
+ },
8316
+ onClick(e, legendItem, legend) {
8317
+ legend.chart.toggleDataVisibility(legendItem.index);
8318
+ legend.chart.update();
8319
+ }
8320
+ },
8321
+ tooltip: {
8322
+ callbacks: {
8323
+ title() {
8324
+ return '';
8325
+ },
8326
+ label(tooltipItem) {
8327
+ let dataLabel = tooltipItem.label;
8328
+ const value = ': ' + tooltipItem.formattedValue;
8329
+ if (isArray(dataLabel)) {
8330
+ dataLabel = dataLabel.slice();
8331
+ dataLabel[0] += value;
8332
+ } else {
8333
+ dataLabel += value;
8334
+ }
8335
+ return dataLabel;
8336
+ }
8337
+ }
8338
+ }
8339
+ }
8340
+ };
8341
+
8342
+ class LineController extends DatasetController {
8343
+ initialize() {
8344
+ this.enableOptionSharing = true;
8345
+ super.initialize();
8346
+ }
8347
+ update(mode) {
8348
+ const meta = this._cachedMeta;
8349
+ const {dataset: line, data: points = [], _dataset} = meta;
8350
+ const animationsDisabled = this.chart._animationsDisabled;
8351
+ let {start, count} = getStartAndCountOfVisiblePoints(meta, points, animationsDisabled);
8352
+ this._drawStart = start;
8353
+ this._drawCount = count;
8354
+ if (scaleRangesChanged(meta)) {
8355
+ start = 0;
8356
+ count = points.length;
8357
+ }
8358
+ line._chart = this.chart;
8359
+ line._datasetIndex = this.index;
8360
+ line._decimated = !!_dataset._decimated;
8361
+ line.points = points;
8362
+ const options = this.resolveDatasetElementOptions(mode);
8363
+ if (!this.options.showLine) {
8364
+ options.borderWidth = 0;
8365
+ }
8366
+ options.segment = this.options.segment;
8367
+ this.updateElement(line, undefined, {
8368
+ animated: !animationsDisabled,
8369
+ options
8370
+ }, mode);
8371
+ this.updateElements(points, start, count, mode);
8372
+ }
8373
+ updateElements(points, start, count, mode) {
8374
+ const reset = mode === 'reset';
8375
+ const {iScale, vScale, _stacked, _dataset} = this._cachedMeta;
8376
+ const firstOpts = this.resolveDataElementOptions(start, mode);
8377
+ const sharedOptions = this.getSharedOptions(firstOpts);
8378
+ const includeOptions = this.includeOptions(mode, sharedOptions);
8379
+ const iAxis = iScale.axis;
8380
+ const vAxis = vScale.axis;
8381
+ const {spanGaps, segment} = this.options;
8382
+ const maxGapLength = isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY;
8383
+ const directUpdate = this.chart._animationsDisabled || reset || mode === 'none';
8384
+ let prevParsed = start > 0 && this.getParsed(start - 1);
8385
+ for (let i = start; i < start + count; ++i) {
8386
+ const point = points[i];
8387
+ const parsed = this.getParsed(i);
8388
+ const properties = directUpdate ? point : {};
8389
+ const nullData = isNullOrUndef(parsed[vAxis]);
8390
+ const iPixel = properties[iAxis] = iScale.getPixelForValue(parsed[iAxis], i);
8391
+ const vPixel = properties[vAxis] = reset || nullData ? vScale.getBasePixel() : vScale.getPixelForValue(_stacked ? this.applyStack(vScale, parsed, _stacked) : parsed[vAxis], i);
8392
+ properties.skip = isNaN(iPixel) || isNaN(vPixel) || nullData;
8393
+ properties.stop = i > 0 && (parsed[iAxis] - prevParsed[iAxis]) > maxGapLength;
8394
+ if (segment) {
8395
+ properties.parsed = parsed;
8396
+ properties.raw = _dataset.data[i];
8397
+ }
8398
+ if (includeOptions) {
8399
+ properties.options = sharedOptions || this.resolveDataElementOptions(i, point.active ? 'active' : mode);
8400
+ }
8401
+ if (!directUpdate) {
8402
+ this.updateElement(point, i, properties, mode);
8403
+ }
8404
+ prevParsed = parsed;
8405
+ }
8406
+ this.updateSharedOptions(sharedOptions, mode, firstOpts);
8407
+ }
8408
+ getMaxOverflow() {
8409
+ const meta = this._cachedMeta;
8410
+ const dataset = meta.dataset;
8411
+ const border = dataset.options && dataset.options.borderWidth || 0;
8412
+ const data = meta.data || [];
8413
+ if (!data.length) {
8414
+ return border;
8415
+ }
8416
+ const firstPoint = data[0].size(this.resolveDataElementOptions(0));
8417
+ const lastPoint = data[data.length - 1].size(this.resolveDataElementOptions(data.length - 1));
8418
+ return Math.max(border, firstPoint, lastPoint) / 2;
8419
+ }
8420
+ draw() {
8421
+ const meta = this._cachedMeta;
8422
+ meta.dataset.updateControlPoints(this.chart.chartArea, meta.iScale.axis);
8423
+ super.draw();
8424
+ }
8425
+ }
8426
+ LineController.id = 'line';
8427
+ LineController.defaults = {
8428
+ datasetElementType: 'line',
8429
+ dataElementType: 'point',
8430
+ showLine: true,
8431
+ spanGaps: false,
8432
+ };
8433
+ LineController.overrides = {
8434
+ scales: {
8435
+ _index_: {
8436
+ type: 'category',
8437
+ },
8438
+ _value_: {
8439
+ type: 'linear',
8440
+ },
8441
+ }
8442
+ };
8443
+ function getStartAndCountOfVisiblePoints(meta, points, animationsDisabled) {
8444
+ const pointCount = points.length;
8445
+ let start = 0;
8446
+ let count = pointCount;
8447
+ if (meta._sorted) {
8448
+ const {iScale, _parsed} = meta;
8449
+ const axis = iScale.axis;
8450
+ const {min, max, minDefined, maxDefined} = iScale.getUserBounds();
8451
+ if (minDefined) {
8452
+ start = _limitValue(Math.min(
8453
+ _lookupByKey(_parsed, iScale.axis, min).lo,
8454
+ animationsDisabled ? pointCount : _lookupByKey(points, axis, iScale.getPixelForValue(min)).lo),
8455
+ 0, pointCount - 1);
8456
+ }
8457
+ if (maxDefined) {
8458
+ count = _limitValue(Math.max(
8459
+ _lookupByKey(_parsed, iScale.axis, max).hi + 1,
8460
+ animationsDisabled ? 0 : _lookupByKey(points, axis, iScale.getPixelForValue(max)).hi + 1),
8461
+ start, pointCount) - start;
8462
+ } else {
8463
+ count = pointCount - start;
8464
+ }
8465
+ }
8466
+ return {start, count};
8467
+ }
8468
+ function scaleRangesChanged(meta) {
8469
+ const {xScale, yScale, _scaleRanges} = meta;
8470
+ const newRanges = {
8471
+ xmin: xScale.min,
8472
+ xmax: xScale.max,
8473
+ ymin: yScale.min,
8474
+ ymax: yScale.max
8475
+ };
8476
+ if (!_scaleRanges) {
8477
+ meta._scaleRanges = newRanges;
8478
+ return true;
8479
+ }
8480
+ const changed = _scaleRanges.xmin !== xScale.min
8481
+ || _scaleRanges.xmax !== xScale.max
8482
+ || _scaleRanges.ymin !== yScale.min
8483
+ || _scaleRanges.ymax !== yScale.max;
8484
+ Object.assign(_scaleRanges, newRanges);
8485
+ return changed;
8486
+ }
8487
+
8488
+ class PolarAreaController extends DatasetController {
8489
+ constructor(chart, datasetIndex) {
8490
+ super(chart, datasetIndex);
8491
+ this.innerRadius = undefined;
8492
+ this.outerRadius = undefined;
8493
+ }
8494
+ getLabelAndValue(index) {
8495
+ const meta = this._cachedMeta;
8496
+ const chart = this.chart;
8497
+ const labels = chart.data.labels || [];
8498
+ const value = formatNumber(meta._parsed[index].r, chart.options.locale);
8499
+ return {
8500
+ label: labels[index] || '',
8501
+ value,
8502
+ };
8503
+ }
8504
+ update(mode) {
8505
+ const arcs = this._cachedMeta.data;
8506
+ this._updateRadius();
8507
+ this.updateElements(arcs, 0, arcs.length, mode);
8508
+ }
8509
+ _updateRadius() {
8510
+ const chart = this.chart;
8511
+ const chartArea = chart.chartArea;
8512
+ const opts = chart.options;
8513
+ const minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
8514
+ const outerRadius = Math.max(minSize / 2, 0);
8515
+ const innerRadius = Math.max(opts.cutoutPercentage ? (outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);
8516
+ const radiusLength = (outerRadius - innerRadius) / chart.getVisibleDatasetCount();
8517
+ this.outerRadius = outerRadius - (radiusLength * this.index);
8518
+ this.innerRadius = this.outerRadius - radiusLength;
8519
+ }
8520
+ updateElements(arcs, start, count, mode) {
8521
+ const reset = mode === 'reset';
8522
+ const chart = this.chart;
8523
+ const dataset = this.getDataset();
8524
+ const opts = chart.options;
8525
+ const animationOpts = opts.animation;
8526
+ const scale = this._cachedMeta.rScale;
8527
+ const centerX = scale.xCenter;
8528
+ const centerY = scale.yCenter;
8529
+ const datasetStartAngle = scale.getIndexAngle(0) - 0.5 * PI;
8530
+ let angle = datasetStartAngle;
8531
+ let i;
8532
+ const defaultAngle = 360 / this.countVisibleElements();
8533
+ for (i = 0; i < start; ++i) {
8534
+ angle += this._computeAngle(i, mode, defaultAngle);
8535
+ }
8536
+ for (i = start; i < start + count; i++) {
8537
+ const arc = arcs[i];
8538
+ let startAngle = angle;
8539
+ let endAngle = angle + this._computeAngle(i, mode, defaultAngle);
8540
+ let outerRadius = chart.getDataVisibility(i) ? scale.getDistanceFromCenterForValue(dataset.data[i]) : 0;
8541
+ angle = endAngle;
8542
+ if (reset) {
8543
+ if (animationOpts.animateScale) {
8544
+ outerRadius = 0;
8545
+ }
8546
+ if (animationOpts.animateRotate) {
8547
+ startAngle = endAngle = datasetStartAngle;
8548
+ }
8549
+ }
8550
+ const properties = {
8551
+ x: centerX,
8552
+ y: centerY,
8553
+ innerRadius: 0,
8554
+ outerRadius,
8555
+ startAngle,
8556
+ endAngle,
8557
+ options: this.resolveDataElementOptions(i, arc.active ? 'active' : mode)
8558
+ };
8559
+ this.updateElement(arc, i, properties, mode);
8560
+ }
8561
+ }
8562
+ countVisibleElements() {
8563
+ const dataset = this.getDataset();
8564
+ const meta = this._cachedMeta;
8565
+ let count = 0;
8566
+ meta.data.forEach((element, index) => {
8567
+ if (!isNaN(dataset.data[index]) && this.chart.getDataVisibility(index)) {
8568
+ count++;
8569
+ }
8570
+ });
8571
+ return count;
8572
+ }
8573
+ _computeAngle(index, mode, defaultAngle) {
8574
+ return this.chart.getDataVisibility(index)
8575
+ ? toRadians(this.resolveDataElementOptions(index, mode).angle || defaultAngle)
8576
+ : 0;
8577
+ }
8578
+ }
8579
+ PolarAreaController.id = 'polarArea';
8580
+ PolarAreaController.defaults = {
8581
+ dataElementType: 'arc',
8582
+ animation: {
8583
+ animateRotate: true,
8584
+ animateScale: true
8585
+ },
8586
+ animations: {
8587
+ numbers: {
8588
+ type: 'number',
8589
+ properties: ['x', 'y', 'startAngle', 'endAngle', 'innerRadius', 'outerRadius']
8590
+ },
8591
+ },
8592
+ indexAxis: 'r',
8593
+ startAngle: 0,
8594
+ };
8595
+ PolarAreaController.overrides = {
8596
+ aspectRatio: 1,
8597
+ plugins: {
8598
+ legend: {
8599
+ labels: {
8600
+ generateLabels(chart) {
8601
+ const data = chart.data;
8602
+ if (data.labels.length && data.datasets.length) {
8603
+ const {labels: {pointStyle}} = chart.legend.options;
8604
+ return data.labels.map((label, i) => {
8605
+ const meta = chart.getDatasetMeta(0);
8606
+ const style = meta.controller.getStyle(i);
8607
+ return {
8608
+ text: label,
8609
+ fillStyle: style.backgroundColor,
8610
+ strokeStyle: style.borderColor,
8611
+ lineWidth: style.borderWidth,
8612
+ pointStyle: pointStyle,
8613
+ hidden: !chart.getDataVisibility(i),
8614
+ index: i
8615
+ };
8616
+ });
8617
+ }
8618
+ return [];
8619
+ }
8620
+ },
8621
+ onClick(e, legendItem, legend) {
8622
+ legend.chart.toggleDataVisibility(legendItem.index);
8623
+ legend.chart.update();
8624
+ }
8625
+ },
8626
+ tooltip: {
8627
+ callbacks: {
8628
+ title() {
8629
+ return '';
8630
+ },
8631
+ label(context) {
8632
+ return context.chart.data.labels[context.dataIndex] + ': ' + context.formattedValue;
8633
+ }
8634
+ }
8635
+ }
8636
+ },
8637
+ scales: {
8638
+ r: {
8639
+ type: 'radialLinear',
8640
+ angleLines: {
8641
+ display: false
8642
+ },
8643
+ beginAtZero: true,
8644
+ grid: {
8645
+ circular: true
8646
+ },
8647
+ pointLabels: {
8648
+ display: false
8649
+ },
8650
+ startAngle: 0
8651
+ }
8652
+ }
8653
+ };
8654
+
8655
+ class PieController extends DoughnutController {
8656
+ }
8657
+ PieController.id = 'pie';
8658
+ PieController.defaults = {
8659
+ cutout: 0,
8660
+ rotation: 0,
8661
+ circumference: 360,
8662
+ radius: '100%'
8663
+ };
8664
+
8665
+ class RadarController extends DatasetController {
8666
+ getLabelAndValue(index) {
8667
+ const vScale = this._cachedMeta.vScale;
8668
+ const parsed = this.getParsed(index);
8669
+ return {
8670
+ label: vScale.getLabels()[index],
8671
+ value: '' + vScale.getLabelForValue(parsed[vScale.axis])
8672
+ };
8673
+ }
8674
+ update(mode) {
8675
+ const meta = this._cachedMeta;
8676
+ const line = meta.dataset;
8677
+ const points = meta.data || [];
8678
+ const labels = meta.iScale.getLabels();
8679
+ line.points = points;
8680
+ if (mode !== 'resize') {
8681
+ const options = this.resolveDatasetElementOptions(mode);
8682
+ if (!this.options.showLine) {
8683
+ options.borderWidth = 0;
8684
+ }
8685
+ const properties = {
8686
+ _loop: true,
8687
+ _fullLoop: labels.length === points.length,
8688
+ options
8689
+ };
8690
+ this.updateElement(line, undefined, properties, mode);
8691
+ }
8692
+ this.updateElements(points, 0, points.length, mode);
8693
+ }
8694
+ updateElements(points, start, count, mode) {
8695
+ const dataset = this.getDataset();
8696
+ const scale = this._cachedMeta.rScale;
8697
+ const reset = mode === 'reset';
8698
+ for (let i = start; i < start + count; i++) {
8699
+ const point = points[i];
8700
+ const options = this.resolveDataElementOptions(i, point.active ? 'active' : mode);
8701
+ const pointPosition = scale.getPointPositionForValue(i, dataset.data[i]);
8702
+ const x = reset ? scale.xCenter : pointPosition.x;
8703
+ const y = reset ? scale.yCenter : pointPosition.y;
8704
+ const properties = {
8705
+ x,
8706
+ y,
8707
+ angle: pointPosition.angle,
8708
+ skip: isNaN(x) || isNaN(y),
8709
+ options
8710
+ };
8711
+ this.updateElement(point, i, properties, mode);
8712
+ }
8713
+ }
8714
+ }
8715
+ RadarController.id = 'radar';
8716
+ RadarController.defaults = {
8717
+ datasetElementType: 'line',
8718
+ dataElementType: 'point',
8719
+ indexAxis: 'r',
8720
+ showLine: true,
8721
+ elements: {
8722
+ line: {
8723
+ fill: 'start'
8724
+ }
8725
+ },
8726
+ };
8727
+ RadarController.overrides = {
8728
+ aspectRatio: 1,
8729
+ scales: {
8730
+ r: {
8731
+ type: 'radialLinear',
8732
+ }
8733
+ }
8734
+ };
8735
+
8736
+ class ScatterController extends LineController {
8737
+ }
8738
+ ScatterController.id = 'scatter';
8739
+ ScatterController.defaults = {
8740
+ showLine: false,
8741
+ fill: false
8742
+ };
8743
+ ScatterController.overrides = {
8744
+ interaction: {
8745
+ mode: 'point'
8746
+ },
8747
+ plugins: {
8748
+ tooltip: {
8749
+ callbacks: {
8750
+ title() {
8751
+ return '';
8752
+ },
8753
+ label(item) {
8754
+ return '(' + item.label + ', ' + item.formattedValue + ')';
8755
+ }
8756
+ }
8757
+ }
8758
+ },
8759
+ scales: {
8760
+ x: {
8761
+ type: 'linear'
8762
+ },
8763
+ y: {
8764
+ type: 'linear'
8765
+ }
8766
+ }
8767
+ };
8768
+
8769
+ var controllers = /*#__PURE__*/Object.freeze({
8770
+ __proto__: null,
8771
+ BarController: BarController,
8772
+ BubbleController: BubbleController,
8773
+ DoughnutController: DoughnutController,
8774
+ LineController: LineController,
8775
+ PolarAreaController: PolarAreaController,
8776
+ PieController: PieController,
8777
+ RadarController: RadarController,
8778
+ ScatterController: ScatterController
8779
+ });
8780
+
8781
+ function clipArc(ctx, element, endAngle) {
8782
+ const {startAngle, pixelMargin, x, y, outerRadius, innerRadius} = element;
8783
+ let angleMargin = pixelMargin / outerRadius;
8784
+ ctx.beginPath();
8785
+ ctx.arc(x, y, outerRadius, startAngle - angleMargin, endAngle + angleMargin);
8786
+ if (innerRadius > pixelMargin) {
8787
+ angleMargin = pixelMargin / innerRadius;
8788
+ ctx.arc(x, y, innerRadius, endAngle + angleMargin, startAngle - angleMargin, true);
8789
+ } else {
8790
+ ctx.arc(x, y, pixelMargin, endAngle + HALF_PI, startAngle - HALF_PI);
8791
+ }
8792
+ ctx.closePath();
8793
+ ctx.clip();
8794
+ }
8795
+ function toRadiusCorners(value) {
8796
+ return _readValueToProps(value, ['outerStart', 'outerEnd', 'innerStart', 'innerEnd']);
8797
+ }
8798
+ function parseBorderRadius$1(arc, innerRadius, outerRadius, angleDelta) {
8799
+ const o = toRadiusCorners(arc.options.borderRadius);
8800
+ const halfThickness = (outerRadius - innerRadius) / 2;
8801
+ const innerLimit = Math.min(halfThickness, angleDelta * innerRadius / 2);
8802
+ const computeOuterLimit = (val) => {
8803
+ const outerArcLimit = (outerRadius - Math.min(halfThickness, val)) * angleDelta / 2;
8804
+ return _limitValue(val, 0, Math.min(halfThickness, outerArcLimit));
8805
+ };
8806
+ return {
8807
+ outerStart: computeOuterLimit(o.outerStart),
8808
+ outerEnd: computeOuterLimit(o.outerEnd),
8809
+ innerStart: _limitValue(o.innerStart, 0, innerLimit),
8810
+ innerEnd: _limitValue(o.innerEnd, 0, innerLimit),
8811
+ };
8812
+ }
8813
+ function rThetaToXY(r, theta, x, y) {
8814
+ return {
8815
+ x: x + r * Math.cos(theta),
8816
+ y: y + r * Math.sin(theta),
8817
+ };
8818
+ }
8819
+ function pathArc(ctx, element, offset, spacing, end) {
8820
+ const {x, y, startAngle: start, pixelMargin, innerRadius: innerR} = element;
8821
+ const outerRadius = Math.max(element.outerRadius + spacing + offset - pixelMargin, 0);
8822
+ const innerRadius = innerR > 0 ? innerR + spacing + offset + pixelMargin : 0;
8823
+ let spacingOffset = 0;
8824
+ const alpha = end - start;
8825
+ if (spacing) {
8826
+ const noSpacingInnerRadius = innerR > 0 ? innerR - spacing : 0;
8827
+ const noSpacingOuterRadius = outerRadius > 0 ? outerRadius - spacing : 0;
8828
+ const avNogSpacingRadius = (noSpacingInnerRadius + noSpacingOuterRadius) / 2;
8829
+ const adjustedAngle = avNogSpacingRadius !== 0 ? (alpha * avNogSpacingRadius) / (avNogSpacingRadius + spacing) : alpha;
8830
+ spacingOffset = (alpha - adjustedAngle) / 2;
8831
+ }
8832
+ const beta = Math.max(0.001, alpha * outerRadius - offset / PI) / outerRadius;
8833
+ const angleOffset = (alpha - beta) / 2;
8834
+ const startAngle = start + angleOffset + spacingOffset;
8835
+ const endAngle = end - angleOffset - spacingOffset;
8836
+ const {outerStart, outerEnd, innerStart, innerEnd} = parseBorderRadius$1(element, innerRadius, outerRadius, endAngle - startAngle);
8837
+ const outerStartAdjustedRadius = outerRadius - outerStart;
8838
+ const outerEndAdjustedRadius = outerRadius - outerEnd;
8839
+ const outerStartAdjustedAngle = startAngle + outerStart / outerStartAdjustedRadius;
8840
+ const outerEndAdjustedAngle = endAngle - outerEnd / outerEndAdjustedRadius;
8841
+ const innerStartAdjustedRadius = innerRadius + innerStart;
8842
+ const innerEndAdjustedRadius = innerRadius + innerEnd;
8843
+ const innerStartAdjustedAngle = startAngle + innerStart / innerStartAdjustedRadius;
8844
+ const innerEndAdjustedAngle = endAngle - innerEnd / innerEndAdjustedRadius;
8845
+ ctx.beginPath();
8846
+ ctx.arc(x, y, outerRadius, outerStartAdjustedAngle, outerEndAdjustedAngle);
8847
+ if (outerEnd > 0) {
8848
+ const pCenter = rThetaToXY(outerEndAdjustedRadius, outerEndAdjustedAngle, x, y);
8849
+ ctx.arc(pCenter.x, pCenter.y, outerEnd, outerEndAdjustedAngle, endAngle + HALF_PI);
8850
+ }
8851
+ const p4 = rThetaToXY(innerEndAdjustedRadius, endAngle, x, y);
8852
+ ctx.lineTo(p4.x, p4.y);
8853
+ if (innerEnd > 0) {
8854
+ const pCenter = rThetaToXY(innerEndAdjustedRadius, innerEndAdjustedAngle, x, y);
8855
+ ctx.arc(pCenter.x, pCenter.y, innerEnd, endAngle + HALF_PI, innerEndAdjustedAngle + Math.PI);
8856
+ }
8857
+ ctx.arc(x, y, innerRadius, endAngle - (innerEnd / innerRadius), startAngle + (innerStart / innerRadius), true);
8858
+ if (innerStart > 0) {
8859
+ const pCenter = rThetaToXY(innerStartAdjustedRadius, innerStartAdjustedAngle, x, y);
8860
+ ctx.arc(pCenter.x, pCenter.y, innerStart, innerStartAdjustedAngle + Math.PI, startAngle - HALF_PI);
8861
+ }
8862
+ const p8 = rThetaToXY(outerStartAdjustedRadius, startAngle, x, y);
8863
+ ctx.lineTo(p8.x, p8.y);
8864
+ if (outerStart > 0) {
8865
+ const pCenter = rThetaToXY(outerStartAdjustedRadius, outerStartAdjustedAngle, x, y);
8866
+ ctx.arc(pCenter.x, pCenter.y, outerStart, startAngle - HALF_PI, outerStartAdjustedAngle);
8867
+ }
8868
+ ctx.closePath();
8869
+ }
8870
+ function drawArc(ctx, element, offset, spacing) {
8871
+ const {fullCircles, startAngle, circumference} = element;
8872
+ let endAngle = element.endAngle;
8873
+ if (fullCircles) {
8874
+ pathArc(ctx, element, offset, spacing, startAngle + TAU);
8875
+ for (let i = 0; i < fullCircles; ++i) {
8876
+ ctx.fill();
8877
+ }
8878
+ if (!isNaN(circumference)) {
8879
+ endAngle = startAngle + circumference % TAU;
8880
+ if (circumference % TAU === 0) {
8881
+ endAngle += TAU;
8882
+ }
8883
+ }
8884
+ }
8885
+ pathArc(ctx, element, offset, spacing, endAngle);
8886
+ ctx.fill();
8887
+ return endAngle;
8888
+ }
8889
+ function drawFullCircleBorders(ctx, element, inner) {
8890
+ const {x, y, startAngle, pixelMargin, fullCircles} = element;
8891
+ const outerRadius = Math.max(element.outerRadius - pixelMargin, 0);
8892
+ const innerRadius = element.innerRadius + pixelMargin;
8893
+ let i;
8894
+ if (inner) {
8895
+ clipArc(ctx, element, startAngle + TAU);
8896
+ }
8897
+ ctx.beginPath();
8898
+ ctx.arc(x, y, innerRadius, startAngle + TAU, startAngle, true);
8899
+ for (i = 0; i < fullCircles; ++i) {
8900
+ ctx.stroke();
8901
+ }
8902
+ ctx.beginPath();
8903
+ ctx.arc(x, y, outerRadius, startAngle, startAngle + TAU);
8904
+ for (i = 0; i < fullCircles; ++i) {
8905
+ ctx.stroke();
8906
+ }
8907
+ }
8908
+ function drawBorder(ctx, element, offset, spacing, endAngle) {
8909
+ const {options} = element;
8910
+ const {borderWidth, borderJoinStyle} = options;
8911
+ const inner = options.borderAlign === 'inner';
8912
+ if (!borderWidth) {
8913
+ return;
8914
+ }
8915
+ if (inner) {
8916
+ ctx.lineWidth = borderWidth * 2;
8917
+ ctx.lineJoin = borderJoinStyle || 'round';
8918
+ } else {
8919
+ ctx.lineWidth = borderWidth;
8920
+ ctx.lineJoin = borderJoinStyle || 'bevel';
8921
+ }
8922
+ if (element.fullCircles) {
8923
+ drawFullCircleBorders(ctx, element, inner);
8924
+ }
8925
+ if (inner) {
8926
+ clipArc(ctx, element, endAngle);
8927
+ }
8928
+ pathArc(ctx, element, offset, spacing, endAngle);
8929
+ ctx.stroke();
8930
+ }
8931
+ class ArcElement extends Element {
8932
+ constructor(cfg) {
8933
+ super();
8934
+ this.options = undefined;
8935
+ this.circumference = undefined;
8936
+ this.startAngle = undefined;
8937
+ this.endAngle = undefined;
8938
+ this.innerRadius = undefined;
8939
+ this.outerRadius = undefined;
8940
+ this.pixelMargin = 0;
8941
+ this.fullCircles = 0;
8942
+ if (cfg) {
8943
+ Object.assign(this, cfg);
8944
+ }
8945
+ }
8946
+ inRange(chartX, chartY, useFinalPosition) {
8947
+ const point = this.getProps(['x', 'y'], useFinalPosition);
8948
+ const {angle, distance} = getAngleFromPoint(point, {x: chartX, y: chartY});
8949
+ const {startAngle, endAngle, innerRadius, outerRadius, circumference} = this.getProps([
8950
+ 'startAngle',
8951
+ 'endAngle',
8952
+ 'innerRadius',
8953
+ 'outerRadius',
8954
+ 'circumference'
8955
+ ], useFinalPosition);
8956
+ const rAdjust = this.options.spacing / 2;
8957
+ const _circumference = valueOrDefault(circumference, endAngle - startAngle);
8958
+ const betweenAngles = _circumference >= TAU || _angleBetween(angle, startAngle, endAngle);
8959
+ const withinRadius = _isBetween(distance, innerRadius + rAdjust, outerRadius + rAdjust);
8960
+ return (betweenAngles && withinRadius);
8961
+ }
8962
+ getCenterPoint(useFinalPosition) {
8963
+ const {x, y, startAngle, endAngle, innerRadius, outerRadius} = this.getProps([
8964
+ 'x',
8965
+ 'y',
8966
+ 'startAngle',
8967
+ 'endAngle',
8968
+ 'innerRadius',
8969
+ 'outerRadius',
8970
+ 'circumference',
8971
+ ], useFinalPosition);
8972
+ const {offset, spacing} = this.options;
8973
+ const halfAngle = (startAngle + endAngle) / 2;
8974
+ const halfRadius = (innerRadius + outerRadius + spacing + offset) / 2;
8975
+ return {
8976
+ x: x + Math.cos(halfAngle) * halfRadius,
8977
+ y: y + Math.sin(halfAngle) * halfRadius
8978
+ };
8979
+ }
8980
+ tooltipPosition(useFinalPosition) {
8981
+ return this.getCenterPoint(useFinalPosition);
8982
+ }
8983
+ draw(ctx) {
8984
+ const {options, circumference} = this;
8985
+ const offset = (options.offset || 0) / 2;
8986
+ const spacing = (options.spacing || 0) / 2;
8987
+ this.pixelMargin = (options.borderAlign === 'inner') ? 0.33 : 0;
8988
+ this.fullCircles = circumference > TAU ? Math.floor(circumference / TAU) : 0;
8989
+ if (circumference === 0 || this.innerRadius < 0 || this.outerRadius < 0) {
8990
+ return;
8991
+ }
8992
+ ctx.save();
8993
+ let radiusOffset = 0;
8994
+ if (offset) {
8995
+ radiusOffset = offset / 2;
8996
+ const halfAngle = (this.startAngle + this.endAngle) / 2;
8997
+ ctx.translate(Math.cos(halfAngle) * radiusOffset, Math.sin(halfAngle) * radiusOffset);
8998
+ if (this.circumference >= PI) {
8999
+ radiusOffset = offset;
9000
+ }
9001
+ }
9002
+ ctx.fillStyle = options.backgroundColor;
9003
+ ctx.strokeStyle = options.borderColor;
9004
+ const endAngle = drawArc(ctx, this, radiusOffset, spacing);
9005
+ drawBorder(ctx, this, radiusOffset, spacing, endAngle);
9006
+ ctx.restore();
9007
+ }
9008
+ }
9009
+ ArcElement.id = 'arc';
9010
+ ArcElement.defaults = {
9011
+ borderAlign: 'center',
9012
+ borderColor: '#fff',
9013
+ borderJoinStyle: undefined,
9014
+ borderRadius: 0,
9015
+ borderWidth: 2,
9016
+ offset: 0,
9017
+ spacing: 0,
9018
+ angle: undefined,
9019
+ };
9020
+ ArcElement.defaultRoutes = {
9021
+ backgroundColor: 'backgroundColor'
9022
+ };
9023
+
9024
+ function setStyle(ctx, options, style = options) {
9025
+ ctx.lineCap = valueOrDefault(style.borderCapStyle, options.borderCapStyle);
9026
+ ctx.setLineDash(valueOrDefault(style.borderDash, options.borderDash));
9027
+ ctx.lineDashOffset = valueOrDefault(style.borderDashOffset, options.borderDashOffset);
9028
+ ctx.lineJoin = valueOrDefault(style.borderJoinStyle, options.borderJoinStyle);
9029
+ ctx.lineWidth = valueOrDefault(style.borderWidth, options.borderWidth);
9030
+ ctx.strokeStyle = valueOrDefault(style.borderColor, options.borderColor);
9031
+ }
9032
+ function lineTo(ctx, previous, target) {
9033
+ ctx.lineTo(target.x, target.y);
9034
+ }
9035
+ function getLineMethod(options) {
9036
+ if (options.stepped) {
9037
+ return _steppedLineTo;
9038
+ }
9039
+ if (options.tension || options.cubicInterpolationMode === 'monotone') {
9040
+ return _bezierCurveTo;
9041
+ }
9042
+ return lineTo;
9043
+ }
9044
+ function pathVars(points, segment, params = {}) {
9045
+ const count = points.length;
9046
+ const {start: paramsStart = 0, end: paramsEnd = count - 1} = params;
9047
+ const {start: segmentStart, end: segmentEnd} = segment;
9048
+ const start = Math.max(paramsStart, segmentStart);
9049
+ const end = Math.min(paramsEnd, segmentEnd);
9050
+ const outside = paramsStart < segmentStart && paramsEnd < segmentStart || paramsStart > segmentEnd && paramsEnd > segmentEnd;
9051
+ return {
9052
+ count,
9053
+ start,
9054
+ loop: segment.loop,
9055
+ ilen: end < start && !outside ? count + end - start : end - start
9056
+ };
9057
+ }
9058
+ function pathSegment(ctx, line, segment, params) {
9059
+ const {points, options} = line;
9060
+ const {count, start, loop, ilen} = pathVars(points, segment, params);
9061
+ const lineMethod = getLineMethod(options);
9062
+ let {move = true, reverse} = params || {};
9063
+ let i, point, prev;
9064
+ for (i = 0; i <= ilen; ++i) {
9065
+ point = points[(start + (reverse ? ilen - i : i)) % count];
9066
+ if (point.skip) {
9067
+ continue;
9068
+ } else if (move) {
9069
+ ctx.moveTo(point.x, point.y);
9070
+ move = false;
9071
+ } else {
9072
+ lineMethod(ctx, prev, point, reverse, options.stepped);
9073
+ }
9074
+ prev = point;
9075
+ }
9076
+ if (loop) {
9077
+ point = points[(start + (reverse ? ilen : 0)) % count];
9078
+ lineMethod(ctx, prev, point, reverse, options.stepped);
9079
+ }
9080
+ return !!loop;
9081
+ }
9082
+ function fastPathSegment(ctx, line, segment, params) {
9083
+ const points = line.points;
9084
+ const {count, start, ilen} = pathVars(points, segment, params);
9085
+ const {move = true, reverse} = params || {};
9086
+ let avgX = 0;
9087
+ let countX = 0;
9088
+ let i, point, prevX, minY, maxY, lastY;
9089
+ const pointIndex = (index) => (start + (reverse ? ilen - index : index)) % count;
9090
+ const drawX = () => {
9091
+ if (minY !== maxY) {
9092
+ ctx.lineTo(avgX, maxY);
9093
+ ctx.lineTo(avgX, minY);
9094
+ ctx.lineTo(avgX, lastY);
9095
+ }
9096
+ };
9097
+ if (move) {
9098
+ point = points[pointIndex(0)];
9099
+ ctx.moveTo(point.x, point.y);
9100
+ }
9101
+ for (i = 0; i <= ilen; ++i) {
9102
+ point = points[pointIndex(i)];
9103
+ if (point.skip) {
9104
+ continue;
9105
+ }
9106
+ const x = point.x;
9107
+ const y = point.y;
9108
+ const truncX = x | 0;
9109
+ if (truncX === prevX) {
9110
+ if (y < minY) {
9111
+ minY = y;
9112
+ } else if (y > maxY) {
9113
+ maxY = y;
9114
+ }
9115
+ avgX = (countX * avgX + x) / ++countX;
9116
+ } else {
9117
+ drawX();
9118
+ ctx.lineTo(x, y);
9119
+ prevX = truncX;
9120
+ countX = 0;
9121
+ minY = maxY = y;
9122
+ }
9123
+ lastY = y;
9124
+ }
9125
+ drawX();
9126
+ }
9127
+ function _getSegmentMethod(line) {
9128
+ const opts = line.options;
9129
+ const borderDash = opts.borderDash && opts.borderDash.length;
9130
+ const useFastPath = !line._decimated && !line._loop && !opts.tension && opts.cubicInterpolationMode !== 'monotone' && !opts.stepped && !borderDash;
9131
+ return useFastPath ? fastPathSegment : pathSegment;
9132
+ }
9133
+ function _getInterpolationMethod(options) {
9134
+ if (options.stepped) {
9135
+ return _steppedInterpolation;
9136
+ }
9137
+ if (options.tension || options.cubicInterpolationMode === 'monotone') {
9138
+ return _bezierInterpolation;
9139
+ }
9140
+ return _pointInLine;
9141
+ }
9142
+ function strokePathWithCache(ctx, line, start, count) {
9143
+ let path = line._path;
9144
+ if (!path) {
9145
+ path = line._path = new Path2D();
9146
+ if (line.path(path, start, count)) {
9147
+ path.closePath();
9148
+ }
9149
+ }
9150
+ setStyle(ctx, line.options);
9151
+ ctx.stroke(path);
9152
+ }
9153
+ function strokePathDirect(ctx, line, start, count) {
9154
+ const {segments, options} = line;
9155
+ const segmentMethod = _getSegmentMethod(line);
9156
+ for (const segment of segments) {
9157
+ setStyle(ctx, options, segment.style);
9158
+ ctx.beginPath();
9159
+ if (segmentMethod(ctx, line, segment, {start, end: start + count - 1})) {
9160
+ ctx.closePath();
9161
+ }
9162
+ ctx.stroke();
9163
+ }
9164
+ }
9165
+ const usePath2D = typeof Path2D === 'function';
9166
+ function draw(ctx, line, start, count) {
9167
+ if (usePath2D && !line.options.segment) {
9168
+ strokePathWithCache(ctx, line, start, count);
9169
+ } else {
9170
+ strokePathDirect(ctx, line, start, count);
9171
+ }
9172
+ }
9173
+ class LineElement extends Element {
9174
+ constructor(cfg) {
9175
+ super();
9176
+ this.animated = true;
9177
+ this.options = undefined;
9178
+ this._chart = undefined;
9179
+ this._loop = undefined;
9180
+ this._fullLoop = undefined;
9181
+ this._path = undefined;
9182
+ this._points = undefined;
9183
+ this._segments = undefined;
9184
+ this._decimated = false;
9185
+ this._pointsUpdated = false;
9186
+ this._datasetIndex = undefined;
9187
+ if (cfg) {
9188
+ Object.assign(this, cfg);
9189
+ }
9190
+ }
9191
+ updateControlPoints(chartArea, indexAxis) {
9192
+ const options = this.options;
9193
+ if ((options.tension || options.cubicInterpolationMode === 'monotone') && !options.stepped && !this._pointsUpdated) {
9194
+ const loop = options.spanGaps ? this._loop : this._fullLoop;
9195
+ _updateBezierControlPoints(this._points, options, chartArea, loop, indexAxis);
9196
+ this._pointsUpdated = true;
9197
+ }
9198
+ }
9199
+ set points(points) {
9200
+ this._points = points;
9201
+ delete this._segments;
9202
+ delete this._path;
9203
+ this._pointsUpdated = false;
9204
+ }
9205
+ get points() {
9206
+ return this._points;
9207
+ }
9208
+ get segments() {
9209
+ return this._segments || (this._segments = _computeSegments(this, this.options.segment));
9210
+ }
9211
+ first() {
9212
+ const segments = this.segments;
9213
+ const points = this.points;
9214
+ return segments.length && points[segments[0].start];
9215
+ }
9216
+ last() {
9217
+ const segments = this.segments;
9218
+ const points = this.points;
9219
+ const count = segments.length;
9220
+ return count && points[segments[count - 1].end];
9221
+ }
9222
+ interpolate(point, property) {
9223
+ const options = this.options;
9224
+ const value = point[property];
9225
+ const points = this.points;
9226
+ const segments = _boundSegments(this, {property, start: value, end: value});
9227
+ if (!segments.length) {
9228
+ return;
9229
+ }
9230
+ const result = [];
9231
+ const _interpolate = _getInterpolationMethod(options);
9232
+ let i, ilen;
9233
+ for (i = 0, ilen = segments.length; i < ilen; ++i) {
9234
+ const {start, end} = segments[i];
9235
+ const p1 = points[start];
9236
+ const p2 = points[end];
9237
+ if (p1 === p2) {
9238
+ result.push(p1);
9239
+ continue;
9240
+ }
9241
+ const t = Math.abs((value - p1[property]) / (p2[property] - p1[property]));
9242
+ const interpolated = _interpolate(p1, p2, t, options.stepped);
9243
+ interpolated[property] = point[property];
9244
+ result.push(interpolated);
9245
+ }
9246
+ return result.length === 1 ? result[0] : result;
9247
+ }
9248
+ pathSegment(ctx, segment, params) {
9249
+ const segmentMethod = _getSegmentMethod(this);
9250
+ return segmentMethod(ctx, this, segment, params);
9251
+ }
9252
+ path(ctx, start, count) {
9253
+ const segments = this.segments;
9254
+ const segmentMethod = _getSegmentMethod(this);
9255
+ let loop = this._loop;
9256
+ start = start || 0;
9257
+ count = count || (this.points.length - start);
9258
+ for (const segment of segments) {
9259
+ loop &= segmentMethod(ctx, this, segment, {start, end: start + count - 1});
9260
+ }
9261
+ return !!loop;
9262
+ }
9263
+ draw(ctx, chartArea, start, count) {
9264
+ const options = this.options || {};
9265
+ const points = this.points || [];
9266
+ if (points.length && options.borderWidth) {
9267
+ ctx.save();
9268
+ draw(ctx, this, start, count);
9269
+ ctx.restore();
9270
+ }
9271
+ if (this.animated) {
9272
+ this._pointsUpdated = false;
9273
+ this._path = undefined;
9274
+ }
9275
+ }
9276
+ }
9277
+ LineElement.id = 'line';
9278
+ LineElement.defaults = {
9279
+ borderCapStyle: 'butt',
9280
+ borderDash: [],
9281
+ borderDashOffset: 0,
9282
+ borderJoinStyle: 'miter',
9283
+ borderWidth: 3,
9284
+ capBezierPoints: true,
9285
+ cubicInterpolationMode: 'default',
9286
+ fill: false,
9287
+ spanGaps: false,
9288
+ stepped: false,
9289
+ tension: 0,
9290
+ };
9291
+ LineElement.defaultRoutes = {
9292
+ backgroundColor: 'backgroundColor',
9293
+ borderColor: 'borderColor'
9294
+ };
9295
+ LineElement.descriptors = {
9296
+ _scriptable: true,
9297
+ _indexable: (name) => name !== 'borderDash' && name !== 'fill',
9298
+ };
9299
+
9300
+ function inRange$1(el, pos, axis, useFinalPosition) {
9301
+ const options = el.options;
9302
+ const {[axis]: value} = el.getProps([axis], useFinalPosition);
9303
+ return (Math.abs(pos - value) < options.radius + options.hitRadius);
9304
+ }
9305
+ class PointElement extends Element {
9306
+ constructor(cfg) {
9307
+ super();
9308
+ this.options = undefined;
9309
+ this.parsed = undefined;
9310
+ this.skip = undefined;
9311
+ this.stop = undefined;
9312
+ if (cfg) {
9313
+ Object.assign(this, cfg);
9314
+ }
9315
+ }
9316
+ inRange(mouseX, mouseY, useFinalPosition) {
9317
+ const options = this.options;
9318
+ const {x, y} = this.getProps(['x', 'y'], useFinalPosition);
9319
+ return ((Math.pow(mouseX - x, 2) + Math.pow(mouseY - y, 2)) < Math.pow(options.hitRadius + options.radius, 2));
9320
+ }
9321
+ inXRange(mouseX, useFinalPosition) {
9322
+ return inRange$1(this, mouseX, 'x', useFinalPosition);
9323
+ }
9324
+ inYRange(mouseY, useFinalPosition) {
9325
+ return inRange$1(this, mouseY, 'y', useFinalPosition);
9326
+ }
9327
+ getCenterPoint(useFinalPosition) {
9328
+ const {x, y} = this.getProps(['x', 'y'], useFinalPosition);
9329
+ return {x, y};
9330
+ }
9331
+ size(options) {
9332
+ options = options || this.options || {};
9333
+ let radius = options.radius || 0;
9334
+ radius = Math.max(radius, radius && options.hoverRadius || 0);
9335
+ const borderWidth = radius && options.borderWidth || 0;
9336
+ return (radius + borderWidth) * 2;
9337
+ }
9338
+ draw(ctx, area) {
9339
+ const options = this.options;
9340
+ if (this.skip || options.radius < 0.1 || !_isPointInArea(this, area, this.size(options) / 2)) {
9341
+ return;
9342
+ }
9343
+ ctx.strokeStyle = options.borderColor;
9344
+ ctx.lineWidth = options.borderWidth;
9345
+ ctx.fillStyle = options.backgroundColor;
9346
+ drawPoint(ctx, options, this.x, this.y);
9347
+ }
9348
+ getRange() {
9349
+ const options = this.options || {};
9350
+ return options.radius + options.hitRadius;
9351
+ }
9352
+ }
9353
+ PointElement.id = 'point';
9354
+ PointElement.defaults = {
9355
+ borderWidth: 1,
9356
+ hitRadius: 1,
9357
+ hoverBorderWidth: 1,
9358
+ hoverRadius: 4,
9359
+ pointStyle: 'circle',
9360
+ radius: 3,
9361
+ rotation: 0
9362
+ };
9363
+ PointElement.defaultRoutes = {
9364
+ backgroundColor: 'backgroundColor',
9365
+ borderColor: 'borderColor'
9366
+ };
9367
+
9368
+ function getBarBounds(bar, useFinalPosition) {
9369
+ const {x, y, base, width, height} = bar.getProps(['x', 'y', 'base', 'width', 'height'], useFinalPosition);
9370
+ let left, right, top, bottom, half;
9371
+ if (bar.horizontal) {
9372
+ half = height / 2;
9373
+ left = Math.min(x, base);
9374
+ right = Math.max(x, base);
9375
+ top = y - half;
9376
+ bottom = y + half;
9377
+ } else {
9378
+ half = width / 2;
9379
+ left = x - half;
9380
+ right = x + half;
9381
+ top = Math.min(y, base);
9382
+ bottom = Math.max(y, base);
9383
+ }
9384
+ return {left, top, right, bottom};
9385
+ }
9386
+ function skipOrLimit(skip, value, min, max) {
9387
+ return skip ? 0 : _limitValue(value, min, max);
9388
+ }
9389
+ function parseBorderWidth(bar, maxW, maxH) {
9390
+ const value = bar.options.borderWidth;
9391
+ const skip = bar.borderSkipped;
9392
+ const o = toTRBL(value);
9393
+ return {
9394
+ t: skipOrLimit(skip.top, o.top, 0, maxH),
9395
+ r: skipOrLimit(skip.right, o.right, 0, maxW),
9396
+ b: skipOrLimit(skip.bottom, o.bottom, 0, maxH),
9397
+ l: skipOrLimit(skip.left, o.left, 0, maxW)
9398
+ };
9399
+ }
9400
+ function parseBorderRadius(bar, maxW, maxH) {
9401
+ const {enableBorderRadius} = bar.getProps(['enableBorderRadius']);
9402
+ const value = bar.options.borderRadius;
9403
+ const o = toTRBLCorners(value);
9404
+ const maxR = Math.min(maxW, maxH);
9405
+ const skip = bar.borderSkipped;
9406
+ const enableBorder = enableBorderRadius || isObject(value);
9407
+ return {
9408
+ topLeft: skipOrLimit(!enableBorder || skip.top || skip.left, o.topLeft, 0, maxR),
9409
+ topRight: skipOrLimit(!enableBorder || skip.top || skip.right, o.topRight, 0, maxR),
9410
+ bottomLeft: skipOrLimit(!enableBorder || skip.bottom || skip.left, o.bottomLeft, 0, maxR),
9411
+ bottomRight: skipOrLimit(!enableBorder || skip.bottom || skip.right, o.bottomRight, 0, maxR)
9412
+ };
9413
+ }
9414
+ function boundingRects(bar) {
9415
+ const bounds = getBarBounds(bar);
9416
+ const width = bounds.right - bounds.left;
9417
+ const height = bounds.bottom - bounds.top;
9418
+ const border = parseBorderWidth(bar, width / 2, height / 2);
9419
+ const radius = parseBorderRadius(bar, width / 2, height / 2);
9420
+ return {
9421
+ outer: {
9422
+ x: bounds.left,
9423
+ y: bounds.top,
9424
+ w: width,
9425
+ h: height,
9426
+ radius
9427
+ },
9428
+ inner: {
9429
+ x: bounds.left + border.l,
9430
+ y: bounds.top + border.t,
9431
+ w: width - border.l - border.r,
9432
+ h: height - border.t - border.b,
9433
+ radius: {
9434
+ topLeft: Math.max(0, radius.topLeft - Math.max(border.t, border.l)),
9435
+ topRight: Math.max(0, radius.topRight - Math.max(border.t, border.r)),
9436
+ bottomLeft: Math.max(0, radius.bottomLeft - Math.max(border.b, border.l)),
9437
+ bottomRight: Math.max(0, radius.bottomRight - Math.max(border.b, border.r)),
9438
+ }
9439
+ }
9440
+ };
9441
+ }
9442
+ function inRange(bar, x, y, useFinalPosition) {
9443
+ const skipX = x === null;
9444
+ const skipY = y === null;
9445
+ const skipBoth = skipX && skipY;
9446
+ const bounds = bar && !skipBoth && getBarBounds(bar, useFinalPosition);
9447
+ return bounds
9448
+ && (skipX || _isBetween(x, bounds.left, bounds.right))
9449
+ && (skipY || _isBetween(y, bounds.top, bounds.bottom));
9450
+ }
9451
+ function hasRadius(radius) {
9452
+ return radius.topLeft || radius.topRight || radius.bottomLeft || radius.bottomRight;
9453
+ }
9454
+ function addNormalRectPath(ctx, rect) {
9455
+ ctx.rect(rect.x, rect.y, rect.w, rect.h);
9456
+ }
9457
+ function inflateRect(rect, amount, refRect = {}) {
9458
+ const x = rect.x !== refRect.x ? -amount : 0;
9459
+ const y = rect.y !== refRect.y ? -amount : 0;
9460
+ const w = (rect.x + rect.w !== refRect.x + refRect.w ? amount : 0) - x;
9461
+ const h = (rect.y + rect.h !== refRect.y + refRect.h ? amount : 0) - y;
9462
+ return {
9463
+ x: rect.x + x,
9464
+ y: rect.y + y,
9465
+ w: rect.w + w,
9466
+ h: rect.h + h,
9467
+ radius: rect.radius
9468
+ };
9469
+ }
9470
+ class BarElement extends Element {
9471
+ constructor(cfg) {
9472
+ super();
9473
+ this.options = undefined;
9474
+ this.horizontal = undefined;
9475
+ this.base = undefined;
9476
+ this.width = undefined;
9477
+ this.height = undefined;
9478
+ this.inflateAmount = undefined;
9479
+ if (cfg) {
9480
+ Object.assign(this, cfg);
9481
+ }
9482
+ }
9483
+ draw(ctx) {
9484
+ const {inflateAmount, options: {borderColor, backgroundColor}} = this;
9485
+ const {inner, outer} = boundingRects(this);
9486
+ const addRectPath = hasRadius(outer.radius) ? addRoundedRectPath : addNormalRectPath;
9487
+ ctx.save();
9488
+ if (outer.w !== inner.w || outer.h !== inner.h) {
9489
+ ctx.beginPath();
9490
+ addRectPath(ctx, inflateRect(outer, inflateAmount, inner));
9491
+ ctx.clip();
9492
+ addRectPath(ctx, inflateRect(inner, -inflateAmount, outer));
9493
+ ctx.fillStyle = borderColor;
9494
+ ctx.fill('evenodd');
9495
+ }
9496
+ ctx.beginPath();
9497
+ addRectPath(ctx, inflateRect(inner, inflateAmount));
9498
+ ctx.fillStyle = backgroundColor;
9499
+ ctx.fill();
9500
+ ctx.restore();
9501
+ }
9502
+ inRange(mouseX, mouseY, useFinalPosition) {
9503
+ return inRange(this, mouseX, mouseY, useFinalPosition);
9504
+ }
9505
+ inXRange(mouseX, useFinalPosition) {
9506
+ return inRange(this, mouseX, null, useFinalPosition);
9507
+ }
9508
+ inYRange(mouseY, useFinalPosition) {
9509
+ return inRange(this, null, mouseY, useFinalPosition);
9510
+ }
9511
+ getCenterPoint(useFinalPosition) {
9512
+ const {x, y, base, horizontal} = this.getProps(['x', 'y', 'base', 'horizontal'], useFinalPosition);
9513
+ return {
9514
+ x: horizontal ? (x + base) / 2 : x,
9515
+ y: horizontal ? y : (y + base) / 2
9516
+ };
9517
+ }
9518
+ getRange(axis) {
9519
+ return axis === 'x' ? this.width / 2 : this.height / 2;
9520
+ }
9521
+ }
9522
+ BarElement.id = 'bar';
9523
+ BarElement.defaults = {
9524
+ borderSkipped: 'start',
9525
+ borderWidth: 0,
9526
+ borderRadius: 0,
9527
+ inflateAmount: 'auto',
9528
+ pointStyle: undefined
9529
+ };
9530
+ BarElement.defaultRoutes = {
9531
+ backgroundColor: 'backgroundColor',
9532
+ borderColor: 'borderColor'
9533
+ };
9534
+
9535
+ var elements = /*#__PURE__*/Object.freeze({
9536
+ __proto__: null,
9537
+ ArcElement: ArcElement,
9538
+ LineElement: LineElement,
9539
+ PointElement: PointElement,
9540
+ BarElement: BarElement
9541
+ });
9542
+
9543
+ function lttbDecimation(data, start, count, availableWidth, options) {
9544
+ const samples = options.samples || availableWidth;
9545
+ if (samples >= count) {
9546
+ return data.slice(start, start + count);
9547
+ }
9548
+ const decimated = [];
9549
+ const bucketWidth = (count - 2) / (samples - 2);
9550
+ let sampledIndex = 0;
9551
+ const endIndex = start + count - 1;
9552
+ let a = start;
9553
+ let i, maxAreaPoint, maxArea, area, nextA;
9554
+ decimated[sampledIndex++] = data[a];
9555
+ for (i = 0; i < samples - 2; i++) {
9556
+ let avgX = 0;
9557
+ let avgY = 0;
9558
+ let j;
9559
+ const avgRangeStart = Math.floor((i + 1) * bucketWidth) + 1 + start;
9560
+ const avgRangeEnd = Math.min(Math.floor((i + 2) * bucketWidth) + 1, count) + start;
9561
+ const avgRangeLength = avgRangeEnd - avgRangeStart;
9562
+ for (j = avgRangeStart; j < avgRangeEnd; j++) {
9563
+ avgX += data[j].x;
9564
+ avgY += data[j].y;
9565
+ }
9566
+ avgX /= avgRangeLength;
9567
+ avgY /= avgRangeLength;
9568
+ const rangeOffs = Math.floor(i * bucketWidth) + 1 + start;
9569
+ const rangeTo = Math.min(Math.floor((i + 1) * bucketWidth) + 1, count) + start;
9570
+ const {x: pointAx, y: pointAy} = data[a];
9571
+ maxArea = area = -1;
9572
+ for (j = rangeOffs; j < rangeTo; j++) {
9573
+ area = 0.5 * Math.abs(
9574
+ (pointAx - avgX) * (data[j].y - pointAy) -
9575
+ (pointAx - data[j].x) * (avgY - pointAy)
9576
+ );
9577
+ if (area > maxArea) {
9578
+ maxArea = area;
9579
+ maxAreaPoint = data[j];
9580
+ nextA = j;
9581
+ }
9582
+ }
9583
+ decimated[sampledIndex++] = maxAreaPoint;
9584
+ a = nextA;
9585
+ }
9586
+ decimated[sampledIndex++] = data[endIndex];
9587
+ return decimated;
9588
+ }
9589
+ function minMaxDecimation(data, start, count, availableWidth) {
9590
+ let avgX = 0;
9591
+ let countX = 0;
9592
+ let i, point, x, y, prevX, minIndex, maxIndex, startIndex, minY, maxY;
9593
+ const decimated = [];
9594
+ const endIndex = start + count - 1;
9595
+ const xMin = data[start].x;
9596
+ const xMax = data[endIndex].x;
9597
+ const dx = xMax - xMin;
9598
+ for (i = start; i < start + count; ++i) {
9599
+ point = data[i];
9600
+ x = (point.x - xMin) / dx * availableWidth;
9601
+ y = point.y;
9602
+ const truncX = x | 0;
9603
+ if (truncX === prevX) {
9604
+ if (y < minY) {
9605
+ minY = y;
9606
+ minIndex = i;
9607
+ } else if (y > maxY) {
9608
+ maxY = y;
9609
+ maxIndex = i;
9610
+ }
9611
+ avgX = (countX * avgX + point.x) / ++countX;
9612
+ } else {
9613
+ const lastIndex = i - 1;
9614
+ if (!isNullOrUndef(minIndex) && !isNullOrUndef(maxIndex)) {
9615
+ const intermediateIndex1 = Math.min(minIndex, maxIndex);
9616
+ const intermediateIndex2 = Math.max(minIndex, maxIndex);
9617
+ if (intermediateIndex1 !== startIndex && intermediateIndex1 !== lastIndex) {
9618
+ decimated.push({
9619
+ ...data[intermediateIndex1],
9620
+ x: avgX,
9621
+ });
9622
+ }
9623
+ if (intermediateIndex2 !== startIndex && intermediateIndex2 !== lastIndex) {
9624
+ decimated.push({
9625
+ ...data[intermediateIndex2],
9626
+ x: avgX
9627
+ });
9628
+ }
9629
+ }
9630
+ if (i > 0 && lastIndex !== startIndex) {
9631
+ decimated.push(data[lastIndex]);
9632
+ }
9633
+ decimated.push(point);
9634
+ prevX = truncX;
9635
+ countX = 0;
9636
+ minY = maxY = y;
9637
+ minIndex = maxIndex = startIndex = i;
9638
+ }
9639
+ }
9640
+ return decimated;
9641
+ }
9642
+ function cleanDecimatedDataset(dataset) {
9643
+ if (dataset._decimated) {
9644
+ const data = dataset._data;
9645
+ delete dataset._decimated;
9646
+ delete dataset._data;
9647
+ Object.defineProperty(dataset, 'data', {value: data});
9648
+ }
9649
+ }
9650
+ function cleanDecimatedData(chart) {
9651
+ chart.data.datasets.forEach((dataset) => {
9652
+ cleanDecimatedDataset(dataset);
9653
+ });
9654
+ }
9655
+ function getStartAndCountOfVisiblePointsSimplified(meta, points) {
9656
+ const pointCount = points.length;
9657
+ let start = 0;
9658
+ let count;
9659
+ const {iScale} = meta;
9660
+ const {min, max, minDefined, maxDefined} = iScale.getUserBounds();
9661
+ if (minDefined) {
9662
+ start = _limitValue(_lookupByKey(points, iScale.axis, min).lo, 0, pointCount - 1);
9663
+ }
9664
+ if (maxDefined) {
9665
+ count = _limitValue(_lookupByKey(points, iScale.axis, max).hi + 1, start, pointCount) - start;
9666
+ } else {
9667
+ count = pointCount - start;
9668
+ }
9669
+ return {start, count};
9670
+ }
9671
+ var plugin_decimation = {
9672
+ id: 'decimation',
9673
+ defaults: {
9674
+ algorithm: 'min-max',
9675
+ enabled: false,
9676
+ },
9677
+ beforeElementsUpdate: (chart, args, options) => {
9678
+ if (!options.enabled) {
9679
+ cleanDecimatedData(chart);
9680
+ return;
9681
+ }
9682
+ const availableWidth = chart.width;
9683
+ chart.data.datasets.forEach((dataset, datasetIndex) => {
9684
+ const {_data, indexAxis} = dataset;
9685
+ const meta = chart.getDatasetMeta(datasetIndex);
9686
+ const data = _data || dataset.data;
9687
+ if (resolve([indexAxis, chart.options.indexAxis]) === 'y') {
9688
+ return;
9689
+ }
9690
+ if (meta.type !== 'line') {
9691
+ return;
9692
+ }
9693
+ const xAxis = chart.scales[meta.xAxisID];
9694
+ if (xAxis.type !== 'linear' && xAxis.type !== 'time') {
9695
+ return;
9696
+ }
9697
+ if (chart.options.parsing) {
9698
+ return;
9699
+ }
9700
+ let {start, count} = getStartAndCountOfVisiblePointsSimplified(meta, data);
9701
+ const threshold = options.threshold || 4 * availableWidth;
9702
+ if (count <= threshold) {
9703
+ cleanDecimatedDataset(dataset);
9704
+ return;
9705
+ }
9706
+ if (isNullOrUndef(_data)) {
9707
+ dataset._data = data;
9708
+ delete dataset.data;
9709
+ Object.defineProperty(dataset, 'data', {
9710
+ configurable: true,
9711
+ enumerable: true,
9712
+ get: function() {
9713
+ return this._decimated;
9714
+ },
9715
+ set: function(d) {
9716
+ this._data = d;
9717
+ }
9718
+ });
9719
+ }
9720
+ let decimated;
9721
+ switch (options.algorithm) {
9722
+ case 'lttb':
9723
+ decimated = lttbDecimation(data, start, count, availableWidth, options);
9724
+ break;
9725
+ case 'min-max':
9726
+ decimated = minMaxDecimation(data, start, count, availableWidth);
9727
+ break;
9728
+ default:
9729
+ throw new Error(`Unsupported decimation algorithm '${options.algorithm}'`);
9730
+ }
9731
+ dataset._decimated = decimated;
9732
+ });
9733
+ },
9734
+ destroy(chart) {
9735
+ cleanDecimatedData(chart);
9736
+ }
9737
+ };
9738
+
9739
+ function getLineByIndex(chart, index) {
9740
+ const meta = chart.getDatasetMeta(index);
9741
+ const visible = meta && chart.isDatasetVisible(index);
9742
+ return visible ? meta.dataset : null;
9743
+ }
9744
+ function parseFillOption(line) {
9745
+ const options = line.options;
9746
+ const fillOption = options.fill;
9747
+ let fill = valueOrDefault(fillOption && fillOption.target, fillOption);
9748
+ if (fill === undefined) {
9749
+ fill = !!options.backgroundColor;
9750
+ }
9751
+ if (fill === false || fill === null) {
9752
+ return false;
9753
+ }
9754
+ if (fill === true) {
9755
+ return 'origin';
9756
+ }
9757
+ return fill;
9758
+ }
9759
+ function decodeFill(line, index, count) {
9760
+ const fill = parseFillOption(line);
9761
+ if (isObject(fill)) {
9762
+ return isNaN(fill.value) ? false : fill;
9763
+ }
9764
+ let target = parseFloat(fill);
9765
+ if (isNumberFinite(target) && Math.floor(target) === target) {
9766
+ if (fill[0] === '-' || fill[0] === '+') {
9767
+ target = index + target;
9768
+ }
9769
+ if (target === index || target < 0 || target >= count) {
9770
+ return false;
9771
+ }
9772
+ return target;
9773
+ }
9774
+ return ['origin', 'start', 'end', 'stack', 'shape'].indexOf(fill) >= 0 && fill;
9775
+ }
9776
+ function computeLinearBoundary(source) {
9777
+ const {scale = {}, fill} = source;
9778
+ let target = null;
9779
+ let horizontal;
9780
+ if (fill === 'start') {
9781
+ target = scale.bottom;
9782
+ } else if (fill === 'end') {
9783
+ target = scale.top;
9784
+ } else if (isObject(fill)) {
9785
+ target = scale.getPixelForValue(fill.value);
9786
+ } else if (scale.getBasePixel) {
9787
+ target = scale.getBasePixel();
9788
+ }
9789
+ if (isNumberFinite(target)) {
9790
+ horizontal = scale.isHorizontal();
9791
+ return {
9792
+ x: horizontal ? target : null,
9793
+ y: horizontal ? null : target
9794
+ };
9795
+ }
9796
+ return null;
9797
+ }
9798
+ class simpleArc {
9799
+ constructor(opts) {
9800
+ this.x = opts.x;
9801
+ this.y = opts.y;
9802
+ this.radius = opts.radius;
9803
+ }
9804
+ pathSegment(ctx, bounds, opts) {
9805
+ const {x, y, radius} = this;
9806
+ bounds = bounds || {start: 0, end: TAU};
9807
+ ctx.arc(x, y, radius, bounds.end, bounds.start, true);
9808
+ return !opts.bounds;
9809
+ }
9810
+ interpolate(point) {
9811
+ const {x, y, radius} = this;
9812
+ const angle = point.angle;
9813
+ return {
9814
+ x: x + Math.cos(angle) * radius,
9815
+ y: y + Math.sin(angle) * radius,
9816
+ angle
9817
+ };
9818
+ }
9819
+ }
9820
+ function computeCircularBoundary(source) {
9821
+ const {scale, fill} = source;
9822
+ const options = scale.options;
9823
+ const length = scale.getLabels().length;
9824
+ const target = [];
9825
+ const start = options.reverse ? scale.max : scale.min;
9826
+ const end = options.reverse ? scale.min : scale.max;
9827
+ let i, center, value;
9828
+ if (fill === 'start') {
9829
+ value = start;
9830
+ } else if (fill === 'end') {
9831
+ value = end;
9832
+ } else if (isObject(fill)) {
9833
+ value = fill.value;
9834
+ } else {
9835
+ value = scale.getBaseValue();
9836
+ }
9837
+ if (options.grid.circular) {
9838
+ center = scale.getPointPositionForValue(0, start);
9839
+ return new simpleArc({
9840
+ x: center.x,
9841
+ y: center.y,
9842
+ radius: scale.getDistanceFromCenterForValue(value)
9843
+ });
9844
+ }
9845
+ for (i = 0; i < length; ++i) {
9846
+ target.push(scale.getPointPositionForValue(i, value));
9847
+ }
9848
+ return target;
9849
+ }
9850
+ function computeBoundary(source) {
9851
+ const scale = source.scale || {};
9852
+ if (scale.getPointPositionForValue) {
9853
+ return computeCircularBoundary(source);
9854
+ }
9855
+ return computeLinearBoundary(source);
9856
+ }
9857
+ function findSegmentEnd(start, end, points) {
9858
+ for (;end > start; end--) {
9859
+ const point = points[end];
9860
+ if (!isNaN(point.x) && !isNaN(point.y)) {
9861
+ break;
9862
+ }
9863
+ }
9864
+ return end;
9865
+ }
9866
+ function pointsFromSegments(boundary, line) {
9867
+ const {x = null, y = null} = boundary || {};
9868
+ const linePoints = line.points;
9869
+ const points = [];
9870
+ line.segments.forEach(({start, end}) => {
9871
+ end = findSegmentEnd(start, end, linePoints);
9872
+ const first = linePoints[start];
9873
+ const last = linePoints[end];
9874
+ if (y !== null) {
9875
+ points.push({x: first.x, y});
9876
+ points.push({x: last.x, y});
9877
+ } else if (x !== null) {
9878
+ points.push({x, y: first.y});
9879
+ points.push({x, y: last.y});
9880
+ }
9881
+ });
9882
+ return points;
9883
+ }
9884
+ function buildStackLine(source) {
9885
+ const {scale, index, line} = source;
9886
+ const points = [];
9887
+ const segments = line.segments;
9888
+ const sourcePoints = line.points;
9889
+ const linesBelow = getLinesBelow(scale, index);
9890
+ linesBelow.push(createBoundaryLine({x: null, y: scale.bottom}, line));
9891
+ for (let i = 0; i < segments.length; i++) {
9892
+ const segment = segments[i];
9893
+ for (let j = segment.start; j <= segment.end; j++) {
9894
+ addPointsBelow(points, sourcePoints[j], linesBelow);
9895
+ }
9896
+ }
9897
+ return new LineElement({points, options: {}});
9898
+ }
9899
+ function getLinesBelow(scale, index) {
9900
+ const below = [];
9901
+ const metas = scale.getMatchingVisibleMetas('line');
9902
+ for (let i = 0; i < metas.length; i++) {
9903
+ const meta = metas[i];
9904
+ if (meta.index === index) {
9905
+ break;
9906
+ }
9907
+ if (!meta.hidden) {
9908
+ below.unshift(meta.dataset);
9909
+ }
9910
+ }
9911
+ return below;
9912
+ }
9913
+ function addPointsBelow(points, sourcePoint, linesBelow) {
9914
+ const postponed = [];
9915
+ for (let j = 0; j < linesBelow.length; j++) {
9916
+ const line = linesBelow[j];
9917
+ const {first, last, point} = findPoint(line, sourcePoint, 'x');
9918
+ if (!point || (first && last)) {
9919
+ continue;
9920
+ }
9921
+ if (first) {
9922
+ postponed.unshift(point);
9923
+ } else {
9924
+ points.push(point);
9925
+ if (!last) {
9926
+ break;
9927
+ }
9928
+ }
9929
+ }
9930
+ points.push(...postponed);
9931
+ }
9932
+ function findPoint(line, sourcePoint, property) {
9933
+ const point = line.interpolate(sourcePoint, property);
9934
+ if (!point) {
9935
+ return {};
9936
+ }
9937
+ const pointValue = point[property];
9938
+ const segments = line.segments;
9939
+ const linePoints = line.points;
9940
+ let first = false;
9941
+ let last = false;
9942
+ for (let i = 0; i < segments.length; i++) {
9943
+ const segment = segments[i];
9944
+ const firstValue = linePoints[segment.start][property];
9945
+ const lastValue = linePoints[segment.end][property];
9946
+ if (_isBetween(pointValue, firstValue, lastValue)) {
9947
+ first = pointValue === firstValue;
9948
+ last = pointValue === lastValue;
9949
+ break;
9950
+ }
9951
+ }
9952
+ return {first, last, point};
9953
+ }
9954
+ function getTarget(source) {
9955
+ const {chart, fill, line} = source;
9956
+ if (isNumberFinite(fill)) {
9957
+ return getLineByIndex(chart, fill);
9958
+ }
9959
+ if (fill === 'stack') {
9960
+ return buildStackLine(source);
9961
+ }
9962
+ if (fill === 'shape') {
9963
+ return true;
9964
+ }
9965
+ const boundary = computeBoundary(source);
9966
+ if (boundary instanceof simpleArc) {
9967
+ return boundary;
9968
+ }
9969
+ return createBoundaryLine(boundary, line);
9970
+ }
9971
+ function createBoundaryLine(boundary, line) {
9972
+ let points = [];
9973
+ let _loop = false;
9974
+ if (isArray(boundary)) {
9975
+ _loop = true;
9976
+ points = boundary;
9977
+ } else {
9978
+ points = pointsFromSegments(boundary, line);
9979
+ }
9980
+ return points.length ? new LineElement({
9981
+ points,
9982
+ options: {tension: 0},
9983
+ _loop,
9984
+ _fullLoop: _loop
9985
+ }) : null;
9986
+ }
9987
+ function resolveTarget(sources, index, propagate) {
9988
+ const source = sources[index];
9989
+ let fill = source.fill;
9990
+ const visited = [index];
9991
+ let target;
9992
+ if (!propagate) {
9993
+ return fill;
9994
+ }
9995
+ while (fill !== false && visited.indexOf(fill) === -1) {
9996
+ if (!isNumberFinite(fill)) {
9997
+ return fill;
9998
+ }
9999
+ target = sources[fill];
10000
+ if (!target) {
10001
+ return false;
10002
+ }
10003
+ if (target.visible) {
10004
+ return fill;
10005
+ }
10006
+ visited.push(fill);
10007
+ fill = target.fill;
10008
+ }
10009
+ return false;
10010
+ }
10011
+ function _clip(ctx, target, clipY) {
10012
+ const {segments, points} = target;
10013
+ let first = true;
10014
+ let lineLoop = false;
10015
+ ctx.beginPath();
10016
+ for (const segment of segments) {
10017
+ const {start, end} = segment;
10018
+ const firstPoint = points[start];
10019
+ const lastPoint = points[findSegmentEnd(start, end, points)];
10020
+ if (first) {
10021
+ ctx.moveTo(firstPoint.x, firstPoint.y);
10022
+ first = false;
10023
+ } else {
10024
+ ctx.lineTo(firstPoint.x, clipY);
10025
+ ctx.lineTo(firstPoint.x, firstPoint.y);
10026
+ }
10027
+ lineLoop = !!target.pathSegment(ctx, segment, {move: lineLoop});
10028
+ if (lineLoop) {
10029
+ ctx.closePath();
10030
+ } else {
10031
+ ctx.lineTo(lastPoint.x, clipY);
10032
+ }
10033
+ }
10034
+ ctx.lineTo(target.first().x, clipY);
10035
+ ctx.closePath();
10036
+ ctx.clip();
10037
+ }
10038
+ function getBounds(property, first, last, loop) {
10039
+ if (loop) {
10040
+ return;
10041
+ }
10042
+ let start = first[property];
10043
+ let end = last[property];
10044
+ if (property === 'angle') {
10045
+ start = _normalizeAngle(start);
10046
+ end = _normalizeAngle(end);
10047
+ }
10048
+ return {property, start, end};
10049
+ }
10050
+ function _getEdge(a, b, prop, fn) {
10051
+ if (a && b) {
10052
+ return fn(a[prop], b[prop]);
10053
+ }
10054
+ return a ? a[prop] : b ? b[prop] : 0;
10055
+ }
10056
+ function _segments(line, target, property) {
10057
+ const segments = line.segments;
10058
+ const points = line.points;
10059
+ const tpoints = target.points;
10060
+ const parts = [];
10061
+ for (const segment of segments) {
10062
+ let {start, end} = segment;
10063
+ end = findSegmentEnd(start, end, points);
10064
+ const bounds = getBounds(property, points[start], points[end], segment.loop);
10065
+ if (!target.segments) {
10066
+ parts.push({
10067
+ source: segment,
10068
+ target: bounds,
10069
+ start: points[start],
10070
+ end: points[end]
10071
+ });
10072
+ continue;
10073
+ }
10074
+ const targetSegments = _boundSegments(target, bounds);
10075
+ for (const tgt of targetSegments) {
10076
+ const subBounds = getBounds(property, tpoints[tgt.start], tpoints[tgt.end], tgt.loop);
10077
+ const fillSources = _boundSegment(segment, points, subBounds);
10078
+ for (const fillSource of fillSources) {
10079
+ parts.push({
10080
+ source: fillSource,
10081
+ target: tgt,
10082
+ start: {
10083
+ [property]: _getEdge(bounds, subBounds, 'start', Math.max)
10084
+ },
10085
+ end: {
10086
+ [property]: _getEdge(bounds, subBounds, 'end', Math.min)
10087
+ }
10088
+ });
10089
+ }
10090
+ }
10091
+ }
10092
+ return parts;
10093
+ }
10094
+ function clipBounds(ctx, scale, bounds) {
10095
+ const {top, bottom} = scale.chart.chartArea;
10096
+ const {property, start, end} = bounds || {};
10097
+ if (property === 'x') {
10098
+ ctx.beginPath();
10099
+ ctx.rect(start, top, end - start, bottom - top);
10100
+ ctx.clip();
10101
+ }
10102
+ }
10103
+ function interpolatedLineTo(ctx, target, point, property) {
10104
+ const interpolatedPoint = target.interpolate(point, property);
10105
+ if (interpolatedPoint) {
10106
+ ctx.lineTo(interpolatedPoint.x, interpolatedPoint.y);
10107
+ }
10108
+ }
10109
+ function _fill(ctx, cfg) {
10110
+ const {line, target, property, color, scale} = cfg;
10111
+ const segments = _segments(line, target, property);
10112
+ for (const {source: src, target: tgt, start, end} of segments) {
10113
+ const {style: {backgroundColor = color} = {}} = src;
10114
+ const notShape = target !== true;
10115
+ ctx.save();
10116
+ ctx.fillStyle = backgroundColor;
10117
+ clipBounds(ctx, scale, notShape && getBounds(property, start, end));
10118
+ ctx.beginPath();
10119
+ const lineLoop = !!line.pathSegment(ctx, src);
10120
+ let loop;
10121
+ if (notShape) {
10122
+ if (lineLoop) {
10123
+ ctx.closePath();
10124
+ } else {
10125
+ interpolatedLineTo(ctx, target, end, property);
10126
+ }
10127
+ const targetLoop = !!target.pathSegment(ctx, tgt, {move: lineLoop, reverse: true});
10128
+ loop = lineLoop && targetLoop;
10129
+ if (!loop) {
10130
+ interpolatedLineTo(ctx, target, start, property);
10131
+ }
10132
+ }
10133
+ ctx.closePath();
10134
+ ctx.fill(loop ? 'evenodd' : 'nonzero');
10135
+ ctx.restore();
10136
+ }
10137
+ }
10138
+ function doFill(ctx, cfg) {
10139
+ const {line, target, above, below, area, scale} = cfg;
10140
+ const property = line._loop ? 'angle' : cfg.axis;
10141
+ ctx.save();
10142
+ if (property === 'x' && below !== above) {
10143
+ _clip(ctx, target, area.top);
10144
+ _fill(ctx, {line, target, color: above, scale, property});
10145
+ ctx.restore();
10146
+ ctx.save();
10147
+ _clip(ctx, target, area.bottom);
10148
+ }
10149
+ _fill(ctx, {line, target, color: below, scale, property});
10150
+ ctx.restore();
10151
+ }
10152
+ function drawfill(ctx, source, area) {
10153
+ const target = getTarget(source);
10154
+ const {line, scale, axis} = source;
10155
+ const lineOpts = line.options;
10156
+ const fillOption = lineOpts.fill;
10157
+ const color = lineOpts.backgroundColor;
10158
+ const {above = color, below = color} = fillOption || {};
10159
+ if (target && line.points.length) {
10160
+ clipArea(ctx, area);
10161
+ doFill(ctx, {line, target, above, below, area, scale, axis});
10162
+ unclipArea(ctx);
10163
+ }
10164
+ }
10165
+ var plugin_filler = {
10166
+ id: 'filler',
10167
+ afterDatasetsUpdate(chart, _args, options) {
10168
+ const count = (chart.data.datasets || []).length;
10169
+ const sources = [];
10170
+ let meta, i, line, source;
10171
+ for (i = 0; i < count; ++i) {
10172
+ meta = chart.getDatasetMeta(i);
10173
+ line = meta.dataset;
10174
+ source = null;
10175
+ if (line && line.options && line instanceof LineElement) {
10176
+ source = {
10177
+ visible: chart.isDatasetVisible(i),
10178
+ index: i,
10179
+ fill: decodeFill(line, i, count),
10180
+ chart,
10181
+ axis: meta.controller.options.indexAxis,
10182
+ scale: meta.vScale,
10183
+ line,
10184
+ };
10185
+ }
10186
+ meta.$filler = source;
10187
+ sources.push(source);
10188
+ }
10189
+ for (i = 0; i < count; ++i) {
10190
+ source = sources[i];
10191
+ if (!source || source.fill === false) {
10192
+ continue;
10193
+ }
10194
+ source.fill = resolveTarget(sources, i, options.propagate);
10195
+ }
10196
+ },
10197
+ beforeDraw(chart, _args, options) {
10198
+ const draw = options.drawTime === 'beforeDraw';
10199
+ const metasets = chart.getSortedVisibleDatasetMetas();
10200
+ const area = chart.chartArea;
10201
+ for (let i = metasets.length - 1; i >= 0; --i) {
10202
+ const source = metasets[i].$filler;
10203
+ if (!source) {
10204
+ continue;
10205
+ }
10206
+ source.line.updateControlPoints(area, source.axis);
10207
+ if (draw) {
10208
+ drawfill(chart.ctx, source, area);
10209
+ }
10210
+ }
10211
+ },
10212
+ beforeDatasetsDraw(chart, _args, options) {
10213
+ if (options.drawTime !== 'beforeDatasetsDraw') {
10214
+ return;
10215
+ }
10216
+ const metasets = chart.getSortedVisibleDatasetMetas();
10217
+ for (let i = metasets.length - 1; i >= 0; --i) {
10218
+ const source = metasets[i].$filler;
10219
+ if (source) {
10220
+ drawfill(chart.ctx, source, chart.chartArea);
10221
+ }
10222
+ }
10223
+ },
10224
+ beforeDatasetDraw(chart, args, options) {
10225
+ const source = args.meta.$filler;
10226
+ if (!source || source.fill === false || options.drawTime !== 'beforeDatasetDraw') {
10227
+ return;
10228
+ }
10229
+ drawfill(chart.ctx, source, chart.chartArea);
10230
+ },
10231
+ defaults: {
10232
+ propagate: true,
10233
+ drawTime: 'beforeDatasetDraw'
10234
+ }
10235
+ };
10236
+
10237
+ const getBoxSize = (labelOpts, fontSize) => {
10238
+ let {boxHeight = fontSize, boxWidth = fontSize} = labelOpts;
10239
+ if (labelOpts.usePointStyle) {
10240
+ boxHeight = Math.min(boxHeight, fontSize);
10241
+ boxWidth = Math.min(boxWidth, fontSize);
10242
+ }
10243
+ return {
10244
+ boxWidth,
10245
+ boxHeight,
10246
+ itemHeight: Math.max(fontSize, boxHeight)
10247
+ };
10248
+ };
10249
+ const itemsEqual = (a, b) => a !== null && b !== null && a.datasetIndex === b.datasetIndex && a.index === b.index;
10250
+ class Legend extends Element {
10251
+ constructor(config) {
10252
+ super();
10253
+ this._added = false;
10254
+ this.legendHitBoxes = [];
10255
+ this._hoveredItem = null;
10256
+ this.doughnutMode = false;
10257
+ this.chart = config.chart;
10258
+ this.options = config.options;
10259
+ this.ctx = config.ctx;
10260
+ this.legendItems = undefined;
10261
+ this.columnSizes = undefined;
10262
+ this.lineWidths = undefined;
10263
+ this.maxHeight = undefined;
10264
+ this.maxWidth = undefined;
10265
+ this.top = undefined;
10266
+ this.bottom = undefined;
10267
+ this.left = undefined;
10268
+ this.right = undefined;
10269
+ this.height = undefined;
10270
+ this.width = undefined;
10271
+ this._margins = undefined;
10272
+ this.position = undefined;
10273
+ this.weight = undefined;
10274
+ this.fullSize = undefined;
10275
+ }
10276
+ update(maxWidth, maxHeight, margins) {
10277
+ this.maxWidth = maxWidth;
10278
+ this.maxHeight = maxHeight;
10279
+ this._margins = margins;
10280
+ this.setDimensions();
10281
+ this.buildLabels();
10282
+ this.fit();
10283
+ }
10284
+ setDimensions() {
10285
+ if (this.isHorizontal()) {
10286
+ this.width = this.maxWidth;
10287
+ this.left = this._margins.left;
10288
+ this.right = this.width;
10289
+ } else {
10290
+ this.height = this.maxHeight;
10291
+ this.top = this._margins.top;
10292
+ this.bottom = this.height;
10293
+ }
10294
+ }
10295
+ buildLabels() {
10296
+ const labelOpts = this.options.labels || {};
10297
+ let legendItems = callback(labelOpts.generateLabels, [this.chart], this) || [];
10298
+ if (labelOpts.filter) {
10299
+ legendItems = legendItems.filter((item) => labelOpts.filter(item, this.chart.data));
10300
+ }
10301
+ if (labelOpts.sort) {
10302
+ legendItems = legendItems.sort((a, b) => labelOpts.sort(a, b, this.chart.data));
10303
+ }
10304
+ if (this.options.reverse) {
10305
+ legendItems.reverse();
10306
+ }
10307
+ this.legendItems = legendItems;
10308
+ }
10309
+ fit() {
10310
+ const {options, ctx} = this;
10311
+ if (!options.display) {
10312
+ this.width = this.height = 0;
10313
+ return;
10314
+ }
10315
+ const labelOpts = options.labels;
10316
+ const labelFont = toFont(labelOpts.font);
10317
+ const fontSize = labelFont.size;
10318
+ const titleHeight = this._computeTitleHeight();
10319
+ const {boxWidth, itemHeight} = getBoxSize(labelOpts, fontSize);
10320
+ let width, height;
10321
+ ctx.font = labelFont.string;
10322
+ if (this.isHorizontal()) {
10323
+ width = this.maxWidth;
10324
+ height = this._fitRows(titleHeight, fontSize, boxWidth, itemHeight) + 10;
10325
+ } else {
10326
+ height = this.maxHeight;
10327
+ width = this._fitCols(titleHeight, fontSize, boxWidth, itemHeight) + 10;
10328
+ }
10329
+ this.width = Math.min(width, options.maxWidth || this.maxWidth);
10330
+ this.height = Math.min(height, options.maxHeight || this.maxHeight);
10331
+ }
10332
+ _fitRows(titleHeight, fontSize, boxWidth, itemHeight) {
10333
+ const {ctx, maxWidth, options: {labels: {padding}}} = this;
10334
+ const hitboxes = this.legendHitBoxes = [];
10335
+ const lineWidths = this.lineWidths = [0];
10336
+ const lineHeight = itemHeight + padding;
10337
+ let totalHeight = titleHeight;
10338
+ ctx.textAlign = 'left';
10339
+ ctx.textBaseline = 'middle';
10340
+ let row = -1;
10341
+ let top = -lineHeight;
10342
+ this.legendItems.forEach((legendItem, i) => {
10343
+ const itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
10344
+ if (i === 0 || lineWidths[lineWidths.length - 1] + itemWidth + 2 * padding > maxWidth) {
10345
+ totalHeight += lineHeight;
10346
+ lineWidths[lineWidths.length - (i > 0 ? 0 : 1)] = 0;
10347
+ top += lineHeight;
10348
+ row++;
10349
+ }
10350
+ hitboxes[i] = {left: 0, top, row, width: itemWidth, height: itemHeight};
10351
+ lineWidths[lineWidths.length - 1] += itemWidth + padding;
10352
+ });
10353
+ return totalHeight;
10354
+ }
10355
+ _fitCols(titleHeight, fontSize, boxWidth, itemHeight) {
10356
+ const {ctx, maxHeight, options: {labels: {padding}}} = this;
10357
+ const hitboxes = this.legendHitBoxes = [];
10358
+ const columnSizes = this.columnSizes = [];
10359
+ const heightLimit = maxHeight - titleHeight;
10360
+ let totalWidth = padding;
10361
+ let currentColWidth = 0;
10362
+ let currentColHeight = 0;
10363
+ let left = 0;
10364
+ let col = 0;
10365
+ this.legendItems.forEach((legendItem, i) => {
10366
+ const itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
10367
+ if (i > 0 && currentColHeight + itemHeight + 2 * padding > heightLimit) {
10368
+ totalWidth += currentColWidth + padding;
10369
+ columnSizes.push({width: currentColWidth, height: currentColHeight});
10370
+ left += currentColWidth + padding;
10371
+ col++;
10372
+ currentColWidth = currentColHeight = 0;
10373
+ }
10374
+ hitboxes[i] = {left, top: currentColHeight, col, width: itemWidth, height: itemHeight};
10375
+ currentColWidth = Math.max(currentColWidth, itemWidth);
10376
+ currentColHeight += itemHeight + padding;
10377
+ });
10378
+ totalWidth += currentColWidth;
10379
+ columnSizes.push({width: currentColWidth, height: currentColHeight});
10380
+ return totalWidth;
10381
+ }
10382
+ adjustHitBoxes() {
10383
+ if (!this.options.display) {
10384
+ return;
10385
+ }
10386
+ const titleHeight = this._computeTitleHeight();
10387
+ const {legendHitBoxes: hitboxes, options: {align, labels: {padding}, rtl}} = this;
10388
+ const rtlHelper = getRtlAdapter(rtl, this.left, this.width);
10389
+ if (this.isHorizontal()) {
10390
+ let row = 0;
10391
+ let left = _alignStartEnd(align, this.left + padding, this.right - this.lineWidths[row]);
10392
+ for (const hitbox of hitboxes) {
10393
+ if (row !== hitbox.row) {
10394
+ row = hitbox.row;
10395
+ left = _alignStartEnd(align, this.left + padding, this.right - this.lineWidths[row]);
10396
+ }
10397
+ hitbox.top += this.top + titleHeight + padding;
10398
+ hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(left), hitbox.width);
10399
+ left += hitbox.width + padding;
10400
+ }
10401
+ } else {
10402
+ let col = 0;
10403
+ let top = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height);
10404
+ for (const hitbox of hitboxes) {
10405
+ if (hitbox.col !== col) {
10406
+ col = hitbox.col;
10407
+ top = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - this.columnSizes[col].height);
10408
+ }
10409
+ hitbox.top = top;
10410
+ hitbox.left += this.left + padding;
10411
+ hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(hitbox.left), hitbox.width);
10412
+ top += hitbox.height + padding;
10413
+ }
10414
+ }
10415
+ }
10416
+ isHorizontal() {
10417
+ return this.options.position === 'top' || this.options.position === 'bottom';
10418
+ }
10419
+ draw() {
10420
+ if (this.options.display) {
10421
+ const ctx = this.ctx;
10422
+ clipArea(ctx, this);
10423
+ this._draw();
10424
+ unclipArea(ctx);
10425
+ }
10426
+ }
10427
+ _draw() {
10428
+ const {options: opts, columnSizes, lineWidths, ctx} = this;
10429
+ const {align, labels: labelOpts} = opts;
10430
+ const defaultColor = defaults.color;
10431
+ const rtlHelper = getRtlAdapter(opts.rtl, this.left, this.width);
10432
+ const labelFont = toFont(labelOpts.font);
10433
+ const {color: fontColor, padding} = labelOpts;
10434
+ const fontSize = labelFont.size;
10435
+ const halfFontSize = fontSize / 2;
10436
+ let cursor;
10437
+ this.drawTitle();
10438
+ ctx.textAlign = rtlHelper.textAlign('left');
10439
+ ctx.textBaseline = 'middle';
10440
+ ctx.lineWidth = 0.5;
10441
+ ctx.font = labelFont.string;
10442
+ const {boxWidth, boxHeight, itemHeight} = getBoxSize(labelOpts, fontSize);
10443
+ const drawLegendBox = function(x, y, legendItem) {
10444
+ if (isNaN(boxWidth) || boxWidth <= 0 || isNaN(boxHeight) || boxHeight < 0) {
10445
+ return;
10446
+ }
10447
+ ctx.save();
10448
+ const lineWidth = valueOrDefault(legendItem.lineWidth, 1);
10449
+ ctx.fillStyle = valueOrDefault(legendItem.fillStyle, defaultColor);
10450
+ ctx.lineCap = valueOrDefault(legendItem.lineCap, 'butt');
10451
+ ctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, 0);
10452
+ ctx.lineJoin = valueOrDefault(legendItem.lineJoin, 'miter');
10453
+ ctx.lineWidth = lineWidth;
10454
+ ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, defaultColor);
10455
+ ctx.setLineDash(valueOrDefault(legendItem.lineDash, []));
10456
+ if (labelOpts.usePointStyle) {
10457
+ const drawOptions = {
10458
+ radius: boxWidth * Math.SQRT2 / 2,
10459
+ pointStyle: legendItem.pointStyle,
10460
+ rotation: legendItem.rotation,
10461
+ borderWidth: lineWidth
10462
+ };
10463
+ const centerX = rtlHelper.xPlus(x, boxWidth / 2);
10464
+ const centerY = y + halfFontSize;
10465
+ drawPoint(ctx, drawOptions, centerX, centerY);
10466
+ } else {
10467
+ const yBoxTop = y + Math.max((fontSize - boxHeight) / 2, 0);
10468
+ const xBoxLeft = rtlHelper.leftForLtr(x, boxWidth);
10469
+ const borderRadius = toTRBLCorners(legendItem.borderRadius);
10470
+ ctx.beginPath();
10471
+ if (Object.values(borderRadius).some(v => v !== 0)) {
10472
+ addRoundedRectPath(ctx, {
10473
+ x: xBoxLeft,
10474
+ y: yBoxTop,
10475
+ w: boxWidth,
10476
+ h: boxHeight,
10477
+ radius: borderRadius,
10478
+ });
10479
+ } else {
10480
+ ctx.rect(xBoxLeft, yBoxTop, boxWidth, boxHeight);
10481
+ }
10482
+ ctx.fill();
10483
+ if (lineWidth !== 0) {
10484
+ ctx.stroke();
10485
+ }
10486
+ }
10487
+ ctx.restore();
10488
+ };
10489
+ const fillText = function(x, y, legendItem) {
10490
+ renderText(ctx, legendItem.text, x, y + (itemHeight / 2), labelFont, {
10491
+ strikethrough: legendItem.hidden,
10492
+ textAlign: rtlHelper.textAlign(legendItem.textAlign)
10493
+ });
10494
+ };
10495
+ const isHorizontal = this.isHorizontal();
10496
+ const titleHeight = this._computeTitleHeight();
10497
+ if (isHorizontal) {
10498
+ cursor = {
10499
+ x: _alignStartEnd(align, this.left + padding, this.right - lineWidths[0]),
10500
+ y: this.top + padding + titleHeight,
10501
+ line: 0
10502
+ };
10503
+ } else {
10504
+ cursor = {
10505
+ x: this.left + padding,
10506
+ y: _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSizes[0].height),
10507
+ line: 0
10508
+ };
10509
+ }
10510
+ overrideTextDirection(this.ctx, opts.textDirection);
10511
+ const lineHeight = itemHeight + padding;
10512
+ this.legendItems.forEach((legendItem, i) => {
10513
+ ctx.strokeStyle = legendItem.fontColor || fontColor;
10514
+ ctx.fillStyle = legendItem.fontColor || fontColor;
10515
+ const textWidth = ctx.measureText(legendItem.text).width;
10516
+ const textAlign = rtlHelper.textAlign(legendItem.textAlign || (legendItem.textAlign = labelOpts.textAlign));
10517
+ const width = boxWidth + halfFontSize + textWidth;
10518
+ let x = cursor.x;
10519
+ let y = cursor.y;
10520
+ rtlHelper.setWidth(this.width);
10521
+ if (isHorizontal) {
10522
+ if (i > 0 && x + width + padding > this.right) {
10523
+ y = cursor.y += lineHeight;
10524
+ cursor.line++;
10525
+ x = cursor.x = _alignStartEnd(align, this.left + padding, this.right - lineWidths[cursor.line]);
10526
+ }
10527
+ } else if (i > 0 && y + lineHeight > this.bottom) {
10528
+ x = cursor.x = x + columnSizes[cursor.line].width + padding;
10529
+ cursor.line++;
10530
+ y = cursor.y = _alignStartEnd(align, this.top + titleHeight + padding, this.bottom - columnSizes[cursor.line].height);
10531
+ }
10532
+ const realX = rtlHelper.x(x);
10533
+ drawLegendBox(realX, y, legendItem);
10534
+ x = _textX(textAlign, x + boxWidth + halfFontSize, isHorizontal ? x + width : this.right, opts.rtl);
10535
+ fillText(rtlHelper.x(x), y, legendItem);
10536
+ if (isHorizontal) {
10537
+ cursor.x += width + padding;
10538
+ } else {
10539
+ cursor.y += lineHeight;
10540
+ }
10541
+ });
10542
+ restoreTextDirection(this.ctx, opts.textDirection);
10543
+ }
10544
+ drawTitle() {
10545
+ const opts = this.options;
10546
+ const titleOpts = opts.title;
10547
+ const titleFont = toFont(titleOpts.font);
10548
+ const titlePadding = toPadding(titleOpts.padding);
10549
+ if (!titleOpts.display) {
10550
+ return;
10551
+ }
10552
+ const rtlHelper = getRtlAdapter(opts.rtl, this.left, this.width);
10553
+ const ctx = this.ctx;
10554
+ const position = titleOpts.position;
10555
+ const halfFontSize = titleFont.size / 2;
10556
+ const topPaddingPlusHalfFontSize = titlePadding.top + halfFontSize;
10557
+ let y;
10558
+ let left = this.left;
10559
+ let maxWidth = this.width;
10560
+ if (this.isHorizontal()) {
10561
+ maxWidth = Math.max(...this.lineWidths);
10562
+ y = this.top + topPaddingPlusHalfFontSize;
10563
+ left = _alignStartEnd(opts.align, left, this.right - maxWidth);
10564
+ } else {
10565
+ const maxHeight = this.columnSizes.reduce((acc, size) => Math.max(acc, size.height), 0);
10566
+ y = topPaddingPlusHalfFontSize + _alignStartEnd(opts.align, this.top, this.bottom - maxHeight - opts.labels.padding - this._computeTitleHeight());
10567
+ }
10568
+ const x = _alignStartEnd(position, left, left + maxWidth);
10569
+ ctx.textAlign = rtlHelper.textAlign(_toLeftRightCenter(position));
10570
+ ctx.textBaseline = 'middle';
10571
+ ctx.strokeStyle = titleOpts.color;
10572
+ ctx.fillStyle = titleOpts.color;
10573
+ ctx.font = titleFont.string;
10574
+ renderText(ctx, titleOpts.text, x, y, titleFont);
10575
+ }
10576
+ _computeTitleHeight() {
10577
+ const titleOpts = this.options.title;
10578
+ const titleFont = toFont(titleOpts.font);
10579
+ const titlePadding = toPadding(titleOpts.padding);
10580
+ return titleOpts.display ? titleFont.lineHeight + titlePadding.height : 0;
10581
+ }
10582
+ _getLegendItemAt(x, y) {
10583
+ let i, hitBox, lh;
10584
+ if (_isBetween(x, this.left, this.right)
10585
+ && _isBetween(y, this.top, this.bottom)) {
10586
+ lh = this.legendHitBoxes;
10587
+ for (i = 0; i < lh.length; ++i) {
10588
+ hitBox = lh[i];
10589
+ if (_isBetween(x, hitBox.left, hitBox.left + hitBox.width)
10590
+ && _isBetween(y, hitBox.top, hitBox.top + hitBox.height)) {
10591
+ return this.legendItems[i];
10592
+ }
10593
+ }
10594
+ }
10595
+ return null;
10596
+ }
10597
+ handleEvent(e) {
10598
+ const opts = this.options;
10599
+ if (!isListened(e.type, opts)) {
10600
+ return;
10601
+ }
10602
+ const hoveredItem = this._getLegendItemAt(e.x, e.y);
10603
+ if (e.type === 'mousemove') {
10604
+ const previous = this._hoveredItem;
10605
+ const sameItem = itemsEqual(previous, hoveredItem);
10606
+ if (previous && !sameItem) {
10607
+ callback(opts.onLeave, [e, previous, this], this);
10608
+ }
10609
+ this._hoveredItem = hoveredItem;
10610
+ if (hoveredItem && !sameItem) {
10611
+ callback(opts.onHover, [e, hoveredItem, this], this);
10612
+ }
10613
+ } else if (hoveredItem) {
10614
+ callback(opts.onClick, [e, hoveredItem, this], this);
10615
+ }
10616
+ }
10617
+ }
10618
+ function isListened(type, opts) {
10619
+ if (type === 'mousemove' && (opts.onHover || opts.onLeave)) {
10620
+ return true;
10621
+ }
10622
+ if (opts.onClick && (type === 'click' || type === 'mouseup')) {
10623
+ return true;
10624
+ }
10625
+ return false;
10626
+ }
10627
+ var plugin_legend = {
10628
+ id: 'legend',
10629
+ _element: Legend,
10630
+ start(chart, _args, options) {
10631
+ const legend = chart.legend = new Legend({ctx: chart.ctx, options, chart});
10632
+ layouts.configure(chart, legend, options);
10633
+ layouts.addBox(chart, legend);
10634
+ },
10635
+ stop(chart) {
10636
+ layouts.removeBox(chart, chart.legend);
10637
+ delete chart.legend;
10638
+ },
10639
+ beforeUpdate(chart, _args, options) {
10640
+ const legend = chart.legend;
10641
+ layouts.configure(chart, legend, options);
10642
+ legend.options = options;
10643
+ },
10644
+ afterUpdate(chart) {
10645
+ const legend = chart.legend;
10646
+ legend.buildLabels();
10647
+ legend.adjustHitBoxes();
10648
+ },
10649
+ afterEvent(chart, args) {
10650
+ if (!args.replay) {
10651
+ chart.legend.handleEvent(args.event);
10652
+ }
10653
+ },
10654
+ defaults: {
10655
+ display: true,
10656
+ position: 'top',
10657
+ align: 'center',
10658
+ fullSize: true,
10659
+ reverse: false,
10660
+ weight: 1000,
10661
+ onClick(e, legendItem, legend) {
10662
+ const index = legendItem.datasetIndex;
10663
+ const ci = legend.chart;
10664
+ if (ci.isDatasetVisible(index)) {
10665
+ ci.hide(index);
10666
+ legendItem.hidden = true;
10667
+ } else {
10668
+ ci.show(index);
10669
+ legendItem.hidden = false;
10670
+ }
10671
+ },
10672
+ onHover: null,
10673
+ onLeave: null,
10674
+ labels: {
10675
+ color: (ctx) => ctx.chart.options.color,
10676
+ boxWidth: 40,
10677
+ padding: 10,
10678
+ generateLabels(chart) {
10679
+ const datasets = chart.data.datasets;
10680
+ const {labels: {usePointStyle, pointStyle, textAlign, color}} = chart.legend.options;
10681
+ return chart._getSortedDatasetMetas().map((meta) => {
10682
+ const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
10683
+ const borderWidth = toPadding(style.borderWidth);
10684
+ return {
10685
+ text: datasets[meta.index].label,
10686
+ fillStyle: style.backgroundColor,
10687
+ fontColor: color,
10688
+ hidden: !meta.visible,
10689
+ lineCap: style.borderCapStyle,
10690
+ lineDash: style.borderDash,
10691
+ lineDashOffset: style.borderDashOffset,
10692
+ lineJoin: style.borderJoinStyle,
10693
+ lineWidth: (borderWidth.width + borderWidth.height) / 4,
10694
+ strokeStyle: style.borderColor,
10695
+ pointStyle: pointStyle || style.pointStyle,
10696
+ rotation: style.rotation,
10697
+ textAlign: textAlign || style.textAlign,
10698
+ borderRadius: 0,
10699
+ datasetIndex: meta.index
10700
+ };
10701
+ }, this);
10702
+ }
10703
+ },
10704
+ title: {
10705
+ color: (ctx) => ctx.chart.options.color,
10706
+ display: false,
10707
+ position: 'center',
10708
+ text: '',
10709
+ }
10710
+ },
10711
+ descriptors: {
10712
+ _scriptable: (name) => !name.startsWith('on'),
10713
+ labels: {
10714
+ _scriptable: (name) => !['generateLabels', 'filter', 'sort'].includes(name),
10715
+ }
10716
+ },
10717
+ };
10718
+
10719
+ class Title extends Element {
10720
+ constructor(config) {
10721
+ super();
10722
+ this.chart = config.chart;
10723
+ this.options = config.options;
10724
+ this.ctx = config.ctx;
10725
+ this._padding = undefined;
10726
+ this.top = undefined;
10727
+ this.bottom = undefined;
10728
+ this.left = undefined;
10729
+ this.right = undefined;
10730
+ this.width = undefined;
10731
+ this.height = undefined;
10732
+ this.position = undefined;
10733
+ this.weight = undefined;
10734
+ this.fullSize = undefined;
10735
+ }
10736
+ update(maxWidth, maxHeight) {
10737
+ const opts = this.options;
10738
+ this.left = 0;
10739
+ this.top = 0;
10740
+ if (!opts.display) {
10741
+ this.width = this.height = this.right = this.bottom = 0;
10742
+ return;
10743
+ }
10744
+ this.width = this.right = maxWidth;
10745
+ this.height = this.bottom = maxHeight;
10746
+ const lineCount = isArray(opts.text) ? opts.text.length : 1;
10747
+ this._padding = toPadding(opts.padding);
10748
+ const textSize = lineCount * toFont(opts.font).lineHeight + this._padding.height;
10749
+ if (this.isHorizontal()) {
10750
+ this.height = textSize;
10751
+ } else {
10752
+ this.width = textSize;
10753
+ }
10754
+ }
10755
+ isHorizontal() {
10756
+ const pos = this.options.position;
10757
+ return pos === 'top' || pos === 'bottom';
10758
+ }
10759
+ _drawArgs(offset) {
10760
+ const {top, left, bottom, right, options} = this;
10761
+ const align = options.align;
10762
+ let rotation = 0;
10763
+ let maxWidth, titleX, titleY;
10764
+ if (this.isHorizontal()) {
10765
+ titleX = _alignStartEnd(align, left, right);
10766
+ titleY = top + offset;
10767
+ maxWidth = right - left;
10768
+ } else {
10769
+ if (options.position === 'left') {
10770
+ titleX = left + offset;
10771
+ titleY = _alignStartEnd(align, bottom, top);
10772
+ rotation = PI * -0.5;
10773
+ } else {
10774
+ titleX = right - offset;
10775
+ titleY = _alignStartEnd(align, top, bottom);
10776
+ rotation = PI * 0.5;
10777
+ }
10778
+ maxWidth = bottom - top;
10779
+ }
10780
+ return {titleX, titleY, maxWidth, rotation};
10781
+ }
10782
+ draw() {
10783
+ const ctx = this.ctx;
10784
+ const opts = this.options;
10785
+ if (!opts.display) {
10786
+ return;
10787
+ }
10788
+ const fontOpts = toFont(opts.font);
10789
+ const lineHeight = fontOpts.lineHeight;
10790
+ const offset = lineHeight / 2 + this._padding.top;
10791
+ const {titleX, titleY, maxWidth, rotation} = this._drawArgs(offset);
10792
+ renderText(ctx, opts.text, 0, 0, fontOpts, {
10793
+ color: opts.color,
10794
+ maxWidth,
10795
+ rotation,
10796
+ textAlign: _toLeftRightCenter(opts.align),
10797
+ textBaseline: 'middle',
10798
+ translation: [titleX, titleY],
10799
+ });
10800
+ }
10801
+ }
10802
+ function createTitle(chart, titleOpts) {
10803
+ const title = new Title({
10804
+ ctx: chart.ctx,
10805
+ options: titleOpts,
10806
+ chart
10807
+ });
10808
+ layouts.configure(chart, title, titleOpts);
10809
+ layouts.addBox(chart, title);
10810
+ chart.titleBlock = title;
10811
+ }
10812
+ var plugin_title = {
10813
+ id: 'title',
10814
+ _element: Title,
10815
+ start(chart, _args, options) {
10816
+ createTitle(chart, options);
10817
+ },
10818
+ stop(chart) {
10819
+ const titleBlock = chart.titleBlock;
10820
+ layouts.removeBox(chart, titleBlock);
10821
+ delete chart.titleBlock;
10822
+ },
10823
+ beforeUpdate(chart, _args, options) {
10824
+ const title = chart.titleBlock;
10825
+ layouts.configure(chart, title, options);
10826
+ title.options = options;
10827
+ },
10828
+ defaults: {
10829
+ align: 'center',
10830
+ display: false,
10831
+ font: {
10832
+ weight: 'bold',
10833
+ },
10834
+ fullSize: true,
10835
+ padding: 10,
10836
+ position: 'top',
10837
+ text: '',
10838
+ weight: 2000
10839
+ },
10840
+ defaultRoutes: {
10841
+ color: 'color'
10842
+ },
10843
+ descriptors: {
10844
+ _scriptable: true,
10845
+ _indexable: false,
10846
+ },
10847
+ };
10848
+
10849
+ const map = new WeakMap();
10850
+ var plugin_subtitle = {
10851
+ id: 'subtitle',
10852
+ start(chart, _args, options) {
10853
+ const title = new Title({
10854
+ ctx: chart.ctx,
10855
+ options,
10856
+ chart
10857
+ });
10858
+ layouts.configure(chart, title, options);
10859
+ layouts.addBox(chart, title);
10860
+ map.set(chart, title);
10861
+ },
10862
+ stop(chart) {
10863
+ layouts.removeBox(chart, map.get(chart));
10864
+ map.delete(chart);
10865
+ },
10866
+ beforeUpdate(chart, _args, options) {
10867
+ const title = map.get(chart);
10868
+ layouts.configure(chart, title, options);
10869
+ title.options = options;
10870
+ },
10871
+ defaults: {
10872
+ align: 'center',
10873
+ display: false,
10874
+ font: {
10875
+ weight: 'normal',
10876
+ },
10877
+ fullSize: true,
10878
+ padding: 0,
10879
+ position: 'top',
10880
+ text: '',
10881
+ weight: 1500
10882
+ },
10883
+ defaultRoutes: {
10884
+ color: 'color'
10885
+ },
10886
+ descriptors: {
10887
+ _scriptable: true,
10888
+ _indexable: false,
10889
+ },
10890
+ };
10891
+
10892
+ const positioners = {
10893
+ average(items) {
10894
+ if (!items.length) {
10895
+ return false;
10896
+ }
10897
+ let i, len;
10898
+ let x = 0;
10899
+ let y = 0;
10900
+ let count = 0;
10901
+ for (i = 0, len = items.length; i < len; ++i) {
10902
+ const el = items[i].element;
10903
+ if (el && el.hasValue()) {
10904
+ const pos = el.tooltipPosition();
10905
+ x += pos.x;
10906
+ y += pos.y;
10907
+ ++count;
10908
+ }
10909
+ }
10910
+ return {
10911
+ x: x / count,
10912
+ y: y / count
10913
+ };
10914
+ },
10915
+ nearest(items, eventPosition) {
10916
+ if (!items.length) {
10917
+ return false;
10918
+ }
10919
+ let x = eventPosition.x;
10920
+ let y = eventPosition.y;
10921
+ let minDistance = Number.POSITIVE_INFINITY;
10922
+ let i, len, nearestElement;
10923
+ for (i = 0, len = items.length; i < len; ++i) {
10924
+ const el = items[i].element;
10925
+ if (el && el.hasValue()) {
10926
+ const center = el.getCenterPoint();
10927
+ const d = distanceBetweenPoints(eventPosition, center);
10928
+ if (d < minDistance) {
10929
+ minDistance = d;
10930
+ nearestElement = el;
10931
+ }
10932
+ }
10933
+ }
10934
+ if (nearestElement) {
10935
+ const tp = nearestElement.tooltipPosition();
10936
+ x = tp.x;
10937
+ y = tp.y;
10938
+ }
10939
+ return {
10940
+ x,
10941
+ y
10942
+ };
10943
+ }
10944
+ };
10945
+ function pushOrConcat(base, toPush) {
10946
+ if (toPush) {
10947
+ if (isArray(toPush)) {
10948
+ Array.prototype.push.apply(base, toPush);
10949
+ } else {
10950
+ base.push(toPush);
10951
+ }
10952
+ }
10953
+ return base;
10954
+ }
10955
+ function splitNewlines(str) {
10956
+ if ((typeof str === 'string' || str instanceof String) && str.indexOf('\n') > -1) {
10957
+ return str.split('\n');
10958
+ }
10959
+ return str;
10960
+ }
10961
+ function createTooltipItem(chart, item) {
10962
+ const {element, datasetIndex, index} = item;
10963
+ const controller = chart.getDatasetMeta(datasetIndex).controller;
10964
+ const {label, value} = controller.getLabelAndValue(index);
10965
+ return {
10966
+ chart,
10967
+ label,
10968
+ parsed: controller.getParsed(index),
10969
+ raw: chart.data.datasets[datasetIndex].data[index],
10970
+ formattedValue: value,
10971
+ dataset: controller.getDataset(),
10972
+ dataIndex: index,
10973
+ datasetIndex,
10974
+ element
10975
+ };
10976
+ }
10977
+ function getTooltipSize(tooltip, options) {
10978
+ const ctx = tooltip.chart.ctx;
10979
+ const {body, footer, title} = tooltip;
10980
+ const {boxWidth, boxHeight} = options;
10981
+ const bodyFont = toFont(options.bodyFont);
10982
+ const titleFont = toFont(options.titleFont);
10983
+ const footerFont = toFont(options.footerFont);
10984
+ const titleLineCount = title.length;
10985
+ const footerLineCount = footer.length;
10986
+ const bodyLineItemCount = body.length;
10987
+ const padding = toPadding(options.padding);
10988
+ let height = padding.height;
10989
+ let width = 0;
10990
+ let combinedBodyLength = body.reduce((count, bodyItem) => count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length, 0);
10991
+ combinedBodyLength += tooltip.beforeBody.length + tooltip.afterBody.length;
10992
+ if (titleLineCount) {
10993
+ height += titleLineCount * titleFont.lineHeight
10994
+ + (titleLineCount - 1) * options.titleSpacing
10995
+ + options.titleMarginBottom;
10996
+ }
10997
+ if (combinedBodyLength) {
10998
+ const bodyLineHeight = options.displayColors ? Math.max(boxHeight, bodyFont.lineHeight) : bodyFont.lineHeight;
10999
+ height += bodyLineItemCount * bodyLineHeight
11000
+ + (combinedBodyLength - bodyLineItemCount) * bodyFont.lineHeight
11001
+ + (combinedBodyLength - 1) * options.bodySpacing;
11002
+ }
11003
+ if (footerLineCount) {
11004
+ height += options.footerMarginTop
11005
+ + footerLineCount * footerFont.lineHeight
11006
+ + (footerLineCount - 1) * options.footerSpacing;
11007
+ }
11008
+ let widthPadding = 0;
11009
+ const maxLineWidth = function(line) {
11010
+ width = Math.max(width, ctx.measureText(line).width + widthPadding);
11011
+ };
11012
+ ctx.save();
11013
+ ctx.font = titleFont.string;
11014
+ each(tooltip.title, maxLineWidth);
11015
+ ctx.font = bodyFont.string;
11016
+ each(tooltip.beforeBody.concat(tooltip.afterBody), maxLineWidth);
11017
+ widthPadding = options.displayColors ? (boxWidth + 2 + options.boxPadding) : 0;
11018
+ each(body, (bodyItem) => {
11019
+ each(bodyItem.before, maxLineWidth);
11020
+ each(bodyItem.lines, maxLineWidth);
11021
+ each(bodyItem.after, maxLineWidth);
11022
+ });
11023
+ widthPadding = 0;
11024
+ ctx.font = footerFont.string;
11025
+ each(tooltip.footer, maxLineWidth);
11026
+ ctx.restore();
11027
+ width += padding.width;
11028
+ return {width, height};
11029
+ }
11030
+ function determineYAlign(chart, size) {
11031
+ const {y, height} = size;
11032
+ if (y < height / 2) {
11033
+ return 'top';
11034
+ } else if (y > (chart.height - height / 2)) {
11035
+ return 'bottom';
11036
+ }
11037
+ return 'center';
11038
+ }
11039
+ function doesNotFitWithAlign(xAlign, chart, options, size) {
11040
+ const {x, width} = size;
11041
+ const caret = options.caretSize + options.caretPadding;
11042
+ if (xAlign === 'left' && x + width + caret > chart.width) {
11043
+ return true;
11044
+ }
11045
+ if (xAlign === 'right' && x - width - caret < 0) {
11046
+ return true;
11047
+ }
11048
+ }
11049
+ function determineXAlign(chart, options, size, yAlign) {
11050
+ const {x, width} = size;
11051
+ const {width: chartWidth, chartArea: {left, right}} = chart;
11052
+ let xAlign = 'center';
11053
+ if (yAlign === 'center') {
11054
+ xAlign = x <= (left + right) / 2 ? 'left' : 'right';
11055
+ } else if (x <= width / 2) {
11056
+ xAlign = 'left';
11057
+ } else if (x >= chartWidth - width / 2) {
11058
+ xAlign = 'right';
11059
+ }
11060
+ if (doesNotFitWithAlign(xAlign, chart, options, size)) {
11061
+ xAlign = 'center';
11062
+ }
11063
+ return xAlign;
11064
+ }
11065
+ function determineAlignment(chart, options, size) {
11066
+ const yAlign = size.yAlign || options.yAlign || determineYAlign(chart, size);
11067
+ return {
11068
+ xAlign: size.xAlign || options.xAlign || determineXAlign(chart, options, size, yAlign),
11069
+ yAlign
11070
+ };
11071
+ }
11072
+ function alignX(size, xAlign) {
11073
+ let {x, width} = size;
11074
+ if (xAlign === 'right') {
11075
+ x -= width;
11076
+ } else if (xAlign === 'center') {
11077
+ x -= (width / 2);
11078
+ }
11079
+ return x;
11080
+ }
11081
+ function alignY(size, yAlign, paddingAndSize) {
11082
+ let {y, height} = size;
11083
+ if (yAlign === 'top') {
11084
+ y += paddingAndSize;
11085
+ } else if (yAlign === 'bottom') {
11086
+ y -= height + paddingAndSize;
11087
+ } else {
11088
+ y -= (height / 2);
11089
+ }
11090
+ return y;
11091
+ }
11092
+ function getBackgroundPoint(options, size, alignment, chart) {
11093
+ const {caretSize, caretPadding, cornerRadius} = options;
11094
+ const {xAlign, yAlign} = alignment;
11095
+ const paddingAndSize = caretSize + caretPadding;
11096
+ const {topLeft, topRight, bottomLeft, bottomRight} = toTRBLCorners(cornerRadius);
11097
+ let x = alignX(size, xAlign);
11098
+ const y = alignY(size, yAlign, paddingAndSize);
11099
+ if (yAlign === 'center') {
11100
+ if (xAlign === 'left') {
11101
+ x += paddingAndSize;
11102
+ } else if (xAlign === 'right') {
11103
+ x -= paddingAndSize;
11104
+ }
11105
+ } else if (xAlign === 'left') {
11106
+ x -= Math.max(topLeft, bottomLeft) + caretSize;
11107
+ } else if (xAlign === 'right') {
11108
+ x += Math.max(topRight, bottomRight) + caretSize;
11109
+ }
11110
+ return {
11111
+ x: _limitValue(x, 0, chart.width - size.width),
11112
+ y: _limitValue(y, 0, chart.height - size.height)
11113
+ };
11114
+ }
11115
+ function getAlignedX(tooltip, align, options) {
11116
+ const padding = toPadding(options.padding);
11117
+ return align === 'center'
11118
+ ? tooltip.x + tooltip.width / 2
11119
+ : align === 'right'
11120
+ ? tooltip.x + tooltip.width - padding.right
11121
+ : tooltip.x + padding.left;
11122
+ }
11123
+ function getBeforeAfterBodyLines(callback) {
11124
+ return pushOrConcat([], splitNewlines(callback));
11125
+ }
11126
+ function createTooltipContext(parent, tooltip, tooltipItems) {
11127
+ return createContext(parent, {
11128
+ tooltip,
11129
+ tooltipItems,
11130
+ type: 'tooltip'
11131
+ });
11132
+ }
11133
+ function overrideCallbacks(callbacks, context) {
11134
+ const override = context && context.dataset && context.dataset.tooltip && context.dataset.tooltip.callbacks;
11135
+ return override ? callbacks.override(override) : callbacks;
11136
+ }
11137
+ class Tooltip extends Element {
11138
+ constructor(config) {
11139
+ super();
11140
+ this.opacity = 0;
11141
+ this._active = [];
11142
+ this._eventPosition = undefined;
11143
+ this._size = undefined;
11144
+ this._cachedAnimations = undefined;
11145
+ this._tooltipItems = [];
11146
+ this.$animations = undefined;
11147
+ this.$context = undefined;
11148
+ this.chart = config.chart || config._chart;
11149
+ this._chart = this.chart;
11150
+ this.options = config.options;
11151
+ this.dataPoints = undefined;
11152
+ this.title = undefined;
11153
+ this.beforeBody = undefined;
11154
+ this.body = undefined;
11155
+ this.afterBody = undefined;
11156
+ this.footer = undefined;
11157
+ this.xAlign = undefined;
11158
+ this.yAlign = undefined;
11159
+ this.x = undefined;
11160
+ this.y = undefined;
11161
+ this.height = undefined;
11162
+ this.width = undefined;
11163
+ this.caretX = undefined;
11164
+ this.caretY = undefined;
11165
+ this.labelColors = undefined;
11166
+ this.labelPointStyles = undefined;
11167
+ this.labelTextColors = undefined;
11168
+ }
11169
+ initialize(options) {
11170
+ this.options = options;
11171
+ this._cachedAnimations = undefined;
11172
+ this.$context = undefined;
11173
+ }
11174
+ _resolveAnimations() {
11175
+ const cached = this._cachedAnimations;
11176
+ if (cached) {
11177
+ return cached;
11178
+ }
11179
+ const chart = this.chart;
11180
+ const options = this.options.setContext(this.getContext());
11181
+ const opts = options.enabled && chart.options.animation && options.animations;
11182
+ const animations = new Animations(this.chart, opts);
11183
+ if (opts._cacheable) {
11184
+ this._cachedAnimations = Object.freeze(animations);
11185
+ }
11186
+ return animations;
11187
+ }
11188
+ getContext() {
11189
+ return this.$context ||
11190
+ (this.$context = createTooltipContext(this.chart.getContext(), this, this._tooltipItems));
11191
+ }
11192
+ getTitle(context, options) {
11193
+ const {callbacks} = options;
11194
+ const beforeTitle = callbacks.beforeTitle.apply(this, [context]);
11195
+ const title = callbacks.title.apply(this, [context]);
11196
+ const afterTitle = callbacks.afterTitle.apply(this, [context]);
11197
+ let lines = [];
11198
+ lines = pushOrConcat(lines, splitNewlines(beforeTitle));
11199
+ lines = pushOrConcat(lines, splitNewlines(title));
11200
+ lines = pushOrConcat(lines, splitNewlines(afterTitle));
11201
+ return lines;
11202
+ }
11203
+ getBeforeBody(tooltipItems, options) {
11204
+ return getBeforeAfterBodyLines(options.callbacks.beforeBody.apply(this, [tooltipItems]));
11205
+ }
11206
+ getBody(tooltipItems, options) {
11207
+ const {callbacks} = options;
11208
+ const bodyItems = [];
11209
+ each(tooltipItems, (context) => {
11210
+ const bodyItem = {
11211
+ before: [],
11212
+ lines: [],
11213
+ after: []
11214
+ };
11215
+ const scoped = overrideCallbacks(callbacks, context);
11216
+ pushOrConcat(bodyItem.before, splitNewlines(scoped.beforeLabel.call(this, context)));
11217
+ pushOrConcat(bodyItem.lines, scoped.label.call(this, context));
11218
+ pushOrConcat(bodyItem.after, splitNewlines(scoped.afterLabel.call(this, context)));
11219
+ bodyItems.push(bodyItem);
11220
+ });
11221
+ return bodyItems;
11222
+ }
11223
+ getAfterBody(tooltipItems, options) {
11224
+ return getBeforeAfterBodyLines(options.callbacks.afterBody.apply(this, [tooltipItems]));
11225
+ }
11226
+ getFooter(tooltipItems, options) {
11227
+ const {callbacks} = options;
11228
+ const beforeFooter = callbacks.beforeFooter.apply(this, [tooltipItems]);
11229
+ const footer = callbacks.footer.apply(this, [tooltipItems]);
11230
+ const afterFooter = callbacks.afterFooter.apply(this, [tooltipItems]);
11231
+ let lines = [];
11232
+ lines = pushOrConcat(lines, splitNewlines(beforeFooter));
11233
+ lines = pushOrConcat(lines, splitNewlines(footer));
11234
+ lines = pushOrConcat(lines, splitNewlines(afterFooter));
11235
+ return lines;
11236
+ }
11237
+ _createItems(options) {
11238
+ const active = this._active;
11239
+ const data = this.chart.data;
11240
+ const labelColors = [];
11241
+ const labelPointStyles = [];
11242
+ const labelTextColors = [];
11243
+ let tooltipItems = [];
11244
+ let i, len;
11245
+ for (i = 0, len = active.length; i < len; ++i) {
11246
+ tooltipItems.push(createTooltipItem(this.chart, active[i]));
11247
+ }
11248
+ if (options.filter) {
11249
+ tooltipItems = tooltipItems.filter((element, index, array) => options.filter(element, index, array, data));
11250
+ }
11251
+ if (options.itemSort) {
11252
+ tooltipItems = tooltipItems.sort((a, b) => options.itemSort(a, b, data));
11253
+ }
11254
+ each(tooltipItems, (context) => {
11255
+ const scoped = overrideCallbacks(options.callbacks, context);
11256
+ labelColors.push(scoped.labelColor.call(this, context));
11257
+ labelPointStyles.push(scoped.labelPointStyle.call(this, context));
11258
+ labelTextColors.push(scoped.labelTextColor.call(this, context));
11259
+ });
11260
+ this.labelColors = labelColors;
11261
+ this.labelPointStyles = labelPointStyles;
11262
+ this.labelTextColors = labelTextColors;
11263
+ this.dataPoints = tooltipItems;
11264
+ return tooltipItems;
11265
+ }
11266
+ update(changed, replay) {
11267
+ const options = this.options.setContext(this.getContext());
11268
+ const active = this._active;
11269
+ let properties;
11270
+ let tooltipItems = [];
11271
+ if (!active.length) {
11272
+ if (this.opacity !== 0) {
11273
+ properties = {
11274
+ opacity: 0
11275
+ };
11276
+ }
11277
+ } else {
11278
+ const position = positioners[options.position].call(this, active, this._eventPosition);
11279
+ tooltipItems = this._createItems(options);
11280
+ this.title = this.getTitle(tooltipItems, options);
11281
+ this.beforeBody = this.getBeforeBody(tooltipItems, options);
11282
+ this.body = this.getBody(tooltipItems, options);
11283
+ this.afterBody = this.getAfterBody(tooltipItems, options);
11284
+ this.footer = this.getFooter(tooltipItems, options);
11285
+ const size = this._size = getTooltipSize(this, options);
11286
+ const positionAndSize = Object.assign({}, position, size);
11287
+ const alignment = determineAlignment(this.chart, options, positionAndSize);
11288
+ const backgroundPoint = getBackgroundPoint(options, positionAndSize, alignment, this.chart);
11289
+ this.xAlign = alignment.xAlign;
11290
+ this.yAlign = alignment.yAlign;
11291
+ properties = {
11292
+ opacity: 1,
11293
+ x: backgroundPoint.x,
11294
+ y: backgroundPoint.y,
11295
+ width: size.width,
11296
+ height: size.height,
11297
+ caretX: position.x,
11298
+ caretY: position.y
11299
+ };
11300
+ }
11301
+ this._tooltipItems = tooltipItems;
11302
+ this.$context = undefined;
11303
+ if (properties) {
11304
+ this._resolveAnimations().update(this, properties);
11305
+ }
11306
+ if (changed && options.external) {
11307
+ options.external.call(this, {chart: this.chart, tooltip: this, replay});
11308
+ }
11309
+ }
11310
+ drawCaret(tooltipPoint, ctx, size, options) {
11311
+ const caretPosition = this.getCaretPosition(tooltipPoint, size, options);
11312
+ ctx.lineTo(caretPosition.x1, caretPosition.y1);
11313
+ ctx.lineTo(caretPosition.x2, caretPosition.y2);
11314
+ ctx.lineTo(caretPosition.x3, caretPosition.y3);
11315
+ }
11316
+ getCaretPosition(tooltipPoint, size, options) {
11317
+ const {xAlign, yAlign} = this;
11318
+ const {caretSize, cornerRadius} = options;
11319
+ const {topLeft, topRight, bottomLeft, bottomRight} = toTRBLCorners(cornerRadius);
11320
+ const {x: ptX, y: ptY} = tooltipPoint;
11321
+ const {width, height} = size;
11322
+ let x1, x2, x3, y1, y2, y3;
11323
+ if (yAlign === 'center') {
11324
+ y2 = ptY + (height / 2);
11325
+ if (xAlign === 'left') {
11326
+ x1 = ptX;
11327
+ x2 = x1 - caretSize;
11328
+ y1 = y2 + caretSize;
11329
+ y3 = y2 - caretSize;
11330
+ } else {
11331
+ x1 = ptX + width;
11332
+ x2 = x1 + caretSize;
11333
+ y1 = y2 - caretSize;
11334
+ y3 = y2 + caretSize;
11335
+ }
11336
+ x3 = x1;
11337
+ } else {
11338
+ if (xAlign === 'left') {
11339
+ x2 = ptX + Math.max(topLeft, bottomLeft) + (caretSize);
11340
+ } else if (xAlign === 'right') {
11341
+ x2 = ptX + width - Math.max(topRight, bottomRight) - caretSize;
11342
+ } else {
11343
+ x2 = this.caretX;
11344
+ }
11345
+ if (yAlign === 'top') {
11346
+ y1 = ptY;
11347
+ y2 = y1 - caretSize;
11348
+ x1 = x2 - caretSize;
11349
+ x3 = x2 + caretSize;
11350
+ } else {
11351
+ y1 = ptY + height;
11352
+ y2 = y1 + caretSize;
11353
+ x1 = x2 + caretSize;
11354
+ x3 = x2 - caretSize;
11355
+ }
11356
+ y3 = y1;
11357
+ }
11358
+ return {x1, x2, x3, y1, y2, y3};
11359
+ }
11360
+ drawTitle(pt, ctx, options) {
11361
+ const title = this.title;
11362
+ const length = title.length;
11363
+ let titleFont, titleSpacing, i;
11364
+ if (length) {
11365
+ const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width);
11366
+ pt.x = getAlignedX(this, options.titleAlign, options);
11367
+ ctx.textAlign = rtlHelper.textAlign(options.titleAlign);
11368
+ ctx.textBaseline = 'middle';
11369
+ titleFont = toFont(options.titleFont);
11370
+ titleSpacing = options.titleSpacing;
11371
+ ctx.fillStyle = options.titleColor;
11372
+ ctx.font = titleFont.string;
11373
+ for (i = 0; i < length; ++i) {
11374
+ ctx.fillText(title[i], rtlHelper.x(pt.x), pt.y + titleFont.lineHeight / 2);
11375
+ pt.y += titleFont.lineHeight + titleSpacing;
11376
+ if (i + 1 === length) {
11377
+ pt.y += options.titleMarginBottom - titleSpacing;
11378
+ }
11379
+ }
11380
+ }
11381
+ }
11382
+ _drawColorBox(ctx, pt, i, rtlHelper, options) {
11383
+ const labelColors = this.labelColors[i];
11384
+ const labelPointStyle = this.labelPointStyles[i];
11385
+ const {boxHeight, boxWidth, boxPadding} = options;
11386
+ const bodyFont = toFont(options.bodyFont);
11387
+ const colorX = getAlignedX(this, 'left', options);
11388
+ const rtlColorX = rtlHelper.x(colorX);
11389
+ const yOffSet = boxHeight < bodyFont.lineHeight ? (bodyFont.lineHeight - boxHeight) / 2 : 0;
11390
+ const colorY = pt.y + yOffSet;
11391
+ if (options.usePointStyle) {
11392
+ const drawOptions = {
11393
+ radius: Math.min(boxWidth, boxHeight) / 2,
11394
+ pointStyle: labelPointStyle.pointStyle,
11395
+ rotation: labelPointStyle.rotation,
11396
+ borderWidth: 1
11397
+ };
11398
+ const centerX = rtlHelper.leftForLtr(rtlColorX, boxWidth) + boxWidth / 2;
11399
+ const centerY = colorY + boxHeight / 2;
11400
+ ctx.strokeStyle = options.multiKeyBackground;
11401
+ ctx.fillStyle = options.multiKeyBackground;
11402
+ drawPoint(ctx, drawOptions, centerX, centerY);
11403
+ ctx.strokeStyle = labelColors.borderColor;
11404
+ ctx.fillStyle = labelColors.backgroundColor;
11405
+ drawPoint(ctx, drawOptions, centerX, centerY);
11406
+ } else {
11407
+ ctx.lineWidth = labelColors.borderWidth || 1;
11408
+ ctx.strokeStyle = labelColors.borderColor;
11409
+ ctx.setLineDash(labelColors.borderDash || []);
11410
+ ctx.lineDashOffset = labelColors.borderDashOffset || 0;
11411
+ const outerX = rtlHelper.leftForLtr(rtlColorX, boxWidth - boxPadding);
11412
+ const innerX = rtlHelper.leftForLtr(rtlHelper.xPlus(rtlColorX, 1), boxWidth - boxPadding - 2);
11413
+ const borderRadius = toTRBLCorners(labelColors.borderRadius);
11414
+ if (Object.values(borderRadius).some(v => v !== 0)) {
11415
+ ctx.beginPath();
11416
+ ctx.fillStyle = options.multiKeyBackground;
11417
+ addRoundedRectPath(ctx, {
11418
+ x: outerX,
11419
+ y: colorY,
11420
+ w: boxWidth,
11421
+ h: boxHeight,
11422
+ radius: borderRadius,
11423
+ });
11424
+ ctx.fill();
11425
+ ctx.stroke();
11426
+ ctx.fillStyle = labelColors.backgroundColor;
11427
+ ctx.beginPath();
11428
+ addRoundedRectPath(ctx, {
11429
+ x: innerX,
11430
+ y: colorY + 1,
11431
+ w: boxWidth - 2,
11432
+ h: boxHeight - 2,
11433
+ radius: borderRadius,
11434
+ });
11435
+ ctx.fill();
11436
+ } else {
11437
+ ctx.fillStyle = options.multiKeyBackground;
11438
+ ctx.fillRect(outerX, colorY, boxWidth, boxHeight);
11439
+ ctx.strokeRect(outerX, colorY, boxWidth, boxHeight);
11440
+ ctx.fillStyle = labelColors.backgroundColor;
11441
+ ctx.fillRect(innerX, colorY + 1, boxWidth - 2, boxHeight - 2);
11442
+ }
11443
+ }
11444
+ ctx.fillStyle = this.labelTextColors[i];
11445
+ }
11446
+ drawBody(pt, ctx, options) {
11447
+ const {body} = this;
11448
+ const {bodySpacing, bodyAlign, displayColors, boxHeight, boxWidth, boxPadding} = options;
11449
+ const bodyFont = toFont(options.bodyFont);
11450
+ let bodyLineHeight = bodyFont.lineHeight;
11451
+ let xLinePadding = 0;
11452
+ const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width);
11453
+ const fillLineOfText = function(line) {
11454
+ ctx.fillText(line, rtlHelper.x(pt.x + xLinePadding), pt.y + bodyLineHeight / 2);
11455
+ pt.y += bodyLineHeight + bodySpacing;
11456
+ };
11457
+ const bodyAlignForCalculation = rtlHelper.textAlign(bodyAlign);
11458
+ let bodyItem, textColor, lines, i, j, ilen, jlen;
11459
+ ctx.textAlign = bodyAlign;
11460
+ ctx.textBaseline = 'middle';
11461
+ ctx.font = bodyFont.string;
11462
+ pt.x = getAlignedX(this, bodyAlignForCalculation, options);
11463
+ ctx.fillStyle = options.bodyColor;
11464
+ each(this.beforeBody, fillLineOfText);
11465
+ xLinePadding = displayColors && bodyAlignForCalculation !== 'right'
11466
+ ? bodyAlign === 'center' ? (boxWidth / 2 + boxPadding) : (boxWidth + 2 + boxPadding)
11467
+ : 0;
11468
+ for (i = 0, ilen = body.length; i < ilen; ++i) {
11469
+ bodyItem = body[i];
11470
+ textColor = this.labelTextColors[i];
11471
+ ctx.fillStyle = textColor;
11472
+ each(bodyItem.before, fillLineOfText);
11473
+ lines = bodyItem.lines;
11474
+ if (displayColors && lines.length) {
11475
+ this._drawColorBox(ctx, pt, i, rtlHelper, options);
11476
+ bodyLineHeight = Math.max(bodyFont.lineHeight, boxHeight);
11477
+ }
11478
+ for (j = 0, jlen = lines.length; j < jlen; ++j) {
11479
+ fillLineOfText(lines[j]);
11480
+ bodyLineHeight = bodyFont.lineHeight;
11481
+ }
11482
+ each(bodyItem.after, fillLineOfText);
11483
+ }
11484
+ xLinePadding = 0;
11485
+ bodyLineHeight = bodyFont.lineHeight;
11486
+ each(this.afterBody, fillLineOfText);
11487
+ pt.y -= bodySpacing;
11488
+ }
11489
+ drawFooter(pt, ctx, options) {
11490
+ const footer = this.footer;
11491
+ const length = footer.length;
11492
+ let footerFont, i;
11493
+ if (length) {
11494
+ const rtlHelper = getRtlAdapter(options.rtl, this.x, this.width);
11495
+ pt.x = getAlignedX(this, options.footerAlign, options);
11496
+ pt.y += options.footerMarginTop;
11497
+ ctx.textAlign = rtlHelper.textAlign(options.footerAlign);
11498
+ ctx.textBaseline = 'middle';
11499
+ footerFont = toFont(options.footerFont);
11500
+ ctx.fillStyle = options.footerColor;
11501
+ ctx.font = footerFont.string;
11502
+ for (i = 0; i < length; ++i) {
11503
+ ctx.fillText(footer[i], rtlHelper.x(pt.x), pt.y + footerFont.lineHeight / 2);
11504
+ pt.y += footerFont.lineHeight + options.footerSpacing;
11505
+ }
11506
+ }
11507
+ }
11508
+ drawBackground(pt, ctx, tooltipSize, options) {
11509
+ const {xAlign, yAlign} = this;
11510
+ const {x, y} = pt;
11511
+ const {width, height} = tooltipSize;
11512
+ const {topLeft, topRight, bottomLeft, bottomRight} = toTRBLCorners(options.cornerRadius);
11513
+ ctx.fillStyle = options.backgroundColor;
11514
+ ctx.strokeStyle = options.borderColor;
11515
+ ctx.lineWidth = options.borderWidth;
11516
+ ctx.beginPath();
11517
+ ctx.moveTo(x + topLeft, y);
11518
+ if (yAlign === 'top') {
11519
+ this.drawCaret(pt, ctx, tooltipSize, options);
11520
+ }
11521
+ ctx.lineTo(x + width - topRight, y);
11522
+ ctx.quadraticCurveTo(x + width, y, x + width, y + topRight);
11523
+ if (yAlign === 'center' && xAlign === 'right') {
11524
+ this.drawCaret(pt, ctx, tooltipSize, options);
11525
+ }
11526
+ ctx.lineTo(x + width, y + height - bottomRight);
11527
+ ctx.quadraticCurveTo(x + width, y + height, x + width - bottomRight, y + height);
11528
+ if (yAlign === 'bottom') {
11529
+ this.drawCaret(pt, ctx, tooltipSize, options);
11530
+ }
11531
+ ctx.lineTo(x + bottomLeft, y + height);
11532
+ ctx.quadraticCurveTo(x, y + height, x, y + height - bottomLeft);
11533
+ if (yAlign === 'center' && xAlign === 'left') {
11534
+ this.drawCaret(pt, ctx, tooltipSize, options);
11535
+ }
11536
+ ctx.lineTo(x, y + topLeft);
11537
+ ctx.quadraticCurveTo(x, y, x + topLeft, y);
11538
+ ctx.closePath();
11539
+ ctx.fill();
11540
+ if (options.borderWidth > 0) {
11541
+ ctx.stroke();
11542
+ }
11543
+ }
11544
+ _updateAnimationTarget(options) {
11545
+ const chart = this.chart;
11546
+ const anims = this.$animations;
11547
+ const animX = anims && anims.x;
11548
+ const animY = anims && anims.y;
11549
+ if (animX || animY) {
11550
+ const position = positioners[options.position].call(this, this._active, this._eventPosition);
11551
+ if (!position) {
11552
+ return;
11553
+ }
11554
+ const size = this._size = getTooltipSize(this, options);
11555
+ const positionAndSize = Object.assign({}, position, this._size);
11556
+ const alignment = determineAlignment(chart, options, positionAndSize);
11557
+ const point = getBackgroundPoint(options, positionAndSize, alignment, chart);
11558
+ if (animX._to !== point.x || animY._to !== point.y) {
11559
+ this.xAlign = alignment.xAlign;
11560
+ this.yAlign = alignment.yAlign;
11561
+ this.width = size.width;
11562
+ this.height = size.height;
11563
+ this.caretX = position.x;
11564
+ this.caretY = position.y;
11565
+ this._resolveAnimations().update(this, point);
11566
+ }
11567
+ }
11568
+ }
11569
+ draw(ctx) {
11570
+ const options = this.options.setContext(this.getContext());
11571
+ let opacity = this.opacity;
11572
+ if (!opacity) {
11573
+ return;
11574
+ }
11575
+ this._updateAnimationTarget(options);
11576
+ const tooltipSize = {
11577
+ width: this.width,
11578
+ height: this.height
11579
+ };
11580
+ const pt = {
11581
+ x: this.x,
11582
+ y: this.y
11583
+ };
11584
+ opacity = Math.abs(opacity) < 1e-3 ? 0 : opacity;
11585
+ const padding = toPadding(options.padding);
11586
+ const hasTooltipContent = this.title.length || this.beforeBody.length || this.body.length || this.afterBody.length || this.footer.length;
11587
+ if (options.enabled && hasTooltipContent) {
11588
+ ctx.save();
11589
+ ctx.globalAlpha = opacity;
11590
+ this.drawBackground(pt, ctx, tooltipSize, options);
11591
+ overrideTextDirection(ctx, options.textDirection);
11592
+ pt.y += padding.top;
11593
+ this.drawTitle(pt, ctx, options);
11594
+ this.drawBody(pt, ctx, options);
11595
+ this.drawFooter(pt, ctx, options);
11596
+ restoreTextDirection(ctx, options.textDirection);
11597
+ ctx.restore();
11598
+ }
11599
+ }
11600
+ getActiveElements() {
11601
+ return this._active || [];
11602
+ }
11603
+ setActiveElements(activeElements, eventPosition) {
11604
+ const lastActive = this._active;
11605
+ const active = activeElements.map(({datasetIndex, index}) => {
11606
+ const meta = this.chart.getDatasetMeta(datasetIndex);
11607
+ if (!meta) {
11608
+ throw new Error('Cannot find a dataset at index ' + datasetIndex);
11609
+ }
11610
+ return {
11611
+ datasetIndex,
11612
+ element: meta.data[index],
11613
+ index,
11614
+ };
11615
+ });
11616
+ const changed = !_elementsEqual(lastActive, active);
11617
+ const positionChanged = this._positionChanged(active, eventPosition);
11618
+ if (changed || positionChanged) {
11619
+ this._active = active;
11620
+ this._eventPosition = eventPosition;
11621
+ this._ignoreReplayEvents = true;
11622
+ this.update(true);
11623
+ }
11624
+ }
11625
+ handleEvent(e, replay, inChartArea = true) {
11626
+ if (replay && this._ignoreReplayEvents) {
11627
+ return false;
11628
+ }
11629
+ this._ignoreReplayEvents = false;
11630
+ const options = this.options;
11631
+ const lastActive = this._active || [];
11632
+ const active = this._getActiveElements(e, lastActive, replay, inChartArea);
11633
+ const positionChanged = this._positionChanged(active, e);
11634
+ const changed = replay || !_elementsEqual(active, lastActive) || positionChanged;
11635
+ if (changed) {
11636
+ this._active = active;
11637
+ if (options.enabled || options.external) {
11638
+ this._eventPosition = {
11639
+ x: e.x,
11640
+ y: e.y
11641
+ };
11642
+ this.update(true, replay);
11643
+ }
11644
+ }
11645
+ return changed;
11646
+ }
11647
+ _getActiveElements(e, lastActive, replay, inChartArea) {
11648
+ const options = this.options;
11649
+ if (e.type === 'mouseout') {
11650
+ return [];
11651
+ }
11652
+ if (!inChartArea) {
11653
+ return lastActive;
11654
+ }
11655
+ const active = this.chart.getElementsAtEventForMode(e, options.mode, options, replay);
11656
+ if (options.reverse) {
11657
+ active.reverse();
11658
+ }
11659
+ return active;
11660
+ }
11661
+ _positionChanged(active, e) {
11662
+ const {caretX, caretY, options} = this;
11663
+ const position = positioners[options.position].call(this, active, e);
11664
+ return position !== false && (caretX !== position.x || caretY !== position.y);
11665
+ }
11666
+ }
11667
+ Tooltip.positioners = positioners;
11668
+ var plugin_tooltip = {
11669
+ id: 'tooltip',
11670
+ _element: Tooltip,
11671
+ positioners,
11672
+ afterInit(chart, _args, options) {
11673
+ if (options) {
11674
+ chart.tooltip = new Tooltip({chart, options});
11675
+ }
11676
+ },
11677
+ beforeUpdate(chart, _args, options) {
11678
+ if (chart.tooltip) {
11679
+ chart.tooltip.initialize(options);
11680
+ }
11681
+ },
11682
+ reset(chart, _args, options) {
11683
+ if (chart.tooltip) {
11684
+ chart.tooltip.initialize(options);
11685
+ }
11686
+ },
11687
+ afterDraw(chart) {
11688
+ const tooltip = chart.tooltip;
11689
+ const args = {
11690
+ tooltip
11691
+ };
11692
+ if (chart.notifyPlugins('beforeTooltipDraw', args) === false) {
11693
+ return;
11694
+ }
11695
+ if (tooltip) {
11696
+ tooltip.draw(chart.ctx);
11697
+ }
11698
+ chart.notifyPlugins('afterTooltipDraw', args);
11699
+ },
11700
+ afterEvent(chart, args) {
11701
+ if (chart.tooltip) {
11702
+ const useFinalPosition = args.replay;
11703
+ if (chart.tooltip.handleEvent(args.event, useFinalPosition, args.inChartArea)) {
11704
+ args.changed = true;
11705
+ }
11706
+ }
11707
+ },
11708
+ defaults: {
11709
+ enabled: true,
11710
+ external: null,
11711
+ position: 'average',
11712
+ backgroundColor: 'rgba(0,0,0,0.8)',
11713
+ titleColor: '#fff',
11714
+ titleFont: {
11715
+ weight: 'bold',
11716
+ },
11717
+ titleSpacing: 2,
11718
+ titleMarginBottom: 6,
11719
+ titleAlign: 'left',
11720
+ bodyColor: '#fff',
11721
+ bodySpacing: 2,
11722
+ bodyFont: {
11723
+ },
11724
+ bodyAlign: 'left',
11725
+ footerColor: '#fff',
11726
+ footerSpacing: 2,
11727
+ footerMarginTop: 6,
11728
+ footerFont: {
11729
+ weight: 'bold',
11730
+ },
11731
+ footerAlign: 'left',
11732
+ padding: 6,
11733
+ caretPadding: 2,
11734
+ caretSize: 5,
11735
+ cornerRadius: 6,
11736
+ boxHeight: (ctx, opts) => opts.bodyFont.size,
11737
+ boxWidth: (ctx, opts) => opts.bodyFont.size,
11738
+ multiKeyBackground: '#fff',
11739
+ displayColors: true,
11740
+ boxPadding: 0,
11741
+ borderColor: 'rgba(0,0,0,0)',
11742
+ borderWidth: 0,
11743
+ animation: {
11744
+ duration: 400,
11745
+ easing: 'easeOutQuart',
11746
+ },
11747
+ animations: {
11748
+ numbers: {
11749
+ type: 'number',
11750
+ properties: ['x', 'y', 'width', 'height', 'caretX', 'caretY'],
11751
+ },
11752
+ opacity: {
11753
+ easing: 'linear',
11754
+ duration: 200
11755
+ }
11756
+ },
11757
+ callbacks: {
11758
+ beforeTitle: noop,
11759
+ title(tooltipItems) {
11760
+ if (tooltipItems.length > 0) {
11761
+ const item = tooltipItems[0];
11762
+ const labels = item.chart.data.labels;
11763
+ const labelCount = labels ? labels.length : 0;
11764
+ if (this && this.options && this.options.mode === 'dataset') {
11765
+ return item.dataset.label || '';
11766
+ } else if (item.label) {
11767
+ return item.label;
11768
+ } else if (labelCount > 0 && item.dataIndex < labelCount) {
11769
+ return labels[item.dataIndex];
11770
+ }
11771
+ }
11772
+ return '';
11773
+ },
11774
+ afterTitle: noop,
11775
+ beforeBody: noop,
11776
+ beforeLabel: noop,
11777
+ label(tooltipItem) {
11778
+ if (this && this.options && this.options.mode === 'dataset') {
11779
+ return tooltipItem.label + ': ' + tooltipItem.formattedValue || tooltipItem.formattedValue;
11780
+ }
11781
+ let label = tooltipItem.dataset.label || '';
11782
+ if (label) {
11783
+ label += ': ';
11784
+ }
11785
+ const value = tooltipItem.formattedValue;
11786
+ if (!isNullOrUndef(value)) {
11787
+ label += value;
11788
+ }
11789
+ return label;
11790
+ },
11791
+ labelColor(tooltipItem) {
11792
+ const meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex);
11793
+ const options = meta.controller.getStyle(tooltipItem.dataIndex);
11794
+ return {
11795
+ borderColor: options.borderColor,
11796
+ backgroundColor: options.backgroundColor,
11797
+ borderWidth: options.borderWidth,
11798
+ borderDash: options.borderDash,
11799
+ borderDashOffset: options.borderDashOffset,
11800
+ borderRadius: 0,
11801
+ };
11802
+ },
11803
+ labelTextColor() {
11804
+ return this.options.bodyColor;
11805
+ },
11806
+ labelPointStyle(tooltipItem) {
11807
+ const meta = tooltipItem.chart.getDatasetMeta(tooltipItem.datasetIndex);
11808
+ const options = meta.controller.getStyle(tooltipItem.dataIndex);
11809
+ return {
11810
+ pointStyle: options.pointStyle,
11811
+ rotation: options.rotation,
11812
+ };
11813
+ },
11814
+ afterLabel: noop,
11815
+ afterBody: noop,
11816
+ beforeFooter: noop,
11817
+ footer: noop,
11818
+ afterFooter: noop
11819
+ }
11820
+ },
11821
+ defaultRoutes: {
11822
+ bodyFont: 'font',
11823
+ footerFont: 'font',
11824
+ titleFont: 'font'
11825
+ },
11826
+ descriptors: {
11827
+ _scriptable: (name) => name !== 'filter' && name !== 'itemSort' && name !== 'external',
11828
+ _indexable: false,
11829
+ callbacks: {
11830
+ _scriptable: false,
11831
+ _indexable: false,
11832
+ },
11833
+ animation: {
11834
+ _fallback: false
11835
+ },
11836
+ animations: {
11837
+ _fallback: 'animation'
11838
+ }
11839
+ },
11840
+ additionalOptionScopes: ['interaction']
11841
+ };
11842
+
11843
+ var plugins = /*#__PURE__*/Object.freeze({
11844
+ __proto__: null,
11845
+ Decimation: plugin_decimation,
11846
+ Filler: plugin_filler,
11847
+ Legend: plugin_legend,
11848
+ SubTitle: plugin_subtitle,
11849
+ Title: plugin_title,
11850
+ Tooltip: plugin_tooltip
11851
+ });
11852
+
11853
+ const addIfString = (labels, raw, index, addedLabels) => {
11854
+ if (typeof raw === 'string') {
11855
+ index = labels.push(raw) - 1;
11856
+ addedLabels.unshift({index, label: raw});
11857
+ } else if (isNaN(raw)) {
11858
+ index = null;
11859
+ }
11860
+ return index;
11861
+ };
11862
+ function findOrAddLabel(labels, raw, index, addedLabels) {
11863
+ const first = labels.indexOf(raw);
11864
+ if (first === -1) {
11865
+ return addIfString(labels, raw, index, addedLabels);
11866
+ }
11867
+ const last = labels.lastIndexOf(raw);
11868
+ return first !== last ? index : first;
11869
+ }
11870
+ const validIndex = (index, max) => index === null ? null : _limitValue(Math.round(index), 0, max);
11871
+ class CategoryScale extends Scale {
11872
+ constructor(cfg) {
11873
+ super(cfg);
11874
+ this._startValue = undefined;
11875
+ this._valueRange = 0;
11876
+ this._addedLabels = [];
11877
+ }
11878
+ init(scaleOptions) {
11879
+ const added = this._addedLabels;
11880
+ if (added.length) {
11881
+ const labels = this.getLabels();
11882
+ for (const {index, label} of added) {
11883
+ if (labels[index] === label) {
11884
+ labels.splice(index, 1);
11885
+ }
11886
+ }
11887
+ this._addedLabels = [];
11888
+ }
11889
+ super.init(scaleOptions);
11890
+ }
11891
+ parse(raw, index) {
11892
+ if (isNullOrUndef(raw)) {
11893
+ return null;
11894
+ }
11895
+ const labels = this.getLabels();
11896
+ index = isFinite(index) && labels[index] === raw ? index
11897
+ : findOrAddLabel(labels, raw, valueOrDefault(index, raw), this._addedLabels);
11898
+ return validIndex(index, labels.length - 1);
11899
+ }
11900
+ determineDataLimits() {
11901
+ const {minDefined, maxDefined} = this.getUserBounds();
11902
+ let {min, max} = this.getMinMax(true);
11903
+ if (this.options.bounds === 'ticks') {
11904
+ if (!minDefined) {
11905
+ min = 0;
11906
+ }
11907
+ if (!maxDefined) {
11908
+ max = this.getLabels().length - 1;
11909
+ }
11910
+ }
11911
+ this.min = min;
11912
+ this.max = max;
11913
+ }
11914
+ buildTicks() {
11915
+ const min = this.min;
11916
+ const max = this.max;
11917
+ const offset = this.options.offset;
11918
+ const ticks = [];
11919
+ let labels = this.getLabels();
11920
+ labels = (min === 0 && max === labels.length - 1) ? labels : labels.slice(min, max + 1);
11921
+ this._valueRange = Math.max(labels.length - (offset ? 0 : 1), 1);
11922
+ this._startValue = this.min - (offset ? 0.5 : 0);
11923
+ for (let value = min; value <= max; value++) {
11924
+ ticks.push({value});
11925
+ }
11926
+ return ticks;
11927
+ }
11928
+ getLabelForValue(value) {
11929
+ const labels = this.getLabels();
11930
+ if (value >= 0 && value < labels.length) {
11931
+ return labels[value];
11932
+ }
11933
+ return value;
11934
+ }
11935
+ configure() {
11936
+ super.configure();
11937
+ if (!this.isHorizontal()) {
11938
+ this._reversePixels = !this._reversePixels;
11939
+ }
11940
+ }
11941
+ getPixelForValue(value) {
11942
+ if (typeof value !== 'number') {
11943
+ value = this.parse(value);
11944
+ }
11945
+ return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange);
11946
+ }
11947
+ getPixelForTick(index) {
11948
+ const ticks = this.ticks;
11949
+ if (index < 0 || index > ticks.length - 1) {
11950
+ return null;
11951
+ }
11952
+ return this.getPixelForValue(ticks[index].value);
11953
+ }
11954
+ getValueForPixel(pixel) {
11955
+ return Math.round(this._startValue + this.getDecimalForPixel(pixel) * this._valueRange);
11956
+ }
11957
+ getBasePixel() {
11958
+ return this.bottom;
11959
+ }
11960
+ }
11961
+ CategoryScale.id = 'category';
11962
+ CategoryScale.defaults = {
11963
+ ticks: {
11964
+ callback: CategoryScale.prototype.getLabelForValue
11965
+ }
11966
+ };
11967
+
11968
+ function generateTicks$1(generationOptions, dataRange) {
11969
+ const ticks = [];
11970
+ const MIN_SPACING = 1e-14;
11971
+ const {bounds, step, min, max, precision, count, maxTicks, maxDigits, includeBounds} = generationOptions;
11972
+ const unit = step || 1;
11973
+ const maxSpaces = maxTicks - 1;
11974
+ const {min: rmin, max: rmax} = dataRange;
11975
+ const minDefined = !isNullOrUndef(min);
11976
+ const maxDefined = !isNullOrUndef(max);
11977
+ const countDefined = !isNullOrUndef(count);
11978
+ const minSpacing = (rmax - rmin) / (maxDigits + 1);
11979
+ let spacing = niceNum((rmax - rmin) / maxSpaces / unit) * unit;
11980
+ let factor, niceMin, niceMax, numSpaces;
11981
+ if (spacing < MIN_SPACING && !minDefined && !maxDefined) {
11982
+ return [{value: rmin}, {value: rmax}];
11983
+ }
11984
+ numSpaces = Math.ceil(rmax / spacing) - Math.floor(rmin / spacing);
11985
+ if (numSpaces > maxSpaces) {
11986
+ spacing = niceNum(numSpaces * spacing / maxSpaces / unit) * unit;
11987
+ }
11988
+ if (!isNullOrUndef(precision)) {
11989
+ factor = Math.pow(10, precision);
11990
+ spacing = Math.ceil(spacing * factor) / factor;
11991
+ }
11992
+ if (bounds === 'ticks') {
11993
+ niceMin = Math.floor(rmin / spacing) * spacing;
11994
+ niceMax = Math.ceil(rmax / spacing) * spacing;
11995
+ } else {
11996
+ niceMin = rmin;
11997
+ niceMax = rmax;
11998
+ }
11999
+ if (minDefined && maxDefined && step && almostWhole((max - min) / step, spacing / 1000)) {
12000
+ numSpaces = Math.round(Math.min((max - min) / spacing, maxTicks));
12001
+ spacing = (max - min) / numSpaces;
12002
+ niceMin = min;
12003
+ niceMax = max;
12004
+ } else if (countDefined) {
12005
+ niceMin = minDefined ? min : niceMin;
12006
+ niceMax = maxDefined ? max : niceMax;
12007
+ numSpaces = count - 1;
12008
+ spacing = (niceMax - niceMin) / numSpaces;
12009
+ } else {
12010
+ numSpaces = (niceMax - niceMin) / spacing;
12011
+ if (almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {
12012
+ numSpaces = Math.round(numSpaces);
12013
+ } else {
12014
+ numSpaces = Math.ceil(numSpaces);
12015
+ }
12016
+ }
12017
+ const decimalPlaces = Math.max(
12018
+ _decimalPlaces(spacing),
12019
+ _decimalPlaces(niceMin)
12020
+ );
12021
+ factor = Math.pow(10, isNullOrUndef(precision) ? decimalPlaces : precision);
12022
+ niceMin = Math.round(niceMin * factor) / factor;
12023
+ niceMax = Math.round(niceMax * factor) / factor;
12024
+ let j = 0;
12025
+ if (minDefined) {
12026
+ if (includeBounds && niceMin !== min) {
12027
+ ticks.push({value: min});
12028
+ if (niceMin < min) {
12029
+ j++;
12030
+ }
12031
+ if (almostEquals(Math.round((niceMin + j * spacing) * factor) / factor, min, relativeLabelSize(min, minSpacing, generationOptions))) {
12032
+ j++;
12033
+ }
12034
+ } else if (niceMin < min) {
12035
+ j++;
12036
+ }
12037
+ }
12038
+ for (; j < numSpaces; ++j) {
12039
+ ticks.push({value: Math.round((niceMin + j * spacing) * factor) / factor});
12040
+ }
12041
+ if (maxDefined && includeBounds && niceMax !== max) {
12042
+ if (ticks.length && almostEquals(ticks[ticks.length - 1].value, max, relativeLabelSize(max, minSpacing, generationOptions))) {
12043
+ ticks[ticks.length - 1].value = max;
12044
+ } else {
12045
+ ticks.push({value: max});
12046
+ }
12047
+ } else if (!maxDefined || niceMax === max) {
12048
+ ticks.push({value: niceMax});
12049
+ }
12050
+ return ticks;
12051
+ }
12052
+ function relativeLabelSize(value, minSpacing, {horizontal, minRotation}) {
12053
+ const rad = toRadians(minRotation);
12054
+ const ratio = (horizontal ? Math.sin(rad) : Math.cos(rad)) || 0.001;
12055
+ const length = 0.75 * minSpacing * ('' + value).length;
12056
+ return Math.min(minSpacing / ratio, length);
12057
+ }
12058
+ class LinearScaleBase extends Scale {
12059
+ constructor(cfg) {
12060
+ super(cfg);
12061
+ this.start = undefined;
12062
+ this.end = undefined;
12063
+ this._startValue = undefined;
12064
+ this._endValue = undefined;
12065
+ this._valueRange = 0;
12066
+ }
12067
+ parse(raw, index) {
12068
+ if (isNullOrUndef(raw)) {
12069
+ return null;
12070
+ }
12071
+ if ((typeof raw === 'number' || raw instanceof Number) && !isFinite(+raw)) {
12072
+ return null;
12073
+ }
12074
+ return +raw;
12075
+ }
12076
+ handleTickRangeOptions() {
12077
+ const {beginAtZero} = this.options;
12078
+ const {minDefined, maxDefined} = this.getUserBounds();
12079
+ let {min, max} = this;
12080
+ const setMin = v => (min = minDefined ? min : v);
12081
+ const setMax = v => (max = maxDefined ? max : v);
12082
+ if (beginAtZero) {
12083
+ const minSign = sign(min);
12084
+ const maxSign = sign(max);
12085
+ if (minSign < 0 && maxSign < 0) {
12086
+ setMax(0);
12087
+ } else if (minSign > 0 && maxSign > 0) {
12088
+ setMin(0);
12089
+ }
12090
+ }
12091
+ if (min === max) {
12092
+ let offset = 1;
12093
+ if (max >= Number.MAX_SAFE_INTEGER || min <= Number.MIN_SAFE_INTEGER) {
12094
+ offset = Math.abs(max * 0.05);
12095
+ }
12096
+ setMax(max + offset);
12097
+ if (!beginAtZero) {
12098
+ setMin(min - offset);
12099
+ }
12100
+ }
12101
+ this.min = min;
12102
+ this.max = max;
12103
+ }
12104
+ getTickLimit() {
12105
+ const tickOpts = this.options.ticks;
12106
+ let {maxTicksLimit, stepSize} = tickOpts;
12107
+ let maxTicks;
12108
+ if (stepSize) {
12109
+ maxTicks = Math.ceil(this.max / stepSize) - Math.floor(this.min / stepSize) + 1;
12110
+ if (maxTicks > 1000) {
12111
+ console.warn(`scales.${this.id}.ticks.stepSize: ${stepSize} would result generating up to ${maxTicks} ticks. Limiting to 1000.`);
12112
+ maxTicks = 1000;
12113
+ }
12114
+ } else {
12115
+ maxTicks = this.computeTickLimit();
12116
+ maxTicksLimit = maxTicksLimit || 11;
12117
+ }
12118
+ if (maxTicksLimit) {
12119
+ maxTicks = Math.min(maxTicksLimit, maxTicks);
12120
+ }
12121
+ return maxTicks;
12122
+ }
12123
+ computeTickLimit() {
12124
+ return Number.POSITIVE_INFINITY;
12125
+ }
12126
+ buildTicks() {
12127
+ const opts = this.options;
12128
+ const tickOpts = opts.ticks;
12129
+ let maxTicks = this.getTickLimit();
12130
+ maxTicks = Math.max(2, maxTicks);
12131
+ const numericGeneratorOptions = {
12132
+ maxTicks,
12133
+ bounds: opts.bounds,
12134
+ min: opts.min,
12135
+ max: opts.max,
12136
+ precision: tickOpts.precision,
12137
+ step: tickOpts.stepSize,
12138
+ count: tickOpts.count,
12139
+ maxDigits: this._maxDigits(),
12140
+ horizontal: this.isHorizontal(),
12141
+ minRotation: tickOpts.minRotation || 0,
12142
+ includeBounds: tickOpts.includeBounds !== false
12143
+ };
12144
+ const dataRange = this._range || this;
12145
+ const ticks = generateTicks$1(numericGeneratorOptions, dataRange);
12146
+ if (opts.bounds === 'ticks') {
12147
+ _setMinAndMaxByKey(ticks, this, 'value');
12148
+ }
12149
+ if (opts.reverse) {
12150
+ ticks.reverse();
12151
+ this.start = this.max;
12152
+ this.end = this.min;
12153
+ } else {
12154
+ this.start = this.min;
12155
+ this.end = this.max;
12156
+ }
12157
+ return ticks;
12158
+ }
12159
+ configure() {
12160
+ const ticks = this.ticks;
12161
+ let start = this.min;
12162
+ let end = this.max;
12163
+ super.configure();
12164
+ if (this.options.offset && ticks.length) {
12165
+ const offset = (end - start) / Math.max(ticks.length - 1, 1) / 2;
12166
+ start -= offset;
12167
+ end += offset;
12168
+ }
12169
+ this._startValue = start;
12170
+ this._endValue = end;
12171
+ this._valueRange = end - start;
12172
+ }
12173
+ getLabelForValue(value) {
12174
+ return formatNumber(value, this.chart.options.locale, this.options.ticks.format);
12175
+ }
12176
+ }
12177
+
12178
+ class LinearScale extends LinearScaleBase {
12179
+ determineDataLimits() {
12180
+ const {min, max} = this.getMinMax(true);
12181
+ this.min = isNumberFinite(min) ? min : 0;
12182
+ this.max = isNumberFinite(max) ? max : 1;
12183
+ this.handleTickRangeOptions();
12184
+ }
12185
+ computeTickLimit() {
12186
+ const horizontal = this.isHorizontal();
12187
+ const length = horizontal ? this.width : this.height;
12188
+ const minRotation = toRadians(this.options.ticks.minRotation);
12189
+ const ratio = (horizontal ? Math.sin(minRotation) : Math.cos(minRotation)) || 0.001;
12190
+ const tickFont = this._resolveTickFontOptions(0);
12191
+ return Math.ceil(length / Math.min(40, tickFont.lineHeight / ratio));
12192
+ }
12193
+ getPixelForValue(value) {
12194
+ return value === null ? NaN : this.getPixelForDecimal((value - this._startValue) / this._valueRange);
12195
+ }
12196
+ getValueForPixel(pixel) {
12197
+ return this._startValue + this.getDecimalForPixel(pixel) * this._valueRange;
12198
+ }
12199
+ }
12200
+ LinearScale.id = 'linear';
12201
+ LinearScale.defaults = {
12202
+ ticks: {
12203
+ callback: Ticks.formatters.numeric
12204
+ }
12205
+ };
12206
+
12207
+ function isMajor(tickVal) {
12208
+ const remain = tickVal / (Math.pow(10, Math.floor(log10(tickVal))));
12209
+ return remain === 1;
12210
+ }
12211
+ function generateTicks(generationOptions, dataRange) {
12212
+ const endExp = Math.floor(log10(dataRange.max));
12213
+ const endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));
12214
+ const ticks = [];
12215
+ let tickVal = finiteOrDefault(generationOptions.min, Math.pow(10, Math.floor(log10(dataRange.min))));
12216
+ let exp = Math.floor(log10(tickVal));
12217
+ let significand = Math.floor(tickVal / Math.pow(10, exp));
12218
+ let precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1;
12219
+ do {
12220
+ ticks.push({value: tickVal, major: isMajor(tickVal)});
12221
+ ++significand;
12222
+ if (significand === 10) {
12223
+ significand = 1;
12224
+ ++exp;
12225
+ precision = exp >= 0 ? 1 : precision;
12226
+ }
12227
+ tickVal = Math.round(significand * Math.pow(10, exp) * precision) / precision;
12228
+ } while (exp < endExp || (exp === endExp && significand < endSignificand));
12229
+ const lastTick = finiteOrDefault(generationOptions.max, tickVal);
12230
+ ticks.push({value: lastTick, major: isMajor(tickVal)});
12231
+ return ticks;
12232
+ }
12233
+ class LogarithmicScale extends Scale {
12234
+ constructor(cfg) {
12235
+ super(cfg);
12236
+ this.start = undefined;
12237
+ this.end = undefined;
12238
+ this._startValue = undefined;
12239
+ this._valueRange = 0;
12240
+ }
12241
+ parse(raw, index) {
12242
+ const value = LinearScaleBase.prototype.parse.apply(this, [raw, index]);
12243
+ if (value === 0) {
12244
+ this._zero = true;
12245
+ return undefined;
12246
+ }
12247
+ return isNumberFinite(value) && value > 0 ? value : null;
12248
+ }
12249
+ determineDataLimits() {
12250
+ const {min, max} = this.getMinMax(true);
12251
+ this.min = isNumberFinite(min) ? Math.max(0, min) : null;
12252
+ this.max = isNumberFinite(max) ? Math.max(0, max) : null;
12253
+ if (this.options.beginAtZero) {
12254
+ this._zero = true;
12255
+ }
12256
+ this.handleTickRangeOptions();
12257
+ }
12258
+ handleTickRangeOptions() {
12259
+ const {minDefined, maxDefined} = this.getUserBounds();
12260
+ let min = this.min;
12261
+ let max = this.max;
12262
+ const setMin = v => (min = minDefined ? min : v);
12263
+ const setMax = v => (max = maxDefined ? max : v);
12264
+ const exp = (v, m) => Math.pow(10, Math.floor(log10(v)) + m);
12265
+ if (min === max) {
12266
+ if (min <= 0) {
12267
+ setMin(1);
12268
+ setMax(10);
12269
+ } else {
12270
+ setMin(exp(min, -1));
12271
+ setMax(exp(max, +1));
12272
+ }
12273
+ }
12274
+ if (min <= 0) {
12275
+ setMin(exp(max, -1));
12276
+ }
12277
+ if (max <= 0) {
12278
+ setMax(exp(min, +1));
12279
+ }
12280
+ if (this._zero && this.min !== this._suggestedMin && min === exp(this.min, 0)) {
12281
+ setMin(exp(min, -1));
12282
+ }
12283
+ this.min = min;
12284
+ this.max = max;
12285
+ }
12286
+ buildTicks() {
12287
+ const opts = this.options;
12288
+ const generationOptions = {
12289
+ min: this._userMin,
12290
+ max: this._userMax
12291
+ };
12292
+ const ticks = generateTicks(generationOptions, this);
12293
+ if (opts.bounds === 'ticks') {
12294
+ _setMinAndMaxByKey(ticks, this, 'value');
12295
+ }
12296
+ if (opts.reverse) {
12297
+ ticks.reverse();
12298
+ this.start = this.max;
12299
+ this.end = this.min;
12300
+ } else {
12301
+ this.start = this.min;
12302
+ this.end = this.max;
12303
+ }
12304
+ return ticks;
12305
+ }
12306
+ getLabelForValue(value) {
12307
+ return value === undefined
12308
+ ? '0'
12309
+ : formatNumber(value, this.chart.options.locale, this.options.ticks.format);
12310
+ }
12311
+ configure() {
12312
+ const start = this.min;
12313
+ super.configure();
12314
+ this._startValue = log10(start);
12315
+ this._valueRange = log10(this.max) - log10(start);
12316
+ }
12317
+ getPixelForValue(value) {
12318
+ if (value === undefined || value === 0) {
12319
+ value = this.min;
12320
+ }
12321
+ if (value === null || isNaN(value)) {
12322
+ return NaN;
12323
+ }
12324
+ return this.getPixelForDecimal(value === this.min
12325
+ ? 0
12326
+ : (log10(value) - this._startValue) / this._valueRange);
12327
+ }
12328
+ getValueForPixel(pixel) {
12329
+ const decimal = this.getDecimalForPixel(pixel);
12330
+ return Math.pow(10, this._startValue + decimal * this._valueRange);
12331
+ }
12332
+ }
12333
+ LogarithmicScale.id = 'logarithmic';
12334
+ LogarithmicScale.defaults = {
12335
+ ticks: {
12336
+ callback: Ticks.formatters.logarithmic,
12337
+ major: {
12338
+ enabled: true
12339
+ }
12340
+ }
12341
+ };
12342
+
12343
+ function getTickBackdropHeight(opts) {
12344
+ const tickOpts = opts.ticks;
12345
+ if (tickOpts.display && opts.display) {
12346
+ const padding = toPadding(tickOpts.backdropPadding);
12347
+ return valueOrDefault(tickOpts.font && tickOpts.font.size, defaults.font.size) + padding.height;
12348
+ }
12349
+ return 0;
12350
+ }
12351
+ function measureLabelSize(ctx, font, label) {
12352
+ label = isArray(label) ? label : [label];
12353
+ return {
12354
+ w: _longestText(ctx, font.string, label),
12355
+ h: label.length * font.lineHeight
12356
+ };
12357
+ }
12358
+ function determineLimits(angle, pos, size, min, max) {
12359
+ if (angle === min || angle === max) {
12360
+ return {
12361
+ start: pos - (size / 2),
12362
+ end: pos + (size / 2)
12363
+ };
12364
+ } else if (angle < min || angle > max) {
12365
+ return {
12366
+ start: pos - size,
12367
+ end: pos
12368
+ };
12369
+ }
12370
+ return {
12371
+ start: pos,
12372
+ end: pos + size
12373
+ };
12374
+ }
12375
+ function fitWithPointLabels(scale) {
12376
+ const orig = {
12377
+ l: scale.left + scale._padding.left,
12378
+ r: scale.right - scale._padding.right,
12379
+ t: scale.top + scale._padding.top,
12380
+ b: scale.bottom - scale._padding.bottom
12381
+ };
12382
+ const limits = Object.assign({}, orig);
12383
+ const labelSizes = [];
12384
+ const padding = [];
12385
+ const valueCount = scale._pointLabels.length;
12386
+ const pointLabelOpts = scale.options.pointLabels;
12387
+ const additionalAngle = pointLabelOpts.centerPointLabels ? PI / valueCount : 0;
12388
+ for (let i = 0; i < valueCount; i++) {
12389
+ const opts = pointLabelOpts.setContext(scale.getPointLabelContext(i));
12390
+ padding[i] = opts.padding;
12391
+ const pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i], additionalAngle);
12392
+ const plFont = toFont(opts.font);
12393
+ const textSize = measureLabelSize(scale.ctx, plFont, scale._pointLabels[i]);
12394
+ labelSizes[i] = textSize;
12395
+ const angleRadians = _normalizeAngle(scale.getIndexAngle(i) + additionalAngle);
12396
+ const angle = Math.round(toDegrees(angleRadians));
12397
+ const hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);
12398
+ const vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);
12399
+ updateLimits(limits, orig, angleRadians, hLimits, vLimits);
12400
+ }
12401
+ scale.setCenterPoint(
12402
+ orig.l - limits.l,
12403
+ limits.r - orig.r,
12404
+ orig.t - limits.t,
12405
+ limits.b - orig.b
12406
+ );
12407
+ scale._pointLabelItems = buildPointLabelItems(scale, labelSizes, padding);
12408
+ }
12409
+ function updateLimits(limits, orig, angle, hLimits, vLimits) {
12410
+ const sin = Math.abs(Math.sin(angle));
12411
+ const cos = Math.abs(Math.cos(angle));
12412
+ let x = 0;
12413
+ let y = 0;
12414
+ if (hLimits.start < orig.l) {
12415
+ x = (orig.l - hLimits.start) / sin;
12416
+ limits.l = Math.min(limits.l, orig.l - x);
12417
+ } else if (hLimits.end > orig.r) {
12418
+ x = (hLimits.end - orig.r) / sin;
12419
+ limits.r = Math.max(limits.r, orig.r + x);
12420
+ }
12421
+ if (vLimits.start < orig.t) {
12422
+ y = (orig.t - vLimits.start) / cos;
12423
+ limits.t = Math.min(limits.t, orig.t - y);
12424
+ } else if (vLimits.end > orig.b) {
12425
+ y = (vLimits.end - orig.b) / cos;
12426
+ limits.b = Math.max(limits.b, orig.b + y);
12427
+ }
12428
+ }
12429
+ function buildPointLabelItems(scale, labelSizes, padding) {
12430
+ const items = [];
12431
+ const valueCount = scale._pointLabels.length;
12432
+ const opts = scale.options;
12433
+ const extra = getTickBackdropHeight(opts) / 2;
12434
+ const outerDistance = scale.drawingArea;
12435
+ const additionalAngle = opts.pointLabels.centerPointLabels ? PI / valueCount : 0;
12436
+ for (let i = 0; i < valueCount; i++) {
12437
+ const pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + padding[i], additionalAngle);
12438
+ const angle = Math.round(toDegrees(_normalizeAngle(pointLabelPosition.angle + HALF_PI)));
12439
+ const size = labelSizes[i];
12440
+ const y = yForAngle(pointLabelPosition.y, size.h, angle);
12441
+ const textAlign = getTextAlignForAngle(angle);
12442
+ const left = leftForTextAlign(pointLabelPosition.x, size.w, textAlign);
12443
+ items.push({
12444
+ x: pointLabelPosition.x,
12445
+ y,
12446
+ textAlign,
12447
+ left,
12448
+ top: y,
12449
+ right: left + size.w,
12450
+ bottom: y + size.h
12451
+ });
12452
+ }
12453
+ return items;
12454
+ }
12455
+ function getTextAlignForAngle(angle) {
12456
+ if (angle === 0 || angle === 180) {
12457
+ return 'center';
12458
+ } else if (angle < 180) {
12459
+ return 'left';
12460
+ }
12461
+ return 'right';
12462
+ }
12463
+ function leftForTextAlign(x, w, align) {
12464
+ if (align === 'right') {
12465
+ x -= w;
12466
+ } else if (align === 'center') {
12467
+ x -= (w / 2);
12468
+ }
12469
+ return x;
12470
+ }
12471
+ function yForAngle(y, h, angle) {
12472
+ if (angle === 90 || angle === 270) {
12473
+ y -= (h / 2);
12474
+ } else if (angle > 270 || angle < 90) {
12475
+ y -= h;
12476
+ }
12477
+ return y;
12478
+ }
12479
+ function drawPointLabels(scale, labelCount) {
12480
+ const {ctx, options: {pointLabels}} = scale;
12481
+ for (let i = labelCount - 1; i >= 0; i--) {
12482
+ const optsAtIndex = pointLabels.setContext(scale.getPointLabelContext(i));
12483
+ const plFont = toFont(optsAtIndex.font);
12484
+ const {x, y, textAlign, left, top, right, bottom} = scale._pointLabelItems[i];
12485
+ const {backdropColor} = optsAtIndex;
12486
+ if (!isNullOrUndef(backdropColor)) {
12487
+ const padding = toPadding(optsAtIndex.backdropPadding);
12488
+ ctx.fillStyle = backdropColor;
12489
+ ctx.fillRect(left - padding.left, top - padding.top, right - left + padding.width, bottom - top + padding.height);
12490
+ }
12491
+ renderText(
12492
+ ctx,
12493
+ scale._pointLabels[i],
12494
+ x,
12495
+ y + (plFont.lineHeight / 2),
12496
+ plFont,
12497
+ {
12498
+ color: optsAtIndex.color,
12499
+ textAlign: textAlign,
12500
+ textBaseline: 'middle'
12501
+ }
12502
+ );
12503
+ }
12504
+ }
12505
+ function pathRadiusLine(scale, radius, circular, labelCount) {
12506
+ const {ctx} = scale;
12507
+ if (circular) {
12508
+ ctx.arc(scale.xCenter, scale.yCenter, radius, 0, TAU);
12509
+ } else {
12510
+ let pointPosition = scale.getPointPosition(0, radius);
12511
+ ctx.moveTo(pointPosition.x, pointPosition.y);
12512
+ for (let i = 1; i < labelCount; i++) {
12513
+ pointPosition = scale.getPointPosition(i, radius);
12514
+ ctx.lineTo(pointPosition.x, pointPosition.y);
12515
+ }
12516
+ }
12517
+ }
12518
+ function drawRadiusLine(scale, gridLineOpts, radius, labelCount) {
12519
+ const ctx = scale.ctx;
12520
+ const circular = gridLineOpts.circular;
12521
+ const {color, lineWidth} = gridLineOpts;
12522
+ if ((!circular && !labelCount) || !color || !lineWidth || radius < 0) {
12523
+ return;
12524
+ }
12525
+ ctx.save();
12526
+ ctx.strokeStyle = color;
12527
+ ctx.lineWidth = lineWidth;
12528
+ ctx.setLineDash(gridLineOpts.borderDash);
12529
+ ctx.lineDashOffset = gridLineOpts.borderDashOffset;
12530
+ ctx.beginPath();
12531
+ pathRadiusLine(scale, radius, circular, labelCount);
12532
+ ctx.closePath();
12533
+ ctx.stroke();
12534
+ ctx.restore();
12535
+ }
12536
+ function createPointLabelContext(parent, index, label) {
12537
+ return createContext(parent, {
12538
+ label,
12539
+ index,
12540
+ type: 'pointLabel'
12541
+ });
12542
+ }
12543
+ class RadialLinearScale extends LinearScaleBase {
12544
+ constructor(cfg) {
12545
+ super(cfg);
12546
+ this.xCenter = undefined;
12547
+ this.yCenter = undefined;
12548
+ this.drawingArea = undefined;
12549
+ this._pointLabels = [];
12550
+ this._pointLabelItems = [];
12551
+ }
12552
+ setDimensions() {
12553
+ const padding = this._padding = toPadding(getTickBackdropHeight(this.options) / 2);
12554
+ const w = this.width = this.maxWidth - padding.width;
12555
+ const h = this.height = this.maxHeight - padding.height;
12556
+ this.xCenter = Math.floor(this.left + w / 2 + padding.left);
12557
+ this.yCenter = Math.floor(this.top + h / 2 + padding.top);
12558
+ this.drawingArea = Math.floor(Math.min(w, h) / 2);
12559
+ }
12560
+ determineDataLimits() {
12561
+ const {min, max} = this.getMinMax(false);
12562
+ this.min = isNumberFinite(min) && !isNaN(min) ? min : 0;
12563
+ this.max = isNumberFinite(max) && !isNaN(max) ? max : 0;
12564
+ this.handleTickRangeOptions();
12565
+ }
12566
+ computeTickLimit() {
12567
+ return Math.ceil(this.drawingArea / getTickBackdropHeight(this.options));
12568
+ }
12569
+ generateTickLabels(ticks) {
12570
+ LinearScaleBase.prototype.generateTickLabels.call(this, ticks);
12571
+ this._pointLabels = this.getLabels()
12572
+ .map((value, index) => {
12573
+ const label = callback(this.options.pointLabels.callback, [value, index], this);
12574
+ return label || label === 0 ? label : '';
12575
+ })
12576
+ .filter((v, i) => this.chart.getDataVisibility(i));
12577
+ }
12578
+ fit() {
12579
+ const opts = this.options;
12580
+ if (opts.display && opts.pointLabels.display) {
12581
+ fitWithPointLabels(this);
12582
+ } else {
12583
+ this.setCenterPoint(0, 0, 0, 0);
12584
+ }
12585
+ }
12586
+ setCenterPoint(leftMovement, rightMovement, topMovement, bottomMovement) {
12587
+ this.xCenter += Math.floor((leftMovement - rightMovement) / 2);
12588
+ this.yCenter += Math.floor((topMovement - bottomMovement) / 2);
12589
+ this.drawingArea -= Math.min(this.drawingArea / 2, Math.max(leftMovement, rightMovement, topMovement, bottomMovement));
12590
+ }
12591
+ getIndexAngle(index) {
12592
+ const angleMultiplier = TAU / (this._pointLabels.length || 1);
12593
+ const startAngle = this.options.startAngle || 0;
12594
+ return _normalizeAngle(index * angleMultiplier + toRadians(startAngle));
12595
+ }
12596
+ getDistanceFromCenterForValue(value) {
12597
+ if (isNullOrUndef(value)) {
12598
+ return NaN;
12599
+ }
12600
+ const scalingFactor = this.drawingArea / (this.max - this.min);
12601
+ if (this.options.reverse) {
12602
+ return (this.max - value) * scalingFactor;
12603
+ }
12604
+ return (value - this.min) * scalingFactor;
12605
+ }
12606
+ getValueForDistanceFromCenter(distance) {
12607
+ if (isNullOrUndef(distance)) {
12608
+ return NaN;
12609
+ }
12610
+ const scaledDistance = distance / (this.drawingArea / (this.max - this.min));
12611
+ return this.options.reverse ? this.max - scaledDistance : this.min + scaledDistance;
12612
+ }
12613
+ getPointLabelContext(index) {
12614
+ const pointLabels = this._pointLabels || [];
12615
+ if (index >= 0 && index < pointLabels.length) {
12616
+ const pointLabel = pointLabels[index];
12617
+ return createPointLabelContext(this.getContext(), index, pointLabel);
12618
+ }
12619
+ }
12620
+ getPointPosition(index, distanceFromCenter, additionalAngle = 0) {
12621
+ const angle = this.getIndexAngle(index) - HALF_PI + additionalAngle;
12622
+ return {
12623
+ x: Math.cos(angle) * distanceFromCenter + this.xCenter,
12624
+ y: Math.sin(angle) * distanceFromCenter + this.yCenter,
12625
+ angle
12626
+ };
12627
+ }
12628
+ getPointPositionForValue(index, value) {
12629
+ return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));
12630
+ }
12631
+ getBasePosition(index) {
12632
+ return this.getPointPositionForValue(index || 0, this.getBaseValue());
12633
+ }
12634
+ getPointLabelPosition(index) {
12635
+ const {left, top, right, bottom} = this._pointLabelItems[index];
12636
+ return {
12637
+ left,
12638
+ top,
12639
+ right,
12640
+ bottom,
12641
+ };
12642
+ }
12643
+ drawBackground() {
12644
+ const {backgroundColor, grid: {circular}} = this.options;
12645
+ if (backgroundColor) {
12646
+ const ctx = this.ctx;
12647
+ ctx.save();
12648
+ ctx.beginPath();
12649
+ pathRadiusLine(this, this.getDistanceFromCenterForValue(this._endValue), circular, this._pointLabels.length);
12650
+ ctx.closePath();
12651
+ ctx.fillStyle = backgroundColor;
12652
+ ctx.fill();
12653
+ ctx.restore();
12654
+ }
12655
+ }
12656
+ drawGrid() {
12657
+ const ctx = this.ctx;
12658
+ const opts = this.options;
12659
+ const {angleLines, grid} = opts;
12660
+ const labelCount = this._pointLabels.length;
12661
+ let i, offset, position;
12662
+ if (opts.pointLabels.display) {
12663
+ drawPointLabels(this, labelCount);
12664
+ }
12665
+ if (grid.display) {
12666
+ this.ticks.forEach((tick, index) => {
12667
+ if (index !== 0) {
12668
+ offset = this.getDistanceFromCenterForValue(tick.value);
12669
+ const optsAtIndex = grid.setContext(this.getContext(index - 1));
12670
+ drawRadiusLine(this, optsAtIndex, offset, labelCount);
12671
+ }
12672
+ });
12673
+ }
12674
+ if (angleLines.display) {
12675
+ ctx.save();
12676
+ for (i = labelCount - 1; i >= 0; i--) {
12677
+ const optsAtIndex = angleLines.setContext(this.getPointLabelContext(i));
12678
+ const {color, lineWidth} = optsAtIndex;
12679
+ if (!lineWidth || !color) {
12680
+ continue;
12681
+ }
12682
+ ctx.lineWidth = lineWidth;
12683
+ ctx.strokeStyle = color;
12684
+ ctx.setLineDash(optsAtIndex.borderDash);
12685
+ ctx.lineDashOffset = optsAtIndex.borderDashOffset;
12686
+ offset = this.getDistanceFromCenterForValue(opts.ticks.reverse ? this.min : this.max);
12687
+ position = this.getPointPosition(i, offset);
12688
+ ctx.beginPath();
12689
+ ctx.moveTo(this.xCenter, this.yCenter);
12690
+ ctx.lineTo(position.x, position.y);
12691
+ ctx.stroke();
12692
+ }
12693
+ ctx.restore();
12694
+ }
12695
+ }
12696
+ drawBorder() {}
12697
+ drawLabels() {
12698
+ const ctx = this.ctx;
12699
+ const opts = this.options;
12700
+ const tickOpts = opts.ticks;
12701
+ if (!tickOpts.display) {
12702
+ return;
12703
+ }
12704
+ const startAngle = this.getIndexAngle(0);
12705
+ let offset, width;
12706
+ ctx.save();
12707
+ ctx.translate(this.xCenter, this.yCenter);
12708
+ ctx.rotate(startAngle);
12709
+ ctx.textAlign = 'center';
12710
+ ctx.textBaseline = 'middle';
12711
+ this.ticks.forEach((tick, index) => {
12712
+ if (index === 0 && !opts.reverse) {
12713
+ return;
12714
+ }
12715
+ const optsAtIndex = tickOpts.setContext(this.getContext(index));
12716
+ const tickFont = toFont(optsAtIndex.font);
12717
+ offset = this.getDistanceFromCenterForValue(this.ticks[index].value);
12718
+ if (optsAtIndex.showLabelBackdrop) {
12719
+ ctx.font = tickFont.string;
12720
+ width = ctx.measureText(tick.label).width;
12721
+ ctx.fillStyle = optsAtIndex.backdropColor;
12722
+ const padding = toPadding(optsAtIndex.backdropPadding);
12723
+ ctx.fillRect(
12724
+ -width / 2 - padding.left,
12725
+ -offset - tickFont.size / 2 - padding.top,
12726
+ width + padding.width,
12727
+ tickFont.size + padding.height
12728
+ );
12729
+ }
12730
+ renderText(ctx, tick.label, 0, -offset, tickFont, {
12731
+ color: optsAtIndex.color,
12732
+ });
12733
+ });
12734
+ ctx.restore();
12735
+ }
12736
+ drawTitle() {}
12737
+ }
12738
+ RadialLinearScale.id = 'radialLinear';
12739
+ RadialLinearScale.defaults = {
12740
+ display: true,
12741
+ animate: true,
12742
+ position: 'chartArea',
12743
+ angleLines: {
12744
+ display: true,
12745
+ lineWidth: 1,
12746
+ borderDash: [],
12747
+ borderDashOffset: 0.0
12748
+ },
12749
+ grid: {
12750
+ circular: false
12751
+ },
12752
+ startAngle: 0,
12753
+ ticks: {
12754
+ showLabelBackdrop: true,
12755
+ callback: Ticks.formatters.numeric
12756
+ },
12757
+ pointLabels: {
12758
+ backdropColor: undefined,
12759
+ backdropPadding: 2,
12760
+ display: true,
12761
+ font: {
12762
+ size: 10
12763
+ },
12764
+ callback(label) {
12765
+ return label;
12766
+ },
12767
+ padding: 5,
12768
+ centerPointLabels: false
12769
+ }
12770
+ };
12771
+ RadialLinearScale.defaultRoutes = {
12772
+ 'angleLines.color': 'borderColor',
12773
+ 'pointLabels.color': 'color',
12774
+ 'ticks.color': 'color'
12775
+ };
12776
+ RadialLinearScale.descriptors = {
12777
+ angleLines: {
12778
+ _fallback: 'grid'
12779
+ }
12780
+ };
12781
+
12782
+ const INTERVALS = {
12783
+ millisecond: {common: true, size: 1, steps: 1000},
12784
+ second: {common: true, size: 1000, steps: 60},
12785
+ minute: {common: true, size: 60000, steps: 60},
12786
+ hour: {common: true, size: 3600000, steps: 24},
12787
+ day: {common: true, size: 86400000, steps: 30},
12788
+ week: {common: false, size: 604800000, steps: 4},
12789
+ month: {common: true, size: 2.628e9, steps: 12},
12790
+ quarter: {common: false, size: 7.884e9, steps: 4},
12791
+ year: {common: true, size: 3.154e10}
12792
+ };
12793
+ const UNITS = (Object.keys(INTERVALS));
12794
+ function sorter(a, b) {
12795
+ return a - b;
12796
+ }
12797
+ function parse(scale, input) {
12798
+ if (isNullOrUndef(input)) {
12799
+ return null;
12800
+ }
12801
+ const adapter = scale._adapter;
12802
+ const {parser, round, isoWeekday} = scale._parseOpts;
12803
+ let value = input;
12804
+ if (typeof parser === 'function') {
12805
+ value = parser(value);
12806
+ }
12807
+ if (!isNumberFinite(value)) {
12808
+ value = typeof parser === 'string'
12809
+ ? adapter.parse(value, parser)
12810
+ : adapter.parse(value);
12811
+ }
12812
+ if (value === null) {
12813
+ return null;
12814
+ }
12815
+ if (round) {
12816
+ value = round === 'week' && (isNumber(isoWeekday) || isoWeekday === true)
12817
+ ? adapter.startOf(value, 'isoWeek', isoWeekday)
12818
+ : adapter.startOf(value, round);
12819
+ }
12820
+ return +value;
12821
+ }
12822
+ function determineUnitForAutoTicks(minUnit, min, max, capacity) {
12823
+ const ilen = UNITS.length;
12824
+ for (let i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) {
12825
+ const interval = INTERVALS[UNITS[i]];
12826
+ const factor = interval.steps ? interval.steps : Number.MAX_SAFE_INTEGER;
12827
+ if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) {
12828
+ return UNITS[i];
12829
+ }
12830
+ }
12831
+ return UNITS[ilen - 1];
12832
+ }
12833
+ function determineUnitForFormatting(scale, numTicks, minUnit, min, max) {
12834
+ for (let i = UNITS.length - 1; i >= UNITS.indexOf(minUnit); i--) {
12835
+ const unit = UNITS[i];
12836
+ if (INTERVALS[unit].common && scale._adapter.diff(max, min, unit) >= numTicks - 1) {
12837
+ return unit;
12838
+ }
12839
+ }
12840
+ return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0];
12841
+ }
12842
+ function determineMajorUnit(unit) {
12843
+ for (let i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) {
12844
+ if (INTERVALS[UNITS[i]].common) {
12845
+ return UNITS[i];
12846
+ }
12847
+ }
12848
+ }
12849
+ function addTick(ticks, time, timestamps) {
12850
+ if (!timestamps) {
12851
+ ticks[time] = true;
12852
+ } else if (timestamps.length) {
12853
+ const {lo, hi} = _lookup(timestamps, time);
12854
+ const timestamp = timestamps[lo] >= time ? timestamps[lo] : timestamps[hi];
12855
+ ticks[timestamp] = true;
12856
+ }
12857
+ }
12858
+ function setMajorTicks(scale, ticks, map, majorUnit) {
12859
+ const adapter = scale._adapter;
12860
+ const first = +adapter.startOf(ticks[0].value, majorUnit);
12861
+ const last = ticks[ticks.length - 1].value;
12862
+ let major, index;
12863
+ for (major = first; major <= last; major = +adapter.add(major, 1, majorUnit)) {
12864
+ index = map[major];
12865
+ if (index >= 0) {
12866
+ ticks[index].major = true;
12867
+ }
12868
+ }
12869
+ return ticks;
12870
+ }
12871
+ function ticksFromTimestamps(scale, values, majorUnit) {
12872
+ const ticks = [];
12873
+ const map = {};
12874
+ const ilen = values.length;
12875
+ let i, value;
12876
+ for (i = 0; i < ilen; ++i) {
12877
+ value = values[i];
12878
+ map[value] = i;
12879
+ ticks.push({
12880
+ value,
12881
+ major: false
12882
+ });
12883
+ }
12884
+ return (ilen === 0 || !majorUnit) ? ticks : setMajorTicks(scale, ticks, map, majorUnit);
12885
+ }
12886
+ class TimeScale extends Scale {
12887
+ constructor(props) {
12888
+ super(props);
12889
+ this._cache = {
12890
+ data: [],
12891
+ labels: [],
12892
+ all: []
12893
+ };
12894
+ this._unit = 'day';
12895
+ this._majorUnit = undefined;
12896
+ this._offsets = {};
12897
+ this._normalized = false;
12898
+ this._parseOpts = undefined;
12899
+ }
12900
+ init(scaleOpts, opts) {
12901
+ const time = scaleOpts.time || (scaleOpts.time = {});
12902
+ const adapter = this._adapter = new _adapters._date(scaleOpts.adapters.date);
12903
+ mergeIf(time.displayFormats, adapter.formats());
12904
+ this._parseOpts = {
12905
+ parser: time.parser,
12906
+ round: time.round,
12907
+ isoWeekday: time.isoWeekday
12908
+ };
12909
+ super.init(scaleOpts);
12910
+ this._normalized = opts.normalized;
12911
+ }
12912
+ parse(raw, index) {
12913
+ if (raw === undefined) {
12914
+ return null;
12915
+ }
12916
+ return parse(this, raw);
12917
+ }
12918
+ beforeLayout() {
12919
+ super.beforeLayout();
12920
+ this._cache = {
12921
+ data: [],
12922
+ labels: [],
12923
+ all: []
12924
+ };
12925
+ }
12926
+ determineDataLimits() {
12927
+ const options = this.options;
12928
+ const adapter = this._adapter;
12929
+ const unit = options.time.unit || 'day';
12930
+ let {min, max, minDefined, maxDefined} = this.getUserBounds();
12931
+ function _applyBounds(bounds) {
12932
+ if (!minDefined && !isNaN(bounds.min)) {
12933
+ min = Math.min(min, bounds.min);
12934
+ }
12935
+ if (!maxDefined && !isNaN(bounds.max)) {
12936
+ max = Math.max(max, bounds.max);
12937
+ }
12938
+ }
12939
+ if (!minDefined || !maxDefined) {
12940
+ _applyBounds(this._getLabelBounds());
12941
+ if (options.bounds !== 'ticks' || options.ticks.source !== 'labels') {
12942
+ _applyBounds(this.getMinMax(false));
12943
+ }
12944
+ }
12945
+ min = isNumberFinite(min) && !isNaN(min) ? min : +adapter.startOf(Date.now(), unit);
12946
+ max = isNumberFinite(max) && !isNaN(max) ? max : +adapter.endOf(Date.now(), unit) + 1;
12947
+ this.min = Math.min(min, max - 1);
12948
+ this.max = Math.max(min + 1, max);
12949
+ }
12950
+ _getLabelBounds() {
12951
+ const arr = this.getLabelTimestamps();
12952
+ let min = Number.POSITIVE_INFINITY;
12953
+ let max = Number.NEGATIVE_INFINITY;
12954
+ if (arr.length) {
12955
+ min = arr[0];
12956
+ max = arr[arr.length - 1];
12957
+ }
12958
+ return {min, max};
12959
+ }
12960
+ buildTicks() {
12961
+ const options = this.options;
12962
+ const timeOpts = options.time;
12963
+ const tickOpts = options.ticks;
12964
+ const timestamps = tickOpts.source === 'labels' ? this.getLabelTimestamps() : this._generate();
12965
+ if (options.bounds === 'ticks' && timestamps.length) {
12966
+ this.min = this._userMin || timestamps[0];
12967
+ this.max = this._userMax || timestamps[timestamps.length - 1];
12968
+ }
12969
+ const min = this.min;
12970
+ const max = this.max;
12971
+ const ticks = _filterBetween(timestamps, min, max);
12972
+ this._unit = timeOpts.unit || (tickOpts.autoSkip
12973
+ ? determineUnitForAutoTicks(timeOpts.minUnit, this.min, this.max, this._getLabelCapacity(min))
12974
+ : determineUnitForFormatting(this, ticks.length, timeOpts.minUnit, this.min, this.max));
12975
+ this._majorUnit = !tickOpts.major.enabled || this._unit === 'year' ? undefined
12976
+ : determineMajorUnit(this._unit);
12977
+ this.initOffsets(timestamps);
12978
+ if (options.reverse) {
12979
+ ticks.reverse();
12980
+ }
12981
+ return ticksFromTimestamps(this, ticks, this._majorUnit);
12982
+ }
12983
+ initOffsets(timestamps) {
12984
+ let start = 0;
12985
+ let end = 0;
12986
+ let first, last;
12987
+ if (this.options.offset && timestamps.length) {
12988
+ first = this.getDecimalForValue(timestamps[0]);
12989
+ if (timestamps.length === 1) {
12990
+ start = 1 - first;
12991
+ } else {
12992
+ start = (this.getDecimalForValue(timestamps[1]) - first) / 2;
12993
+ }
12994
+ last = this.getDecimalForValue(timestamps[timestamps.length - 1]);
12995
+ if (timestamps.length === 1) {
12996
+ end = last;
12997
+ } else {
12998
+ end = (last - this.getDecimalForValue(timestamps[timestamps.length - 2])) / 2;
12999
+ }
13000
+ }
13001
+ const limit = timestamps.length < 3 ? 0.5 : 0.25;
13002
+ start = _limitValue(start, 0, limit);
13003
+ end = _limitValue(end, 0, limit);
13004
+ this._offsets = {start, end, factor: 1 / (start + 1 + end)};
13005
+ }
13006
+ _generate() {
13007
+ const adapter = this._adapter;
13008
+ const min = this.min;
13009
+ const max = this.max;
13010
+ const options = this.options;
13011
+ const timeOpts = options.time;
13012
+ const minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, this._getLabelCapacity(min));
13013
+ const stepSize = valueOrDefault(timeOpts.stepSize, 1);
13014
+ const weekday = minor === 'week' ? timeOpts.isoWeekday : false;
13015
+ const hasWeekday = isNumber(weekday) || weekday === true;
13016
+ const ticks = {};
13017
+ let first = min;
13018
+ let time, count;
13019
+ if (hasWeekday) {
13020
+ first = +adapter.startOf(first, 'isoWeek', weekday);
13021
+ }
13022
+ first = +adapter.startOf(first, hasWeekday ? 'day' : minor);
13023
+ if (adapter.diff(max, min, minor) > 100000 * stepSize) {
13024
+ throw new Error(min + ' and ' + max + ' are too far apart with stepSize of ' + stepSize + ' ' + minor);
13025
+ }
13026
+ const timestamps = options.ticks.source === 'data' && this.getDataTimestamps();
13027
+ for (time = first, count = 0; time < max; time = +adapter.add(time, stepSize, minor), count++) {
13028
+ addTick(ticks, time, timestamps);
13029
+ }
13030
+ if (time === max || options.bounds === 'ticks' || count === 1) {
13031
+ addTick(ticks, time, timestamps);
13032
+ }
13033
+ return Object.keys(ticks).sort((a, b) => a - b).map(x => +x);
13034
+ }
13035
+ getLabelForValue(value) {
13036
+ const adapter = this._adapter;
13037
+ const timeOpts = this.options.time;
13038
+ if (timeOpts.tooltipFormat) {
13039
+ return adapter.format(value, timeOpts.tooltipFormat);
13040
+ }
13041
+ return adapter.format(value, timeOpts.displayFormats.datetime);
13042
+ }
13043
+ _tickFormatFunction(time, index, ticks, format) {
13044
+ const options = this.options;
13045
+ const formats = options.time.displayFormats;
13046
+ const unit = this._unit;
13047
+ const majorUnit = this._majorUnit;
13048
+ const minorFormat = unit && formats[unit];
13049
+ const majorFormat = majorUnit && formats[majorUnit];
13050
+ const tick = ticks[index];
13051
+ const major = majorUnit && majorFormat && tick && tick.major;
13052
+ const label = this._adapter.format(time, format || (major ? majorFormat : minorFormat));
13053
+ const formatter = options.ticks.callback;
13054
+ return formatter ? callback(formatter, [label, index, ticks], this) : label;
13055
+ }
13056
+ generateTickLabels(ticks) {
13057
+ let i, ilen, tick;
13058
+ for (i = 0, ilen = ticks.length; i < ilen; ++i) {
13059
+ tick = ticks[i];
13060
+ tick.label = this._tickFormatFunction(tick.value, i, ticks);
13061
+ }
13062
+ }
13063
+ getDecimalForValue(value) {
13064
+ return value === null ? NaN : (value - this.min) / (this.max - this.min);
13065
+ }
13066
+ getPixelForValue(value) {
13067
+ const offsets = this._offsets;
13068
+ const pos = this.getDecimalForValue(value);
13069
+ return this.getPixelForDecimal((offsets.start + pos) * offsets.factor);
13070
+ }
13071
+ getValueForPixel(pixel) {
13072
+ const offsets = this._offsets;
13073
+ const pos = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end;
13074
+ return this.min + pos * (this.max - this.min);
13075
+ }
13076
+ _getLabelSize(label) {
13077
+ const ticksOpts = this.options.ticks;
13078
+ const tickLabelWidth = this.ctx.measureText(label).width;
13079
+ const angle = toRadians(this.isHorizontal() ? ticksOpts.maxRotation : ticksOpts.minRotation);
13080
+ const cosRotation = Math.cos(angle);
13081
+ const sinRotation = Math.sin(angle);
13082
+ const tickFontSize = this._resolveTickFontOptions(0).size;
13083
+ return {
13084
+ w: (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation),
13085
+ h: (tickLabelWidth * sinRotation) + (tickFontSize * cosRotation)
13086
+ };
13087
+ }
13088
+ _getLabelCapacity(exampleTime) {
13089
+ const timeOpts = this.options.time;
13090
+ const displayFormats = timeOpts.displayFormats;
13091
+ const format = displayFormats[timeOpts.unit] || displayFormats.millisecond;
13092
+ const exampleLabel = this._tickFormatFunction(exampleTime, 0, ticksFromTimestamps(this, [exampleTime], this._majorUnit), format);
13093
+ const size = this._getLabelSize(exampleLabel);
13094
+ const capacity = Math.floor(this.isHorizontal() ? this.width / size.w : this.height / size.h) - 1;
13095
+ return capacity > 0 ? capacity : 1;
13096
+ }
13097
+ getDataTimestamps() {
13098
+ let timestamps = this._cache.data || [];
13099
+ let i, ilen;
13100
+ if (timestamps.length) {
13101
+ return timestamps;
13102
+ }
13103
+ const metas = this.getMatchingVisibleMetas();
13104
+ if (this._normalized && metas.length) {
13105
+ return (this._cache.data = metas[0].controller.getAllParsedValues(this));
13106
+ }
13107
+ for (i = 0, ilen = metas.length; i < ilen; ++i) {
13108
+ timestamps = timestamps.concat(metas[i].controller.getAllParsedValues(this));
13109
+ }
13110
+ return (this._cache.data = this.normalize(timestamps));
13111
+ }
13112
+ getLabelTimestamps() {
13113
+ const timestamps = this._cache.labels || [];
13114
+ let i, ilen;
13115
+ if (timestamps.length) {
13116
+ return timestamps;
13117
+ }
13118
+ const labels = this.getLabels();
13119
+ for (i = 0, ilen = labels.length; i < ilen; ++i) {
13120
+ timestamps.push(parse(this, labels[i]));
13121
+ }
13122
+ return (this._cache.labels = this._normalized ? timestamps : this.normalize(timestamps));
13123
+ }
13124
+ normalize(values) {
13125
+ return _arrayUnique(values.sort(sorter));
13126
+ }
13127
+ }
13128
+ TimeScale.id = 'time';
13129
+ TimeScale.defaults = {
13130
+ bounds: 'data',
13131
+ adapters: {},
13132
+ time: {
13133
+ parser: false,
13134
+ unit: false,
13135
+ round: false,
13136
+ isoWeekday: false,
13137
+ minUnit: 'millisecond',
13138
+ displayFormats: {}
13139
+ },
13140
+ ticks: {
13141
+ source: 'auto',
13142
+ major: {
13143
+ enabled: false
13144
+ }
13145
+ }
13146
+ };
13147
+
13148
+ function interpolate(table, val, reverse) {
13149
+ let lo = 0;
13150
+ let hi = table.length - 1;
13151
+ let prevSource, nextSource, prevTarget, nextTarget;
13152
+ if (reverse) {
13153
+ if (val >= table[lo].pos && val <= table[hi].pos) {
13154
+ ({lo, hi} = _lookupByKey(table, 'pos', val));
13155
+ }
13156
+ ({pos: prevSource, time: prevTarget} = table[lo]);
13157
+ ({pos: nextSource, time: nextTarget} = table[hi]);
13158
+ } else {
13159
+ if (val >= table[lo].time && val <= table[hi].time) {
13160
+ ({lo, hi} = _lookupByKey(table, 'time', val));
13161
+ }
13162
+ ({time: prevSource, pos: prevTarget} = table[lo]);
13163
+ ({time: nextSource, pos: nextTarget} = table[hi]);
13164
+ }
13165
+ const span = nextSource - prevSource;
13166
+ return span ? prevTarget + (nextTarget - prevTarget) * (val - prevSource) / span : prevTarget;
13167
+ }
13168
+ class TimeSeriesScale extends TimeScale {
13169
+ constructor(props) {
13170
+ super(props);
13171
+ this._table = [];
13172
+ this._minPos = undefined;
13173
+ this._tableRange = undefined;
13174
+ }
13175
+ initOffsets() {
13176
+ const timestamps = this._getTimestampsForTable();
13177
+ const table = this._table = this.buildLookupTable(timestamps);
13178
+ this._minPos = interpolate(table, this.min);
13179
+ this._tableRange = interpolate(table, this.max) - this._minPos;
13180
+ super.initOffsets(timestamps);
13181
+ }
13182
+ buildLookupTable(timestamps) {
13183
+ const {min, max} = this;
13184
+ const items = [];
13185
+ const table = [];
13186
+ let i, ilen, prev, curr, next;
13187
+ for (i = 0, ilen = timestamps.length; i < ilen; ++i) {
13188
+ curr = timestamps[i];
13189
+ if (curr >= min && curr <= max) {
13190
+ items.push(curr);
13191
+ }
13192
+ }
13193
+ if (items.length < 2) {
13194
+ return [
13195
+ {time: min, pos: 0},
13196
+ {time: max, pos: 1}
13197
+ ];
13198
+ }
13199
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
13200
+ next = items[i + 1];
13201
+ prev = items[i - 1];
13202
+ curr = items[i];
13203
+ if (Math.round((next + prev) / 2) !== curr) {
13204
+ table.push({time: curr, pos: i / (ilen - 1)});
13205
+ }
13206
+ }
13207
+ return table;
13208
+ }
13209
+ _getTimestampsForTable() {
13210
+ let timestamps = this._cache.all || [];
13211
+ if (timestamps.length) {
13212
+ return timestamps;
13213
+ }
13214
+ const data = this.getDataTimestamps();
13215
+ const label = this.getLabelTimestamps();
13216
+ if (data.length && label.length) {
13217
+ timestamps = this.normalize(data.concat(label));
13218
+ } else {
13219
+ timestamps = data.length ? data : label;
13220
+ }
13221
+ timestamps = this._cache.all = timestamps;
13222
+ return timestamps;
13223
+ }
13224
+ getDecimalForValue(value) {
13225
+ return (interpolate(this._table, value) - this._minPos) / this._tableRange;
13226
+ }
13227
+ getValueForPixel(pixel) {
13228
+ const offsets = this._offsets;
13229
+ const decimal = this.getDecimalForPixel(pixel) / offsets.factor - offsets.end;
13230
+ return interpolate(this._table, decimal * this._tableRange + this._minPos, true);
13231
+ }
13232
+ }
13233
+ TimeSeriesScale.id = 'timeseries';
13234
+ TimeSeriesScale.defaults = TimeScale.defaults;
13235
+
13236
+ var scales = /*#__PURE__*/Object.freeze({
13237
+ __proto__: null,
13238
+ CategoryScale: CategoryScale,
13239
+ LinearScale: LinearScale,
13240
+ LogarithmicScale: LogarithmicScale,
13241
+ RadialLinearScale: RadialLinearScale,
13242
+ TimeScale: TimeScale,
13243
+ TimeSeriesScale: TimeSeriesScale
13244
+ });
13245
+
13246
+ Chart.register(controllers, scales, elements, plugins);
13247
+ Chart.helpers = {...helpers};
13248
+ Chart._adapters = _adapters;
13249
+ Chart.Animation = Animation;
13250
+ Chart.Animations = Animations;
13251
+ Chart.animator = animator;
13252
+ Chart.controllers = registry.controllers.items;
13253
+ Chart.DatasetController = DatasetController;
13254
+ Chart.Element = Element;
13255
+ Chart.elements = elements;
13256
+ Chart.Interaction = Interaction;
13257
+ Chart.layouts = layouts;
13258
+ Chart.platforms = platforms;
13259
+ Chart.Scale = Scale;
13260
+ Chart.Ticks = Ticks;
13261
+ Object.assign(Chart, controllers, scales, elements, plugins, platforms);
13262
+ Chart.Chart = Chart;
13263
+ if (typeof window !== 'undefined') {
13264
+ window.Chart = Chart;
13265
+ }
13266
+
13267
+ return Chart;
13268
+
13269
+ }));
addons/stats/assets/libs/Chart.bundle.min.js CHANGED
@@ -1,10 +1,13 @@
1
  /*!
2
- * Chart.js
3
- * http://chartjs.org/
4
- * Version: 2.7.0
5
- *
6
- * Copyright 2017 Nick Downie
7
- * Released under the MIT license
8
- * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
9
  */
10
- !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Chart=t()}}(function(){return function t(e,n,i){function a(o,s){if(!n[o]){if(!e[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var d=n[o]={exports:{}};e[o][0].call(d.exports,function(t){var n=e[o][1][t];return a(n||t)},d,d.exports,t,e,n,i)}return n[o].exports}for(var r="function"==typeof require&&require,o=0;o<i.length;o++)a(i[o]);return a}({1:[function(t,e,n){function i(t){if(t){var e=/^#([a-fA-F0-9]{3})$/i,n=/^#([a-fA-F0-9]{6})$/i,i=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,a=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,r=/(\w+)/,o=[0,0,0],s=1,l=t.match(e);if(l){l=l[1];for(d=0;d<o.length;d++)o[d]=parseInt(l[d]+l[d],16)}else if(l=t.match(n)){l=l[1];for(d=0;d<o.length;d++)o[d]=parseInt(l.slice(2*d,2*d+2),16)}else if(l=t.match(i)){for(d=0;d<o.length;d++)o[d]=parseInt(l[d+1]);s=parseFloat(l[4])}else if(l=t.match(a)){for(d=0;d<o.length;d++)o[d]=Math.round(2.55*parseFloat(l[d+1]));s=parseFloat(l[4])}else if(l=t.match(r)){if("transparent"==l[1])return[0,0,0,0];if(!(o=c[l[1]]))return}for(var d=0;d<o.length;d++)o[d]=u(o[d],0,255);return s=s||0==s?u(s,0,1):1,o[3]=s,o}}function a(t){if(t){var e=/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,n=t.match(e);if(n){var i=parseFloat(n[4]);return[u(parseInt(n[1]),0,360),u(parseFloat(n[2]),0,100),u(parseFloat(n[3]),0,100),u(isNaN(i)?1:i,0,1)]}}}function r(t){if(t){var e=/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,n=t.match(e);if(n){var i=parseFloat(n[4]);return[u(parseInt(n[1]),0,360),u(parseFloat(n[2]),0,100),u(parseFloat(n[3]),0,100),u(isNaN(i)?1:i,0,1)]}}}function o(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function s(t,e){return"rgba("+Math.round(t[0]/255*100)+"%, "+Math.round(t[1]/255*100)+"%, "+Math.round(t[2]/255*100)+"%, "+(e||t[3]||1)+")"}function l(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function u(t,e,n){return Math.min(Math.max(e,t),n)}function d(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var c=t(5);e.exports={getRgba:i,getHsla:a,getRgb:function(t){var e=i(t);return e&&e.slice(0,3)},getHsl:function(t){var e=a(t);return e&&e.slice(0,3)},getHwb:r,getAlpha:function(t){var e=i(t);return e?e[3]:(e=a(t))?e[3]:(e=r(t))?e[3]:void 0},hexString:function(t){return"#"+d(t[0])+d(t[1])+d(t[2])},rgbString:function(t,e){return e<1||t[3]&&t[3]<1?o(t,e):"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:o,percentString:function(t,e){return e<1||t[3]&&t[3]<1?s(t,e):"rgb("+Math.round(t[0]/255*100)+"%, "+Math.round(t[1]/255*100)+"%, "+Math.round(t[2]/255*100)+"%)"},percentaString:s,hslString:function(t,e){return e<1||t[3]&&t[3]<1?l(t,e):"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:l,hwbString:function(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return h[t.slice(0,3)]}};var h={};for(var f in c)h[c[f]]=f},{5:5}],2:[function(t,e,n){var i=t(4),a=t(1),r=function(t){if(t instanceof r)return t;if(!(this instanceof r))return new r(t);this.valid=!1,this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1};var e;"string"==typeof t?(e=a.getRgba(t))?this.setValues("rgb",e):(e=a.getHsla(t))?this.setValues("hsl",e):(e=a.getHwb(t))&&this.setValues("hwb",e):"object"==typeof t&&(void 0!==(e=t).r||void 0!==e.red?this.setValues("rgb",e):void 0!==e.l||void 0!==e.lightness?this.setValues("hsl",e):void 0!==e.v||void 0!==e.value?this.setValues("hsv",e):void 0!==e.w||void 0!==e.whiteness?this.setValues("hwb",e):void 0===e.c&&void 0===e.cyan||this.setValues("cmyk",e))};r.prototype={isValid:function(){return this.valid},rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t=(t%=360)<0?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return a.hexString(this.values.rgb)},rgbString:function(){return a.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return a.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return a.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return a.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return a.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return a.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return a.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],n=0;n<t.length;n++){var i=t[n]/255;e[n]=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),n=t.luminosity();return e>n?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=this,i=t,a=void 0===e?.5:e,r=2*a-1,o=n.alpha()-i.alpha(),s=((r*o==-1?r:(r+o)/(1+r*o))+1)/2,l=1-s;return this.rgb(s*n.red()+l*i.red(),s*n.green()+l*i.green(),s*n.blue()+l*i.blue()).alpha(n.alpha()*a+i.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new r,i=this.values,a=n.values;for(var o in i)i.hasOwnProperty(o)&&(t=i[o],"[object Array]"===(e={}.toString.call(t))?a[o]=t.slice(0):"[object Number]"===e?a[o]=t:console.error("unexpected color value:",t));return n}},r.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},r.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},r.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i<t.length;i++)n[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(n.a=e.alpha),n},r.prototype.setValues=function(t,e){var n,a=this.values,r=this.spaces,o=this.maxes,s=1;if(this.valid=!0,"alpha"===t)s=e;else if(e.length)a[t]=e.slice(0,t.length),s=e[t.length];else if(void 0!==e[t.charAt(0)]){for(n=0;n<t.length;n++)a[t][n]=e[t.charAt(n)];s=e.a}else if(void 0!==e[r[t][0]]){var l=r[t];for(n=0;n<t.length;n++)a[t][n]=e[l[n]];s=e.alpha}if(a.alpha=Math.max(0,Math.min(1,void 0===s?a.alpha:s)),"alpha"===t)return!1;var u;for(n=0;n<t.length;n++)u=Math.max(0,Math.min(o[t][n],a[t][n])),a[t][n]=Math.round(u);for(var d in r)d!==t&&(a[d]=i[t][d](a[t]));return!0},r.prototype.setSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n),this)},r.prototype.setChannel=function(t,e,n){var i=this.values[t];return void 0===n?i[e]:n===i[e]?this:(i[e]=n,this.setValues(t,i),this)},"undefined"!=typeof window&&(window.Color=r),e.exports=r},{1:1,4:4}],3:[function(t,e,n){function i(t){var e,n,i,a=t[0]/255,r=t[1]/255,o=t[2]/255,s=Math.min(a,r,o),l=Math.max(a,r,o),u=l-s;return l==s?e=0:a==l?e=(r-o)/u:r==l?e=2+(o-a)/u:o==l&&(e=4+(a-r)/u),(e=Math.min(60*e,360))<0&&(e+=360),i=(s+l)/2,n=l==s?0:i<=.5?u/(l+s):u/(2-l-s),[e,100*n,100*i]}function a(t){var e,n,i,a=t[0],r=t[1],o=t[2],s=Math.min(a,r,o),l=Math.max(a,r,o),u=l-s;return n=0==l?0:u/l*1e3/10,l==s?e=0:a==l?e=(r-o)/u:r==l?e=2+(o-a)/u:o==l&&(e=4+(a-r)/u),(e=Math.min(60*e,360))<0&&(e+=360),i=l/255*1e3/10,[e,n,i]}function o(t){var e=t[0],n=t[1],a=t[2];return[i(t)[0],100*(1/255*Math.min(e,Math.min(n,a))),100*(a=1-1/255*Math.max(e,Math.max(n,a)))]}function s(t){var e,n,i,a,r=t[0]/255,o=t[1]/255,s=t[2]/255;return a=Math.min(1-r,1-o,1-s),e=(1-r-a)/(1-a)||0,n=(1-o-a)/(1-a)||0,i=(1-s-a)/(1-a)||0,[100*e,100*n,100*i,100*a]}function l(t){return S[JSON.stringify(t)]}function u(t){var e=t[0]/255,n=t[1]/255,i=t[2]/255;return[100*(.4124*(e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]}function d(t){var e,n,i,a=u(t),r=a[0],o=a[1],s=a[2];return r/=95.047,o/=100,s/=108.883,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,s=s>.008856?Math.pow(s,1/3):7.787*s+16/116,e=116*o-16,n=500*(r-o),i=200*(o-s),[e,n,i]}function c(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return r=255*l,[r,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a}function h(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r)),i=255*i;switch(a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}}function f(t){var e,n,i,a,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),e=Math.floor(6*o),n=1-l,i=6*o-e,0!=(1&e)&&(i=1-i),a=s+i*(n-s),e){default:case 6:case 0:r=n,g=a,b=s;break;case 1:r=a,g=n,b=s;break;case 2:r=s,g=n,b=a;break;case 3:r=s,g=a,b=n;break;case 4:r=a,g=s,b=n;break;case 5:r=n,g=s,b=a}return[255*r,255*g,255*b]}function m(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100,s=t[3]/100;return e=1-Math.min(1,a*(1-s)+s),n=1-Math.min(1,r*(1-s)+s),i=1-Math.min(1,o*(1-s)+s),[255*e,255*n,255*i]}function p(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return e=3.2406*a+-1.5372*r+-.4986*o,n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,e=Math.min(Math.max(0,e),1),n=Math.min(Math.max(0,n),1),i=Math.min(Math.max(0,i),1),[255*e,255*n,255*i]}function v(t){var e,n,i,a=t[0],r=t[1],o=t[2];return a/=95.047,r/=100,o/=108.883,a=a>.008856?Math.pow(a,1/3):7.787*a+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,e=116*r-16,n=500*(a-r),i=200*(r-o),[e,n,i]}function y(t){var e,n,i,a,r=t[0],o=t[1],s=t[2];return r<=8?a=(n=100*r/903.3)/100*7.787+16/116:(n=100*Math.pow((r+16)/116,3),a=Math.pow(n/100,1/3)),e=e/95.047<=.008856?e=95.047*(o/500+a-16/116)/7.787:95.047*Math.pow(o/500+a,3),i=i/108.883<=.008859?i=108.883*(a-s/200-16/116)/7.787:108.883*Math.pow(a-s/200,3),[e,n,i]}function x(t){var e,n,i,a=t[0],r=t[1],o=t[2];return e=Math.atan2(o,r),(n=360*e/2/Math.PI)<0&&(n+=360),i=Math.sqrt(r*r+o*o),[a,i,n]}function _(t){return p(y(t))}function k(t){var e,n,i,a=t[0],r=t[1];return i=t[2]/360*2*Math.PI,e=r*Math.cos(i),n=r*Math.sin(i),[a,e,n]}function w(t){return M[t]}e.exports={rgb2hsl:i,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:function(t){return x(d(t))},hsl2rgb:c,hsl2hsv:function(t){var e,n,i=t[0],a=t[1]/100,r=t[2]/100;return 0===r?[0,0,0]:(r*=2,a*=r<=1?r:2-r,n=(r+a)/2,e=2*a/(r+a),[i,100*e,100*n])},hsl2hwb:function(t){return o(c(t))},hsl2cmyk:function(t){return s(c(t))},hsl2keyword:function(t){return l(c(t))},hsv2rgb:h,hsv2hsl:function(t){var e,n,i=t[0],a=t[1]/100,r=t[2]/100;return n=(2-a)*r,e=a*r,e/=n<=1?n:2-n,e=e||0,n/=2,[i,100*e,100*n]},hsv2hwb:function(t){return o(h(t))},hsv2cmyk:function(t){return s(h(t))},hsv2keyword:function(t){return l(h(t))},hwb2rgb:f,hwb2hsl:function(t){return i(f(t))},hwb2hsv:function(t){return a(f(t))},hwb2cmyk:function(t){return s(f(t))},hwb2keyword:function(t){return l(f(t))},cmyk2rgb:m,cmyk2hsl:function(t){return i(m(t))},cmyk2hsv:function(t){return a(m(t))},cmyk2hwb:function(t){return o(m(t))},cmyk2keyword:function(t){return l(m(t))},keyword2rgb:w,keyword2hsl:function(t){return i(w(t))},keyword2hsv:function(t){return a(w(t))},keyword2hwb:function(t){return o(w(t))},keyword2cmyk:function(t){return s(w(t))},keyword2lab:function(t){return d(w(t))},keyword2xyz:function(t){return u(w(t))},xyz2rgb:p,xyz2lab:v,xyz2lch:function(t){return x(v(t))},lab2xyz:y,lab2rgb:_,lab2lch:x,lch2lab:k,lch2xyz:function(t){return y(k(t))},lch2rgb:function(t){return _(k(t))}};var M={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},S={};for(var D in M)S[JSON.stringify(M[D])]=D},{}],4:[function(t,e,n){var i=t(3),a=function(){return new u};for(var r in i){a[r+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(r);var o=/(\w+)2(\w+)/.exec(r),s=o[1],l=o[2];(a[s]=a[s]||{})[l]=a[r]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var n=i[t](e);if("string"==typeof n||void 0===n)return n;for(var a=0;a<n.length;a++)n[a]=Math.round(n[a]);return n}}(r)}var u=function(){this.convs={}};u.prototype.routeSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n))},u.prototype.setValues=function(t,e){return this.space=t,this.convs={},this.convs[t]=e,this},u.prototype.getValues=function(t){var e=this.convs[t];if(!e){var n=this.space,i=this.convs[n];e=a[n][t](i),this.convs[t]=e}return e},["rgb","hsl","hsv","cmyk","keyword"].forEach(function(t){u.prototype[t]=function(e){return this.routeSpace(t,arguments)}}),e.exports=a},{3:3}],5:[function(t,e,n){"use strict";e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},{}],6:[function(t,e,n){!function(t,i){"object"==typeof n&&void 0!==e?e.exports=i():t.moment=i()}(this,function(){"use strict";function n(){return xe.apply(null,arguments)}function i(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function a(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function r(t){var e;for(e in t)return!1;return!0}function o(t){return void 0===t}function s(t){return"number"==typeof t||"[object Number]"===Object.prototype.toString.call(t)}function l(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function u(t,e){var n,i=[];for(n=0;n<t.length;++n)i.push(e(t[n],n));return i}function d(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function c(t,e){for(var n in e)d(e,n)&&(t[n]=e[n]);return d(e,"toString")&&(t.toString=e.toString),d(e,"valueOf")&&(t.valueOf=e.valueOf),t}function h(t,e,n,i){return Yt(t,e,n,i,!0).utc()}function f(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}}function g(t){return null==t._pf&&(t._pf=f()),t._pf}function m(t){if(null==t._isValid){var e=g(t),n=ke.call(e.parsedDateParts,function(t){return null!=t}),i=!isNaN(t._d.getTime())&&e.overflow<0&&!e.empty&&!e.invalidMonth&&!e.invalidWeekday&&!e.nullInput&&!e.invalidFormat&&!e.userInvalidated&&(!e.meridiem||e.meridiem&&n);if(t._strict&&(i=i&&0===e.charsLeftOver&&0===e.unusedTokens.length&&void 0===e.bigHour),null!=Object.isFrozen&&Object.isFrozen(t))return i;t._isValid=i}return t._isValid}function p(t){var e=h(NaN);return null!=t?c(g(e),t):g(e).userInvalidated=!0,e}function v(t,e){var n,i,a;if(o(e._isAMomentObject)||(t._isAMomentObject=e._isAMomentObject),o(e._i)||(t._i=e._i),o(e._f)||(t._f=e._f),o(e._l)||(t._l=e._l),o(e._strict)||(t._strict=e._strict),o(e._tzm)||(t._tzm=e._tzm),o(e._isUTC)||(t._isUTC=e._isUTC),o(e._offset)||(t._offset=e._offset),o(e._pf)||(t._pf=g(e)),o(e._locale)||(t._locale=e._locale),we.length>0)for(n=0;n<we.length;n++)o(a=e[i=we[n]])||(t[i]=a);return t}function y(t){v(this,t),this._d=new Date(null!=t._d?t._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===Me&&(Me=!0,n.updateOffset(this),Me=!1)}function b(t){return t instanceof y||null!=t&&null!=t._isAMomentObject}function x(t){return t<0?Math.ceil(t)||0:Math.floor(t)}function _(t){var e=+t,n=0;return 0!==e&&isFinite(e)&&(n=x(e)),n}function k(t,e,n){var i,a=Math.min(t.length,e.length),r=Math.abs(t.length-e.length),o=0;for(i=0;i<a;i++)(n&&t[i]!==e[i]||!n&&_(t[i])!==_(e[i]))&&o++;return o+r}function w(t){!1===n.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+t)}function M(t,e){var i=!0;return c(function(){if(null!=n.deprecationHandler&&n.deprecationHandler(null,t),i){for(var a,r=[],o=0;o<arguments.length;o++){if(a="","object"==typeof arguments[o]){a+="\n["+o+"] ";for(var s in arguments[0])a+=s+": "+arguments[0][s]+", ";a=a.slice(0,-2)}else a=arguments[o];r.push(a)}w(t+"\nArguments: "+Array.prototype.slice.call(r).join("")+"\n"+(new Error).stack),i=!1}return e.apply(this,arguments)},e)}function S(t,e){null!=n.deprecationHandler&&n.deprecationHandler(t,e),Se[t]||(w(e),Se[t]=!0)}function D(t){return t instanceof Function||"[object Function]"===Object.prototype.toString.call(t)}function C(t,e){var n,i=c({},t);for(n in e)d(e,n)&&(a(t[n])&&a(e[n])?(i[n]={},c(i[n],t[n]),c(i[n],e[n])):null!=e[n]?i[n]=e[n]:delete i[n]);for(n in t)d(t,n)&&!d(e,n)&&a(t[n])&&(i[n]=c({},i[n]));return i}function P(t){null!=t&&this.set(t)}function T(t,e){var n=t.toLowerCase();Fe[n]=Fe[n+"s"]=Fe[e]=t}function I(t){return"string"==typeof t?Fe[t]||Fe[t.toLowerCase()]:void 0}function A(t){var e,n,i={};for(n in t)d(t,n)&&(e=I(n))&&(i[e]=t[n]);return i}function O(t,e){Re[t]=e}function F(t){var e=[];for(var n in t)e.push({unit:n,priority:Re[n]});return e.sort(function(t,e){return t.priority-e.priority}),e}function R(t,e){return function(i){return null!=i?(W(this,t,i),n.updateOffset(this,e),this):L(this,t)}}function L(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function W(t,e,n){t.isValid()&&t._d["set"+(t._isUTC?"UTC":"")+e](n)}function Y(t,e,n){var i=""+Math.abs(t),a=e-i.length;return(t>=0?n?"+":"":"-")+Math.pow(10,Math.max(0,a)).toString().substr(1)+i}function N(t,e,n,i){var a=i;"string"==typeof i&&(a=function(){return this[i]()}),t&&(Ne[t]=a),e&&(Ne[e[0]]=function(){return Y(a.apply(this,arguments),e[1],e[2])}),n&&(Ne[n]=function(){return this.localeData().ordinal(a.apply(this,arguments),t)})}function z(t){return t.match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"")}function B(t){var e,n,i=t.match(Le);for(e=0,n=i.length;e<n;e++)Ne[i[e]]?i[e]=Ne[i[e]]:i[e]=z(i[e]);return function(e){var a,r="";for(a=0;a<n;a++)r+=D(i[a])?i[a].call(e,t):i[a];return r}}function V(t,e){return t.isValid()?(e=H(e,t.localeData()),Ye[e]=Ye[e]||B(e),Ye[e](t)):t.localeData().invalidDate()}function H(t,e){var n=5;for(We.lastIndex=0;n>=0&&We.test(t);)t=t.replace(We,function(t){return e.longDateFormat(t)||t}),We.lastIndex=0,n-=1;return t}function E(t,e,n){nn[t]=D(e)?e:function(t,i){return t&&n?n:e}}function j(t,e){return d(nn,t)?nn[t](e._strict,e._locale):new RegExp(U(t))}function U(t){return q(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(t,e,n,i,a){return e||n||i||a}))}function q(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function G(t,e){var n,i=e;for("string"==typeof t&&(t=[t]),s(e)&&(i=function(t,n){n[e]=_(t)}),n=0;n<t.length;n++)an[t[n]]=i}function Z(t,e){G(t,function(t,n,i,a){i._w=i._w||{},e(t,i._w,i,a)})}function X(t,e,n){null!=e&&d(an,t)&&an[t](e,n._a,n,t)}function J(t,e){return new Date(Date.UTC(t,e+1,0)).getUTCDate()}function K(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],i=0;i<12;++i)r=h([2e3,i]),this._shortMonthsParse[i]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[i]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===e?-1!==(a=gn.call(this._shortMonthsParse,o))?a:null:-1!==(a=gn.call(this._longMonthsParse,o))?a:null:"MMM"===e?-1!==(a=gn.call(this._shortMonthsParse,o))?a:-1!==(a=gn.call(this._longMonthsParse,o))?a:null:-1!==(a=gn.call(this._longMonthsParse,o))?a:-1!==(a=gn.call(this._shortMonthsParse,o))?a:null}function Q(t,e){var n;if(!t.isValid())return t;if("string"==typeof e)if(/^\d+$/.test(e))e=_(e);else if(e=t.localeData().monthsParse(e),!s(e))return t;return n=Math.min(t.date(),J(t.year(),e)),t._d["set"+(t._isUTC?"UTC":"")+"Month"](e,n),t}function $(t){return null!=t?(Q(this,t),n.updateOffset(this,!0),this):L(this,"Month")}function tt(){function t(t,e){return e.length-t.length}var e,n,i=[],a=[],r=[];for(e=0;e<12;e++)n=h([2e3,e]),i.push(this.monthsShort(n,"")),a.push(this.months(n,"")),r.push(this.months(n,"")),r.push(this.monthsShort(n,""));for(i.sort(t),a.sort(t),r.sort(t),e=0;e<12;e++)i[e]=q(i[e]),a[e]=q(a[e]);for(e=0;e<24;e++)r[e]=q(r[e]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+i.join("|")+")","i")}function et(t){return nt(t)?366:365}function nt(t){return t%4==0&&t%100!=0||t%400==0}function it(t,e,n,i,a,r,o){var s=new Date(t,e,n,i,a,r,o);return t<100&&t>=0&&isFinite(s.getFullYear())&&s.setFullYear(t),s}function at(t){var e=new Date(Date.UTC.apply(null,arguments));return t<100&&t>=0&&isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t),e}function rt(t,e,n){var i=7+e-n;return-((7+at(t,0,i).getUTCDay()-e)%7)+i-1}function ot(t,e,n,i,a){var r,o,s=1+7*(e-1)+(7+n-i)%7+rt(t,i,a);return s<=0?o=et(r=t-1)+s:s>et(t)?(r=t+1,o=s-et(t)):(r=t,o=s),{year:r,dayOfYear:o}}function st(t,e,n){var i,a,r=rt(t.year(),e,n),o=Math.floor((t.dayOfYear()-r-1)/7)+1;return o<1?i=o+lt(a=t.year()-1,e,n):o>lt(t.year(),e,n)?(i=o-lt(t.year(),e,n),a=t.year()+1):(a=t.year(),i=o),{week:i,year:a}}function lt(t,e,n){var i=rt(t,e,n),a=rt(t+1,e,n);return(et(t)-i+a)/7}function ut(t,e){return"string"!=typeof t?t:isNaN(t)?"number"==typeof(t=e.weekdaysParse(t))?t:null:parseInt(t,10)}function dt(t,e){return"string"==typeof t?e.weekdaysParse(t)%7||7:isNaN(t)?null:t}function ct(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;i<7;++i)r=h([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===e?-1!==(a=gn.call(this._weekdaysParse,o))?a:null:"ddd"===e?-1!==(a=gn.call(this._shortWeekdaysParse,o))?a:null:-1!==(a=gn.call(this._minWeekdaysParse,o))?a:null:"dddd"===e?-1!==(a=gn.call(this._weekdaysParse,o))?a:-1!==(a=gn.call(this._shortWeekdaysParse,o))?a:-1!==(a=gn.call(this._minWeekdaysParse,o))?a:null:"ddd"===e?-1!==(a=gn.call(this._shortWeekdaysParse,o))?a:-1!==(a=gn.call(this._weekdaysParse,o))?a:-1!==(a=gn.call(this._minWeekdaysParse,o))?a:null:-1!==(a=gn.call(this._minWeekdaysParse,o))?a:-1!==(a=gn.call(this._weekdaysParse,o))?a:-1!==(a=gn.call(this._shortWeekdaysParse,o))?a:null}function ht(){function t(t,e){return e.length-t.length}var e,n,i,a,r,o=[],s=[],l=[],u=[];for(e=0;e<7;e++)n=h([2e3,1]).day(e),i=this.weekdaysMin(n,""),a=this.weekdaysShort(n,""),r=this.weekdays(n,""),o.push(i),s.push(a),l.push(r),u.push(i),u.push(a),u.push(r);for(o.sort(t),s.sort(t),l.sort(t),u.sort(t),e=0;e<7;e++)s[e]=q(s[e]),l[e]=q(l[e]),u[e]=q(u[e]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function ft(){return this.hours()%12||12}function gt(t,e){N(t,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)})}function mt(t,e){return e._meridiemParse}function pt(t){return t?t.toLowerCase().replace("_","-"):t}function vt(t){for(var e,n,i,a,r=0;r<t.length;){for(e=(a=pt(t[r]).split("-")).length,n=(n=pt(t[r+1]))?n.split("-"):null;e>0;){if(i=yt(a.slice(0,e).join("-")))return i;if(n&&n.length>=e&&k(a,n,!0)>=e-1)break;e--}r++}return null}function yt(n){var i=null;if(!On[n]&&void 0!==e&&e&&e.exports)try{i=Pn._abbr,t("./locale/"+n),bt(i)}catch(t){}return On[n]}function bt(t,e){var n;return t&&(n=o(e)?_t(t):xt(t,e))&&(Pn=n),Pn._abbr}function xt(t,e){if(null!==e){var n=An;if(e.abbr=t,null!=On[t])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),n=On[t]._config;else if(null!=e.parentLocale){if(null==On[e.parentLocale])return Fn[e.parentLocale]||(Fn[e.parentLocale]=[]),Fn[e.parentLocale].push({name:t,config:e}),null;n=On[e.parentLocale]._config}return On[t]=new P(C(n,e)),Fn[t]&&Fn[t].forEach(function(t){xt(t.name,t.config)}),bt(t),On[t]}return delete On[t],null}function _t(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return Pn;if(!i(t)){if(e=yt(t))return e;t=[t]}return vt(t)}function kt(t){var e,n=t._a;return n&&-2===g(t).overflow&&(e=n[on]<0||n[on]>11?on:n[sn]<1||n[sn]>J(n[rn],n[on])?sn:n[ln]<0||n[ln]>24||24===n[ln]&&(0!==n[un]||0!==n[dn]||0!==n[cn])?ln:n[un]<0||n[un]>59?un:n[dn]<0||n[dn]>59?dn:n[cn]<0||n[cn]>999?cn:-1,g(t)._overflowDayOfYear&&(e<rn||e>sn)&&(e=sn),g(t)._overflowWeeks&&-1===e&&(e=hn),g(t)._overflowWeekday&&-1===e&&(e=fn),g(t).overflow=e),t}function wt(t){var e,n,i,a,r,o,s=t._i,l=Rn.exec(s)||Ln.exec(s);if(l){for(g(t).iso=!0,e=0,n=Yn.length;e<n;e++)if(Yn[e][1].exec(l[1])){a=Yn[e][0],i=!1!==Yn[e][2];break}if(null==a)return void(t._isValid=!1);if(l[3]){for(e=0,n=Nn.length;e<n;e++)if(Nn[e][1].exec(l[3])){r=(l[2]||" ")+Nn[e][0];break}if(null==r)return void(t._isValid=!1)}if(!i&&null!=r)return void(t._isValid=!1);if(l[4]){if(!Wn.exec(l[4]))return void(t._isValid=!1);o="Z"}t._f=a+(r||"")+(o||""),It(t)}else t._isValid=!1}function Mt(t){var e,n,i,a,r,o,s,l,u={" GMT":" +0000"," EDT":" -0400"," EST":" -0500"," CDT":" -0500"," CST":" -0600"," MDT":" -0600"," MST":" -0700"," PDT":" -0700"," PST":" -0800"};if(e=t._i.replace(/\([^\)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s|\s$/g,""),n=Bn.exec(e)){if(i=n[1]?"ddd"+(5===n[1].length?", ":" "):"",a="D MMM "+(n[2].length>10?"YYYY ":"YY "),r="HH:mm"+(n[4]?":ss":""),n[1]){var d=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][new Date(n[2]).getDay()];if(n[1].substr(0,3)!==d)return g(t).weekdayMismatch=!0,void(t._isValid=!1)}switch(n[5].length){case 2:s=0===l?" +0000":((l="YXWVUTSRQPONZABCDEFGHIKLM".indexOf(n[5][1].toUpperCase())-12)<0?" -":" +")+(""+l).replace(/^-?/,"0").match(/..$/)[0]+"00";break;case 4:s=u[n[5]];break;default:s=u[" GMT"]}n[5]=s,t._i=n.splice(1).join(""),o=" ZZ",t._f=i+a+r+o,It(t),g(t).rfc2822=!0}else t._isValid=!1}function St(t){var e=zn.exec(t._i);null===e?(wt(t),!1===t._isValid&&(delete t._isValid,Mt(t),!1===t._isValid&&(delete t._isValid,n.createFromInputFallback(t)))):t._d=new Date(+e[1])}function Dt(t,e,n){return null!=t?t:null!=e?e:n}function Ct(t){var e=new Date(n.now());return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}function Pt(t){var e,n,i,a,r=[];if(!t._d){for(i=Ct(t),t._w&&null==t._a[sn]&&null==t._a[on]&&Tt(t),null!=t._dayOfYear&&(a=Dt(t._a[rn],i[rn]),(t._dayOfYear>et(a)||0===t._dayOfYear)&&(g(t)._overflowDayOfYear=!0),n=at(a,0,t._dayOfYear),t._a[on]=n.getUTCMonth(),t._a[sn]=n.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=r[e]=i[e];for(;e<7;e++)t._a[e]=r[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[ln]&&0===t._a[un]&&0===t._a[dn]&&0===t._a[cn]&&(t._nextDay=!0,t._a[ln]=0),t._d=(t._useUTC?at:it).apply(null,r),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[ln]=24)}}function Tt(t){var e,n,i,a,r,o,s,l;if(null!=(e=t._w).GG||null!=e.W||null!=e.E)r=1,o=4,n=Dt(e.GG,t._a[rn],st(Nt(),1,4).year),i=Dt(e.W,1),((a=Dt(e.E,1))<1||a>7)&&(l=!0);else{r=t._locale._week.dow,o=t._locale._week.doy;var u=st(Nt(),r,o);n=Dt(e.gg,t._a[rn],u.year),i=Dt(e.w,u.week),null!=e.d?((a=e.d)<0||a>6)&&(l=!0):null!=e.e?(a=e.e+r,(e.e<0||e.e>6)&&(l=!0)):a=r}i<1||i>lt(n,r,o)?g(t)._overflowWeeks=!0:null!=l?g(t)._overflowWeekday=!0:(s=ot(n,i,a,r,o),t._a[rn]=s.year,t._dayOfYear=s.dayOfYear)}function It(t){if(t._f!==n.ISO_8601)if(t._f!==n.RFC_2822){t._a=[],g(t).empty=!0;var e,i,a,r,o,s=""+t._i,l=s.length,u=0;for(a=H(t._f,t._locale).match(Le)||[],e=0;e<a.length;e++)r=a[e],(i=(s.match(j(r,t))||[])[0])&&((o=s.substr(0,s.indexOf(i))).length>0&&g(t).unusedInput.push(o),s=s.slice(s.indexOf(i)+i.length),u+=i.length),Ne[r]?(i?g(t).empty=!1:g(t).unusedTokens.push(r),X(r,i,t)):t._strict&&!i&&g(t).unusedTokens.push(r);g(t).charsLeftOver=l-u,s.length>0&&g(t).unusedInput.push(s),t._a[ln]<=12&&!0===g(t).bigHour&&t._a[ln]>0&&(g(t).bigHour=void 0),g(t).parsedDateParts=t._a.slice(0),g(t).meridiem=t._meridiem,t._a[ln]=At(t._locale,t._a[ln],t._meridiem),Pt(t),kt(t)}else Mt(t);else wt(t)}function At(t,e,n){var i;return null==n?e:null!=t.meridiemHour?t.meridiemHour(e,n):null!=t.isPM?((i=t.isPM(n))&&e<12&&(e+=12),i||12!==e||(e=0),e):e}function Ot(t){var e,n,i,a,r;if(0===t._f.length)return g(t).invalidFormat=!0,void(t._d=new Date(NaN));for(a=0;a<t._f.length;a++)r=0,e=v({},t),null!=t._useUTC&&(e._useUTC=t._useUTC),e._f=t._f[a],It(e),m(e)&&(r+=g(e).charsLeftOver,r+=10*g(e).unusedTokens.length,g(e).score=r,(null==i||r<i)&&(i=r,n=e));c(t,n||e)}function Ft(t){if(!t._d){var e=A(t._i);t._a=u([e.year,e.month,e.day||e.date,e.hour,e.minute,e.second,e.millisecond],function(t){return t&&parseInt(t,10)}),Pt(t)}}function Rt(t){var e=new y(kt(Lt(t)));return e._nextDay&&(e.add(1,"d"),e._nextDay=void 0),e}function Lt(t){var e=t._i,n=t._f;return t._locale=t._locale||_t(t._l),null===e||void 0===n&&""===e?p({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),b(e)?new y(kt(e)):(l(e)?t._d=e:i(n)?Ot(t):n?It(t):Wt(t),m(t)||(t._d=null),t))}function Wt(t){var e=t._i;o(e)?t._d=new Date(n.now()):l(e)?t._d=new Date(e.valueOf()):"string"==typeof e?St(t):i(e)?(t._a=u(e.slice(0),function(t){return parseInt(t,10)}),Pt(t)):a(e)?Ft(t):s(e)?t._d=new Date(e):n.createFromInputFallback(t)}function Yt(t,e,n,o,s){var l={};return!0!==n&&!1!==n||(o=n,n=void 0),(a(t)&&r(t)||i(t)&&0===t.length)&&(t=void 0),l._isAMomentObject=!0,l._useUTC=l._isUTC=s,l._l=n,l._i=t,l._f=e,l._strict=o,Rt(l)}function Nt(t,e,n,i){return Yt(t,e,n,i,!1)}function zt(t,e){var n,a;if(1===e.length&&i(e[0])&&(e=e[0]),!e.length)return Nt();for(n=e[0],a=1;a<e.length;++a)e[a].isValid()&&!e[a][t](n)||(n=e[a]);return n}function Bt(t){for(var e in t)if(-1===En.indexOf(e)||null!=t[e]&&isNaN(t[e]))return!1;for(var n=!1,i=0;i<En.length;++i)if(t[En[i]]){if(n)return!1;parseFloat(t[En[i]])!==_(t[En[i]])&&(n=!0)}return!0}function Vt(t){var e=A(t),n=e.year||0,i=e.quarter||0,a=e.month||0,r=e.week||0,o=e.day||0,s=e.hour||0,l=e.minute||0,u=e.second||0,d=e.millisecond||0;this._isValid=Bt(e),this._milliseconds=+d+1e3*u+6e4*l+1e3*s*60*60,this._days=+o+7*r,this._months=+a+3*i+12*n,this._data={},this._locale=_t(),this._bubble()}function Ht(t){return t instanceof Vt}function Et(t){return t<0?-1*Math.round(-1*t):Math.round(t)}function jt(t,e){N(t,0,0,function(){var t=this.utcOffset(),n="+";return t<0&&(t=-t,n="-"),n+Y(~~(t/60),2)+e+Y(~~t%60,2)})}function Ut(t,e){var n=(e||"").match(t);if(null===n)return null;var i=((n[n.length-1]||[])+"").match(jn)||["-",0,0],a=60*i[1]+_(i[2]);return 0===a?0:"+"===i[0]?a:-a}function qt(t,e){var i,a;return e._isUTC?(i=e.clone(),a=(b(t)||l(t)?t.valueOf():Nt(t).valueOf())-i.valueOf(),i._d.setTime(i._d.valueOf()+a),n.updateOffset(i,!1),i):Nt(t).local()}function Gt(t){return 15*-Math.round(t._d.getTimezoneOffset()/15)}function Zt(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function Xt(t,e){var n,i,a,r=t,o=null;return Ht(t)?r={ms:t._milliseconds,d:t._days,M:t._months}:s(t)?(r={},e?r[e]=t:r.milliseconds=t):(o=Un.exec(t))?(n="-"===o[1]?-1:1,r={y:0,d:_(o[sn])*n,h:_(o[ln])*n,m:_(o[un])*n,s:_(o[dn])*n,ms:_(Et(1e3*o[cn]))*n}):(o=qn.exec(t))?(n="-"===o[1]?-1:1,r={y:Jt(o[2],n),M:Jt(o[3],n),w:Jt(o[4],n),d:Jt(o[5],n),h:Jt(o[6],n),m:Jt(o[7],n),s:Jt(o[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(a=Qt(Nt(r.from),Nt(r.to)),(r={}).ms=a.milliseconds,r.M=a.months),i=new Vt(r),Ht(t)&&d(t,"_locale")&&(i._locale=t._locale),i}function Jt(t,e){var n=t&&parseFloat(t.replace(",","."));return(isNaN(n)?0:n)*e}function Kt(t,e){var n={milliseconds:0,months:0};return n.months=e.month()-t.month()+12*(e.year()-t.year()),t.clone().add(n.months,"M").isAfter(e)&&--n.months,n.milliseconds=+e-+t.clone().add(n.months,"M"),n}function Qt(t,e){var n;return t.isValid()&&e.isValid()?(e=qt(e,t),t.isBefore(e)?n=Kt(t,e):((n=Kt(e,t)).milliseconds=-n.milliseconds,n.months=-n.months),n):{milliseconds:0,months:0}}function $t(t,e){return function(n,i){var a,r;return null===i||isNaN(+i)||(S(e,"moment()."+e+"(period, number) is deprecated. Please use moment()."+e+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),r=n,n=i,i=r),n="string"==typeof n?+n:n,a=Xt(n,i),te(this,a,t),this}}function te(t,e,i,a){var r=e._milliseconds,o=Et(e._days),s=Et(e._months);t.isValid()&&(a=null==a||a,r&&t._d.setTime(t._d.valueOf()+r*i),o&&W(t,"Date",L(t,"Date")+o*i),s&&Q(t,L(t,"Month")+s*i),a&&n.updateOffset(t,o||s))}function ee(t,e){var n,i=12*(e.year()-t.year())+(e.month()-t.month()),a=t.clone().add(i,"months");return n=e-a<0?(e-a)/(a-t.clone().add(i-1,"months")):(e-a)/(t.clone().add(i+1,"months")-a),-(i+n)||0}function ne(t){var e;return void 0===t?this._locale._abbr:(null!=(e=_t(t))&&(this._locale=e),this)}function ie(){return this._locale}function ae(t,e){N(0,[t,t.length],0,e)}function re(t,e,n,i,a){var r;return null==t?st(this,i,a).year:(r=lt(t,i,a),e>r&&(e=r),oe.call(this,t,e,n,i,a))}function oe(t,e,n,i,a){var r=ot(t,e,n,i,a),o=at(r.year,0,r.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}function se(t){return t}function le(t,e,n,i){var a=_t(),r=h().set(i,e);return a[n](r,t)}function ue(t,e,n){if(s(t)&&(e=t,t=void 0),t=t||"",null!=e)return le(t,e,n,"month");var i,a=[];for(i=0;i<12;i++)a[i]=le(t,i,n,"month");return a}function de(t,e,n,i){"boolean"==typeof t?(s(e)&&(n=e,e=void 0),e=e||""):(n=e=t,t=!1,s(e)&&(n=e,e=void 0),e=e||"");var a=_t(),r=t?a._week.dow:0;if(null!=n)return le(e,(n+r)%7,i,"day");var o,l=[];for(o=0;o<7;o++)l[o]=le(e,(o+r)%7,i,"day");return l}function ce(t,e,n,i){var a=Xt(e,n);return t._milliseconds+=i*a._milliseconds,t._days+=i*a._days,t._months+=i*a._months,t._bubble()}function he(t){return t<0?Math.floor(t):Math.ceil(t)}function fe(t){return 4800*t/146097}function ge(t){return 146097*t/4800}function me(t){return function(){return this.as(t)}}function pe(t){return function(){return this.isValid()?this._data[t]:NaN}}function ve(t,e,n,i,a){return a.relativeTime(e||1,!!n,t,i)}function ye(t,e,n){var i=Xt(t).abs(),a=bi(i.as("s")),r=bi(i.as("m")),o=bi(i.as("h")),s=bi(i.as("d")),l=bi(i.as("M")),u=bi(i.as("y")),d=a<=xi.ss&&["s",a]||a<xi.s&&["ss",a]||r<=1&&["m"]||r<xi.m&&["mm",r]||o<=1&&["h"]||o<xi.h&&["hh",o]||s<=1&&["d"]||s<xi.d&&["dd",s]||l<=1&&["M"]||l<xi.M&&["MM",l]||u<=1&&["y"]||["yy",u];return d[2]=e,d[3]=+t>0,d[4]=n,ve.apply(null,d)}function be(){if(!this.isValid())return this.localeData().invalidDate();var t,e,n,i=_i(this._milliseconds)/1e3,a=_i(this._days),r=_i(this._months);e=x((t=x(i/60))/60),i%=60,t%=60;var o=n=x(r/12),s=r%=12,l=a,u=e,d=t,c=i,h=this.asSeconds();return h?(h<0?"-":"")+"P"+(o?o+"Y":"")+(s?s+"M":"")+(l?l+"D":"")+(u||d||c?"T":"")+(u?u+"H":"")+(d?d+"M":"")+(c?c+"S":""):"P0D"}var xe,_e,ke=_e=Array.prototype.some?Array.prototype.some:function(t){for(var e=Object(this),n=e.length>>>0,i=0;i<n;i++)if(i in e&&t.call(this,e[i],i,e))return!0;return!1},we=n.momentProperties=[],Me=!1,Se={};n.suppressDeprecationWarnings=!1,n.deprecationHandler=null;var De,Ce,Pe=De=Object.keys?Object.keys:function(t){var e,n=[];for(e in t)d(t,e)&&n.push(e);return n},Te={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Ie={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Ae=/\d{1,2}/,Oe={future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Fe={},Re={},Le=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,We=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Ye={},Ne={},ze=/\d/,Be=/\d\d/,Ve=/\d{3}/,He=/\d{4}/,Ee=/[+-]?\d{6}/,je=/\d\d?/,Ue=/\d\d\d\d?/,qe=/\d\d\d\d\d\d?/,Ge=/\d{1,3}/,Ze=/\d{1,4}/,Xe=/[+-]?\d{1,6}/,Je=/\d+/,Ke=/[+-]?\d+/,Qe=/Z|[+-]\d\d:?\d\d/gi,$e=/Z|[+-]\d\d(?::?\d\d)?/gi,tn=/[+-]?\d+(\.\d{1,3})?/,en=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,nn={},an={},rn=0,on=1,sn=2,ln=3,un=4,dn=5,cn=6,hn=7,fn=8,gn=Ce=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e<this.length;++e)if(this[e]===t)return e;return-1};N("M",["MM",2],"Mo",function(){return this.month()+1}),N("MMM",0,0,function(t){return this.localeData().monthsShort(this,t)}),N("MMMM",0,0,function(t){return this.localeData().months(this,t)}),T("month","M"),O("month",8),E("M",je),E("MM",je,Be),E("MMM",function(t,e){return e.monthsShortRegex(t)}),E("MMMM",function(t,e){return e.monthsRegex(t)}),G(["M","MM"],function(t,e){e[on]=_(t)-1}),G(["MMM","MMMM"],function(t,e,n,i){var a=n._locale.monthsParse(t,i,n._strict);null!=a?e[on]=a:g(n).invalidMonth=t});var mn=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,pn="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),vn="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),yn=en,bn=en;N("Y",0,0,function(){var t=this.year();return t<=9999?""+t:"+"+t}),N(0,["YY",2],0,function(){return this.year()%100}),N(0,["YYYY",4],0,"year"),N(0,["YYYYY",5],0,"year"),N(0,["YYYYYY",6,!0],0,"year"),T("year","y"),O("year",1),E("Y",Ke),E("YY",je,Be),E("YYYY",Ze,He),E("YYYYY",Xe,Ee),E("YYYYYY",Xe,Ee),G(["YYYYY","YYYYYY"],rn),G("YYYY",function(t,e){e[rn]=2===t.length?n.parseTwoDigitYear(t):_(t)}),G("YY",function(t,e){e[rn]=n.parseTwoDigitYear(t)}),G("Y",function(t,e){e[rn]=parseInt(t,10)}),n.parseTwoDigitYear=function(t){return _(t)+(_(t)>68?1900:2e3)};var xn=R("FullYear",!0);N("w",["ww",2],"wo","week"),N("W",["WW",2],"Wo","isoWeek"),T("week","w"),T("isoWeek","W"),O("week",5),O("isoWeek",5),E("w",je),E("ww",je,Be),E("W",je),E("WW",je,Be),Z(["w","ww","W","WW"],function(t,e,n,i){e[i.substr(0,1)]=_(t)});var _n={dow:0,doy:6};N("d",0,"do","day"),N("dd",0,0,function(t){return this.localeData().weekdaysMin(this,t)}),N("ddd",0,0,function(t){return this.localeData().weekdaysShort(this,t)}),N("dddd",0,0,function(t){return this.localeData().weekdays(this,t)}),N("e",0,0,"weekday"),N("E",0,0,"isoWeekday"),T("day","d"),T("weekday","e"),T("isoWeekday","E"),O("day",11),O("weekday",11),O("isoWeekday",11),E("d",je),E("e",je),E("E",je),E("dd",function(t,e){return e.weekdaysMinRegex(t)}),E("ddd",function(t,e){return e.weekdaysShortRegex(t)}),E("dddd",function(t,e){return e.weekdaysRegex(t)}),Z(["dd","ddd","dddd"],function(t,e,n,i){var a=n._locale.weekdaysParse(t,i,n._strict);null!=a?e.d=a:g(n).invalidWeekday=t}),Z(["d","e","E"],function(t,e,n,i){e[i]=_(t)});var kn="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),wn="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Mn="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Sn=en,Dn=en,Cn=en;N("H",["HH",2],0,"hour"),N("h",["hh",2],0,ft),N("k",["kk",2],0,function(){return this.hours()||24}),N("hmm",0,0,function(){return""+ft.apply(this)+Y(this.minutes(),2)}),N("hmmss",0,0,function(){return""+ft.apply(this)+Y(this.minutes(),2)+Y(this.seconds(),2)}),N("Hmm",0,0,function(){return""+this.hours()+Y(this.minutes(),2)}),N("Hmmss",0,0,function(){return""+this.hours()+Y(this.minutes(),2)+Y(this.seconds(),2)}),gt("a",!0),gt("A",!1),T("hour","h"),O("hour",13),E("a",mt),E("A",mt),E("H",je),E("h",je),E("k",je),E("HH",je,Be),E("hh",je,Be),E("kk",je,Be),E("hmm",Ue),E("hmmss",qe),E("Hmm",Ue),E("Hmmss",qe),G(["H","HH"],ln),G(["k","kk"],function(t,e,n){var i=_(t);e[ln]=24===i?0:i}),G(["a","A"],function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t}),G(["h","hh"],function(t,e,n){e[ln]=_(t),g(n).bigHour=!0}),G("hmm",function(t,e,n){var i=t.length-2;e[ln]=_(t.substr(0,i)),e[un]=_(t.substr(i)),g(n).bigHour=!0}),G("hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[ln]=_(t.substr(0,i)),e[un]=_(t.substr(i,2)),e[dn]=_(t.substr(a)),g(n).bigHour=!0}),G("Hmm",function(t,e,n){var i=t.length-2;e[ln]=_(t.substr(0,i)),e[un]=_(t.substr(i))}),G("Hmmss",function(t,e,n){var i=t.length-4,a=t.length-2;e[ln]=_(t.substr(0,i)),e[un]=_(t.substr(i,2)),e[dn]=_(t.substr(a))});var Pn,Tn=/[ap]\.?m?\.?/i,In=R("Hours",!0),An={calendar:Te,longDateFormat:Ie,invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:Ae,relativeTime:Oe,months:pn,monthsShort:vn,week:_n,weekdays:kn,weekdaysMin:Mn,weekdaysShort:wn,meridiemParse:Tn},On={},Fn={},Rn=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Ln=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Wn=/Z|[+-]\d\d(?::?\d\d)?/,Yn=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Nn=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],zn=/^\/?Date\((\-?\d+)/i,Bn=/^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d?\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(?:\d\d)?\d\d\s)(\d\d:\d\d)(\:\d\d)?(\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\d{4}))$/;n.createFromInputFallback=M("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(t){t._d=new Date(t._i+(t._useUTC?" UTC":""))}),n.ISO_8601=function(){},n.RFC_2822=function(){};var Vn=M("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=Nt.apply(null,arguments);return this.isValid()&&t.isValid()?t<this?this:t:p()}),Hn=M("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var t=Nt.apply(null,arguments);return this.isValid()&&t.isValid()?t>this?this:t:p()}),En=["year","quarter","month","week","day","hour","minute","second","millisecond"];jt("Z",":"),jt("ZZ",""),E("Z",$e),E("ZZ",$e),G(["Z","ZZ"],function(t,e,n){n._useUTC=!0,n._tzm=Ut($e,t)});var jn=/([\+\-]|\d\d)/gi;n.updateOffset=function(){};var Un=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,qn=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;Xt.fn=Vt.prototype,Xt.invalid=function(){return Xt(NaN)};var Gn=$t(1,"add"),Zn=$t(-1,"subtract");n.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",n.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Xn=M("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(t){return void 0===t?this.localeData():this.locale(t)});N(0,["gg",2],0,function(){return this.weekYear()%100}),N(0,["GG",2],0,function(){return this.isoWeekYear()%100}),ae("gggg","weekYear"),ae("ggggg","weekYear"),ae("GGGG","isoWeekYear"),ae("GGGGG","isoWeekYear"),T("weekYear","gg"),T("isoWeekYear","GG"),O("weekYear",1),O("isoWeekYear",1),E("G",Ke),E("g",Ke),E("GG",je,Be),E("gg",je,Be),E("GGGG",Ze,He),E("gggg",Ze,He),E("GGGGG",Xe,Ee),E("ggggg",Xe,Ee),Z(["gggg","ggggg","GGGG","GGGGG"],function(t,e,n,i){e[i.substr(0,2)]=_(t)}),Z(["gg","GG"],function(t,e,i,a){e[a]=n.parseTwoDigitYear(t)}),N("Q",0,"Qo","quarter"),T("quarter","Q"),O("quarter",7),E("Q",ze),G("Q",function(t,e){e[on]=3*(_(t)-1)}),N("D",["DD",2],"Do","date"),T("date","D"),O("date",9),E("D",je),E("DD",je,Be),E("Do",function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient}),G(["D","DD"],sn),G("Do",function(t,e){e[sn]=_(t.match(je)[0],10)});var Jn=R("Date",!0);N("DDD",["DDDD",3],"DDDo","dayOfYear"),T("dayOfYear","DDD"),O("dayOfYear",4),E("DDD",Ge),E("DDDD",Ve),G(["DDD","DDDD"],function(t,e,n){n._dayOfYear=_(t)}),N("m",["mm",2],0,"minute"),T("minute","m"),O("minute",14),E("m",je),E("mm",je,Be),G(["m","mm"],un);var Kn=R("Minutes",!1);N("s",["ss",2],0,"second"),T("second","s"),O("second",15),E("s",je),E("ss",je,Be),G(["s","ss"],dn);var Qn=R("Seconds",!1);N("S",0,0,function(){return~~(this.millisecond()/100)}),N(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),N(0,["SSS",3],0,"millisecond"),N(0,["SSSS",4],0,function(){return 10*this.millisecond()}),N(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),N(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),N(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),N(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),N(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),T("millisecond","ms"),O("millisecond",16),E("S",Ge,ze),E("SS",Ge,Be),E("SSS",Ge,Ve);var $n;for($n="SSSS";$n.length<=9;$n+="S")E($n,Je);for($n="S";$n.length<=9;$n+="S")G($n,function(t,e){e[cn]=_(1e3*("0."+t))});var ti=R("Milliseconds",!1);N("z",0,0,"zoneAbbr"),N("zz",0,0,"zoneName");var ei=y.prototype;ei.add=Gn,ei.calendar=function(t,e){var i=t||Nt(),a=qt(i,this).startOf("day"),r=n.calendarFormat(this,a)||"sameElse",o=e&&(D(e[r])?e[r].call(this,i):e[r]);return this.format(o||this.localeData().calendar(r,this,Nt(i)))},ei.clone=function(){return new y(this)},ei.diff=function(t,e,n){var i,a,r,o;return this.isValid()&&(i=qt(t,this)).isValid()?(a=6e4*(i.utcOffset()-this.utcOffset()),"year"===(e=I(e))||"month"===e||"quarter"===e?(o=ee(this,i),"quarter"===e?o/=3:"year"===e&&(o/=12)):(r=this-i,o="second"===e?r/1e3:"minute"===e?r/6e4:"hour"===e?r/36e5:"day"===e?(r-a)/864e5:"week"===e?(r-a)/6048e5:r),n?o:x(o)):NaN},ei.endOf=function(t){return void 0===(t=I(t))||"millisecond"===t?this:("date"===t&&(t="day"),this.startOf(t).add(1,"isoWeek"===t?"week":t).subtract(1,"ms"))},ei.format=function(t){t||(t=this.isUtc()?n.defaultFormatUtc:n.defaultFormat);var e=V(this,t);return this.localeData().postformat(e)},ei.from=function(t,e){return this.isValid()&&(b(t)&&t.isValid()||Nt(t).isValid())?Xt({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},ei.fromNow=function(t){return this.from(Nt(),t)},ei.to=function(t,e){return this.isValid()&&(b(t)&&t.isValid()||Nt(t).isValid())?Xt({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},ei.toNow=function(t){return this.to(Nt(),t)},ei.get=function(t){return t=I(t),D(this[t])?this[t]():this},ei.invalidAt=function(){return g(this).overflow},ei.isAfter=function(t,e){var n=b(t)?t:Nt(t);return!(!this.isValid()||!n.isValid())&&("millisecond"===(e=I(o(e)?"millisecond":e))?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(e).valueOf())},ei.isBefore=function(t,e){var n=b(t)?t:Nt(t);return!(!this.isValid()||!n.isValid())&&("millisecond"===(e=I(o(e)?"millisecond":e))?this.valueOf()<n.valueOf():this.clone().endOf(e).valueOf()<n.valueOf())},ei.isBetween=function(t,e,n,i){return("("===(i=i||"()")[0]?this.isAfter(t,n):!this.isBefore(t,n))&&(")"===i[1]?this.isBefore(e,n):!this.isAfter(e,n))},ei.isSame=function(t,e){var n,i=b(t)?t:Nt(t);return!(!this.isValid()||!i.isValid())&&("millisecond"===(e=I(e||"millisecond"))?this.valueOf()===i.valueOf():(n=i.valueOf(),this.clone().startOf(e).valueOf()<=n&&n<=this.clone().endOf(e).valueOf()))},ei.isSameOrAfter=function(t,e){return this.isSame(t,e)||this.isAfter(t,e)},ei.isSameOrBefore=function(t,e){return this.isSame(t,e)||this.isBefore(t,e)},ei.isValid=function(){return m(this)},ei.lang=Xn,ei.locale=ne,ei.localeData=ie,ei.max=Hn,ei.min=Vn,ei.parsingFlags=function(){return c({},g(this))},ei.set=function(t,e){if("object"==typeof t)for(var n=F(t=A(t)),i=0;i<n.length;i++)this[n[i].unit](t[n[i].unit]);else if(t=I(t),D(this[t]))return this[t](e);return this},ei.startOf=function(t){switch(t=I(t)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===t&&this.weekday(0),"isoWeek"===t&&this.isoWeekday(1),"quarter"===t&&this.month(3*Math.floor(this.month()/3)),this},ei.subtract=Zn,ei.toArray=function(){var t=this;return[t.year(),t.month(),t.date(),t.hour(),t.minute(),t.second(),t.millisecond()]},ei.toObject=function(){var t=this;return{years:t.year(),months:t.month(),date:t.date(),hours:t.hours(),minutes:t.minutes(),seconds:t.seconds(),milliseconds:t.milliseconds()}},ei.toDate=function(){return new Date(this.valueOf())},ei.toISOString=function(){if(!this.isValid())return null;var t=this.clone().utc();return t.year()<0||t.year()>9999?V(t,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):D(Date.prototype.toISOString)?this.toDate().toISOString():V(t,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},ei.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var n="["+t+'("]',i=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",a=e+'[")]';return this.format(n+i+"-MM-DD[T]HH:mm:ss.SSS"+a)},ei.toJSON=function(){return this.isValid()?this.toISOString():null},ei.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},ei.unix=function(){return Math.floor(this.valueOf()/1e3)},ei.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},ei.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},ei.year=xn,ei.isLeapYear=function(){return nt(this.year())},ei.weekYear=function(t){return re.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},ei.isoWeekYear=function(t){return re.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)},ei.quarter=ei.quarters=function(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)},ei.month=$,ei.daysInMonth=function(){return J(this.year(),this.month())},ei.week=ei.weeks=function(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")},ei.isoWeek=ei.isoWeeks=function(t){var e=st(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")},ei.weeksInYear=function(){var t=this.localeData()._week;return lt(this.year(),t.dow,t.doy)},ei.isoWeeksInYear=function(){return lt(this.year(),1,4)},ei.date=Jn,ei.day=ei.days=function(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=ut(t,this.localeData()),this.add(t-e,"d")):e},ei.weekday=function(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")},ei.isoWeekday=function(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=dt(t,this.localeData());return this.day(this.day()%7?e:e-7)}return this.day()||7},ei.dayOfYear=function(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")},ei.hour=ei.hours=In,ei.minute=ei.minutes=Kn,ei.second=ei.seconds=Qn,ei.millisecond=ei.milliseconds=ti,ei.utcOffset=function(t,e,i){var a,r=this._offset||0;if(!this.isValid())return null!=t?this:NaN;if(null!=t){if("string"==typeof t){if(null===(t=Ut($e,t)))return this}else Math.abs(t)<16&&!i&&(t*=60);return!this._isUTC&&e&&(a=Gt(this)),this._offset=t,this._isUTC=!0,null!=a&&this.add(a,"m"),r!==t&&(!e||this._changeInProgress?te(this,Xt(t-r,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,n.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?r:Gt(this)},ei.utc=function(t){return this.utcOffset(0,t)},ei.local=function(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Gt(this),"m")),this},ei.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var t=Ut(Qe,this._i);null!=t?this.utcOffset(t):this.utcOffset(0,!0)}return this},ei.hasAlignedHourOffset=function(t){return!!this.isValid()&&(t=t?Nt(t).utcOffset():0,(this.utcOffset()-t)%60==0)},ei.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},ei.isLocal=function(){return!!this.isValid()&&!this._isUTC},ei.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},ei.isUtc=Zt,ei.isUTC=Zt,ei.zoneAbbr=function(){return this._isUTC?"UTC":""},ei.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},ei.dates=M("dates accessor is deprecated. Use date instead.",Jn),ei.months=M("months accessor is deprecated. Use month instead",$),ei.years=M("years accessor is deprecated. Use year instead",xn),ei.zone=M("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()}),ei.isDSTShifted=M("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!o(this._isDSTShifted))return this._isDSTShifted;var t={};if(v(t,this),(t=Lt(t))._a){var e=t._isUTC?h(t._a):Nt(t._a);this._isDSTShifted=this.isValid()&&k(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted});var ni=P.prototype;ni.calendar=function(t,e,n){var i=this._calendar[t]||this._calendar.sameElse;return D(i)?i.call(e,n):i},ni.longDateFormat=function(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,function(t){return t.slice(1)}),this._longDateFormat[t])},ni.invalidDate=function(){return this._invalidDate},ni.ordinal=function(t){return this._ordinal.replace("%d",t)},ni.preparse=se,ni.postformat=se,ni.relativeTime=function(t,e,n,i){var a=this._relativeTime[n];return D(a)?a(t,e,n,i):a.replace(/%d/i,t)},ni.pastFuture=function(t,e){var n=this._relativeTime[t>0?"future":"past"];return D(n)?n(e):n.replace(/%s/i,e)},ni.set=function(t){var e,n;for(n in t)D(e=t[n])?this[n]=e:this["_"+n]=e;this._config=t,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},ni.months=function(t,e){return t?i(this._months)?this._months[t.month()]:this._months[(this._months.isFormat||mn).test(e)?"format":"standalone"][t.month()]:i(this._months)?this._months:this._months.standalone},ni.monthsShort=function(t,e){return t?i(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[mn.test(e)?"format":"standalone"][t.month()]:i(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},ni.monthsParse=function(t,e,n){var i,a,r;if(this._monthsParseExact)return K.call(this,t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;i<12;i++){if(a=h([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(a,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(a,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(a,"")+"|^"+this.monthsShort(a,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}},ni.monthsRegex=function(t){return this._monthsParseExact?(d(this,"_monthsRegex")||tt.call(this),t?this._monthsStrictRegex:this._monthsRegex):(d(this,"_monthsRegex")||(this._monthsRegex=bn),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)},ni.monthsShortRegex=function(t){return this._monthsParseExact?(d(this,"_monthsRegex")||tt.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(d(this,"_monthsShortRegex")||(this._monthsShortRegex=yn),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)},ni.week=function(t){return st(t,this._week.dow,this._week.doy).week},ni.firstDayOfYear=function(){return this._week.doy},ni.firstDayOfWeek=function(){return this._week.dow},ni.weekdays=function(t,e){return t?i(this._weekdays)?this._weekdays[t.day()]:this._weekdays[this._weekdays.isFormat.test(e)?"format":"standalone"][t.day()]:i(this._weekdays)?this._weekdays:this._weekdays.standalone},ni.weekdaysMin=function(t){return t?this._weekdaysMin[t.day()]:this._weekdaysMin},ni.weekdaysShort=function(t){return t?this._weekdaysShort[t.day()]:this._weekdaysShort},ni.weekdaysParse=function(t,e,n){var i,a,r;if(this._weekdaysParseExact)return ct.call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;i<7;i++){if(a=h([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(a,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(a,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(a,"").replace(".",".?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[i].test(t))return i;if(n&&"ddd"===e&&this._shortWeekdaysParse[i].test(t))return i;if(n&&"dd"===e&&this._minWeekdaysParse[i].test(t))return i;if(!n&&this._weekdaysParse[i].test(t))return i}},ni.weekdaysRegex=function(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||ht.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(d(this,"_weekdaysRegex")||(this._weekdaysRegex=Sn),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)},ni.weekdaysShortRegex=function(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||ht.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(d(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Dn),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},ni.weekdaysMinRegex=function(t){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||ht.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(d(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Cn),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},ni.isPM=function(t){return"p"===(t+"").toLowerCase().charAt(0)},ni.meridiem=function(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"},bt("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10;return t+(1===_(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")}}),n.lang=M("moment.lang is deprecated. Use moment.locale instead.",bt),n.langData=M("moment.langData is deprecated. Use moment.localeData instead.",_t);var ii=Math.abs,ai=me("ms"),ri=me("s"),oi=me("m"),si=me("h"),li=me("d"),ui=me("w"),di=me("M"),ci=me("y"),hi=pe("milliseconds"),fi=pe("seconds"),gi=pe("minutes"),mi=pe("hours"),pi=pe("days"),vi=pe("months"),yi=pe("years"),bi=Math.round,xi={ss:44,s:45,m:45,h:22,d:26,M:11},_i=Math.abs,ki=Vt.prototype;return ki.isValid=function(){return this._isValid},ki.abs=function(){var t=this._data;return this._milliseconds=ii(this._milliseconds),this._days=ii(this._days),this._months=ii(this._months),t.milliseconds=ii(t.milliseconds),t.seconds=ii(t.seconds),t.minutes=ii(t.minutes),t.hours=ii(t.hours),t.months=ii(t.months),t.years=ii(t.years),this},ki.add=function(t,e){return ce(this,t,e,1)},ki.subtract=function(t,e){return ce(this,t,e,-1)},ki.as=function(t){if(!this.isValid())return NaN;var e,n,i=this._milliseconds;if("month"===(t=I(t))||"year"===t)return e=this._days+i/864e5,n=this._months+fe(e),"month"===t?n:n/12;switch(e=this._days+Math.round(ge(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}},ki.asMilliseconds=ai,ki.asSeconds=ri,ki.asMinutes=oi,ki.asHours=si,ki.asDays=li,ki.asWeeks=ui,ki.asMonths=di,ki.asYears=ci,ki.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*_(this._months/12):NaN},ki._bubble=function(){var t,e,n,i,a,r=this._milliseconds,o=this._days,s=this._months,l=this._data;return r>=0&&o>=0&&s>=0||r<=0&&o<=0&&s<=0||(r+=864e5*he(ge(s)+o),o=0,s=0),l.milliseconds=r%1e3,t=x(r/1e3),l.seconds=t%60,e=x(t/60),l.minutes=e%60,n=x(e/60),l.hours=n%24,o+=x(n/24),a=x(fe(o)),s+=a,o-=he(ge(a)),i=x(s/12),s%=12,l.days=o,l.months=s,l.years=i,this},ki.get=function(t){return t=I(t),this.isValid()?this[t+"s"]():NaN},ki.milliseconds=hi,ki.seconds=fi,ki.minutes=gi,ki.hours=mi,ki.days=pi,ki.weeks=function(){return x(this.days()/7)},ki.months=vi,ki.years=yi,ki.humanize=function(t){if(!this.isValid())return this.localeData().invalidDate();var e=this.localeData(),n=ye(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)},ki.toISOString=be,ki.toString=be,ki.toJSON=be,ki.locale=ne,ki.localeData=ie,ki.toIsoString=M("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",be),ki.lang=Xn,N("X",0,0,"unix"),N("x",0,0,"valueOf"),E("x",Ke),E("X",tn),G("X",function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))}),G("x",function(t,e,n){n._d=new Date(_(t))}),n.version="2.18.1",function(t){xe=t}(Nt),n.fn=ei,n.min=function(){return zt("isBefore",[].slice.call(arguments,0))},n.max=function(){return zt("isAfter",[].slice.call(arguments,0))},n.now=function(){return Date.now?Date.now():+new Date},n.utc=h,n.unix=function(t){return Nt(1e3*t)},n.months=function(t,e){return ue(t,e,"months")},n.isDate=l,n.locale=bt,n.invalid=p,n.duration=Xt,n.isMoment=b,n.weekdays=function(t,e,n){return de(t,e,n,"weekdays")},n.parseZone=function(){return Nt.apply(null,arguments).parseZone()},n.localeData=_t,n.isDuration=Ht,n.monthsShort=function(t,e){return ue(t,e,"monthsShort")},n.weekdaysMin=function(t,e,n){return de(t,e,n,"weekdaysMin")},n.defineLocale=xt,n.updateLocale=function(t,e){if(null!=e){var n,i=An;null!=On[t]&&(i=On[t]._config),(n=new P(e=C(i,e))).parentLocale=On[t],On[t]=n,bt(t)}else null!=On[t]&&(null!=On[t].parentLocale?On[t]=On[t].parentLocale:null!=On[t]&&delete On[t]);return On[t]},n.locales=function(){return Pe(On)},n.weekdaysShort=function(t,e,n){return de(t,e,n,"weekdaysShort")},n.normalizeUnits=I,n.relativeTimeRounding=function(t){return void 0===t?bi:"function"==typeof t&&(bi=t,!0)},n.relativeTimeThreshold=function(t,e){return void 0!==xi[t]&&(void 0===e?xi[t]:(xi[t]=e,"s"===t&&(xi.ss=e-1),!0))},n.calendarFormat=function(t,e){var n=t.diff(e,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},n.prototype=ei,n})},{}],7:[function(t,e,n){var i=t(29)();i.helpers=t(45),t(27)(i),i.defaults=t(25),i.Element=t(26),i.elements=t(40),i.Interaction=t(28),i.platform=t(48),t(31)(i),t(22)(i),t(23)(i),t(24)(i),t(30)(i),t(33)(i),t(32)(i),t(35)(i),t(54)(i),t(52)(i),t(53)(i),t(55)(i),t(56)(i),t(57)(i),t(15)(i),t(16)(i),t(17)(i),t(18)(i),t(19)(i),t(20)(i),t(21)(i),t(8)(i),t(9)(i),t(10)(i),t(11)(i),t(12)(i),t(13)(i),t(14)(i);var a=[];a.push(t(49)(i),t(50)(i),t(51)(i)),i.plugins.register(a),i.platform.initialize(),e.exports=i,"undefined"!=typeof window&&(window.Chart=i),i.canvasHelpers=i.helpers.canvas},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,35:35,40:40,45:45,48:48,49:49,50:50,51:51,52:52,53:53,54:54,55:55,56:56,57:57,8:8,9:9}],8:[function(t,e,n){"use strict";e.exports=function(t){t.Bar=function(e,n){return n.type="bar",new t(e,n)}}},{}],9:[function(t,e,n){"use strict";e.exports=function(t){t.Bubble=function(e,n){return n.type="bubble",new t(e,n)}}},{}],10:[function(t,e,n){"use strict";e.exports=function(t){t.Doughnut=function(e,n){return n.type="doughnut",new t(e,n)}}},{}],11:[function(t,e,n){"use strict";e.exports=function(t){t.Line=function(e,n){return n.type="line",new t(e,n)}}},{}],12:[function(t,e,n){"use strict";e.exports=function(t){t.PolarArea=function(e,n){return n.type="polarArea",new t(e,n)}}},{}],13:[function(t,e,n){"use strict";e.exports=function(t){t.Radar=function(e,n){return n.type="radar",new t(e,n)}}},{}],14:[function(t,e,n){"use strict";e.exports=function(t){t.Scatter=function(e,n){return n.type="scatter",new t(e,n)}}},{}],15:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),i._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var n="";return t.length>0&&(t[0].yLabel?n=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(n=e.labels[t[0].index])),n},label:function(t,e){return(e.datasets[t.datasetIndex].label||"")+": "+t.xLabel}},mode:"index",axis:"y"}}),e.exports=function(t){t.controllers.bar=t.DatasetController.extend({dataElementType:a.Rectangle,initialize:function(){var e,n=this;t.DatasetController.prototype.initialize.apply(n,arguments),(e=n.getMeta()).stack=n.getDataset().stack,e.bar=!0},update:function(t){var e,n,i=this,a=i.getMeta().data;for(i._ruler=i.getRuler(),e=0,n=a.length;e<n;++e)i.updateElement(a[e],e,t)},updateElement:function(t,e,n){var i=this,a=i.chart,o=i.getMeta(),s=i.getDataset(),l=t.custom||{},u=a.options.elements.rectangle;t._xScale=i.getScaleForId(o.xAxisID),t._yScale=i.getScaleForId(o.yAxisID),t._datasetIndex=i.index,t._index=e,t._model={datasetLabel:s.label,label:a.data.labels[e],borderSkipped:l.borderSkipped?l.borderSkipped:u.borderSkipped,backgroundColor:l.backgroundColor?l.backgroundColor:r.valueAtIndexOrDefault(s.backgroundColor,e,u.backgroundColor),borderColor:l.borderColor?l.borderColor:r.valueAtIndexOrDefault(s.borderColor,e,u.borderColor),borderWidth:l.borderWidth?l.borderWidth:r.valueAtIndexOrDefault(s.borderWidth,e,u.borderWidth)},i.updateElementGeometry(t,e,n),t.pivot()},updateElementGeometry:function(t,e,n){var i=this,a=t._model,r=i.getValueScale(),o=r.getBasePixel(),s=r.isHorizontal(),l=i._ruler||i.getRuler(),u=i.calculateBarValuePixels(i.index,e),d=i.calculateBarIndexPixels(i.index,e,l);a.horizontal=s,a.base=n?o:u.base,a.x=s?n?o:u.head:d.center,a.y=s?d.center:n?o:u.head,a.height=s?d.size:void 0,a.width=s?void 0:d.size},getValueScaleId:function(){return this.getMeta().yAxisID},getIndexScaleId:function(){return this.getMeta().xAxisID},getValueScale:function(){return this.getScaleForId(this.getValueScaleId())},getIndexScale:function(){return this.getScaleForId(this.getIndexScaleId())},getStackCount:function(t){var e,n,i=this,a=i.chart,r=i.getIndexScale().options.stacked,o=void 0===t?a.data.datasets.length:t+1,s=[];for(e=0;e<o;++e)(n=a.getDatasetMeta(e)).bar&&a.isDatasetVisible(e)&&(!1===r||!0===r&&-1===s.indexOf(n.stack)||void 0===r&&(void 0===n.stack||-1===s.indexOf(n.stack)))&&s.push(n.stack);return s.length},getStackIndex:function(t){return this.getStackCount(t)-1},getRuler:function(){var t,e,n=this,i=n.getIndexScale(),a=n.getStackCount(),r=n.index,o=[],s=i.isHorizontal(),l=s?i.left:i.top,u=l+(s?i.width:i.height);for(t=0,e=n.getMeta().data.length;t<e;++t)o.push(i.getPixelForValue(null,t,r));return{pixels:o,start:l,end:u,stackCount:a,scale:i}},calculateBarValuePixels:function(t,e){var n,i,a,r,o,s,l=this,u=l.chart,d=l.getMeta(),c=l.getValueScale(),h=u.data.datasets,f=c.getRightValue(h[t].data[e]),g=c.options.stacked,m=d.stack,p=0;if(g||void 0===g&&void 0!==m)for(n=0;n<t;++n)(i=u.getDatasetMeta(n)).bar&&i.stack===m&&i.controller.getValueScaleId()===c.id&&u.isDatasetVisible(n)&&(a=c.getRightValue(h[n].data[e]),(f<0&&a<0||f>=0&&a>0)&&(p+=a));return r=c.getPixelForValue(p),o=c.getPixelForValue(p+f),s=(o-r)/2,{size:s,base:r,head:o,center:o+s/2}},calculateBarIndexPixels:function(t,e,n){var i,a,o,s,l,u,d=this,c=n.scale.options,h=d.getStackIndex(t),f=n.pixels,g=f[e],m=f.length,p=n.start,v=n.end;return 1===m?(i=g>p?g-p:v-g,a=g<v?v-g:g-p):(e>0&&(i=(g-f[e-1])/2,e===m-1&&(a=i)),e<m-1&&(a=(f[e+1]-g)/2,0===e&&(i=a))),o=i*c.categoryPercentage,s=a*c.categoryPercentage,l=(o+s)/n.stackCount,u=l*c.barPercentage,u=Math.min(r.valueOrDefault(c.barThickness,u),r.valueOrDefault(c.maxBarThickness,1/0)),g-=o,g+=l*h,g+=(l-u)/2,{size:u,base:g,head:g+u,center:g+u/2}},draw:function(){var t=this,e=t.chart,n=t.getValueScale(),i=t.getMeta().data,a=t.getDataset(),o=i.length,s=0;for(r.canvas.clipArea(e.ctx,e.chartArea);s<o;++s)isNaN(n.getRightValue(a.data[s]))||i[s].draw();r.canvas.unclipArea(e.ctx)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,i=t.custom||{},a=t._model;a.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:r.valueAtIndexOrDefault(e.hoverBackgroundColor,n,r.getHoverColor(a.backgroundColor)),a.borderColor=i.hoverBorderColor?i.hoverBorderColor:r.valueAtIndexOrDefault(e.hoverBorderColor,n,r.getHoverColor(a.borderColor)),a.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:r.valueAtIndexOrDefault(e.hoverBorderWidth,n,a.borderWidth)},removeHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,i=t.custom||{},a=t._model,o=this.chart.options.elements.rectangle;a.backgroundColor=i.backgroundColor?i.backgroundColor:r.valueAtIndexOrDefault(e.backgroundColor,n,o.backgroundColor),a.borderColor=i.borderColor?i.borderColor:r.valueAtIndexOrDefault(e.borderColor,n,o.borderColor),a.borderWidth=i.borderWidth?i.borderWidth:r.valueAtIndexOrDefault(e.borderWidth,n,o.borderWidth)}}),t.controllers.horizontalBar=t.controllers.bar.extend({getValueScaleId:function(){return this.getMeta().xAxisID},getIndexScaleId:function(){return this.getMeta().yAxisID}})}},{25:25,40:40,45:45}],16:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._set("bubble",{hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return n+": ("+t.xLabel+", "+t.yLabel+", "+i.r+")"}}}}),e.exports=function(t){t.controllers.bubble=t.DatasetController.extend({dataElementType:a.Point,update:function(t){var e=this,n=e.getMeta().data;r.each(n,function(n,i){e.updateElement(n,i,t)})},updateElement:function(t,e,n){var i=this,a=i.getMeta(),r=t.custom||{},o=i.getScaleForId(a.xAxisID),s=i.getScaleForId(a.yAxisID),l=i._resolveElementOptions(t,e),u=i.getDataset().data[e],d=i.index,c=n?o.getPixelForDecimal(.5):o.getPixelForValue("object"==typeof u?u:NaN,e,d),h=n?s.getBasePixel():s.getPixelForValue(u,e,d);t._xScale=o,t._yScale=s,t._options=l,t._datasetIndex=d,t._index=e,t._model={backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,hitRadius:l.hitRadius,pointStyle:l.pointStyle,radius:n?0:l.radius,skip:r.skip||isNaN(c)||isNaN(h),x:c,y:h},t.pivot()},setHoverStyle:function(t){var e=t._model,n=t._options;e.backgroundColor=r.valueOrDefault(n.hoverBackgroundColor,r.getHoverColor(n.backgroundColor)),e.borderColor=r.valueOrDefault(n.hoverBorderColor,r.getHoverColor(n.borderColor)),e.borderWidth=r.valueOrDefault(n.hoverBorderWidth,n.borderWidth),e.radius=n.radius+n.hoverRadius},removeHoverStyle:function(t){var e=t._model,n=t._options;e.backgroundColor=n.backgroundColor,e.borderColor=n.borderColor,e.borderWidth=n.borderWidth,e.radius=n.radius},_resolveElementOptions:function(t,e){var n,i,a,o=this,s=o.chart,l=s.data.datasets[o.index],u=t.custom||{},d=s.options.elements.point,c=r.options.resolve,h=l.data[e],f={},g={chart:s,dataIndex:e,dataset:l,datasetIndex:o.index},m=["backgroundColor","borderColor","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","pointStyle"];for(n=0,i=m.length;n<i;++n)f[a=m[n]]=c([u[a],l[a],d[a]],g,e);return f.radius=c([u.radius,h?h.r:void 0,l.radius,d.radius],g,e),f}})}},{25:25,40:40,45:45}],17:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._set("doughnut",{animation:{animateRotate:!0,animateScale:!1},hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var r=0;r<i[0].data.length;++r)e.push('<li><span style="background-color:'+i[0].backgroundColor[r]+'"></span>'),a[r]&&e.push(a[r]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(n,i){var a=t.getDatasetMeta(0),o=e.datasets[0],s=a.data[i],l=s&&s.custom||{},u=r.valueAtIndexOrDefault,d=t.options.elements.arc;return{text:n,fillStyle:l.backgroundColor?l.backgroundColor:u(o.backgroundColor,i,d.backgroundColor),strokeStyle:l.borderColor?l.borderColor:u(o.borderColor,i,d.borderColor),lineWidth:l.borderWidth?l.borderWidth:u(o.borderWidth,i,d.borderWidth),hidden:isNaN(o.data[i])||a.data[i].hidden,index:i}}):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;n<i;++n)(a=o.getDatasetMeta(n)).data[r]&&(a.data[r].hidden=!a.data[r].hidden);o.update()}},cutoutPercentage:50,rotation:-.5*Math.PI,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.labels[t.index],i=": "+e.datasets[t.datasetIndex].data[t.index];return r.isArray(n)?(n=n.slice())[0]+=i:n+=i,n}}}}),i._set("pie",r.clone(i.doughnut)),i._set("pie",{cutoutPercentage:0}),e.exports=function(t){t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:a.Arc,linkScales:r.noop,getRingIndex:function(t){for(var e=0,n=0;n<t;++n)this.chart.isDatasetVisible(n)&&++e;return e},update:function(t){var e=this,n=e.chart,i=n.chartArea,a=n.options,o=a.elements.arc,s=i.right-i.left-o.borderWidth,l=i.bottom-i.top-o.borderWidth,u=Math.min(s,l),d={x:0,y:0},c=e.getMeta(),h=a.cutoutPercentage,f=a.circumference;if(f<2*Math.PI){var g=a.rotation%(2*Math.PI),m=(g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0))+f,p={x:Math.cos(g),y:Math.sin(g)},v={x:Math.cos(m),y:Math.sin(m)},y=g<=0&&m>=0||g<=2*Math.PI&&2*Math.PI<=m,b=g<=.5*Math.PI&&.5*Math.PI<=m||g<=2.5*Math.PI&&2.5*Math.PI<=m,x=g<=-Math.PI&&-Math.PI<=m||g<=Math.PI&&Math.PI<=m,_=g<=.5*-Math.PI&&.5*-Math.PI<=m||g<=1.5*Math.PI&&1.5*Math.PI<=m,k=h/100,w={x:x?-1:Math.min(p.x*(p.x<0?1:k),v.x*(v.x<0?1:k)),y:_?-1:Math.min(p.y*(p.y<0?1:k),v.y*(v.y<0?1:k))},M={x:y?1:Math.max(p.x*(p.x>0?1:k),v.x*(v.x>0?1:k)),y:b?1:Math.max(p.y*(p.y>0?1:k),v.y*(v.y>0?1:k))},S={width:.5*(M.x-w.x),height:.5*(M.y-w.y)};u=Math.min(s/S.width,l/S.height),d={x:-.5*(M.x+w.x),y:-.5*(M.y+w.y)}}n.borderWidth=e.getMaxBorderWidth(c.data),n.outerRadius=Math.max((u-n.borderWidth)/2,0),n.innerRadius=Math.max(h?n.outerRadius/100*h:0,0),n.radiusLength=(n.outerRadius-n.innerRadius)/n.getVisibleDatasetCount(),n.offsetX=d.x*n.outerRadius,n.offsetY=d.y*n.outerRadius,c.total=e.calculateTotal(),e.outerRadius=n.outerRadius-n.radiusLength*e.getRingIndex(e.index),e.innerRadius=Math.max(e.outerRadius-n.radiusLength,0),r.each(c.data,function(n,i){e.updateElement(n,i,t)})},updateElement:function(t,e,n){var i=this,a=i.chart,o=a.chartArea,s=a.options,l=s.animation,u=(o.left+o.right)/2,d=(o.top+o.bottom)/2,c=s.rotation,h=s.rotation,f=i.getDataset(),g=n&&l.animateRotate?0:t.hidden?0:i.calculateCircumference(f.data[e])*(s.circumference/(2*Math.PI)),m=n&&l.animateScale?0:i.innerRadius,p=n&&l.animateScale?0:i.outerRadius,v=r.valueAtIndexOrDefault;r.extend(t,{_datasetIndex:i.index,_index:e,_model:{x:u+a.offsetX,y:d+a.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:p,innerRadius:m,label:v(f.label,e,a.data.labels[e])}});var y=t._model;this.removeHoverStyle(t),n&&l.animateRotate||(y.startAngle=0===e?s.rotation:i.getMeta().data[e-1]._model.endAngle,y.endAngle=y.startAngle+y.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,e=this.getDataset(),n=this.getMeta(),i=0;return r.each(n.data,function(n,a){t=e.data[a],isNaN(t)||n.hidden||(i+=Math.abs(t))}),i},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(t/e):0},getMaxBorderWidth:function(t){for(var e,n,i=0,a=this.index,r=t.length,o=0;o<r;o++)e=t[o]._model?t[o]._model.borderWidth:0,i=(n=t[o]._chart?t[o]._chart.config.data.datasets[a].hoverBorderWidth:0)>(i=e>i?e:i)?n:i;return i}})}},{25:25,40:40,45:45}],18:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}}),e.exports=function(t){function e(t,e){return r.valueOrDefault(t.showLine,e.showLines)}t.controllers.line=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,update:function(t){var n,i,a,o=this,s=o.getMeta(),l=s.dataset,u=s.data||[],d=o.chart.options,c=d.elements.line,h=o.getScaleForId(s.yAxisID),f=o.getDataset(),g=e(f,d);for(g&&(a=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=h,l._datasetIndex=o.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:a.tension?a.tension:r.valueOrDefault(f.lineTension,c.tension),backgroundColor:a.backgroundColor?a.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:a.borderWidth?a.borderWidth:f.borderWidth||c.borderWidth,borderColor:a.borderColor?a.borderColor:f.borderColor||c.borderColor,borderCapStyle:a.borderCapStyle?a.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:a.borderDash?a.borderDash:f.borderDash||c.borderDash,borderDashOffset:a.borderDashOffset?a.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:a.borderJoinStyle?a.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:a.fill?a.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:a.steppedLine?a.steppedLine:r.valueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:a.cubicInterpolationMode?a.cubicInterpolationMode:r.valueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode)},l.pivot()),n=0,i=u.length;n<i;++n)o.updateElement(u[n],n,t);for(g&&0!==l._model.tension&&o.updateBezierControlPoints(),n=0,i=u.length;n<i;++n)u[n].pivot()},getPointBackgroundColor:function(t,e){var n=this.chart.options.elements.point.backgroundColor,i=this.getDataset(),a=t.custom||{};return a.backgroundColor?n=a.backgroundColor:i.pointBackgroundColor?n=r.valueAtIndexOrDefault(i.pointBackgroundColor,e,n):i.backgroundColor&&(n=i.backgroundColor),n},getPointBorderColor:function(t,e){var n=this.chart.options.elements.point.borderColor,i=this.getDataset(),a=t.custom||{};return a.borderColor?n=a.borderColor:i.pointBorderColor?n=r.valueAtIndexOrDefault(i.pointBorderColor,e,n):i.borderColor&&(n=i.borderColor),n},getPointBorderWidth:function(t,e){var n=this.chart.options.elements.point.borderWidth,i=this.getDataset(),a=t.custom||{};return isNaN(a.borderWidth)?!isNaN(i.pointBorderWidth)||r.isArray(i.pointBorderWidth)?n=r.valueAtIndexOrDefault(i.pointBorderWidth,e,n):isNaN(i.borderWidth)||(n=i.borderWidth):n=a.borderWidth,n},updateElement:function(t,e,n){var i,a,o=this,s=o.getMeta(),l=t.custom||{},u=o.getDataset(),d=o.index,c=u.data[e],h=o.getScaleForId(s.yAxisID),f=o.getScaleForId(s.xAxisID),g=o.chart.options.elements.point;void 0!==u.radius&&void 0===u.pointRadius&&(u.pointRadius=u.radius),void 0!==u.hitRadius&&void 0===u.pointHitRadius&&(u.pointHitRadius=u.hitRadius),i=f.getPixelForValue("object"==typeof c?c:NaN,e,d),a=n?h.getBasePixel():o.calculatePointY(c,e,d),t._xScale=f,t._yScale=h,t._datasetIndex=d,t._index=e,t._model={x:i,y:a,skip:l.skip||isNaN(i)||isNaN(a),radius:l.radius||r.valueAtIndexOrDefault(u.pointRadius,e,g.radius),pointStyle:l.pointStyle||r.valueAtIndexOrDefault(u.pointStyle,e,g.pointStyle),backgroundColor:o.getPointBackgroundColor(t,e),borderColor:o.getPointBorderColor(t,e),borderWidth:o.getPointBorderWidth(t,e),tension:s.dataset._model?s.dataset._model.tension:0,steppedLine:!!s.dataset._model&&s.dataset._model.steppedLine,hitRadius:l.hitRadius||r.valueAtIndexOrDefault(u.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,n){var i,a,r,o=this,s=o.chart,l=o.getMeta(),u=o.getScaleForId(l.yAxisID),d=0,c=0;if(u.options.stacked){for(i=0;i<n;i++)if(a=s.data.datasets[i],"line"===(r=s.getDatasetMeta(i)).type&&r.yAxisID===u.id&&s.isDatasetVisible(i)){var h=Number(u.getRightValue(a.data[e]));h<0?c+=h||0:d+=h||0}var f=Number(u.getRightValue(t));return f<0?u.getPixelForValue(c+f):u.getPixelForValue(d+f)}return u.getPixelForValue(t)},updateBezierControlPoints:function(){function t(t,e,n){return Math.max(Math.min(t,n),e)}var e,n,i,a,o=this,s=o.getMeta(),l=o.chart.chartArea,u=s.data||[];if(s.dataset._model.spanGaps&&(u=u.filter(function(t){return!t._model.skip})),"monotone"===s.dataset._model.cubicInterpolationMode)r.splineCurveMonotone(u);else for(e=0,n=u.length;e<n;++e)i=u[e]._model,a=r.splineCurve(r.previousItem(u,e)._model,i,r.nextItem(u,e)._model,s.dataset._model.tension),i.controlPointPreviousX=a.previous.x,i.controlPointPreviousY=a.previous.y,i.controlPointNextX=a.next.x,i.controlPointNextY=a.next.y;if(o.chart.options.elements.line.capBezierPoints)for(e=0,n=u.length;e<n;++e)(i=u[e]._model).controlPointPreviousX=t(i.controlPointPreviousX,l.left,l.right),i.controlPointPreviousY=t(i.controlPointPreviousY,l.top,l.bottom),i.controlPointNextX=t(i.controlPointNextX,l.left,l.right),i.controlPointNextY=t(i.controlPointNextY,l.top,l.bottom)},draw:function(){var t=this,n=t.chart,i=t.getMeta(),a=i.data||[],o=n.chartArea,s=a.length,l=0;for(r.canvas.clipArea(n.ctx,o),e(t.getDataset(),n.options)&&i.dataset.draw(),r.canvas.unclipArea(n.ctx);l<s;++l)a[l].draw(o)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,i=t.custom||{},a=t._model;a.radius=i.hoverRadius||r.valueAtIndexOrDefault(e.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),a.backgroundColor=i.hoverBackgroundColor||r.valueAtIndexOrDefault(e.pointHoverBackgroundColor,n,r.getHoverColor(a.backgroundColor)),a.borderColor=i.hoverBorderColor||r.valueAtIndexOrDefault(e.pointHoverBorderColor,n,r.getHoverColor(a.borderColor)),a.borderWidth=i.hoverBorderWidth||r.valueAtIndexOrDefault(e.pointHoverBorderWidth,n,a.borderWidth)},removeHoverStyle:function(t){var e=this,n=e.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},o=t._model;void 0!==n.radius&&void 0===n.pointRadius&&(n.pointRadius=n.radius),o.radius=a.radius||r.valueAtIndexOrDefault(n.pointRadius,i,e.chart.options.elements.point.radius),o.backgroundColor=e.getPointBackgroundColor(t,i),o.borderColor=e.getPointBorderColor(t,i),o.borderWidth=e.getPointBorderWidth(t,i)}})}},{25:25,40:40,45:45}],19:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._set("polarArea",{scale:{type:"radialLinear",angleLines:{display:!1},gridLines:{circular:!0},pointLabels:{display:!1},ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var n=t.data,i=n.datasets,a=n.labels;if(i.length)for(var r=0;r<i[0].data.length;++r)e.push('<li><span style="background-color:'+i[0].backgroundColor[r]+'"></span>'),a[r]&&e.push(a[r]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(n,i){var a=t.getDatasetMeta(0),o=e.datasets[0],s=a.data[i].custom||{},l=r.valueAtIndexOrDefault,u=t.options.elements.arc;return{text:n,fillStyle:s.backgroundColor?s.backgroundColor:l(o.backgroundColor,i,u.backgroundColor),strokeStyle:s.borderColor?s.borderColor:l(o.borderColor,i,u.borderColor),lineWidth:s.borderWidth?s.borderWidth:l(o.borderWidth,i,u.borderWidth),hidden:isNaN(o.data[i])||a.data[i].hidden,index:i}}):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;n<i;++n)(a=o.getDatasetMeta(n)).data[r].hidden=!a.data[r].hidden;o.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}}),e.exports=function(t){t.controllers.polarArea=t.DatasetController.extend({dataElementType:a.Arc,linkScales:r.noop,update:function(t){var e=this,n=e.chart,i=n.chartArea,a=e.getMeta(),o=n.options,s=o.elements.arc,l=Math.min(i.right-i.left,i.bottom-i.top);n.outerRadius=Math.max((l-s.borderWidth/2)/2,0),n.innerRadius=Math.max(o.cutoutPercentage?n.outerRadius/100*o.cutoutPercentage:1,0),n.radiusLength=(n.outerRadius-n.innerRadius)/n.getVisibleDatasetCount(),e.outerRadius=n.outerRadius-n.radiusLength*e.index,e.innerRadius=e.outerRadius-n.radiusLength,a.count=e.countVisibleElements(),r.each(a.data,function(n,i){e.updateElement(n,i,t)})},updateElement:function(t,e,n){for(var i=this,a=i.chart,o=i.getDataset(),s=a.options,l=s.animation,u=a.scale,d=a.data.labels,c=i.calculateCircumference(o.data[e]),h=u.xCenter,f=u.yCenter,g=0,m=i.getMeta(),p=0;p<e;++p)isNaN(o.data[p])||m.data[p].hidden||++g;var v=s.startAngle,y=t.hidden?0:u.getDistanceFromCenterForValue(o.data[e]),b=v+c*g,x=b+(t.hidden?0:c),_=l.animateScale?0:u.getDistanceFromCenterForValue(o.data[e]);r.extend(t,{_datasetIndex:i.index,_index:e,_scale:u,_model:{x:h,y:f,innerRadius:0,outerRadius:n?_:y,startAngle:n&&l.animateRotate?v:b,endAngle:n&&l.animateRotate?v:x,label:r.valueAtIndexOrDefault(d,e,d[e])}}),i.removeHoverStyle(t),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},countVisibleElements:function(){var t=this.getDataset(),e=this.getMeta(),n=0;return r.each(e.data,function(e,i){isNaN(t.data[i])||e.hidden||n++}),n},calculateCircumference:function(t){var e=this.getMeta().count;return e>0&&!isNaN(t)?2*Math.PI/e:0}})}},{25:25,40:40,45:45}],20:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._set("radar",{scale:{type:"radialLinear"},elements:{line:{tension:0}}}),e.exports=function(t){t.controllers.radar=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,linkScales:r.noop,update:function(t){var e=this,n=e.getMeta(),i=n.dataset,a=n.data,o=i.custom||{},s=e.getDataset(),l=e.chart.options.elements.line,u=e.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),r.extend(n.dataset,{_datasetIndex:e.index,_scale:u,_children:a,_loop:!0,_model:{tension:o.tension?o.tension:r.valueOrDefault(s.lineTension,l.tension),backgroundColor:o.backgroundColor?o.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:s.borderWidth||l.borderWidth,borderColor:o.borderColor?o.borderColor:s.borderColor||l.borderColor,fill:o.fill?o.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:o.borderCapStyle?o.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:o.borderDash?o.borderDash:s.borderDash||l.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle}}),n.dataset.pivot(),r.each(a,function(n,i){e.updateElement(n,i,t)},e),e.updateBezierControlPoints()},updateElement:function(t,e,n){var i=this,a=t.custom||{},o=i.getDataset(),s=i.chart.scale,l=i.chart.options.elements.point,u=s.getPointPositionForValue(e,o.data[e]);void 0!==o.radius&&void 0===o.pointRadius&&(o.pointRadius=o.radius),void 0!==o.hitRadius&&void 0===o.pointHitRadius&&(o.pointHitRadius=o.hitRadius),r.extend(t,{_datasetIndex:i.index,_index:e,_scale:s,_model:{x:n?s.xCenter:u.x,y:n?s.yCenter:u.y,tension:a.tension?a.tension:r.valueOrDefault(o.lineTension,i.chart.options.elements.line.tension),radius:a.radius?a.radius:r.valueAtIndexOrDefault(o.pointRadius,e,l.radius),backgroundColor:a.backgroundColor?a.backgroundColor:r.valueAtIndexOrDefault(o.pointBackgroundColor,e,l.backgroundColor),borderColor:a.borderColor?a.borderColor:r.valueAtIndexOrDefault(o.pointBorderColor,e,l.borderColor),borderWidth:a.borderWidth?a.borderWidth:r.valueAtIndexOrDefault(o.pointBorderWidth,e,l.borderWidth),pointStyle:a.pointStyle?a.pointStyle:r.valueAtIndexOrDefault(o.pointStyle,e,l.pointStyle),hitRadius:a.hitRadius?a.hitRadius:r.valueAtIndexOrDefault(o.pointHitRadius,e,l.hitRadius)}}),t._model.skip=a.skip?a.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,e=this.getMeta();r.each(e.data,function(n,i){var a=n._model,o=r.splineCurve(r.previousItem(e.data,i,!0)._model,a,r.nextItem(e.data,i,!0)._model,a.tension);a.controlPointPreviousX=Math.max(Math.min(o.previous.x,t.right),t.left),a.controlPointPreviousY=Math.max(Math.min(o.previous.y,t.bottom),t.top),a.controlPointNextX=Math.max(Math.min(o.next.x,t.right),t.left),a.controlPointNextY=Math.max(Math.min(o.next.y,t.bottom),t.top),n.pivot()})},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t.custom||{},i=t._index,a=t._model;a.radius=n.hoverRadius?n.hoverRadius:r.valueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),a.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:r.valueAtIndexOrDefault(e.pointHoverBackgroundColor,i,r.getHoverColor(a.backgroundColor)),a.borderColor=n.hoverBorderColor?n.hoverBorderColor:r.valueAtIndexOrDefault(e.pointHoverBorderColor,i,r.getHoverColor(a.borderColor)),a.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:r.valueAtIndexOrDefault(e.pointHoverBorderWidth,i,a.borderWidth)},removeHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t.custom||{},i=t._index,a=t._model,o=this.chart.options.elements.point;a.radius=n.radius?n.radius:r.valueAtIndexOrDefault(e.pointRadius,i,o.radius),a.backgroundColor=n.backgroundColor?n.backgroundColor:r.valueAtIndexOrDefault(e.pointBackgroundColor,i,o.backgroundColor),a.borderColor=n.borderColor?n.borderColor:r.valueAtIndexOrDefault(e.pointBorderColor,i,o.borderColor),a.borderWidth=n.borderWidth?n.borderWidth:r.valueAtIndexOrDefault(e.pointBorderWidth,i,o.borderWidth)}})}},{25:25,40:40,45:45}],21:[function(t,e,n){"use strict";t(25)._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},showLines:!1,tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}}),e.exports=function(t){t.controllers.scatter=t.controllers.line}},{25:25}],22:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45);i._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:r.noop,onComplete:r.noop}}),e.exports=function(t){t.Animation=a.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,n,i){var a,r,o=this.animations;for(e.chart=t,i||(t.animating=!0),a=0,r=o.length;a<r;++a)if(o[a].chart===t)return void(o[a]=e);o.push(e),1===o.length&&this.requestAnimationFrame()},cancelAnimation:function(t){var e=r.findIndex(this.animations,function(e){return e.chart===t});-1!==e&&(this.animations.splice(e,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=r.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),n=0;t.dropFrames>1&&(n=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1),t.advance(1+n);var i=Date.now();t.dropFrames+=(i-e)/t.frameDuration,t.animations.length>0&&t.requestAnimationFrame()},advance:function(t){for(var e,n,i=this.animations,a=0;a<i.length;)n=(e=i[a]).chart,e.currentStep=(e.currentStep||0)+t,e.currentStep=Math.min(e.currentStep,e.numSteps),r.callback(e.render,[n,e],n),r.callback(e.onAnimationProgress,[e],n),e.currentStep>=e.numSteps?(r.callback(e.onAnimationComplete,[e],n),n.animating=!1,i.splice(a,1)):++a}},Object.defineProperty(t.Animation.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(t.Animation.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}})}},{25:25,26:26,45:45}],23:[function(t,e,n){"use strict";var i=t(25),a=t(45),r=t(28),o=t(48);e.exports=function(t){function e(t){var e=(t=t||{}).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=a.configMerge(i.global,i[t.type],t.options||{}),t}function n(t){var e=t.options;e.scale?t.scale.options=e.scale:e.scales&&e.scales.xAxes.concat(e.scales.yAxes).forEach(function(e){t.scales[e.id].options=e}),t.tooltip._options=e.tooltips}function s(t){return"top"===t||"bottom"===t}var l=t.plugins;t.types={},t.instances={},t.controllers={},a.extend(t.prototype,{construct:function(n,i){var r=this;i=e(i);var s=o.acquireContext(n,i),l=s&&s.canvas,u=l&&l.height,d=l&&l.width;r.id=a.uid(),r.ctx=s,r.canvas=l,r.config=i,r.width=d,r.height=u,r.aspectRatio=u?d/u:null,r.options=i.options,r._bufferedRender=!1,r.chart=r,r.controller=r,t.instances[r.id]=r,Object.defineProperty(r,"data",{get:function(){return r.config.data},set:function(t){r.config.data=t}}),s&&l?(r.initialize(),r.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return l.notify(t,"beforeInit"),a.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildScales(),t.initToolTip(),l.notify(t,"afterInit"),t},clear:function(){return a.canvas.clear(this),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,r=n.maintainAspectRatio&&e.aspectRatio||null,o=Math.max(0,Math.floor(a.getMaximumWidth(i))),s=Math.max(0,Math.floor(r?o/r:a.getMaximumHeight(i)));if((e.width!==o||e.height!==s)&&(i.width=e.width=o,i.height=e.height=s,i.style.width=o+"px",i.style.height=s+"px",a.retinaScale(e,n.devicePixelRatio),!t)){var u={width:o,height:s};l.notify(e,"resize",[u]),e.options.onResize&&e.options.onResize(e,u),e.stop(),e.update(e.options.responsiveAnimationDuration)}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;a.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),a.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),n&&(n.id=n.id||"scale")},buildScales:function(){var e=this,n=e.options,i=e.scales={},r=[];n.scales&&(r=r.concat((n.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(n.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),n.scale&&r.push({options:n.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),a.each(r,function(n){var r=n.options,o=a.valueOrDefault(r.type,n.dtype),l=t.scaleService.getScaleConstructor(o);if(l){s(r.position)!==s(n.dposition)&&(r.position=n.dposition);var u=new l({id:r.id,options:r,ctx:e.ctx,chart:e});i[u.id]=u,u.mergeTicksOptions(),n.isDefault&&(e.scale=u)}}),t.scaleService.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,n=[],i=[];return a.each(e.data.datasets,function(a,r){var o=e.getDatasetMeta(r),s=a.type||e.config.type;if(o.type&&o.type!==s&&(e.destroyDatasetMeta(r),o=e.getDatasetMeta(r)),o.type=s,n.push(o.type),o.controller)o.controller.updateIndex(r);else{var l=t.controllers[o.type];if(void 0===l)throw new Error('"'+o.type+'" is not a chart type.');o.controller=new l(e,r),i.push(o.controller)}},e),i},resetElements:function(){var t=this;a.each(t.data.datasets,function(e,n){t.getDatasetMeta(n).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(t){var e=this;if(t&&"object"==typeof t||(t={duration:t,lazy:arguments[1]}),n(e),!1!==l.notify(e,"beforeUpdate")){e.tooltip._data=e.data;var i=e.buildOrUpdateControllers();a.each(e.data.datasets,function(t,n){e.getDatasetMeta(n).controller.buildOrUpdateElements()},e),e.updateLayout(),a.each(i,function(t){t.reset()}),e.updateDatasets(),l.notify(e,"afterUpdate"),e._bufferedRender?e._bufferedRequest={duration:t.duration,easing:t.easing,lazy:t.lazy}:e.render(t)}},updateLayout:function(){var e=this;!1!==l.notify(e,"beforeLayout")&&(t.layoutService.update(this,this.width,this.height),l.notify(e,"afterScaleUpdate"),l.notify(e,"afterLayout"))},updateDatasets:function(){var t=this;if(!1!==l.notify(t,"beforeDatasetsUpdate")){for(var e=0,n=t.data.datasets.length;e<n;++e)t.updateDataset(e);l.notify(t,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this,n=e.getDatasetMeta(t),i={meta:n,index:t};!1!==l.notify(e,"beforeDatasetUpdate",[i])&&(n.controller.update(),l.notify(e,"afterDatasetUpdate",[i]))},render:function(e){var n=this;e&&"object"==typeof e||(e={duration:e,lazy:arguments[1]});var i=e.duration,r=e.lazy;if(!1!==l.notify(n,"beforeRender")){var o=n.options.animation,s=function(t){l.notify(n,"afterRender"),a.callback(o&&o.onComplete,[t],n)};if(o&&(void 0!==i&&0!==i||void 0===i&&0!==o.duration)){var u=new t.Animation({numSteps:(i||o.duration)/16.66,easing:e.easing||o.easing,render:function(t,e){var n=a.easing.effects[e.easing],i=e.currentStep,r=i/e.numSteps;t.draw(n(r),r,i)},onAnimationProgress:o.onProgress,onAnimationComplete:s});t.animationService.addAnimation(n,u,i,r)}else n.draw(),s(new t.Animation({numSteps:0,chart:n}));return n}},draw:function(t){var e=this;e.clear(),a.isNullOrUndef(t)&&(t=1),e.transition(t),!1!==l.notify(e,"beforeDraw",[t])&&(a.each(e.boxes,function(t){t.draw(e.chartArea)},e),e.scale&&e.scale.draw(),e.drawDatasets(t),e.tooltip.draw(),l.notify(e,"afterDraw",[t]))},transition:function(t){for(var e=this,n=0,i=(e.data.datasets||[]).length;n<i;++n)e.isDatasetVisible(n)&&e.getDatasetMeta(n).controller.transition(t);e.tooltip.transition(t)},drawDatasets:function(t){var e=this;if(!1!==l.notify(e,"beforeDatasetsDraw",[t])){for(var n=(e.data.datasets||[]).length-1;n>=0;--n)e.isDatasetVisible(n)&&e.drawDataset(n,t);l.notify(e,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n=this,i=n.getDatasetMeta(t),a={meta:i,index:t,easingValue:e};!1!==l.notify(n,"beforeDatasetDraw",[a])&&(i.controller.draw(e),l.notify(n,"afterDatasetDraw",[a]))},getElementAtEvent:function(t){return r.modes.single(this,t)},getElementsAtEvent:function(t){return r.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return r.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=r.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return r.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this,n=e.data.datasets[t];n._meta||(n._meta={});var i=n._meta[e.id];return i||(i=n._meta[e.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e<n;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroyDatasetMeta:function(t){var e=this.id,n=this.data.datasets[t],i=n._meta&&n._meta[e];i&&(i.controller.destroy(),delete n._meta[e])},destroy:function(){var e,n,i=this,r=i.canvas;for(i.stop(),e=0,n=i.data.datasets.length;e<n;++e)i.destroyDatasetMeta(e);r&&(i.unbindEvents(),a.canvas.clear(i),o.releaseContext(i.ctx),i.canvas=null,i.ctx=null),l.notify(i,"destroy"),delete t.instances[i.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e)},bindEvents:function(){var t=this,e=t._listeners={},n=function(){t.eventHandler.apply(t,arguments)};a.each(t.options.events,function(i){o.addEventListener(t,i,n),e[i]=n}),t.options.responsive&&(n=function(){t.resize()},o.addEventListener(t,"resize",n),e.resize=n)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,a.each(e,function(e,n){o.removeEventListener(t,n,e)}))},updateHoverStyle:function(t,e,n){var i,a,r,o=n?"setHoverStyle":"removeHoverStyle";for(a=0,r=t.length;a<r;++a)(i=t[a])&&this.getDatasetMeta(i._datasetIndex).controller[o](i)},eventHandler:function(t){var e=this,n=e.tooltip;if(!1!==l.notify(e,"beforeEvent",[t])){e._bufferedRender=!0,e._bufferedRequest=null;var i=e.handleEvent(t);i|=n&&n.handleEvent(t),l.notify(e,"afterEvent",[t]);var a=e._bufferedRequest;return a?e.render(a):i&&!e.animating&&(e.stop(),e.render(e.options.hover.animationDuration,!0)),e._bufferedRender=!1,e._bufferedRequest=null,e}},handleEvent:function(t){var e=this,n=e.options||{},i=n.hover,r=!1;return e.lastActive=e.lastActive||[],"mouseout"===t.type?e.active=[]:e.active=e.getElementsAtEventForMode(t,i.mode,i),a.callback(n.onHover||n.hover.onHover,[t.native,e.active],e),"mouseup"!==t.type&&"click"!==t.type||n.onClick&&n.onClick.call(e,t.native,e.active),e.lastActive.length&&e.updateHoverStyle(e.lastActive,i.mode,!1),e.active.length&&i.mode&&e.updateHoverStyle(e.active,i.mode,!0),r=!a.arrayEquals(e.active,e.lastActive),e.lastActive=e.active,r}}),t.Controller=t}},{25:25,28:28,45:45,48:48}],24:[function(t,e,n){"use strict";var i=t(45);e.exports=function(t){function e(t,e){t._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),a.forEach(function(e){var n="onData"+e.charAt(0).toUpperCase()+e.slice(1),a=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),r=a.apply(this,e);return i.each(t._chartjs.listeners,function(t){"function"==typeof t[n]&&t[n].apply(t,e)}),r}})}))}function n(t,e){var n=t._chartjs;if(n){var i=n.listeners,r=i.indexOf(e);-1!==r&&i.splice(r,1),i.length>0||(a.forEach(function(e){delete t[e]}),delete t._chartjs)}}var a=["push","pop","shift","splice","unshift"];t.DatasetController=function(t,e){this.initialize(t,e)},i.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),n=t.getDataset();null===e.xAxisID&&(e.xAxisID=n.xAxisID||t.chart.options.scales.xAxes[0].id),null===e.yAxisID&&(e.yAxisID=n.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&n(this._data,this)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,n=e.dataElementType;return n&&new n({_chart:e.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,n=this,i=n.getMeta(),a=n.getDataset().data||[],r=i.data;for(t=0,e=a.length;t<e;++t)r[t]=r[t]||n.createMetaData(t);i.dataset=i.dataset||n.createMetaDataset()},addElementAndReset:function(t){var e=this.createMetaData(t);this.getMeta().data.splice(t,0,e),this.updateElement(e,t,!0)},buildOrUpdateElements:function(){var t=this,i=t.getDataset(),a=i.data||(i.data=[]);t._data!==a&&(t._data&&n(t._data,t),e(a,t),t._data=a),t.resyncElements()},update:i.noop,transition:function(t){for(var e=this.getMeta(),n=e.data||[],i=n.length,a=0;a<i;++a)n[a].transition(t);e.dataset&&e.dataset.transition(t)},draw:function(){var t=this.getMeta(),e=t.data||[],n=e.length,i=0;for(t.dataset&&t.dataset.draw();i<n;++i)e[i].draw()},removeHoverStyle:function(t,e){var n=this.chart.data.datasets[t._datasetIndex],a=t._index,r=t.custom||{},o=i.valueAtIndexOrDefault,s=t._model;s.backgroundColor=r.backgroundColor?r.backgroundColor:o(n.backgroundColor,a,e.backgroundColor),s.borderColor=r.borderColor?r.borderColor:o(n.borderColor,a,e.borderColor),s.borderWidth=r.borderWidth?r.borderWidth:o(n.borderWidth,a,e.borderWidth)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,a=t.custom||{},r=i.valueAtIndexOrDefault,o=i.getHoverColor,s=t._model;s.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:r(e.hoverBackgroundColor,n,o(s.backgroundColor)),s.borderColor=a.hoverBorderColor?a.hoverBorderColor:r(e.hoverBorderColor,n,o(s.borderColor)),s.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:r(e.hoverBorderWidth,n,s.borderWidth)},resyncElements:function(){var t=this,e=t.getMeta(),n=t.getDataset().data,i=e.data.length,a=n.length;a<i?e.data.splice(a,i-a):a>i&&t.insertElements(i,a-i)},insertElements:function(t,e){for(var n=0;n<e;++n)this.addElementAndReset(t+n)},onDataPush:function(){this.insertElements(this.getDataset().data.length-1,arguments.length)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(t,e){this.getMeta().data.splice(t,e),this.insertElements(t,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),t.DatasetController.extend=i.inherits}},{45:45}],25:[function(t,e,n){"use strict";var i=t(45);e.exports={_set:function(t,e){return i.merge(this[t]||(this[t]={}),e)}}},{45:45}],26:[function(t,e,n){"use strict";function i(t,e,n,i){var r,o,s,l,u,d,c,h,f,g=Object.keys(n);for(r=0,o=g.length;r<o;++r)if(s=g[r],d=n[s],e.hasOwnProperty(s)||(e[s]=d),(l=e[s])!==d&&"_"!==s[0]){if(t.hasOwnProperty(s)||(t[s]=l),u=t[s],(c=typeof d)===typeof u)if("string"===c){if((h=a(u)).valid&&(f=a(d)).valid){e[s]=f.mix(h,i).rgbString();continue}}else if("number"===c&&isFinite(u)&&isFinite(d)){e[s]=u+(d-u)*i;continue}e[s]=d}}var a=t(2),r=t(45),o=function(t){r.extend(this,t),this.initialize.apply(this,arguments)};r.extend(o.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=r.clone(t._model)),t._start={},t},transition:function(t){var e=this,n=e._model,a=e._start,r=e._view;return n&&1!==t?(r||(r=e._view={}),a||(a=e._start={}),i(a,r,n,t),e):(e._view=n,e._start=null,e)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return r.isNumber(this._model.x)&&r.isNumber(this._model.y)}}),o.extend=r.inherits,e.exports=o},{2:2,45:45}],27:[function(t,e,n){"use strict";var i=t(2),a=t(25),r=t(45);e.exports=function(t){function e(t,e,n){var i;return"string"==typeof t?(i=parseInt(t,10),-1!==t.indexOf("%")&&(i=i/100*e.parentNode[n])):i=t,i}function n(t){return void 0!==t&&null!==t&&"none"!==t}function o(t,i,a){var r=document.defaultView,o=t.parentNode,s=r.getComputedStyle(t)[i],l=r.getComputedStyle(o)[i],u=n(s),d=n(l),c=Number.POSITIVE_INFINITY;return u||d?Math.min(u?e(s,t,a):c,d?e(l,o,a):c):"none"}r.extend=function(t){for(var e=1,n=arguments.length;e<n;e++)r.each(arguments[e],function(e,n){t[n]=e});return t},r.configMerge=function(){return r.merge(r.clone(arguments[0]),[].slice.call(arguments,1),{merger:function(e,n,i,a){var o=n[e]||{},s=i[e];"scales"===e?n[e]=r.scaleMerge(o,s):"scale"===e?n[e]=r.merge(o,[t.scaleService.getScaleDefaults(s.type),s]):r._merger(e,n,i,a)}})},r.scaleMerge=function(){return r.merge(r.clone(arguments[0]),[].slice.call(arguments,1),{merger:function(e,n,i,a){if("xAxes"===e||"yAxes"===e){var o,s,l,u=i[e].length;for(n[e]||(n[e]=[]),o=0;o<u;++o)l=i[e][o],s=r.valueOrDefault(l.type,"xAxes"===e?"category":"linear"),o>=n[e].length&&n[e].push({}),!n[e][o].type||l.type&&l.type!==n[e][o].type?r.merge(n[e][o],[t.scaleService.getScaleDefaults(s),l]):r.merge(n[e][o],l)}else r._merger(e,n,i,a)}})},r.where=function(t,e){if(r.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return r.each(t,function(t){e(t)&&n.push(t)}),n},r.findIndex=Array.prototype.findIndex?function(t,e,n){return t.findIndex(e,n)}:function(t,e,n){n=void 0===n?t:n;for(var i=0,a=t.length;i<a;++i)if(e.call(n,t[i],i,t))return i;return-1},r.findNextWhere=function(t,e,n){r.isNullOrUndef(n)&&(n=-1);for(var i=n+1;i<t.length;i++){var a=t[i];if(e(a))return a}},r.findPreviousWhere=function(t,e,n){r.isNullOrUndef(n)&&(n=t.length);for(var i=n-1;i>=0;i--){var a=t[i];if(e(a))return a}},r.inherits=function(t){var e=this,n=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=n};return i.prototype=e.prototype,n.prototype=new i,n.extend=r.inherits,t&&r.extend(n.prototype,t),n.__super__=e.prototype,n},r.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},r.almostEquals=function(t,e,n){return Math.abs(t-e)<n},r.almostWhole=function(t,e){var n=Math.round(t);return n-e<t&&n+e>t},r.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},r.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},r.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0==(t=+t)||isNaN(t)?t:t>0?1:-1},r.log10=Math.log10?function(t){return Math.log10(t)}:function(t){return Math.log(t)/Math.LN10},r.toRadians=function(t){return t*(Math.PI/180)},r.toDegrees=function(t){return t*(180/Math.PI)},r.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},r.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},r.aliasPixel=function(t){return t%2==0?0:.5},r.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),c=i*(u=isNaN(u)?0:u),h=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-c*(o.x-a.x),y:r.y-c*(o.y-a.y)},next:{x:r.x+h*(o.x-a.x),y:r.y+h*(o.y-a.y)}}},r.EPSILON=Number.EPSILON||1e-14,r.splineCurveMonotone=function(t){var e,n,i,a,o=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),s=o.length;for(e=0;e<s;++e)if(!(i=o[e]).model.skip){if(n=e>0?o[e-1]:null,(a=e<s-1?o[e+1]:null)&&!a.model.skip){var l=a.model.x-i.model.x;i.deltaK=0!==l?(a.model.y-i.model.y)/l:0}!n||n.model.skip?i.mK=i.deltaK:!a||a.model.skip?i.mK=n.deltaK:this.sign(n.deltaK)!==this.sign(i.deltaK)?i.mK=0:i.mK=(n.deltaK+i.deltaK)/2}var u,d,c,h;for(e=0;e<s-1;++e)i=o[e],a=o[e+1],i.model.skip||a.model.skip||(r.almostEquals(i.deltaK,0,this.EPSILON)?i.mK=a.mK=0:(u=i.mK/i.deltaK,d=a.mK/i.deltaK,(h=Math.pow(u,2)+Math.pow(d,2))<=9||(c=3/Math.sqrt(h),i.mK=u*c*i.deltaK,a.mK=d*c*i.deltaK)));var f;for(e=0;e<s;++e)(i=o[e]).model.skip||(n=e>0?o[e-1]:null,a=e<s-1?o[e+1]:null,n&&!n.model.skip&&(f=(i.model.x-n.model.x)/3,i.model.controlPointPreviousX=i.model.x-f,i.model.controlPointPreviousY=i.model.y-f*i.mK),a&&!a.model.skip&&(f=(a.model.x-i.model.x)/3,i.model.controlPointNextX=i.model.x+f,i.model.controlPointNextY=i.model.y+f*i.mK))},r.nextItem=function(t,e,n){return n?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},r.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},r.niceNum=function(t,e){var n=Math.floor(r.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},r.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},r.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,o=t.currentTarget||t.srcElement,s=o.getBoundingClientRect(),l=a.touches;l&&l.length>0?(n=l[0].clientX,i=l[0].clientY):(n=a.clientX,i=a.clientY);var u=parseFloat(r.getStyle(o,"padding-left")),d=parseFloat(r.getStyle(o,"padding-top")),c=parseFloat(r.getStyle(o,"padding-right")),h=parseFloat(r.getStyle(o,"padding-bottom")),f=s.right-s.left-u-c,g=s.bottom-s.top-d-h;return n=Math.round((n-s.left-u)/f*o.width/e.currentDevicePixelRatio),i=Math.round((i-s.top-d)/g*o.height/e.currentDevicePixelRatio),{x:n,y:i}},r.getConstraintWidth=function(t){return o(t,"max-width","clientWidth")},r.getConstraintHeight=function(t){return o(t,"max-height","clientHeight")},r.getMaximumWidth=function(t){var e=t.parentNode;if(!e)return t.clientWidth;var n=parseInt(r.getStyle(e,"padding-left"),10),i=parseInt(r.getStyle(e,"padding-right"),10),a=e.clientWidth-n-i,o=r.getConstraintWidth(t);return isNaN(o)?a:Math.min(a,o)},r.getMaximumHeight=function(t){var e=t.parentNode;if(!e)return t.clientHeight;var n=parseInt(r.getStyle(e,"padding-top"),10),i=parseInt(r.getStyle(e,"padding-bottom"),10),a=e.clientHeight-n-i,o=r.getConstraintHeight(t);return isNaN(o)?a:Math.min(a,o)},r.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},r.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height=a+"px",i.style.width=r+"px"}},r.fontString=function(t,e,n){return e+" "+t+"px "+n},r.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},o=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},o=i.garbageCollect=[],i.font=e),t.font=e;var s=0;r.each(n,function(e){void 0!==e&&null!==e&&!0!==r.isArray(e)?s=r.measureText(t,a,o,s,e):r.isArray(e)&&r.each(e,function(e){void 0===e||null===e||r.isArray(e)||(s=r.measureText(t,a,o,s,e))})});var l=o.length/2;if(l>n.length){for(var u=0;u<l;u++)delete a[o[u]];o.splice(0,l)}return s},r.measureText=function(t,e,n,i,a){var r=e[a];return r||(r=e[a]=t.measureText(a).width,n.push(a)),r>i&&(i=r),i},r.numberOfLabelLines=function(t){var e=1;return r.each(t,function(t){r.isArray(t)&&t.length>e&&(e=t.length)}),e},r.color=i?function(t){return t instanceof CanvasGradient&&(t=a.global.defaultColor),i(t)}:function(t){return console.error("Color.js not found!"),t},r.getHoverColor=function(t){return t instanceof CanvasPattern?t:r.color(t).saturate(.5).darken(.1).rgbString()}}},{2:2,25:25,45:45}],28:[function(t,e,n){"use strict";function i(t,e){return t.native?{x:t.x,y:t.y}:u.getRelativePosition(t,e)}function a(t,e){var n,i,a,r,o;for(i=0,r=t.data.datasets.length;i<r;++i)if(t.isDatasetVisible(i))for(a=0,o=(n=t.getDatasetMeta(i)).data.length;a<o;++a){var s=n.data[a];s._view.skip||e(s)}}function r(t,e){var n=[];return a(t,function(t){t.inRange(e.x,e.y)&&n.push(t)}),n}function o(t,e,n,i){var r=Number.POSITIVE_INFINITY,o=[];return a(t,function(t){if(!n||t.inRange(e.x,e.y)){var a=t.getCenterPoint(),s=i(e,a);s<r?(o=[t],r=s):s===r&&o.push(t)}}),o}function s(t){var e=-1!==t.indexOf("x"),n=-1!==t.indexOf("y");return function(t,i){var a=e?Math.abs(t.x-i.x):0,r=n?Math.abs(t.y-i.y):0;return Math.sqrt(Math.pow(a,2)+Math.pow(r,2))}}function l(t,e,n){var a=i(e,t);n.axis=n.axis||"x";var l=s(n.axis),u=n.intersect?r(t,a):o(t,a,!1,l),d=[];return u.length?(t.data.datasets.forEach(function(e,n){if(t.isDatasetVisible(n)){var i=t.getDatasetMeta(n).data[u[0]._index];i&&!i._view.skip&&d.push(i)}}),d):[]}var u=t(45);e.exports={modes:{single:function(t,e){var n=i(e,t),r=[];return a(t,function(t){if(t.inRange(n.x,n.y))return r.push(t),r}),r.slice(0,1)},label:l,index:l,dataset:function(t,e,n){var a=i(e,t);n.axis=n.axis||"xy";var l=s(n.axis),u=n.intersect?r(t,a):o(t,a,!1,l);return u.length>0&&(u=t.getDatasetMeta(u[0]._datasetIndex).data),u},"x-axis":function(t,e){return l(t,e,{intersect:!0})},point:function(t,e){return r(t,i(e,t))},nearest:function(t,e,n){var a=i(e,t);n.axis=n.axis||"xy";var r=s(n.axis),l=o(t,a,n.intersect,r);return l.length>1&&l.sort(function(t,e){var n=t.getArea()-e.getArea();return 0===n&&(n=t._datasetIndex-e._datasetIndex),n}),l.slice(0,1)},x:function(t,e,n){var r=i(e,t),o=[],s=!1;return a(t,function(t){t.inXRange(r.x)&&o.push(t),t.inRange(r.x,r.y)&&(s=!0)}),n.intersect&&!s&&(o=[]),o},y:function(t,e,n){var r=i(e,t),o=[],s=!1;return a(t,function(t){t.inYRange(r.y)&&o.push(t),t.inRange(r.x,r.y)&&(s=!0)}),n.intersect&&!s&&(o=[]),o}}}},{45:45}],29:[function(t,e,n){"use strict";t(25)._set("global",{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},layout:{padding:{top:0,right:0,bottom:0,left:0}}}),e.exports=function(){var t=function(t,e){return this.construct(t,e),this};return t.Chart=t,t}},{25:25}],30:[function(t,e,n){"use strict";var i=t(45);e.exports=function(t){function e(t,e){return i.where(t,function(t){return t.position===e})}function n(t,e){t.forEach(function(t,e){return t._tmpIndex_=e,t}),t.sort(function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i._tmpIndex_-a._tmpIndex_:i.weight-a.weight}),t.forEach(function(t){delete t._tmpIndex_})}t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,t.boxes.push(e)},removeBox:function(t,e){var n=t.boxes?t.boxes.indexOf(e):-1;-1!==n&&t.boxes.splice(n,1)},configure:function(t,e,n){for(var i,a=["fullWidth","position","weight"],r=a.length,o=0;o<r;++o)i=a[o],n.hasOwnProperty(i)&&(e[i]=n[i])},update:function(t,a,r){function o(t){var e=i.findNextWhere(D,function(e){return e.box===t});if(e)if(t.isHorizontal()){var n={left:Math.max(A,C),right:Math.max(O,P),top:0,bottom:0};t.update(t.fullWidth?b:M,x/2,n)}else t.update(e.minSize.width,S)}function s(t){t.isHorizontal()?(t.left=t.fullWidth?d:A,t.right=t.fullWidth?a-c:A+M,t.top=B,t.bottom=B+t.height,B=t.bottom):(t.left=z,t.right=z+t.width,t.top=F,t.bottom=F+S,z=t.right)}if(t){var l=t.options.layout||{},u=i.options.toPadding(l.padding),d=u.left,c=u.right,h=u.top,f=u.bottom,g=e(t.boxes,"left"),m=e(t.boxes,"right"),p=e(t.boxes,"top"),v=e(t.boxes,"bottom"),y=e(t.boxes,"chartArea");n(g,!0),n(m,!1),n(p,!0),n(v,!1);var b=a-d-c,x=r-h-f,_=x/2,k=(a-b/2)/(g.length+m.length),w=(r-_)/(p.length+v.length),M=b,S=x,D=[];i.each(g.concat(m,p,v),function(t){var e,n=t.isHorizontal();n?(e=t.update(t.fullWidth?b:M,w),S-=e.height):(e=t.update(k,_),M-=e.width),D.push({horizontal:n,minSize:e,box:t})});var C=0,P=0,T=0,I=0;i.each(p.concat(v),function(t){if(t.getPadding){var e=t.getPadding();C=Math.max(C,e.left),P=Math.max(P,e.right)}}),i.each(g.concat(m),function(t){if(t.getPadding){var e=t.getPadding();T=Math.max(T,e.top),I=Math.max(I,e.bottom)}});var A=d,O=c,F=h,R=f;i.each(g.concat(m),o),i.each(g,function(t){A+=t.width}),i.each(m,function(t){O+=t.width}),i.each(p.concat(v),o),i.each(p,function(t){F+=t.height}),i.each(v,function(t){R+=t.height}),i.each(g.concat(m),function(t){var e=i.findNextWhere(D,function(e){return e.box===t}),n={left:0,right:0,top:F,bottom:R};e&&t.update(e.minSize.width,S,n)}),A=d,O=c,F=h,R=f,i.each(g,function(t){A+=t.width}),i.each(m,function(t){O+=t.width}),i.each(p,function(t){F+=t.height}),i.each(v,function(t){R+=t.height});var L=Math.max(C-A,0);A+=L,O+=Math.max(P-O,0);var W=Math.max(T-F,0);F+=W,R+=Math.max(I-R,0);var Y=r-F-R,N=a-A-O;N===M&&Y===S||(i.each(g,function(t){t.height=Y}),i.each(m,function(t){t.height=Y}),i.each(p,function(t){t.fullWidth||(t.width=N)}),i.each(v,function(t){t.fullWidth||(t.width=N)}),S=Y,M=N);var z=d+L,B=h+W;i.each(g.concat(p),s),z+=M,B+=S,i.each(m,s),i.each(v,s),t.chartArea={left:A,top:F,right:A+M,bottom:F+S},i.each(y,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(M,S)})}}}}},{45:45}],31:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45);i._set("global",{plugins:{}}),e.exports=function(t){t.plugins={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){-1===e.indexOf(t)&&e.push(t)}),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var n=e.indexOf(t);-1!==n&&e.splice(n,1)}),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e,n){var i,a,r,o,s,l=this.descriptors(t),u=l.length;for(i=0;i<u;++i)if(a=l[i],r=a.plugin,"function"==typeof(s=r[e])&&((o=[t].concat(n||[])).push(a.options),!1===s.apply(r,o)))return!1;return!0},descriptors:function(t){var e=t._plugins||(t._plugins={});if(e.id===this._cacheId)return e.descriptors;var n=[],a=[],o=t&&t.config||{},s=o.options&&o.options.plugins||{};return this._plugins.concat(o.plugins||[]).forEach(function(t){if(-1===n.indexOf(t)){var e=t.id,o=s[e];!1!==o&&(!0===o&&(o=r.clone(i.global.plugins[e])),n.push(t),a.push({plugin:t,options:o||{}}))}}),e.descriptors=a,e.id=this._cacheId,a}},t.pluginService=t.plugins,t.PluginBase=a.extend({})}},{25:25,26:26,45:45}],32:[function(t,e,n){"use strict";function i(t){var e,n,i=[];for(e=0,n=t.length;e<n;++e)i.push(t[e].label);return i}function a(t,e,n){var i=t.getPixelForTick(e);return n&&(i-=0===e?(t.getPixelForTick(1)-i)/2:(i-t.getPixelForTick(e-1))/2),i}var r=t(25),o=t(26),s=t(45),l=t(34);r._set("scale",{display:!0,position:"left",offset:!1,gridLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",zeroLineBorderDash:[],zeroLineBorderDashOffset:0,offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{display:!1,labelString:"",lineHeight:1.2,padding:{top:4,bottom:4}},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:0,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:l.formatters.values,minor:{},major:{}}}),e.exports=function(t){function e(t,e,n){return s.isArray(e)?s.longestText(t,n,e):t.measureText(e).width}function n(t){var e=s.valueOrDefault,n=r.global,i=e(t.fontSize,n.defaultFontSize),a=e(t.fontStyle,n.defaultFontStyle),o=e(t.fontFamily,n.defaultFontFamily);return{size:i,style:a,family:o,font:s.fontString(i,a,o)}}function l(t){return s.options.toLineHeight(s.valueOrDefault(t.lineHeight,1.2),s.valueOrDefault(t.fontSize,r.global.defaultFontSize))}t.Scale=o.extend({getPadding:function(){var t=this;return{left:t.paddingLeft||0,top:t.paddingTop||0,right:t.paddingRight||0,bottom:t.paddingBottom||0}},getTicks:function(){return this._ticks},mergeTicksOptions:function(){var t=this.options.ticks;!1===t.minor&&(t.minor={display:!1}),!1===t.major&&(t.major={display:!1});for(var e in t)"major"!==e&&"minor"!==e&&(void 0===t.minor[e]&&(t.minor[e]=t[e]),void 0===t.major[e]&&(t.major[e]=t[e]))},beforeUpdate:function(){s.callback(this.options.beforeUpdate,[this])},update:function(t,e,n){var i,a,r,o,l,u,d=this;for(d.beforeUpdate(),d.maxWidth=t,d.maxHeight=e,d.margins=s.extend({left:0,right:0,top:0,bottom:0},n),d.longestTextCache=d.longestTextCache||{},d.beforeSetDimensions(),d.setDimensions(),d.afterSetDimensions(),d.beforeDataLimits(),d.determineDataLimits(),d.afterDataLimits(),d.beforeBuildTicks(),l=d.buildTicks()||[],d.afterBuildTicks(),d.beforeTickToLabelConversion(),r=d.convertTicksToLabels(l)||d.ticks,d.afterTickToLabelConversion(),d.ticks=r,i=0,a=r.length;i<a;++i)o=r[i],(u=l[i])?u.label=o:l.push(u={label:o,major:!1});return d._ticks=l,d.beforeCalculateTickRotation(),d.calculateTickRotation(),d.afterCalculateTickRotation(),d.beforeFit(),d.fit(),d.afterFit(),d.afterUpdate(),d.minSize},afterUpdate:function(){s.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){s.callback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){s.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){s.callback(this.options.beforeDataLimits,[this])},determineDataLimits:s.noop,afterDataLimits:function(){s.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){s.callback(this.options.beforeBuildTicks,[this])},buildTicks:s.noop,afterBuildTicks:function(){s.callback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){s.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this,e=t.options.ticks;t.ticks=t.ticks.map(e.userCallback||e.callback,this)},afterTickToLabelConversion:function(){s.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){s.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t=this,e=t.ctx,a=t.options.ticks,r=i(t._ticks),o=n(a);e.font=o.font;var l=a.minRotation||0;if(r.length&&t.options.display&&t.isHorizontal())for(var u,d=s.longestText(e,o.font,r,t.longestTextCache),c=d,h=t.getPixelForTick(1)-t.getPixelForTick(0)-6;c>h&&l<a.maxRotation;){var f=s.toRadians(l);if(u=Math.cos(f),Math.sin(f)*d>t.maxHeight){l--;break}l++,c=u*d}t.labelRotation=l},afterCalculateTickRotation:function(){s.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){s.callback(this.options.beforeFit,[this])},fit:function(){var t=this,a=t.minSize={width:0,height:0},r=i(t._ticks),o=t.options,u=o.ticks,d=o.scaleLabel,c=o.gridLines,h=o.display,f=t.isHorizontal(),g=n(u),m=o.gridLines.tickMarkLength;if(a.width=f?t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:h&&c.drawTicks?m:0,a.height=f?h&&c.drawTicks?m:0:t.maxHeight,d.display&&h){var p=l(d)+s.options.toPadding(d.padding).height;f?a.height+=p:a.width+=p}if(u.display&&h){var v=s.longestText(t.ctx,g.font,r,t.longestTextCache),y=s.numberOfLabelLines(r),b=.5*g.size,x=t.options.ticks.padding;if(f){t.longestLabelWidth=v;var _=s.toRadians(t.labelRotation),k=Math.cos(_),w=Math.sin(_)*v+g.size*y+b*(y-1)+b;a.height=Math.min(t.maxHeight,a.height+w+x),t.ctx.font=g.font;var M=e(t.ctx,r[0],g.font),S=e(t.ctx,r[r.length-1],g.font);0!==t.labelRotation?(t.paddingLeft="bottom"===o.position?k*M+3:k*b+3,t.paddingRight="bottom"===o.position?k*b+3:k*S+3):(t.paddingLeft=M/2+3,t.paddingRight=S/2+3)}else u.mirror?v=0:v+=x+b,a.width=Math.min(t.maxWidth,a.width+v),t.paddingTop=g.size/2,t.paddingBottom=g.size/2}t.handleMargins(),t.width=a.width,t.height=a.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){s.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(s.isNullOrUndef(t))return NaN;if("number"==typeof t&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},getLabelForIndex:s.noop,getPixelForValue:s.noop,getValueForPixel:s.noop,getPixelForTick:function(t){var e=this,n=e.options.offset;if(e.isHorizontal()){var i=(e.width-(e.paddingLeft+e.paddingRight))/Math.max(e._ticks.length-(n?0:1),1),a=i*t+e.paddingLeft;n&&(a+=i/2);var r=e.left+Math.round(a);return r+=e.isFullWidth()?e.margins.left:0}var o=e.height-(e.paddingTop+e.paddingBottom);return e.top+t*(o/(e._ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var n=(e.width-(e.paddingLeft+e.paddingRight))*t+e.paddingLeft,i=e.left+Math.round(n);return i+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this,e=t.min,n=t.max;return t.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0},_autoSkip:function(t){var e,n,i,a,r=this,o=r.isHorizontal(),l=r.options.ticks.minor,u=t.length,d=s.toRadians(r.labelRotation),c=Math.cos(d),h=r.longestLabelWidth*c,f=[];for(l.maxTicksLimit&&(a=l.maxTicksLimit),o&&(e=!1,(h+l.autoSkipPadding)*u>r.width-(r.paddingLeft+r.paddingRight)&&(e=1+Math.floor((h+l.autoSkipPadding)*u/(r.width-(r.paddingLeft+r.paddingRight)))),a&&u>a&&(e=Math.max(e,Math.floor(u/a)))),n=0;n<u;n++)i=t[n],((e>1&&n%e>0||n%e==0&&n+e>=u)&&n!==u-1||s.isNullOrUndef(i.label))&&delete i.label,f.push(i);return f},draw:function(t){var e=this,i=e.options;if(i.display){var o=e.ctx,u=r.global,d=i.ticks.minor,c=i.ticks.major||d,h=i.gridLines,f=i.scaleLabel,g=0!==e.labelRotation,m=e.isHorizontal(),p=d.autoSkip?e._autoSkip(e.getTicks()):e.getTicks(),v=s.valueOrDefault(d.fontColor,u.defaultFontColor),y=n(d),b=s.valueOrDefault(c.fontColor,u.defaultFontColor),x=n(c),_=h.drawTicks?h.tickMarkLength:0,k=s.valueOrDefault(f.fontColor,u.defaultFontColor),w=n(f),M=s.options.toPadding(f.padding),S=s.toRadians(e.labelRotation),D=[],C="right"===i.position?e.left:e.right-_,P="right"===i.position?e.left+_:e.right,T="bottom"===i.position?e.top:e.bottom-_,I="bottom"===i.position?e.top+_:e.bottom;if(s.each(p,function(n,r){if(void 0!==n.label){var o,l,c,f,v=n.label;r===e.zeroLineIndex&&i.offset===h.offsetGridLines?(o=h.zeroLineWidth,l=h.zeroLineColor,c=h.zeroLineBorderDash,f=h.zeroLineBorderDashOffset):(o=s.valueAtIndexOrDefault(h.lineWidth,r),l=s.valueAtIndexOrDefault(h.color,r),c=s.valueOrDefault(h.borderDash,u.borderDash),f=s.valueOrDefault(h.borderDashOffset,u.borderDashOffset));var y,b,x,k,w,M,A,O,F,R,L="middle",W="middle",Y=d.padding;if(m){var N=_+Y;"bottom"===i.position?(W=g?"middle":"top",L=g?"right":"center",R=e.top+N):(W=g?"middle":"bottom",L=g?"left":"center",R=e.bottom-N);var z=a(e,r,h.offsetGridLines&&p.length>1);z<e.left&&(l="rgba(0,0,0,0)"),z+=s.aliasPixel(o),F=e.getPixelForTick(r)+d.labelOffset,y=x=w=A=z,b=T,k=I,M=t.top,O=t.bottom}else{var B,V="left"===i.position;d.mirror?(L=V?"left":"right",B=Y):(L=V?"right":"left",B=_+Y),F=V?e.right-B:e.left+B;var H=a(e,r,h.offsetGridLines&&p.length>1);H<e.top&&(l="rgba(0,0,0,0)"),H+=s.aliasPixel(o),R=e.getPixelForTick(r)+d.labelOffset,y=C,x=P,w=t.left,A=t.right,b=k=M=O=H}D.push({tx1:y,ty1:b,tx2:x,ty2:k,x1:w,y1:M,x2:A,y2:O,labelX:F,labelY:R,glWidth:o,glColor:l,glBorderDash:c,glBorderDashOffset:f,rotation:-1*S,label:v,major:n.major,textBaseline:W,textAlign:L})}}),s.each(D,function(t){if(h.display&&(o.save(),o.lineWidth=t.glWidth,o.strokeStyle=t.glColor,o.setLineDash&&(o.setLineDash(t.glBorderDash),o.lineDashOffset=t.glBorderDashOffset),o.beginPath(),h.drawTicks&&(o.moveTo(t.tx1,t.ty1),o.lineTo(t.tx2,t.ty2)),h.drawOnChartArea&&(o.moveTo(t.x1,t.y1),o.lineTo(t.x2,t.y2)),o.stroke(),o.restore()),d.display){o.save(),o.translate(t.labelX,t.labelY),o.rotate(t.rotation),o.font=t.major?x.font:y.font,o.fillStyle=t.major?b:v,o.textBaseline=t.textBaseline,o.textAlign=t.textAlign;var e=t.label;if(s.isArray(e))for(var n=0,i=0;n<e.length;++n)o.fillText(""+e[n],0,i),i+=1.5*y.size;else o.fillText(e,0,0);o.restore()}}),f.display){var A,O,F=0,R=l(f)/2;if(m)A=e.left+(e.right-e.left)/2,O="bottom"===i.position?e.bottom-R-M.bottom:e.top+R+M.top;else{var L="left"===i.position;A=L?e.left+R+M.top:e.right-R-M.top,O=e.top+(e.bottom-e.top)/2,F=L?-.5*Math.PI:.5*Math.PI}o.save(),o.translate(A,O),o.rotate(F),o.textAlign="center",o.textBaseline="middle",o.fillStyle=k,o.font=w.font,o.fillText(f.labelString,0,0),o.restore()}if(h.drawBorder){o.lineWidth=s.valueAtIndexOrDefault(h.lineWidth,0),o.strokeStyle=s.valueAtIndexOrDefault(h.color,0);var W=e.left,Y=e.right,N=e.top,z=e.bottom,B=s.aliasPixel(o.lineWidth);m?(N=z="top"===i.position?e.bottom:e.top,N+=B,z+=B):(W=Y="left"===i.position?e.right:e.left,W+=B,Y+=B),o.beginPath(),o.moveTo(W,N),o.lineTo(Y,z),o.stroke()}}}})}},{25:25,26:26,34:34,45:45}],33:[function(t,e,n){"use strict";var i=t(25),a=t(45);e.exports=function(t){t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,e,n){this.constructors[t]=e,this.defaults[t]=a.clone(n)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(t){return this.defaults.hasOwnProperty(t)?a.merge({},[i.scale,this.defaults[t]]):{}},updateScaleDefaults:function(t,e){var n=this;n.defaults.hasOwnProperty(t)&&(n.defaults[t]=a.extend(n.defaults[t],e))},addScalesToLayout:function(e){a.each(e.scales,function(n){n.fullWidth=n.options.fullWidth,n.position=n.options.position,n.weight=n.options.weight,t.layoutService.addBox(e,n)})}}}},{25:25,45:45}],34:[function(t,e,n){"use strict";var i=t(45);e.exports={generators:{linear:function(t,e){var n,a=[];if(t.stepSize&&t.stepSize>0)n=t.stepSize;else{var r=i.niceNum(e.max-e.min,!1);n=i.niceNum(r/(t.maxTicks-1),!0)}var o=Math.floor(e.min/n)*n,s=Math.ceil(e.max/n)*n;t.min&&t.max&&t.stepSize&&i.almostWhole((t.max-t.min)/t.stepSize,n/1e3)&&(o=t.min,s=t.max);var l=(s-o)/n;l=i.almostEquals(l,Math.round(l),n/1e3)?Math.round(l):Math.ceil(l),a.push(void 0!==t.min?t.min:o);for(var u=1;u<l;++u)a.push(o+u*n);return a.push(void 0!==t.max?t.max:s),a},logarithmic:function(t,e){var n,a,r=[],o=i.valueOrDefault,s=o(t.min,Math.pow(10,Math.floor(i.log10(e.min)))),l=Math.floor(i.log10(e.max)),u=Math.ceil(e.max/Math.pow(10,l));0===s?(n=Math.floor(i.log10(e.minNotZero)),a=Math.floor(e.minNotZero/Math.pow(10,n)),r.push(s),s=a*Math.pow(10,n)):(n=Math.floor(i.log10(s)),a=Math.floor(s/Math.pow(10,n)));do{r.push(s),10===++a&&(a=1,++n),s=a*Math.pow(10,n)}while(n<l||n===l&&a<u);var d=o(t.max,s);return r.push(d),r}},formatters:{values:function(t){return i.isArray(t)?t:""+t},linear:function(t,e,n){var a=n.length>3?n[2]-n[1]:n[1]-n[0];Math.abs(a)>1&&t!==Math.floor(t)&&(a=t-Math.floor(t));var r=i.log10(Math.abs(a)),o="";if(0!==t){var s=-1*Math.floor(r);s=Math.max(Math.min(s,20),0),o=t.toFixed(s)}else o="0";return o},logarithmic:function(t,e,n){var a=t/Math.pow(10,Math.floor(i.log10(t)));return 0===t?"0":1===a||2===a||5===a||0===e||e===n.length-1?t.toExponential():""}}}},{45:45}],35:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45);i._set("global",{tooltips:{enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:r.noop,title:function(t,e){var n="",i=e.labels,a=i?i.length:0;if(t.length>0){var r=t[0];r.xLabel?n=r.xLabel:a>0&&r.index<a&&(n=i[r.index])}return n},afterTitle:r.noop,beforeBody:r.noop,beforeLabel:r.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n&&(n+=": "),n+=t.yLabel},labelColor:function(t,e){var n=e.getDatasetMeta(t.datasetIndex).data[t.index]._view;return{borderColor:n.borderColor,backgroundColor:n.backgroundColor}},labelTextColor:function(){return this._options.bodyFontColor},afterLabel:r.noop,afterBody:r.noop,beforeFooter:r.noop,footer:r.noop,afterFooter:r.noop}}}),e.exports=function(t){function e(t,e){var n=r.color(t);return n.alpha(e*n.alpha()).rgbaString()}function n(t,e){return e&&(r.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function o(t){var e=t._xScale,n=t._yScale||t._scale,i=t._index,a=t._datasetIndex;return{xLabel:e?e.getLabelForIndex(i,a):"",yLabel:n?n.getLabelForIndex(i,a):"",index:i,datasetIndex:a,x:t._model.x,y:t._model.y}}function s(t){var e=i.global,n=r.valueOrDefault;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,bodyFontColor:t.bodyFontColor,_bodyFontFamily:n(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:n(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:n(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:n(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:n(t.titleFontStyle,e.defaultFontStyle),titleFontSize:n(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:n(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:n(t.footerFontStyle,e.defaultFontStyle),footerFontSize:n(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function l(t,e){var n=t._chart.ctx,i=2*e.yPadding,a=0,o=e.body,s=o.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);s+=e.beforeBody.length+e.afterBody.length;var l=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;i+=l*d,i+=l?(l-1)*e.titleSpacing:0,i+=l?e.titleMarginBottom:0,i+=s*c,i+=s?(s-1)*e.bodySpacing:0,i+=u?e.footerMarginTop:0,i+=u*h,i+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){a=Math.max(a,n.measureText(t).width+f)};return n.font=r.fontString(d,e._titleFontStyle,e._titleFontFamily),r.each(e.title,g),n.font=r.fontString(c,e._bodyFontStyle,e._bodyFontFamily),r.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,r.each(o,function(t){r.each(t.before,g),r.each(t.lines,g),r.each(t.after,g)}),f=0,n.font=r.fontString(h,e._footerFontStyle,e._footerFontFamily),r.each(e.footer,g),a+=2*e.xPadding,{width:a,height:i}}function u(t,e){var n=t._model,i=t._chart,a=t._chart.chartArea,r="center",o="center";n.y<e.height?o="top":n.y>i.height-e.height&&(o="bottom");var s,l,u,d,c,h=(a.left+a.right)/2,f=(a.top+a.bottom)/2;"center"===o?(s=function(t){return t<=h},l=function(t){return t>h}):(s=function(t){return t<=e.width/2},l=function(t){return t>=i.width-e.width/2}),u=function(t){return t+e.width>i.width},d=function(t){return t-e.width<0},c=function(t){return t<=f?"top":"bottom"},s(n.x)?(r="left",u(n.x)&&(r="center",o=c(n.y))):l(n.x)&&(r="right",d(n.x)&&(r="center",o=c(n.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:r,yAlign:g.yAlign?g.yAlign:o}}function d(t,e,n){var i=t.x,a=t.y,r=t.caretSize,o=t.caretPadding,s=t.cornerRadius,l=n.xAlign,u=n.yAlign,d=r+o,c=s+o;return"right"===l?i-=e.width:"center"===l&&(i-=e.width/2),"top"===u?a+=d:a-="bottom"===u?e.height+d:e.height/2,"center"===u?"left"===l?i+=d:"right"===l&&(i-=d):"left"===l?i-=c:"right"===l&&(i+=c),{x:i,y:a}}t.Tooltip=a.extend({initialize:function(){this._model=s(this._options)},getTitle:function(){var t=this,e=t._options.callbacks,i=e.beforeTitle.apply(t,arguments),a=e.title.apply(t,arguments),r=e.afterTitle.apply(t,arguments),o=[];return o=n(o,i),o=n(o,a),o=n(o,r)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return r.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,e){var i=this,a=i._options.callbacks,o=[];return r.each(t,function(t){var r={before:[],lines:[],after:[]};n(r.before,a.beforeLabel.call(i,t,e)),n(r.lines,a.label.call(i,t,e)),n(r.after,a.afterLabel.call(i,t,e)),o.push(r)}),o},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return r.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this,e=t._options.callbacks,i=e.beforeFooter.apply(t,arguments),a=e.footer.apply(t,arguments),r=e.afterFooter.apply(t,arguments),o=[];return o=n(o,i),o=n(o,a),o=n(o,r)},update:function(e){var n,i,a=this,c=a._options,h=a._model,f=a._model=s(c),g=a._active,m=a._data,p={xAlign:h.xAlign,yAlign:h.yAlign},v={x:h.x,y:h.y},y={width:h.width,height:h.height},b={x:h.caretX,y:h.caretY};if(g.length){f.opacity=1;var x=[],_=[];b=t.Tooltip.positioners[c.position](g,a._eventPosition);var k=[];for(n=0,i=g.length;n<i;++n)k.push(o(g[n]));c.filter&&(k=k.filter(function(t){return c.filter(t,m)})),c.itemSort&&(k=k.sort(function(t,e){return c.itemSort(t,e,m)})),r.each(k,function(t){x.push(c.callbacks.labelColor.call(a,t,a._chart)),_.push(c.callbacks.labelTextColor.call(a,t,a._chart))}),f.title=a.getTitle(k,m),f.beforeBody=a.getBeforeBody(k,m),f.body=a.getBody(k,m),f.afterBody=a.getAfterBody(k,m),f.footer=a.getFooter(k,m),f.x=Math.round(b.x),f.y=Math.round(b.y),f.caretPadding=c.caretPadding,f.labelColors=x,f.labelTextColors=_,f.dataPoints=k,v=d(f,y=l(this,f),p=u(this,y))}else f.opacity=0;return f.xAlign=p.xAlign,f.yAlign=p.yAlign,f.x=v.x,f.y=v.y,f.width=y.width,f.height=y.height,f.caretX=b.x,f.caretY=b.y,a._model=f,e&&c.custom&&c.custom.call(a,f),a},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,c=n.xAlign,h=n.yAlign,f=t.x,g=t.y,m=e.width,p=e.height;if("center"===h)s=g+p/2,"left"===c?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+m)+u,r=i,o=s-u,l=s+u);else if("left"===c?(i=(a=f+d+u)-u,r=a+u):"right"===c?(i=(a=f+m-d-u)-u,r=a+u):(i=(a=f+m/2)-u,r=a+u),"top"===h)s=(o=g)-u,l=o;else{s=(o=g+p)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,n,i,a){var o=n.title;if(o.length){i.textAlign=n._titleAlign,i.textBaseline="top";var s=n.titleFontSize,l=n.titleSpacing;i.fillStyle=e(n.titleFontColor,a),i.font=r.fontString(s,n._titleFontStyle,n._titleFontFamily);var u,d;for(u=0,d=o.length;u<d;++u)i.fillText(o[u],t.x,t.y),t.y+=s+l,u+1===o.length&&(t.y+=n.titleMarginBottom-l)}},drawBody:function(t,n,i,a){var o=n.bodyFontSize,s=n.bodySpacing,l=n.body;i.textAlign=n._bodyAlign,i.textBaseline="top",i.font=r.fontString(o,n._bodyFontStyle,n._bodyFontFamily);var u=0,d=function(e){i.fillText(e,t.x+u,t.y),t.y+=o+s};r.each(n.beforeBody,d);var c=n.displayColors;u=c?o+2:0,r.each(l,function(s,l){r.each(s.before,d),r.each(s.lines,function(r){if(c){i.fillStyle=e(n.legendColorBackground,a),i.fillRect(t.x,t.y,o,o),i.lineWidth=1,i.strokeStyle=e(n.labelColors[l].borderColor,a),i.strokeRect(t.x,t.y,o,o),i.fillStyle=e(n.labelColors[l].backgroundColor,a),i.fillRect(t.x+1,t.y+1,o-2,o-2);var s=e(n.labelTextColors[l],a);i.fillStyle=s}d(r)}),r.each(s.after,d)}),u=0,r.each(n.afterBody,d),t.y-=s},drawFooter:function(t,n,i,a){var o=n.footer;o.length&&(t.y+=n.footerMarginTop,i.textAlign=n._footerAlign,i.textBaseline="top",i.fillStyle=e(n.footerFontColor,a),i.font=r.fontString(n.footerFontSize,n._footerFontStyle,n._footerFontFamily),r.each(o,function(e){i.fillText(e,t.x,t.y),t.y+=n.footerFontSize+n.footerSpacing}))},drawBackground:function(t,n,i,a,r){i.fillStyle=e(n.backgroundColor,r),i.strokeStyle=e(n.borderColor,r),i.lineWidth=n.borderWidth;var o=n.xAlign,s=n.yAlign,l=t.x,u=t.y,d=a.width,c=a.height,h=n.cornerRadius;i.beginPath(),i.moveTo(l+h,u),"top"===s&&this.drawCaret(t,a),i.lineTo(l+d-h,u),i.quadraticCurveTo(l+d,u,l+d,u+h),"center"===s&&"right"===o&&this.drawCaret(t,a),i.lineTo(l+d,u+c-h),i.quadraticCurveTo(l+d,u+c,l+d-h,u+c),"bottom"===s&&this.drawCaret(t,a),i.lineTo(l+h,u+c),i.quadraticCurveTo(l,u+c,l,u+c-h),"center"===s&&"left"===o&&this.drawCaret(t,a),i.lineTo(l,u+h),i.quadraticCurveTo(l,u,l+h,u),i.closePath(),i.fill(),n.borderWidth>0&&i.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(this.drawBackground(i,e,t,n,a),i.x+=e.xPadding,i.y+=e.yPadding,this.drawTitle(i,e,t,a),this.drawBody(i,e,t,a),this.drawFooter(i,e,t,a))}},handleEvent:function(t){var e=this,n=e._options,i=!1;if(e._lastActive=e._lastActive||[],"mouseout"===t.type?e._active=[]:e._active=e._chart.getElementsAtEventForMode(t,n.mode,n),!(i=!r.arrayEquals(e._active,e._lastActive)))return!1;if(e._lastActive=e._active,n.enabled||n.custom){e._eventPosition={x:t.x,y:t.y};var a=e._model;e.update(!0),e.pivot(),i|=a.x!==e._model.x||a.y!==e._model.y}return i}}),t.Tooltip.positioners={average:function(t){if(!t.length)return!1;var e,n,i=0,a=0,r=0;for(e=0,n=t.length;e<n;++e){var o=t[e];if(o&&o.hasValue()){var s=o.tooltipPosition();i+=s.x,a+=s.y,++r}}return{x:Math.round(i/r),y:Math.round(a/r)}},nearest:function(t,e){var n,i,a,o=e.x,s=e.y,l=Number.POSITIVE_INFINITY;for(n=0,i=t.length;n<i;++n){var u=t[n];if(u&&u.hasValue()){var d=u.getCenterPoint(),c=r.distanceBetweenPoints(e,d);c<l&&(l=c,a=u)}}if(a){var h=a.tooltipPosition();o=h.x,s=h.y}return{x:o,y:s}}}}},{25:25,26:26,45:45}],36:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45);i._set("global",{elements:{arc:{backgroundColor:i.global.defaultColor,borderColor:"#fff",borderWidth:2}}}),e.exports=a.extend({inLabelRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2)},inRange:function(t,e){var n=this._view;if(n){for(var i=r.getAngleFromPoint(n,{x:t,y:e}),a=i.angle,o=i.distance,s=n.startAngle,l=n.endAngle;l<s;)l+=2*Math.PI;for(;a>l;)a-=2*Math.PI;for(;a<s;)a+=2*Math.PI;var u=a>=s&&a<=l,d=o>=n.innerRadius&&o<=n.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t=this._chart.ctx,e=this._view,n=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,n,i),t.arc(e.x,e.y,e.innerRadius,i,n,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})},{25:25,26:26,45:45}],37:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45),o=i.global;i._set("global",{elements:{line:{tension:.4,backgroundColor:o.defaultColor,borderWidth:3,borderColor:o.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}}),e.exports=a.extend({draw:function(){var t,e,n,i,a=this,s=a._view,l=a._chart.ctx,u=s.spanGaps,d=a._children.slice(),c=o.elements.line,h=-1;for(a._loop&&d.length&&d.push(d[0]),l.save(),l.lineCap=s.borderCapStyle||c.borderCapStyle,l.setLineDash&&l.setLineDash(s.borderDash||c.borderDash),l.lineDashOffset=s.borderDashOffset||c.borderDashOffset,l.lineJoin=s.borderJoinStyle||c.borderJoinStyle,l.lineWidth=s.borderWidth||c.borderWidth,l.strokeStyle=s.borderColor||o.defaultColor,l.beginPath(),h=-1,t=0;t<d.length;++t)e=d[t],n=r.previousItem(d,t),i=e._view,0===t?i.skip||(l.moveTo(i.x,i.y),h=t):(n=-1===h?n:d[h],i.skip||(h!==t-1&&!u||-1===h?l.moveTo(i.x,i.y):r.canvas.lineTo(l,n._view,e._view),h=t));l.stroke(),l.restore()}})},{25:25,26:26,45:45}],38:[function(t,e,n){"use strict";function i(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hitRadius,2)}var a=t(25),r=t(26),o=t(45),s=a.global.defaultColor;a._set("global",{elements:{point:{radius:3,pointStyle:"circle",backgroundColor:s,borderColor:s,borderWidth:1,hitRadius:1,hoverRadius:4,hoverBorderWidth:1}}}),e.exports=r.extend({inRange:function(t,e){var n=this._view;return!!n&&Math.pow(t-n.x,2)+Math.pow(e-n.y,2)<Math.pow(n.hitRadius+n.radius,2)},inLabelRange:i,inXRange:i,inYRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.y,2)<Math.pow(e.radius+e.hitRadius,2)},getCenterPoint:function(){var t=this._view;return{x:t.x,y:t.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(t){var e=this._view,n=this._model,i=this._chart.ctx,r=e.pointStyle,l=e.radius,u=e.x,d=e.y,c=o.color,h=0;e.skip||(i.strokeStyle=e.borderColor||s,i.lineWidth=o.valueOrDefault(e.borderWidth,a.global.elements.point.borderWidth),i.fillStyle=e.backgroundColor||s,void 0!==t&&(n.x<t.left||1.01*t.right<n.x||n.y<t.top||1.01*t.bottom<n.y)&&(n.x<t.left?h=(u-n.x)/(t.left-n.x):1.01*t.right<n.x?h=(n.x-u)/(n.x-t.right):n.y<t.top?h=(d-n.y)/(t.top-n.y):1.01*t.bottom<n.y&&(h=(n.y-d)/(n.y-t.bottom)),h=Math.round(100*h)/100,i.strokeStyle=c(i.strokeStyle).alpha(h).rgbString(),i.fillStyle=c(i.fillStyle).alpha(h).rgbString()),o.canvas.drawPoint(i,r,l,u,d))}})},{25:25,26:26,45:45}],39:[function(t,e,n){"use strict";function i(t){return void 0!==t._view.width}function a(t){var e,n,a,r,o=t._view;if(i(t)){var s=o.width/2;e=o.x-s,n=o.x+s,a=Math.min(o.y,o.base),r=Math.max(o.y,o.base)}else{var l=o.height/2;e=Math.min(o.x,o.base),n=Math.max(o.x,o.base),a=o.y-l,r=o.y+l}return{left:e,top:a,right:n,bottom:r}}var r=t(25),o=t(26);r._set("global",{elements:{rectangle:{backgroundColor:r.global.defaultColor,borderColor:r.global.defaultColor,borderSkipped:"bottom",borderWidth:0}}}),e.exports=o.extend({draw:function(){function t(t){return v[(y+t)%4]}var e,n,i,a,r,o,s,l=this._chart.ctx,u=this._view,d=u.borderWidth;if(u.horizontal?(e=u.base,n=u.x,i=u.y-u.height/2,a=u.y+u.height/2,r=n>e?1:-1,o=1,s=u.borderSkipped||"left"):(e=u.x-u.width/2,n=u.x+u.width/2,i=u.y,r=1,o=(a=u.base)>i?1:-1,s=u.borderSkipped||"bottom"),d){var c=Math.min(Math.abs(e-n),Math.abs(i-a)),h=(d=d>c?c:d)/2,f=e+("left"!==s?h*r:0),g=n+("right"!==s?-h*r:0),m=i+("top"!==s?h*o:0),p=a+("bottom"!==s?-h*o:0);f!==g&&(i=m,a=p),m!==p&&(e=f,n=g)}l.beginPath(),l.fillStyle=u.backgroundColor,l.strokeStyle=u.borderColor,l.lineWidth=d;var v=[[e,a],[e,i],[n,i],[n,a]],y=["bottom","left","top","right"].indexOf(s,0);-1===y&&(y=0);var b=t(0);l.moveTo(b[0],b[1]);for(var x=1;x<4;x++)b=t(x),l.lineTo(b[0],b[1]);l.fill(),d&&l.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var n=!1;if(this._view){var i=a(this);n=t>=i.left&&t<=i.right&&e>=i.top&&e<=i.bottom}return n},inLabelRange:function(t,e){var n=this;if(!n._view)return!1;var r=a(n);return i(n)?t>=r.left&&t<=r.right:e>=r.top&&e<=r.bottom},inXRange:function(t){var e=a(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=a(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,e,n=this._view;return i(this)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})},{25:25,26:26}],40:[function(t,e,n){"use strict";e.exports={},e.exports.Arc=t(36),e.exports.Line=t(37),e.exports.Point=t(38),e.exports.Rectangle=t(39)},{36:36,37:37,38:38,39:39}],41:[function(t,e,n){"use strict";var i=t(42),n=e.exports={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,i/2),s=Math.min(r,a/2);t.moveTo(e+o,n),t.lineTo(e+i-o,n),t.quadraticCurveTo(e+i,n,e+i,n+s),t.lineTo(e+i,n+a-s),t.quadraticCurveTo(e+i,n+a,e+i-o,n+a),t.lineTo(e+o,n+a),t.quadraticCurveTo(e,n+a,e,n+a-s),t.lineTo(e,n+s),t.quadraticCurveTo(e,n,e+o,n)}else t.rect(e,n,i,a)},drawPoint:function(t,e,n,i,a){var r,o,s,l,u,d;if("object"!=typeof e||"[object HTMLImageElement]"!==(r=e.toString())&&"[object HTMLCanvasElement]"!==r){if(!(isNaN(n)||n<=0)){switch(e){default:t.beginPath(),t.arc(i,a,n,0,2*Math.PI),t.closePath(),t.fill();break;case"triangle":t.beginPath(),u=(o=3*n/Math.sqrt(3))*Math.sqrt(3)/2,t.moveTo(i-o/2,a+u/3),t.lineTo(i+o/2,a+u/3),t.lineTo(i,a-2*u/3),t.closePath(),t.fill();break;case"rect":d=1/Math.SQRT2*n,t.beginPath(),t.fillRect(i-d,a-d,2*d,2*d),t.strokeRect(i-d,a-d,2*d,2*d);break;case"rectRounded":var c=n/Math.SQRT2,h=i-c,f=a-c,g=Math.SQRT2*n;t.beginPath(),this.roundedRect(t,h,f,g,g,n/2),t.closePath(),t.fill();break;case"rectRot":d=1/Math.SQRT2*n,t.beginPath(),t.moveTo(i-d,a),t.lineTo(i,a+d),t.lineTo(i+d,a),t.lineTo(i,a-d),t.closePath(),t.fill();break;case"cross":t.beginPath(),t.moveTo(i,a+n),t.lineTo(i,a-n),t.moveTo(i-n,a),t.lineTo(i+n,a),t.closePath();break;case"crossRot":t.beginPath(),s=Math.cos(Math.PI/4)*n,l=Math.sin(Math.PI/4)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i-s,a+l),t.lineTo(i+s,a-l),t.closePath();break;case"star":t.beginPath(),t.moveTo(i,a+n),t.lineTo(i,a-n),t.moveTo(i-n,a),t.lineTo(i+n,a),s=Math.cos(Math.PI/4)*n,l=Math.sin(Math.PI/4)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i-s,a+l),t.lineTo(i+s,a-l),t.closePath();break;case"line":t.beginPath(),t.moveTo(i-n,a),t.lineTo(i+n,a),t.closePath();break;case"dash":t.beginPath(),t.moveTo(i,a),t.lineTo(i+n,a),t.closePath()}t.stroke()}}else t.drawImage(e,i-e.width/2,a-e.height/2,e.width,e.height)},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,n,i){if(n.steppedLine)return"after"===n.steppedLine&&!i||"after"!==n.steppedLine&&i?t.lineTo(e.x,n.y):t.lineTo(n.x,e.y),void t.lineTo(n.x,n.y);n.tension?t.bezierCurveTo(i?e.controlPointPreviousX:e.controlPointNextX,i?e.controlPointPreviousY:e.controlPointNextY,i?n.controlPointNextX:n.controlPointPreviousX,i?n.controlPointNextY:n.controlPointPreviousY,n.x,n.y):t.lineTo(n.x,n.y)}};i.clear=n.clear,i.drawRoundedRectangle=function(t){t.beginPath(),n.roundedRect.apply(n,arguments),t.closePath()}},{42:42}],42:[function(t,e,n){"use strict";var i={noop:function(){},uid:function(){var t=0;return function(){return t++}}(),isNullOrUndef:function(t){return null===t||void 0===t},isArray:Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,n){return i.valueOrDefault(i.isArray(t)?t[e]:t,n)},callback:function(t,e,n){if(t&&"function"==typeof t.call)return t.apply(n,e)},each:function(t,e,n,a){var r,o,s;if(i.isArray(t))if(o=t.length,a)for(r=o-1;r>=0;r--)e.call(n,t[r],r);else for(r=0;r<o;r++)e.call(n,t[r],r);else if(i.isObject(t))for(o=(s=Object.keys(t)).length,r=0;r<o;r++)e.call(n,t[s[r]],s[r])},arrayEquals:function(t,e){var n,a,r,o;if(!t||!e||t.length!==e.length)return!1;for(n=0,a=t.length;n<a;++n)if(r=t[n],o=e[n],r instanceof Array&&o instanceof Array){if(!i.arrayEquals(r,o))return!1}else if(r!==o)return!1;return!0},clone:function(t){if(i.isArray(t))return t.map(i.clone);if(i.isObject(t)){for(var e={},n=Object.keys(t),a=n.length,r=0;r<a;++r)e[n[r]]=i.clone(t[n[r]]);return e}return t},_merger:function(t,e,n,a){var r=e[t],o=n[t];i.isObject(r)&&i.isObject(o)?i.merge(r,o,a):e[t]=i.clone(o)},_mergerIf:function(t,e,n){var a=e[t],r=n[t];i.isObject(a)&&i.isObject(r)?i.mergeIf(a,r):e.hasOwnProperty(t)||(e[t]=i.clone(r))},merge:function(t,e,n){var a,r,o,s,l,u=i.isArray(e)?e:[e],d=u.length;if(!i.isObject(t))return t;for(a=(n=n||{}).merger||i._merger,r=0;r<d;++r)if(e=u[r],i.isObject(e))for(l=0,s=(o=Object.keys(e)).length;l<s;++l)a(o[l],t,e,n);return t},mergeIf:function(t,e){return i.merge(t,e,{merger:i._mergerIf})}};e.exports=i,i.callCallback=i.callback,i.indexOf=function(t,e,n){return Array.prototype.indexOf.call(t,e,n)},i.getValueOrDefault=i.valueOrDefault,i.getValueAtIndexOrDefault=i.valueAtIndexOrDefault},{}],43:[function(t,e,n){"use strict";var i=t(42),a={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return(t-=1)*t*t+1},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-((t-=1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return(t-=1)*t*t*t*t+1},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return 1-Math.cos(t*(Math.PI/2))},easeOutSine:function(t){return Math.sin(t*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t)-1)},easeInExpo:function(t){return 0===t?0:Math.pow(2,10*(t-1))},easeOutExpo:function(t){return 1===t?1:1-Math.pow(2,-10*t)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*--t))},easeInCirc:function(t){return t>=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-a.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*a.easeInBounce(2*t):.5*a.easeOutBounce(2*t-1)+.5}};e.exports={effects:a},i.easingEffects=a},{42:42}],44:[function(t,e,n){"use strict";var i=t(42);e.exports={toLineHeight:function(t,e){var n=(""+t).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!n||"normal"===n[1])return 1.2*e;switch(t=+n[2],n[3]){case"px":return t;case"%":t/=100}return e*t},toPadding:function(t){var e,n,a,r;return i.isObject(t)?(e=+t.top||0,n=+t.right||0,a=+t.bottom||0,r=+t.left||0):e=n=a=r=+t||0,{top:e,right:n,bottom:a,left:r,height:e+a,width:r+n}},resolve:function(t,e,n){var a,r,o;for(a=0,r=t.length;a<r;++a)if(void 0!==(o=t[a])&&(void 0!==e&&"function"==typeof o&&(o=o(e)),void 0!==n&&i.isArray(o)&&(o=o[n]),void 0!==o))return o}}},{42:42}],45:[function(t,e,n){"use strict";e.exports=t(42),e.exports.easing=t(43),e.exports.canvas=t(41),e.exports.options=t(44)},{41:41,42:42,43:43,44:44}],46:[function(t,e,n){e.exports={acquireContext:function(t){return t&&t.canvas&&(t=t.canvas),t&&t.getContext("2d")||null}}},{}],47:[function(t,e,n){"use strict";function i(t,e){var n=p.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}function a(t,e){var n=t.style,a=t.getAttribute("height"),r=t.getAttribute("width");if(t[v]={initial:{height:a,width:r,style:{display:n.display,height:n.height,width:n.width}}},n.display=n.display||"block",null===r||""===r){var o=i(t,"width");void 0!==o&&(t.width=o)}if(null===a||""===a)if(""===t.style.height)t.height=t.width/(e.options.aspectRatio||2);else{var s=i(t,"height");void 0!==o&&(t.height=s)}return t}function r(t,e,n){t.addEventListener(e,n,w)}function o(t,e,n){t.removeEventListener(e,n,w)}function s(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function l(t,e){var n=k[t.type]||t.type,i=p.getRelativePosition(t,e);return s(n,e,i.x,i.y,t)}function u(t,e){var n=!1,i=[];return function(){i=Array.prototype.slice.call(arguments),e=e||this,n||(n=!0,p.requestAnimFrame.call(window,function(){n=!1,t.apply(e,i)}))}}function d(t){var e=document.createElement("div"),n=y+"size-monitor",i="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;";e.style.cssText=i,e.className=n,e.innerHTML='<div class="'+n+'-expand" style="'+i+'"><div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div></div><div class="'+n+'-shrink" style="'+i+'"><div style="position:absolute;width:200%;height:200%;left:0; top:0"></div></div>';var a=e.childNodes[0],o=e.childNodes[1];e._reset=function(){a.scrollLeft=1e6,a.scrollTop=1e6,o.scrollLeft=1e6,o.scrollTop=1e6};var s=function(){e._reset(),t()};return r(a,"scroll",s.bind(a,"expand")),r(o,"scroll",s.bind(o,"shrink")),e}function c(t,e){var n=(t[v]||(t[v]={})).renderProxy=function(t){t.animationName===x&&e()};p.each(_,function(e){r(t,e,n)}),t.classList.add(b)}function h(t){var e=t[v]||{},n=e.renderProxy;n&&(p.each(_,function(e){o(t,e,n)}),delete e.renderProxy),t.classList.remove(b)}function f(t,e,n){var i=t[v]||(t[v]={}),a=i.resizer=d(u(function(){if(i.resizer)return e(s("resize",n))}));c(t,function(){if(i.resizer){var e=t.parentNode;e&&e!==a.parentNode&&e.insertBefore(a,e.firstChild),a._reset()}})}function g(t){var e=t[v]||{},n=e.resizer;delete e.resizer,h(t),n&&n.parentNode&&n.parentNode.removeChild(n)}function m(t,e){var n=t._style||document.createElement("style");t._style||(t._style=n,e="/* Chart.js */\n"+e,n.setAttribute("type","text/css"),document.getElementsByTagName("head")[0].appendChild(n)),n.appendChild(document.createTextNode(e))}var p=t(45),v="$chartjs",y="chartjs-",b=y+"render-monitor",x=y+"render-animation",_=["animationstart","webkitAnimationStart"],k={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},w=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};e.exports={_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,initialize:function(){var t="from{opacity:0.99}to{opacity:1}";m(this,"@-webkit-keyframes "+x+"{"+t+"}@keyframes "+x+"{"+t+"}."+b+"{-webkit-animation:"+x+" 0.001s;animation:"+x+" 0.001s;}")},acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var n=t&&t.getContext&&t.getContext("2d");return n&&n.canvas===t?(a(t,e),n):null},releaseContext:function(t){var e=t.canvas;if(e[v]){var n=e[v].initial;["height","width"].forEach(function(t){var i=n[t];p.isNullOrUndef(i)?e.removeAttribute(t):e.setAttribute(t,i)}),p.each(n.style||{},function(t,n){e.style[n]=t}),e.width=e.width,delete e[v]}},addEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=n[v]||(n[v]={});r(i,e,(a.proxies||(a.proxies={}))[t.id+"_"+e]=function(e){n(l(e,t))})}else f(i,n,t)},removeEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=((n[v]||{}).proxies||{})[t.id+"_"+e];a&&o(i,e,a)}else g(i)}},p.addEvent=r,p.removeEvent=o},{45:45}],48:[function(t,e,n){"use strict";var i=t(45),a=t(46),r=t(47),o=r._enabled?r:a;e.exports=i.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},o)},{45:45,46:46,47:47}],49:[function(t,e,n){"use strict";var i=t(25),a=t(40),r=t(45);i._set("global",{plugins:{filler:{propagate:!0}}}),e.exports=function(){function t(t,e,n){var i,a=t._model||{},r=a.fill;if(void 0===r&&(r=!!a.backgroundColor),!1===r||null===r)return!1;if(!0===r)return"origin";if(i=parseFloat(r,10),isFinite(i)&&Math.floor(i)===i)return"-"!==r[0]&&"+"!==r[0]||(i=e+i),!(i===e||i<0||i>=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function e(t){var e,n=t.el._model||{},i=t.el._scale||{},a=t.fill,r=null;if(isFinite(a))return null;if("start"===a?r=void 0===n.scaleBottom?i.bottom:n.scaleBottom:"end"===a?r=void 0===n.scaleTop?i.top:n.scaleTop:void 0!==n.scaleZero?r=n.scaleZero:i.getBasePosition?r=i.getBasePosition():i.getBasePixel&&(r=i.getBasePixel()),void 0!==r&&null!==r){if(void 0!==r.x&&void 0!==r.y)return r;if("number"==typeof r&&isFinite(r))return e=i.isHorizontal(),{x:e?r:null,y:e?null:r}}return null}function n(t,e,n){var i,a=t[e].fill,r=[e];if(!n)return a;for(;!1!==a&&-1===r.indexOf(a);){if(!isFinite(a))return a;if(!(i=t[a]))return!1;if(i.visible)return a;r.push(a),a=i.fill}return!1}function o(t){var e=t.fill,n="dataset";return!1===e?null:(isFinite(e)||(n="boundary"),d[n](t))}function s(t){return t&&!t.skip}function l(t,e,n,i,a){var o;if(i&&a){for(t.moveTo(e[0].x,e[0].y),o=1;o<i;++o)r.canvas.lineTo(t,e[o-1],e[o]);for(t.lineTo(n[a-1].x,n[a-1].y),o=a-1;o>0;--o)r.canvas.lineTo(t,n[o],n[o-1],!0)}}function u(t,e,n,i,a,r){var o,u,d,c,h,f,g,m=e.length,p=i.spanGaps,v=[],y=[],b=0,x=0;for(t.beginPath(),o=0,u=m+!!r;o<u;++o)h=n(c=e[d=o%m]._view,d,i),f=s(c),g=s(h),f&&g?(b=v.push(c),x=y.push(h)):b&&x&&(p?(f&&v.push(c),g&&y.push(h)):(l(t,v,y,b,x),b=x=0,v=[],y=[]));l(t,v,y,b,x),t.closePath(),t.fillStyle=a,t.fill()}var d={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e<r&&a[e]._view||null}:null},boundary:function(t){var e=t.boundary,n=e?e.x:null,i=e?e.y:null;return function(t){return{x:null===n?t.x:n,y:null===i?t.y:i}}}};return{id:"filler",afterDatasetsUpdate:function(i,r){var s,l,u,d,c=(i.data.datasets||[]).length,h=r.propagate,f=[];for(l=0;l<c;++l)d=null,(u=(s=i.getDatasetMeta(l)).dataset)&&u._model&&u instanceof a.Line&&(d={visible:i.isDatasetVisible(l),fill:t(u,l,c),chart:i,el:u}),s.$filler=d,f.push(d);for(l=0;l<c;++l)(d=f[l])&&(d.fill=n(f,l,h),d.boundary=e(d),d.mapper=o(d))},beforeDatasetDraw:function(t,e){var n=e.meta.$filler;if(n){var a=t.ctx,o=n.el,s=o._view,l=o._children||[],d=n.mapper,c=s.backgroundColor||i.global.defaultColor;d&&c&&l.length&&(r.canvas.clipArea(a,t.chartArea),u(a,l,d,s,c,o._loop),r.canvas.unclipArea(a))}}}}},{25:25,40:40,45:45}],50:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45);i._set("global",{legend:{display:!0,position:"top",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return r.isArray(e.datasets)?e.datasets.map(function(e,n){return{text:e.label,fillStyle:r.isArray(e.backgroundColor)?e.backgroundColor[0]:e.backgroundColor,hidden:!t.isDatasetVisible(n),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,datasetIndex:n}},this):[]}}},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var n=0;n<t.data.datasets.length;n++)e.push('<li><span style="background-color:'+t.data.datasets[n].backgroundColor+'"></span>'),t.data.datasets[n].label&&e.push(t.data.datasets[n].label),e.push("</li>");return e.push("</ul>"),e.join("")}}),e.exports=function(t){function e(t,e){return t.usePointStyle?e*Math.SQRT2:t.boxWidth}function n(e,n){var i=new t.Legend({ctx:e.ctx,options:n,chart:e});o.configure(e,i,n),o.addBox(e,i),e.legend=i}var o=t.layoutService,s=r.noop;return t.Legend=a.extend({initialize:function(t){r.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:s,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:s,beforeSetDimensions:s,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:s,beforeBuildLabels:s,buildLabels:function(){var t=this,e=t.options.labels||{},n=r.callback(e.generateLabels,[t.chart],t)||[];e.filter&&(n=n.filter(function(n){return e.filter(n,t.chart.data)})),t.options.reverse&&n.reverse(),t.legendItems=n},afterBuildLabels:s,beforeFit:s,fit:function(){var t=this,n=t.options,a=n.labels,o=n.display,s=t.ctx,l=i.global,u=r.valueOrDefault,d=u(a.fontSize,l.defaultFontSize),c=u(a.fontStyle,l.defaultFontStyle),h=u(a.fontFamily,l.defaultFontFamily),f=r.fontString(d,c,h),g=t.legendHitBoxes=[],m=t.minSize,p=t.isHorizontal();if(p?(m.width=t.maxWidth,m.height=o?10:0):(m.width=o?10:0,m.height=t.maxHeight),o)if(s.font=f,p){var v=t.lineWidths=[0],y=t.legendItems.length?d+a.padding:0;s.textAlign="left",s.textBaseline="top",r.each(t.legendItems,function(n,i){var r=e(a,d)+d/2+s.measureText(n.text).width;v[v.length-1]+r+a.padding>=t.width&&(y+=d+a.padding,v[v.length]=t.left),g[i]={left:0,top:0,width:r,height:d},v[v.length-1]+=r+a.padding}),m.height+=y}else{var b=a.padding,x=t.columnWidths=[],_=a.padding,k=0,w=0,M=d+b;r.each(t.legendItems,function(t,n){var i=e(a,d)+d/2+s.measureText(t.text).width;w+M>m.height&&(_+=k+a.padding,x.push(k),k=0,w=0),k=Math.max(k,i),w+=M,g[n]={left:0,top:0,width:i,height:d}}),_+=k,x.push(k),m.width+=_}t.width=m.width,t.height=m.height},afterFit:s,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,n=t.options,a=n.labels,o=i.global,s=o.elements.line,l=t.width,u=t.lineWidths;if(n.display){var d,c=t.ctx,h=r.valueOrDefault,f=h(a.fontColor,o.defaultFontColor),g=h(a.fontSize,o.defaultFontSize),m=h(a.fontStyle,o.defaultFontStyle),p=h(a.fontFamily,o.defaultFontFamily),v=r.fontString(g,m,p);c.textAlign="left",c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=v;var y=e(a,g),b=t.legendHitBoxes,x=function(t,e,i){if(!(isNaN(y)||y<=0)){c.save(),c.fillStyle=h(i.fillStyle,o.defaultColor),c.lineCap=h(i.lineCap,s.borderCapStyle),c.lineDashOffset=h(i.lineDashOffset,s.borderDashOffset),c.lineJoin=h(i.lineJoin,s.borderJoinStyle),c.lineWidth=h(i.lineWidth,s.borderWidth),c.strokeStyle=h(i.strokeStyle,o.defaultColor);var a=0===h(i.lineWidth,s.borderWidth);if(c.setLineDash&&c.setLineDash(h(i.lineDash,s.borderDash)),n.labels&&n.labels.usePointStyle){var l=g*Math.SQRT2/2,u=l/Math.SQRT2,d=t+u,f=e+u;r.canvas.drawPoint(c,i.pointStyle,l,d,f)}else a||c.strokeRect(t,e,y,g),c.fillRect(t,e,y,g);c.restore()}},_=function(t,e,n,i){var a=g/2,r=y+a+t,o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(r+i,o),c.stroke())},k=t.isHorizontal();d=k?{x:t.left+(l-u[0])/2,y:t.top+a.padding,line:0}:{x:t.left+a.padding,y:t.top+a.padding,line:0};var w=g+a.padding;r.each(t.legendItems,function(e,n){var i=c.measureText(e.text).width,r=y+g/2+i,o=d.x,s=d.y;k?o+r>=l&&(s=d.y+=w,d.line++,o=d.x=t.left+(l-u[d.line])/2):s+w>t.bottom&&(o=d.x=o+t.columnWidths[d.line]+a.padding,s=d.y=t.top+a.padding,d.line++),x(o,s,e),b[n].left=o,b[n].top=s,_(o,s,e,i),k?d.x+=r+a.padding:d.y+=w})}},handleEvent:function(t){var e=this,n=e.options,i="mouseup"===t.type?"click":t.type,a=!1;if("mousemove"===i){if(!n.onHover)return}else{if("click"!==i)return;if(!n.onClick)return}var r=t.x,o=t.y;if(r>=e.left&&r<=e.right&&o>=e.top&&o<=e.bottom)for(var s=e.legendHitBoxes,l=0;l<s.length;++l){var u=s[l];if(r>=u.left&&r<=u.left+u.width&&o>=u.top&&o<=u.top+u.height){if("click"===i){n.onClick.call(e,t.native,e.legendItems[l]),a=!0;break}if("mousemove"===i){n.onHover.call(e,t.native,e.legendItems[l]),a=!0;break}}}return a}}),{id:"legend",beforeInit:function(t){var e=t.options.legend;e&&n(t,e)},beforeUpdate:function(t){var e=t.options.legend,a=t.legend;e?(r.mergeIf(e,i.global.legend),a?(o.configure(t,a,e),a.options=e):n(t,e)):a&&(o.removeBox(t,a),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}}}},{25:25,26:26,45:45}],51:[function(t,e,n){"use strict";var i=t(25),a=t(26),r=t(45);i._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,lineHeight:1.2,padding:10,position:"top",text:"",weight:2e3}}),e.exports=function(t){function e(e,i){var a=new t.Title({ctx:e.ctx,options:i,chart:e});n.configure(e,a,i),n.addBox(e,a),e.titleBlock=a}var n=t.layoutService,o=r.noop;return t.Title=a.extend({initialize:function(t){var e=this;r.extend(e,t),e.legendHitBoxes=[]},beforeUpdate:o,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:o,beforeSetDimensions:o,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:o,beforeBuildLabels:o,buildLabels:o,afterBuildLabels:o,beforeFit:o,fit:function(){var t=this,e=r.valueOrDefault,n=t.options,a=n.display,o=e(n.fontSize,i.global.defaultFontSize),s=t.minSize,l=r.isArray(n.text)?n.text.length:1,u=r.options.toLineHeight(n.lineHeight,o),d=a?l*u+2*n.padding:0;t.isHorizontal()?(s.width=t.maxWidth,s.height=d):(s.width=d,s.height=t.maxHeight),t.width=s.width,t.height=s.height},afterFit:o,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=r.valueOrDefault,a=t.options,o=i.global;if(a.display){var s,l,u,d=n(a.fontSize,o.defaultFontSize),c=n(a.fontStyle,o.defaultFontStyle),h=n(a.fontFamily,o.defaultFontFamily),f=r.fontString(d,c,h),g=r.options.toLineHeight(a.lineHeight,d),m=g/2+a.padding,p=0,v=t.top,y=t.left,b=t.bottom,x=t.right;e.fillStyle=n(a.fontColor,o.defaultFontColor),e.font=f,t.isHorizontal()?(l=y+(x-y)/2,u=v+m,s=x-y):(l="left"===a.position?y+m:x-m,u=v+(b-v)/2,s=b-v,p=Math.PI*("left"===a.position?-.5:.5)),e.save(),e.translate(l,u),e.rotate(p),e.textAlign="center",e.textBaseline="middle";var _=a.text;if(r.isArray(_))for(var k=0,w=0;w<_.length;++w)e.fillText(_[w],0,k,s),k+=g;else e.fillText(_,0,0,s);e.restore()}}}),{id:"title",beforeInit:function(t){var n=t.options.title;n&&e(t,n)},beforeUpdate:function(a){var o=a.options.title,s=a.titleBlock;o?(r.mergeIf(o,i.global.title),s?(n.configure(a,s,o),s.options=o):e(a,o)):s&&(t.layoutService.removeBox(a,s),delete a.titleBlock)}}}},{25:25,26:26,45:45}],52:[function(t,e,n){"use strict";e.exports=function(t){var e={position:"bottom"},n=t.Scale.extend({getLabels:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t=this,e=t.getLabels();t.minIndex=0,t.maxIndex=e.length-1;var n;void 0!==t.options.ticks.min&&(n=e.indexOf(t.options.ticks.min),t.minIndex=-1!==n?n:t.minIndex),void 0!==t.options.ticks.max&&(n=e.indexOf(t.options.ticks.max),t.maxIndex=-1!==n?n:t.maxIndex),t.min=e[t.minIndex],t.max=e[t.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var n=this,i=n.chart.data,a=n.isHorizontal();return i.yLabels&&!a?n.getRightValue(i.datasets[e].data[t]):n.ticks[t-n.minIndex]},getPixelForValue:function(t,e){var n,i=this,a=i.options.offset,r=Math.max(i.maxIndex+1-i.minIndex-(a?0:1),1);if(void 0!==t&&null!==t&&(n=i.isHorizontal()?t.x:t.y),void 0!==n||void 0!==t&&isNaN(e)){var o=i.getLabels();t=n||t;var s=o.indexOf(t);e=-1!==s?s:e}if(i.isHorizontal()){var l=i.width/r,u=l*(e-i.minIndex);return a&&(u+=l/2),i.left+Math.round(u)}var d=i.height/r,c=d*(e-i.minIndex);return a&&(c+=d/2),i.top+Math.round(c)},getPixelForTick:function(t){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null)},getValueForPixel:function(t){var e=this,n=e.options.offset,i=Math.max(e._ticks.length-(n?0:1),1),a=e.isHorizontal(),r=(a?e.width:e.height)/i;return t-=a?e.left:e.top,n&&(t-=r/2),(t<=0?0:Math.round(t/r))+e.minIndex},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",n,e)}},{}],53:[function(t,e,n){"use strict";var i=t(25),a=t(45),r=t(34);e.exports=function(t){var e={position:"left",ticks:{callback:r.formatters.linear}},n=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return o?t.xAxisID===e.id:t.yAxisID===e.id}var e=this,n=e.options,i=e.chart,r=i.data.datasets,o=e.isHorizontal();e.min=null,e.max=null;var s=n.stacked;if(void 0===s&&a.each(r,function(e,n){if(!s){var a=i.getDatasetMeta(n);i.isDatasetVisible(n)&&t(a)&&void 0!==a.stack&&(s=!0)}}),n.stacked||s){var l={};a.each(r,function(r,o){var s=i.getDatasetMeta(o),u=[s.type,void 0===n.stacked&&void 0===s.stack?o:"",s.stack].join(".");void 0===l[u]&&(l[u]={positiveValues:[],negativeValues:[]});var d=l[u].positiveValues,c=l[u].negativeValues;i.isDatasetVisible(o)&&t(s)&&a.each(r.data,function(t,i){var a=+e.getRightValue(t);isNaN(a)||s.data[i].hidden||(d[i]=d[i]||0,c[i]=c[i]||0,n.relativePoints?d[i]=100:a<0?c[i]+=a:d[i]+=a)})}),a.each(l,function(t){var n=t.positiveValues.concat(t.negativeValues),i=a.min(n),r=a.max(n);e.min=null===e.min?i:Math.min(e.min,i),e.max=null===e.max?r:Math.max(e.max,r)})}else a.each(r,function(n,r){var o=i.getDatasetMeta(r);i.isDatasetVisible(r)&&t(o)&&a.each(n.data,function(t,n){var i=+e.getRightValue(t);isNaN(i)||o.data[n].hidden||(null===e.min?e.min=i:i<e.min&&(e.min=i),null===e.max?e.max=i:i>e.max&&(e.max=i))})});e.min=isFinite(e.min)&&!isNaN(e.min)?e.min:0,e.max=isFinite(e.max)&&!isNaN(e.max)?e.max:1,this.handleTickRangeOptions()},getTickLimit:function(){var t,e=this,n=e.options.ticks;if(e.isHorizontal())t=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(e.width/50));else{var r=a.valueOrDefault(n.fontSize,i.global.defaultFontSize);t=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(e.height/(2*r)))}return t},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e,n=this,i=n.start,a=+n.getRightValue(t),r=n.end-i;return n.isHorizontal()?(e=n.left+n.width/r*(a-i),Math.round(e)):(e=n.bottom-n.height/r*(a-i),Math.round(e))},getValueForPixel:function(t){var e=this,n=e.isHorizontal(),i=n?e.width:e.height,a=(n?t-e.left:e.bottom-t)/i;return e.start+(e.end-e.start)*a},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",n,e)}},{25:25,34:34,45:45}],54:[function(t,e,n){"use strict";var i=t(45),a=t(34);e.exports=function(t){var e=i.noop;t.LinearScaleBase=t.Scale.extend({getRightValue:function(e){return"string"==typeof e?+e:t.Scale.prototype.getRightValue.call(this,e)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=i.sign(t.min),a=i.sign(t.max);n<0&&a<0?t.max=0:n>0&&a>0&&(t.min=0)}var r=void 0!==e.min||void 0!==e.suggestedMin,o=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),r!==o&&t.min>=t.max&&(r?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:e,handleDirectionalChanges:e,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),r={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,stepSize:i.valueOrDefault(e.fixedStepSize,e.stepSize)},o=t.ticks=a.generators.linear(r,t);t.handleDirectionalChanges(),t.max=i.max(o),t.min=i.min(o),e.reverse?(o.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{34:34,45:45}],55:[function(t,e,n){"use strict";var i=t(45),a=t(34);e.exports=function(t){var e={position:"left",ticks:{callback:a.formatters.logarithmic}},n=t.Scale.extend({determineDataLimits:function(){function t(t){return l?t.xAxisID===e.id:t.yAxisID===e.id}var e=this,n=e.options,a=n.ticks,r=e.chart,o=r.data.datasets,s=i.valueOrDefault,l=e.isHorizontal();e.min=null,e.max=null,e.minNotZero=null;var u=n.stacked;if(void 0===u&&i.each(o,function(e,n){if(!u){var i=r.getDatasetMeta(n);r.isDatasetVisible(n)&&t(i)&&void 0!==i.stack&&(u=!0)}}),n.stacked||u){var d={};i.each(o,function(a,o){var s=r.getDatasetMeta(o),l=[s.type,void 0===n.stacked&&void 0===s.stack?o:"",s.stack].join(".");r.isDatasetVisible(o)&&t(s)&&(void 0===d[l]&&(d[l]=[]),i.each(a.data,function(t,i){var a=d[l],r=+e.getRightValue(t);isNaN(r)||s.data[i].hidden||(a[i]=a[i]||0,n.relativePoints?a[i]=100:a[i]+=r)}))}),i.each(d,function(t){var n=i.min(t),a=i.max(t);e.min=null===e.min?n:Math.min(e.min,n),e.max=null===e.max?a:Math.max(e.max,a)})}else i.each(o,function(n,a){var o=r.getDatasetMeta(a);r.isDatasetVisible(a)&&t(o)&&i.each(n.data,function(t,n){var i=+e.getRightValue(t);isNaN(i)||o.data[n].hidden||(null===e.min?e.min=i:i<e.min&&(e.min=i),null===e.max?e.max=i:i>e.max&&(e.max=i),0!==i&&(null===e.minNotZero||i<e.minNotZero)&&(e.minNotZero=i))})});e.min=s(a.min,e.min),e.max=s(a.max,e.max),e.min===e.max&&(0!==e.min&&null!==e.min?(e.min=Math.pow(10,Math.floor(i.log10(e.min))-1),e.max=Math.pow(10,Math.floor(i.log10(e.max))+1)):(e.min=1,e.max=10))},buildTicks:function(){var t=this,e=t.options.ticks,n={min:e.min,max:e.max},r=t.ticks=a.generators.logarithmic(n,t);t.isHorizontal()||r.reverse(),t.max=i.max(r),t.min=i.min(r),e.reverse?(r.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),t.Scale.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){return this.getPixelForValue(this.tickValues[t])},getPixelForValue:function(t){var e,n,a,r=this,o=r.start,s=+r.getRightValue(t),l=r.options.ticks;return r.isHorizontal()?(a=i.log10(r.end)-i.log10(o),0===s?n=r.left:(e=r.width,n=r.left+e/a*(i.log10(s)-i.log10(o)))):(e=r.height,0!==o||l.reverse?0===r.end&&l.reverse?(a=i.log10(r.start)-i.log10(r.minNotZero),n=s===r.end?r.top:s===r.minNotZero?r.top+.02*e:r.top+.02*e+.98*e/a*(i.log10(s)-i.log10(r.minNotZero))):0===s?n=l.reverse?r.top:r.bottom:(a=i.log10(r.end)-i.log10(o),e=r.height,n=r.bottom-e/a*(i.log10(s)-i.log10(o))):(a=i.log10(r.end)-i.log10(r.minNotZero),n=s===o?r.bottom:s===r.minNotZero?r.bottom-.02*e:r.bottom-.02*e-.98*e/a*(i.log10(s)-i.log10(r.minNotZero)))),n},getValueForPixel:function(t){var e,n,a=this,r=i.log10(a.end)-i.log10(a.start);return a.isHorizontal()?(n=a.width,e=a.start*Math.pow(10,(t-a.left)*r/n)):(n=a.height,e=Math.pow(10,(a.bottom-t)*r/n)/a.start),e}});t.scaleService.registerScaleType("logarithmic",n,e)}},{34:34,45:45}],56:[function(t,e,n){"use strict";var i=t(25),a=t(45),r=t(34);e.exports=function(t){function e(t){var e=t.options;return e.angleLines.display||e.pointLabels.display?t.chart.data.labels.length:0}function n(t){var e=t.options.pointLabels,n=a.valueOrDefault(e.fontSize,p.defaultFontSize),i=a.valueOrDefault(e.fontStyle,p.defaultFontStyle),r=a.valueOrDefault(e.fontFamily,p.defaultFontFamily);return{size:n,style:i,family:r,font:a.fontString(n,i,r)}}function o(t,e,n){return a.isArray(n)?{w:a.longestText(t,t.font,n),h:n.length*e+1.5*(n.length-1)*e}:{w:t.measureText(n).width,h:e}}function s(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:t<i||t>a?{start:e-n-5,end:e}:{start:e,end:e+n+5}}function l(t){var i,r,l,u=n(t),d=Math.min(t.height/2,t.width/2),c={r:t.width,l:0,t:t.height,b:0},h={};t.ctx.font=u.font,t._pointLabelSizes=[];var f=e(t);for(i=0;i<f;i++){l=t.getPointPosition(i,d),r=o(t.ctx,u.size,t.pointLabels[i]||""),t._pointLabelSizes[i]=r;var g=t.getIndexAngle(i),m=a.toDegrees(g)%360,p=s(m,l.x,r.w,0,180),v=s(m,l.y,r.h,90,270);p.start<c.l&&(c.l=p.start,h.l=g),p.end>c.r&&(c.r=p.end,h.r=g),v.start<c.t&&(c.t=v.start,h.t=g),v.end>c.b&&(c.b=v.end,h.b=g)}t.setReductions(d,c,h)}function u(t){var e=Math.min(t.height/2,t.width/2);t.drawingArea=Math.round(e),t.setCenterPoint(0,0,0,0)}function d(t){return 0===t||180===t?"center":t<180?"left":"right"}function c(t,e,n,i){if(a.isArray(e))for(var r=n.y,o=1.5*i,s=0;s<e.length;++s)t.fillText(e[s],n.x,r),r+=o;else t.fillText(e,n.x,n.y)}function h(t,e,n){90===t||270===t?n.y-=e.h/2:(t>270||t<90)&&(n.y-=e.h)}function f(t){var i=t.ctx,r=a.valueOrDefault,o=t.options,s=o.angleLines,l=o.pointLabels;i.lineWidth=s.lineWidth,i.strokeStyle=s.color;var u=t.getDistanceFromCenterForValue(o.ticks.reverse?t.min:t.max),f=n(t);i.textBaseline="top";for(var g=e(t)-1;g>=0;g--){if(s.display){var m=t.getPointPosition(g,u);i.beginPath(),i.moveTo(t.xCenter,t.yCenter),i.lineTo(m.x,m.y),i.stroke(),i.closePath()}if(l.display){var v=t.getPointPosition(g,u+5),y=r(l.fontColor,p.defaultFontColor);i.font=f.font,i.fillStyle=y;var b=t.getIndexAngle(g),x=a.toDegrees(b);i.textAlign=d(x),h(x,t._pointLabelSizes[g],v),c(i,t.pointLabels[g]||"",v,f.size)}}}function g(t,n,i,r){var o=t.ctx;if(o.strokeStyle=a.valueAtIndexOrDefault(n.color,r-1),o.lineWidth=a.valueAtIndexOrDefault(n.lineWidth,r-1),t.options.gridLines.circular)o.beginPath(),o.arc(t.xCenter,t.yCenter,i,0,2*Math.PI),o.closePath(),o.stroke();else{var s=e(t);if(0===s)return;o.beginPath();var l=t.getPointPosition(0,i);o.moveTo(l.x,l.y);for(var u=1;u<s;u++)l=t.getPointPosition(u,i),o.lineTo(l.x,l.y);o.closePath(),o.stroke()}}function m(t){return a.isNumber(t)?t:0}var p=i.global,v={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:r.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}},y=t.LinearScaleBase.extend({setDimensions:function(){var t=this,e=t.options,n=e.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var i=a.min([t.height,t.width]),r=a.valueOrDefault(n.fontSize,p.defaultFontSize);t.drawingArea=e.display?i/2-(r/2+n.backdropPaddingY):i/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;a.each(e.data.datasets,function(r,o){if(e.isDatasetVisible(o)){var s=e.getDatasetMeta(o);a.each(r.data,function(e,a){var r=+t.getRightValue(e);isNaN(r)||s.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))})}}),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,e=a.valueOrDefault(t.fontSize,p.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*e)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){this.options.pointLabels.display?l(this):u(this)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),r=Math.max(e.r-i.width,0)/Math.sin(n.r),o=-e.t/Math.cos(n.t),s=-Math.max(e.b-i.height,0)/Math.cos(n.b);a=m(a),r=m(r),o=m(o),s=m(s),i.drawingArea=Math.min(Math.round(t-(a+r)/2),Math.round(t-(o+s)/2)),i.setCenterPoint(a,r,o,s)},setCenterPoint:function(t,e,n,i){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=n+a.drawingArea,l=a.height-i-a.drawingArea;a.xCenter=Math.round((o+r)/2+a.left),a.yCenter=Math.round((s+l)/2+a.top)},getIndexAngle:function(t){return t*(2*Math.PI/e(this))+(this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this,i=n.getIndexAngle(t)-Math.PI/2;return{x:Math.round(Math.cos(i)*e)+n.xCenter,y:Math.round(Math.sin(i)*e)+n.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this,e=t.min,n=t.max;return t.getPointPositionForValue(0,t.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},draw:function(){var t=this,e=t.options,n=e.gridLines,i=e.ticks,r=a.valueOrDefault;if(e.display){var o=t.ctx,s=this.getIndexAngle(0),l=r(i.fontSize,p.defaultFontSize),u=r(i.fontStyle,p.defaultFontStyle),d=r(i.fontFamily,p.defaultFontFamily),c=a.fontString(l,u,d);a.each(t.ticks,function(e,a){if(a>0||i.reverse){var u=t.getDistanceFromCenterForValue(t.ticksAsNumbers[a]);if(n.display&&0!==a&&g(t,n,u,a),i.display){var d=r(i.fontColor,p.defaultFontColor);if(o.font=c,o.save(),o.translate(t.xCenter,t.yCenter),o.rotate(s),i.showLabelBackdrop){var h=o.measureText(e).width;o.fillStyle=i.backdropColor,o.fillRect(-h/2-i.backdropPaddingX,-u-l/2-i.backdropPaddingY,h+2*i.backdropPaddingX,l+2*i.backdropPaddingY)}o.textAlign="center",o.textBaseline="middle",o.fillStyle=d,o.fillText(e,0,-u),o.restore()}}}),(e.angleLines.display||e.pointLabels.display)&&f(t)}}});t.scaleService.registerScaleType("radialLinear",y,v)}},{25:25,34:34,45:45}],57:[function(t,e,n){"use strict";function i(t,e){return t-e}function a(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e<n;++e)a[i=t[e]]||(a[i]=!0,r.push(i));return r}function r(t,e,n,i){if("linear"===i||!t.length)return[{time:e,pos:0},{time:n,pos:1}];var a,r,o,s,l,u=[],d=[e];for(a=0,r=t.length;a<r;++a)(s=t[a])>e&&s<n&&d.push(s);for(d.push(n),a=0,r=d.length;a<r;++a)l=d[a+1],o=d[a-1],s=d[a],void 0!==o&&void 0!==l&&Math.round((l+o)/2)===s||u.push({time:s,pos:a/(r-1)});return u}function o(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(i=o+s>>1,a=t[i-1]||null,r=t[i],!a)return{lo:null,hi:r};if(r[e]<n)o=i+1;else{if(!(a[e]>n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}function s(t,e,n,i){var a=o(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],s=a.lo?a.hi?a.hi:t[t.length-1]:t[1],l=s[e]-r[e],u=l?(n-r[e])/l:0,d=(s[i]-r[i])*u;return r[i]+d}function l(t,e){var n=e.parser,i=e.parser||e.format;return"function"==typeof n?n(t):"string"==typeof t&&"string"==typeof i?p(t,i):(t instanceof p||(t=p(t)),t.isValid()?t:"function"==typeof i?i(t):t)}function u(t,e){if(y.isNullOrUndef(t))return null;var n=e.options.time,i=l(e.getRightValue(t),n);return i.isValid()?(n.round&&i.startOf(n.round),i.valueOf()):null}function d(t,e,n,i){var a,r,o,s=e-t,l=_[n],u=l.size,d=l.steps;if(!d)return Math.ceil(s/((i||1)*u));for(a=0,r=d.length;a<r&&(o=d[a],!(Math.ceil(s/(u*o))<=i));++a);return o}function c(t,e,n,i){var a,r,o,s=k.length;for(a=k.indexOf(t);a<s-1;++a)if(r=_[k[a]],o=r.steps?r.steps[r.steps.length-1]:x,Math.ceil((n-e)/(o*r.size))<=i)return k[a];return k[s-1]}function h(t){for(var e=k.indexOf(t)+1,n=k.length;e<n;++e)if(_[k[e]].major)return k[e]}function f(t,e,n,i,a,r){var o,s=r.time,l=y.valueOrDefault(s.stepSize,s.unitStepSize),u="week"===n&&s.isoWeekday,c=r.ticks.major.enabled,h=_[n],f=p(t),g=p(e),m=[];for(l||(l=d(t,e,n,a)),u&&(f=f.isoWeekday(u),g=g.isoWeekday(u)),f=f.startOf(u?"day":n),(g=g.startOf(u?"day":n))<e&&g.add(1,n),o=p(f),c&&i&&!u&&!s.round&&(o.startOf(i),o.add(~~((f-o)/(h.size*l))*l,n));o<g;o.add(l,n))m.push(+o);return m.push(+o),m}function g(t,e,n,i,a){var r,o,l=0,u=0;return a.offset&&e.length&&(a.time.min||(r=e.length>1?e[1]:i,o=e[0],l=(s(t,"time",r,"pos")-s(t,"time",o,"pos"))/2),a.time.max||(r=e[e.length-1],o=e.length>1?e[e.length-2]:n,u=(s(t,"time",r,"pos")-s(t,"time",o,"pos"))/2)),{left:l,right:u}}function m(t,e){var n,i,a,r,o=[];for(n=0,i=t.length;n<i;++n)a=t[n],r=!!e&&a===+p(a).startOf(e),o.push({value:a,major:r});return o}var p=t(6);p="function"==typeof p?p:window.moment;var v=t(25),y=t(45),b=Number.MIN_SAFE_INTEGER||-9007199254740991,x=Number.MAX_SAFE_INTEGER||9007199254740991,_={millisecond:{major:!0,size:1,steps:[1,2,5,10,20,50,100,250,500]},second:{major:!0,size:1e3,steps:[1,2,5,10,30]},minute:{major:!0,size:6e4,steps:[1,2,5,10,30]},hour:{major:!0,size:36e5,steps:[1,2,3,6,12]},day:{major:!0,size:864e5,steps:[1,2,5]},week:{major:!1,size:6048e5,steps:[1,2,3,4]},month:{major:!0,size:2628e6,steps:[1,2,3]},quarter:{major:!1,size:7884e6,steps:[1,2,3,4]},year:{major:!0,size:3154e7}},k=Object.keys(_);e.exports=function(t){var e={position:"bottom",distribution:"linear",bounds:"data",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}},n=t.Scale.extend({initialize:function(){if(!p)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");this.mergeTicksOptions(),t.Scale.prototype.initialize.call(this)},update:function(){var e=this,n=e.options;return n.time&&n.time.format&&console.warn("options.time.format is deprecated and replaced by options.time.parser."),t.Scale.prototype.update.apply(e,arguments)},getRightValue:function(e){return e&&void 0!==e.t&&(e=e.t),t.Scale.prototype.getRightValue.call(this,e)},determineDataLimits:function(){var t,e,n,r,o,s,l=this,d=l.chart,c=l.options.time,h=u(c.min,l)||x,f=u(c.max,l)||b,g=[],m=[],v=[];for(t=0,n=d.data.labels.length;t<n;++t)v.push(u(d.data.labels[t],l));for(t=0,n=(d.data.datasets||[]).length;t<n;++t)if(d.isDatasetVisible(t))if(o=d.data.datasets[t].data,y.isObject(o[0]))for(m[t]=[],e=0,r=o.length;e<r;++e)s=u(o[e],l),g.push(s),m[t][e]=s;else g.push.apply(g,v),m[t]=v.slice(0);else m[t]=[];v.length&&(v=a(v).sort(i),h=Math.min(h,v[0]),f=Math.max(f,v[v.length-1])),g.length&&(g=a(g).sort(i),h=Math.min(h,g[0]),f=Math.max(f,g[g.length-1])),h=h===x?+p().startOf("day"):h,f=f===b?+p().endOf("day")+1:f,l.min=Math.min(h,f),l.max=Math.max(h+1,f),l._horizontal=l.isHorizontal(),l._table=[],l._timestamps={data:g,datasets:m,labels:v}},buildTicks:function(){var t,e,n,i=this,a=i.min,o=i.max,s=i.options,l=s.time,d=l.displayFormats,p=i.getLabelCapacity(a),v=l.unit||c(l.minUnit,a,o,p),y=h(v),b=[],x=[];switch(s.ticks.source){case"data":b=i._timestamps.data;break;case"labels":b=i._timestamps.labels;break;case"auto":default:b=f(a,o,v,y,p,s)}for("ticks"===s.bounds&&b.length&&(a=b[0],o=b[b.length-1]),a=u(l.min,i)||a,o=u(l.max,i)||o,t=0,e=b.length;t<e;++t)(n=b[t])>=a&&n<=o&&x.push(n);return i.min=a,i.max=o,i._unit=v,i._majorUnit=y,i._minorFormat=d[v],i._majorFormat=d[y],i._table=r(i._timestamps.data,a,o,s.distribution),i._offsets=g(i._table,x,a,o,s),m(x,y)},getLabelForIndex:function(t,e){var n=this,i=n.chart.data,a=n.options.time,r=i.labels&&t<i.labels.length?i.labels[t]:"",o=i.datasets[e].data[t];return y.isObject(o)&&(r=n.getRightValue(o)),a.tooltipFormat&&(r=l(r,a).format(a.tooltipFormat)),r},tickFormatFunction:function(t,e,n){var i=this,a=i.options,r=t.valueOf(),o=i._majorUnit,s=i._majorFormat,l=t.clone().startOf(i._majorUnit).valueOf(),u=a.ticks.major,d=u.enabled&&o&&s&&r===l,c=t.format(d?s:i._minorFormat),h=d?u:a.ticks.minor,f=y.valueOrDefault(h.callback,h.userCallback);return f?f(c,e,n):c},convertTicksToLabels:function(t){var e,n,i=[];for(e=0,n=t.length;e<n;++e)i.push(this.tickFormatFunction(p(t[e].value),e,t));return i},getPixelForOffset:function(t){var e=this,n=e._horizontal?e.width:e.height,i=e._horizontal?e.left:e.top,a=s(e._table,"time",t,"pos");return i+n*(e._offsets.left+a)/(e._offsets.left+1+e._offsets.right)},getPixelForValue:function(t,e,n){var i=this,a=null;if(void 0!==e&&void 0!==n&&(a=i._timestamps.datasets[n][e]),null===a&&(a=u(t,i)),null!==a)return i.getPixelForOffset(a)},getPixelForTick:function(t){var e=this.getTicks();return t>=0&&t<e.length?this.getPixelForOffset(e[t].value):null},getValueForPixel:function(t){var e=this,n=e._horizontal?e.width:e.height,i=e._horizontal?e.left:e.top,a=(n?(t-i)/n:0)*(e._offsets.left+1+e._offsets.left)-e._offsets.right,r=s(e._table,"pos",a,"time");return p(r)},getLabelWidth:function(t){var e=this,n=e.options.ticks,i=e.ctx.measureText(t).width,a=y.toRadians(n.maxRotation),r=Math.cos(a),o=Math.sin(a);return i*r+y.valueOrDefault(n.fontSize,v.global.defaultFontSize)*o},getLabelCapacity:function(t){var e=this;e._minorFormat=e.options.time.displayFormats.millisecond;var n=e.tickFormatFunction(p(t),0,[]),i=e.getLabelWidth(n),a=e.isHorizontal()?e.width:e.height;return Math.floor(a/i)}});t.scaleService.registerScaleType("time",n,e)}},{25:25,45:45,6:6}]},{},[7])(7)});
 
 
 
 
 
 
1
  /*!
2
+ * Chart.js v3.7.1
3
+ * https://www.chartjs.org
4
+ * (c) 2022 Chart.js Contributors
5
+ * Released under the MIT License
 
 
 
6
  */
7
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Chart=e()}(this,(function(){"use strict";const t="undefined"==typeof window?function(t){return t()}:window.requestAnimationFrame;function e(e,i,s){const n=s||(t=>Array.prototype.slice.call(t));let o=!1,a=[];return function(...s){a=n(s),o||(o=!0,t.call(window,(()=>{o=!1,e.apply(i,a)})))}}function i(t,e){let i;return function(...s){return e?(clearTimeout(i),i=setTimeout(t,e,s)):t.apply(this,s),e}}const s=t=>"start"===t?"left":"end"===t?"right":"center",n=(t,e,i)=>"start"===t?e:"end"===t?i:(e+i)/2,o=(t,e,i,s)=>t===(s?"left":"right")?i:"center"===t?(e+i)/2:e;var a=new class{constructor(){this._request=null,this._charts=new Map,this._running=!1,this._lastDate=void 0}_notify(t,e,i,s){const n=e.listeners[s],o=e.duration;n.forEach((s=>s({chart:t,initial:e.initial,numSteps:o,currentStep:Math.min(i-e.start,o)})))}_refresh(){this._request||(this._running=!0,this._request=t.call(window,(()=>{this._update(),this._request=null,this._running&&this._refresh()})))}_update(t=Date.now()){let e=0;this._charts.forEach(((i,s)=>{if(!i.running||!i.items.length)return;const n=i.items;let o,a=n.length-1,r=!1;for(;a>=0;--a)o=n[a],o._active?(o._total>i.duration&&(i.duration=o._total),o.tick(t),r=!0):(n[a]=n[n.length-1],n.pop());r&&(s.draw(),this._notify(s,i,t,"progress")),n.length||(i.running=!1,this._notify(s,i,t,"complete"),i.initial=!1),e+=n.length})),this._lastDate=t,0===e&&(this._running=!1)}_getAnims(t){const e=this._charts;let i=e.get(t);return i||(i={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,i)),i}listen(t,e,i){this._getAnims(t).listeners[e].push(i)}add(t,e){e&&e.length&&this._getAnims(t).items.push(...e)}has(t){return this._getAnims(t).items.length>0}start(t){const e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce(((t,e)=>Math.max(t,e._duration)),0),this._refresh())}running(t){if(!this._running)return!1;const e=this._charts.get(t);return!!(e&&e.running&&e.items.length)}stop(t){const e=this._charts.get(t);if(!e||!e.items.length)return;const i=e.items;let s=i.length-1;for(;s>=0;--s)i[s].cancel();e.items=[],this._notify(t,e,Date.now(),"complete")}remove(t){return this._charts.delete(t)}};
8
+ /*!
9
+ * @kurkle/color v0.1.9
10
+ * https://github.com/kurkle/color#readme
11
+ * (c) 2020 Jukka Kurkela
12
+ * Released under the MIT License
13
+ */const r={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},l="0123456789ABCDEF",h=t=>l[15&t],c=t=>l[(240&t)>>4]+l[15&t],d=t=>(240&t)>>4==(15&t);function u(t){var e=function(t){return d(t.r)&&d(t.g)&&d(t.b)&&d(t.a)}(t)?h:c;return t?"#"+e(t.r)+e(t.g)+e(t.b)+(t.a<255?e(t.a):""):t}function f(t){return t+.5|0}const g=(t,e,i)=>Math.max(Math.min(t,i),e);function p(t){return g(f(2.55*t),0,255)}function m(t){return g(f(255*t),0,255)}function x(t){return g(f(t/2.55)/100,0,1)}function b(t){return g(f(100*t),0,100)}const _=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;const y=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function v(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function w(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function M(t,e,i){const s=v(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function k(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=n===e?(i-s)/h+(i<s?6:0):n===i?(s-e)/h+2:(e-i)/h+4,r=60*r+.5),[0|r,l||0,a]}function S(t,e,i,s){return(Array.isArray(e)?t(e[0],e[1],e[2]):t(e,i,s)).map(m)}function P(t,e,i){return S(v,t,e,i)}function D(t){return(t%360+360)%360}function C(t){const e=y.exec(t);let i,s=255;if(!e)return;e[5]!==i&&(s=e[6]?p(+e[5]):m(+e[5]));const n=D(+e[2]),o=+e[3]/100,a=+e[4]/100;return i="hwb"===e[1]?function(t,e,i){return S(M,t,e,i)}(n,o,a):"hsv"===e[1]?function(t,e,i){return S(w,t,e,i)}(n,o,a):P(n,o,a),{r:i[0],g:i[1],b:i[2],a:s}}const O={x:"dark",Z:"light",Y:"re",X:"blu",W:"gr",V:"medium",U:"slate",A:"ee",T:"ol",S:"or",B:"ra",C:"lateg",D:"ights",R:"in",Q:"turquois",E:"hi",P:"ro",O:"al",N:"le",M:"de",L:"yello",F:"en",K:"ch",G:"arks",H:"ea",I:"ightg",J:"wh"},A={OiceXe:"f0f8ff",antiquewEte:"faebd7",aqua:"ffff",aquamarRe:"7fffd4",azuY:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"0",blanKedOmond:"ffebcd",Xe:"ff",XeviTet:"8a2be2",bPwn:"a52a2a",burlywood:"deb887",caMtXe:"5f9ea0",KartYuse:"7fff00",KocTate:"d2691e",cSO:"ff7f50",cSnflowerXe:"6495ed",cSnsilk:"fff8dc",crimson:"dc143c",cyan:"ffff",xXe:"8b",xcyan:"8b8b",xgTMnPd:"b8860b",xWay:"a9a9a9",xgYF:"6400",xgYy:"a9a9a9",xkhaki:"bdb76b",xmagFta:"8b008b",xTivegYF:"556b2f",xSange:"ff8c00",xScEd:"9932cc",xYd:"8b0000",xsOmon:"e9967a",xsHgYF:"8fbc8f",xUXe:"483d8b",xUWay:"2f4f4f",xUgYy:"2f4f4f",xQe:"ced1",xviTet:"9400d3",dAppRk:"ff1493",dApskyXe:"bfff",dimWay:"696969",dimgYy:"696969",dodgerXe:"1e90ff",fiYbrick:"b22222",flSOwEte:"fffaf0",foYstWAn:"228b22",fuKsia:"ff00ff",gaRsbSo:"dcdcdc",ghostwEte:"f8f8ff",gTd:"ffd700",gTMnPd:"daa520",Way:"808080",gYF:"8000",gYFLw:"adff2f",gYy:"808080",honeyMw:"f0fff0",hotpRk:"ff69b4",RdianYd:"cd5c5c",Rdigo:"4b0082",ivSy:"fffff0",khaki:"f0e68c",lavFMr:"e6e6fa",lavFMrXsh:"fff0f5",lawngYF:"7cfc00",NmoncEffon:"fffacd",ZXe:"add8e6",ZcSO:"f08080",Zcyan:"e0ffff",ZgTMnPdLw:"fafad2",ZWay:"d3d3d3",ZgYF:"90ee90",ZgYy:"d3d3d3",ZpRk:"ffb6c1",ZsOmon:"ffa07a",ZsHgYF:"20b2aa",ZskyXe:"87cefa",ZUWay:"778899",ZUgYy:"778899",ZstAlXe:"b0c4de",ZLw:"ffffe0",lime:"ff00",limegYF:"32cd32",lRF:"faf0e6",magFta:"ff00ff",maPon:"800000",VaquamarRe:"66cdaa",VXe:"cd",VScEd:"ba55d3",VpurpN:"9370db",VsHgYF:"3cb371",VUXe:"7b68ee",VsprRggYF:"fa9a",VQe:"48d1cc",VviTetYd:"c71585",midnightXe:"191970",mRtcYam:"f5fffa",mistyPse:"ffe4e1",moccasR:"ffe4b5",navajowEte:"ffdead",navy:"80",Tdlace:"fdf5e6",Tive:"808000",TivedBb:"6b8e23",Sange:"ffa500",SangeYd:"ff4500",ScEd:"da70d6",pOegTMnPd:"eee8aa",pOegYF:"98fb98",pOeQe:"afeeee",pOeviTetYd:"db7093",papayawEp:"ffefd5",pHKpuff:"ffdab9",peru:"cd853f",pRk:"ffc0cb",plum:"dda0dd",powMrXe:"b0e0e6",purpN:"800080",YbeccapurpN:"663399",Yd:"ff0000",Psybrown:"bc8f8f",PyOXe:"4169e1",saddNbPwn:"8b4513",sOmon:"fa8072",sandybPwn:"f4a460",sHgYF:"2e8b57",sHshell:"fff5ee",siFna:"a0522d",silver:"c0c0c0",skyXe:"87ceeb",UXe:"6a5acd",UWay:"708090",UgYy:"708090",snow:"fffafa",sprRggYF:"ff7f",stAlXe:"4682b4",tan:"d2b48c",teO:"8080",tEstN:"d8bfd8",tomato:"ff6347",Qe:"40e0d0",viTet:"ee82ee",JHt:"f5deb3",wEte:"ffffff",wEtesmoke:"f5f5f5",Lw:"ffff00",LwgYF:"9acd32"};let T;function L(t){T||(T=function(){const t={},e=Object.keys(A),i=Object.keys(O);let s,n,o,a,r;for(s=0;s<e.length;s++){for(a=r=e[s],n=0;n<i.length;n++)o=i[n],r=r.replace(o,O[o]);o=parseInt(A[a],16),t[r]=[o>>16&255,o>>8&255,255&o]}return t}(),T.transparent=[0,0,0,0]);const e=T[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}function R(t,e,i){if(t){let s=k(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:1)),s=P(s),t.r=s[0],t.g=s[1],t.b=s[2]}}function E(t,e){return t?Object.assign(e||{},t):t}function I(t){var e={r:0,g:0,b:0,a:255};return Array.isArray(t)?t.length>=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=m(t[3]))):(e=E(t,{r:0,g:0,b:0,a:1})).a=m(e.a),e}function z(t){return"r"===t.charAt(0)?function(t){const e=_.exec(t);let i,s,n,o=255;if(e){if(e[7]!==i){const t=+e[7];o=255&(e[8]?p(t):255*t)}return i=+e[1],s=+e[3],n=+e[5],i=255&(e[2]?p(i):i),s=255&(e[4]?p(s):s),n=255&(e[6]?p(n):n),{r:i,g:s,b:n,a:o}}}(t):C(t)}class F{constructor(t){if(t instanceof F)return t;const e=typeof t;let i;var s,n,o;"object"===e?i=I(t):"string"===e&&(o=(s=t).length,"#"===s[0]&&(4===o||5===o?n={r:255&17*r[s[1]],g:255&17*r[s[2]],b:255&17*r[s[3]],a:5===o?17*r[s[4]]:255}:7!==o&&9!==o||(n={r:r[s[1]]<<4|r[s[2]],g:r[s[3]]<<4|r[s[4]],b:r[s[5]]<<4|r[s[6]],a:9===o?r[s[7]]<<4|r[s[8]]:255})),i=n||L(t)||z(t)),this._rgb=i,this._valid=!!i}get valid(){return this._valid}get rgb(){var t=E(this._rgb);return t&&(t.a=x(t.a)),t}set rgb(t){this._rgb=I(t)}rgbString(){return this._valid?(t=this._rgb)&&(t.a<255?`rgba(${t.r}, ${t.g}, ${t.b}, ${x(t.a)})`:`rgb(${t.r}, ${t.g}, ${t.b})`):this._rgb;var t}hexString(){return this._valid?u(this._rgb):this._rgb}hslString(){return this._valid?function(t){if(!t)return;const e=k(t),i=e[0],s=b(e[1]),n=b(e[2]);return t.a<255?`hsla(${i}, ${s}%, ${n}%, ${x(t.a)})`:`hsl(${i}, ${s}%, ${n}%)`}(this._rgb):this._rgb}mix(t,e){const i=this;if(t){const s=i.rgb,n=t.rgb;let o;const a=e===o?.5:e,r=2*a-1,l=s.a-n.a,h=((r*l==-1?r:(r+l)/(1+r*l))+1)/2;o=1-h,s.r=255&h*s.r+o*n.r+.5,s.g=255&h*s.g+o*n.g+.5,s.b=255&h*s.b+o*n.b+.5,s.a=a*s.a+(1-a)*n.a,i.rgb=s}return i}clone(){return new F(this.rgb)}alpha(t){return this._rgb.a=m(t),this}clearer(t){return this._rgb.a*=1-t,this}greyscale(){const t=this._rgb,e=f(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}opaquer(t){return this._rgb.a*=1+t,this}negate(){const t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}lighten(t){return R(this._rgb,2,t),this}darken(t){return R(this._rgb,2,-t),this}saturate(t){return R(this._rgb,1,t),this}desaturate(t){return R(this._rgb,1,-t),this}rotate(t){return function(t,e){var i=k(t);i[0]=D(i[0]+e),i=P(i),t.r=i[0],t.g=i[1],t.b=i[2]}(this._rgb,t),this}}function B(t){return new F(t)}const V=t=>t instanceof CanvasGradient||t instanceof CanvasPattern;function W(t){return V(t)?t:B(t)}function N(t){return V(t)?t:B(t).saturate(.5).darken(.1).hexString()}function H(){}const j=function(){let t=0;return function(){return t++}}();function $(t){return null==t}function Y(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return"[object"===e.substr(0,7)&&"Array]"===e.substr(-6)}function U(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}const X=t=>("number"==typeof t||t instanceof Number)&&isFinite(+t);function q(t,e){return X(t)?t:e}function K(t,e){return void 0===t?e:t}const G=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:t/e,Z=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t;function J(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)}function Q(t,e,i,s){let n,o,a;if(Y(t))if(o=t.length,s)for(n=o-1;n>=0;n--)e.call(i,t[n],n);else for(n=0;n<o;n++)e.call(i,t[n],n);else if(U(t))for(a=Object.keys(t),o=a.length,n=0;n<o;n++)e.call(i,t[a[n]],a[n])}function tt(t,e){let i,s,n,o;if(!t||!e||t.length!==e.length)return!1;for(i=0,s=t.length;i<s;++i)if(n=t[i],o=e[i],n.datasetIndex!==o.datasetIndex||n.index!==o.index)return!1;return!0}function et(t){if(Y(t))return t.map(et);if(U(t)){const e=Object.create(null),i=Object.keys(t),s=i.length;let n=0;for(;n<s;++n)e[i[n]]=et(t[i[n]]);return e}return t}function it(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}function st(t,e,i,s){if(!it(t))return;const n=e[t],o=i[t];U(n)&&U(o)?nt(n,o,s):e[t]=et(o)}function nt(t,e,i){const s=Y(e)?e:[e],n=s.length;if(!U(t))return t;const o=(i=i||{}).merger||st;for(let a=0;a<n;++a){if(!U(e=s[a]))continue;const n=Object.keys(e);for(let s=0,a=n.length;s<a;++s)o(n[s],t,e,i)}return t}function ot(t,e){return nt(t,e,{merger:at})}function at(t,e,i){if(!it(t))return;const s=e[t],n=i[t];U(s)&&U(n)?ot(s,n):Object.prototype.hasOwnProperty.call(e,t)||(e[t]=et(n))}function rt(t,e){const i=t.indexOf(".",e);return-1===i?t.length:i}function lt(t,e){if(""===e)return t;let i=0,s=rt(e,i);for(;t&&s>i;)t=t[e.substr(i,s-i)],i=s+1,s=rt(e,i);return t}function ht(t){return t.charAt(0).toUpperCase()+t.slice(1)}const ct=t=>void 0!==t,dt=t=>"function"==typeof t,ut=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0};function ft(t){return"mouseup"===t.type||"click"===t.type||"contextmenu"===t.type}const gt=Object.create(null),pt=Object.create(null);function mt(t,e){if(!e)return t;const i=e.split(".");for(let e=0,s=i.length;e<s;++e){const s=i[e];t=t[s]||(t[s]=Object.create(null))}return t}function xt(t,e,i){return"string"==typeof e?nt(mt(t,e),i):nt(mt(t,""),e)}var bt=new class{constructor(t){this.animation=void 0,this.backgroundColor="rgba(0,0,0,0.1)",this.borderColor="rgba(0,0,0,0.1)",this.color="#666",this.datasets={},this.devicePixelRatio=t=>t.chart.platform.getDevicePixelRatio(),this.elements={},this.events=["mousemove","mouseout","click","touchstart","touchmove"],this.font={family:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",size:12,style:"normal",lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(t,e)=>N(e.backgroundColor),this.hoverBorderColor=(t,e)=>N(e.borderColor),this.hoverColor=(t,e)=>N(e.color),this.indexAxis="x",this.interaction={mode:"nearest",intersect:!0},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.drawActiveElementsOnTop=!0,this.describe(t)}set(t,e){return xt(this,t,e)}get(t){return mt(this,t)}describe(t,e){return xt(pt,t,e)}override(t,e){return xt(gt,t,e)}route(t,e,i,s){const n=mt(this,t),o=mt(this,i),a="_"+e;Object.defineProperties(n,{[a]:{value:n[e],writable:!0},[e]:{enumerable:!0,get(){const t=this[a],e=o[s];return U(t)?Object.assign({},e,t):K(t,e)},set(t){this[a]=t}}})}}({_scriptable:t=>!t.startsWith("on"),_indexable:t=>"events"!==t,hover:{_fallback:"interaction"},interaction:{_scriptable:!1,_indexable:!1}});const _t=Math.PI,yt=2*_t,vt=yt+_t,wt=Number.POSITIVE_INFINITY,Mt=_t/180,kt=_t/2,St=_t/4,Pt=2*_t/3,Dt=Math.log10,Ct=Math.sign;function Ot(t){const e=Math.round(t);t=Lt(t,e,t/1e3)?e:t;const i=Math.pow(10,Math.floor(Dt(t))),s=t/i;return(s<=1?1:s<=2?2:s<=5?5:10)*i}function At(t){const e=[],i=Math.sqrt(t);let s;for(s=1;s<i;s++)t%s==0&&(e.push(s),e.push(t/s));return i===(0|i)&&e.push(i),e.sort(((t,e)=>t-e)).pop(),e}function Tt(t){return!isNaN(parseFloat(t))&&isFinite(t)}function Lt(t,e,i){return Math.abs(t-e)<i}function Rt(t,e){const i=Math.round(t);return i-e<=t&&i+e>=t}function Et(t,e,i){let s,n,o;for(s=0,n=t.length;s<n;s++)o=t[s][i],isNaN(o)||(e.min=Math.min(e.min,o),e.max=Math.max(e.max,o))}function It(t){return t*(_t/180)}function zt(t){return t*(180/_t)}function Ft(t){if(!X(t))return;let e=1,i=0;for(;Math.round(t*e)/e!==t;)e*=10,i++;return i}function Bt(t,e){const i=e.x-t.x,s=e.y-t.y,n=Math.sqrt(i*i+s*s);let o=Math.atan2(s,i);return o<-.5*_t&&(o+=yt),{angle:o,distance:n}}function Vt(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function Wt(t,e){return(t-e+vt)%yt-_t}function Nt(t){return(t%yt+yt)%yt}function Ht(t,e,i,s){const n=Nt(t),o=Nt(e),a=Nt(i),r=Nt(o-n),l=Nt(a-n),h=Nt(n-o),c=Nt(n-a);return n===o||n===a||s&&o===a||r>l&&h<c}function jt(t,e,i){return Math.max(e,Math.min(i,t))}function $t(t){return jt(t,-32768,32767)}function Yt(t,e,i,s=1e-6){return t>=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function Ut(t){return!t||$(t.size)||$(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}function Xt(t,e,i,s,n){let o=e[n];return o||(o=e[n]=t.measureText(n).width,i.push(n)),o>s&&(s=o),s}function qt(t,e,i,s){let n=(s=s||{}).data=s.data||{},o=s.garbageCollect=s.garbageCollect||[];s.font!==e&&(n=s.data={},o=s.garbageCollect=[],s.font=e),t.save(),t.font=e;let a=0;const r=i.length;let l,h,c,d,u;for(l=0;l<r;l++)if(d=i[l],null!=d&&!0!==Y(d))a=Xt(t,n,o,a,d);else if(Y(d))for(h=0,c=d.length;h<c;h++)u=d[h],null==u||Y(u)||(a=Xt(t,n,o,a,u));t.restore();const f=o.length/2;if(f>i.length){for(l=0;l<f;l++)delete n[o[l]];o.splice(0,f)}return a}function Kt(t,e,i){const s=t.currentDevicePixelRatio,n=0!==i?Math.max(i/2,.5):0;return Math.round((e-n)*s)/s+n}function Gt(t,e){(e=e||t.getContext("2d")).save(),e.resetTransform(),e.clearRect(0,0,t.width,t.height),e.restore()}function Zt(t,e,i,s){let n,o,a,r,l;const h=e.pointStyle,c=e.rotation,d=e.radius;let u=(c||0)*Mt;if(h&&"object"==typeof h&&(n=h.toString(),"[object HTMLImageElement]"===n||"[object HTMLCanvasElement]"===n))return t.save(),t.translate(i,s),t.rotate(u),t.drawImage(h,-h.width/2,-h.height/2,h.width,h.height),void t.restore();if(!(isNaN(d)||d<=0)){switch(t.beginPath(),h){default:t.arc(i,s,d,0,yt),t.closePath();break;case"triangle":t.moveTo(i+Math.sin(u)*d,s-Math.cos(u)*d),u+=Pt,t.lineTo(i+Math.sin(u)*d,s-Math.cos(u)*d),u+=Pt,t.lineTo(i+Math.sin(u)*d,s-Math.cos(u)*d),t.closePath();break;case"rectRounded":l=.516*d,r=d-l,o=Math.cos(u+St)*r,a=Math.sin(u+St)*r,t.arc(i-o,s-a,l,u-_t,u-kt),t.arc(i+a,s-o,l,u-kt,u),t.arc(i+o,s+a,l,u,u+kt),t.arc(i-a,s+o,l,u+kt,u+_t),t.closePath();break;case"rect":if(!c){r=Math.SQRT1_2*d,t.rect(i-r,s-r,2*r,2*r);break}u+=St;case"rectRot":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+a,s-o),t.lineTo(i+o,s+a),t.lineTo(i-a,s+o),t.closePath();break;case"crossRot":u+=St;case"cross":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a),t.moveTo(i+a,s-o),t.lineTo(i-a,s+o);break;case"star":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a),t.moveTo(i+a,s-o),t.lineTo(i-a,s+o),u+=St,o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a),t.moveTo(i+a,s-o),t.lineTo(i-a,s+o);break;case"line":o=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-o,s-a),t.lineTo(i+o,s+a);break;case"dash":t.moveTo(i,s),t.lineTo(i+Math.cos(u)*d,s+Math.sin(u)*d)}t.fill(),e.borderWidth>0&&t.stroke()}}function Jt(t,e,i){return i=i||.5,!e||t&&t.x>e.left-i&&t.x<e.right+i&&t.y>e.top-i&&t.y<e.bottom+i}function Qt(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()}function te(t){t.restore()}function ee(t,e,i,s,n){if(!e)return t.lineTo(i.x,i.y);if("middle"===n){const s=(e.x+i.x)/2;t.lineTo(s,e.y),t.lineTo(s,i.y)}else"after"===n!=!!s?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y);t.lineTo(i.x,i.y)}function ie(t,e,i,s){if(!e)return t.lineTo(i.x,i.y);t.bezierCurveTo(s?e.cp1x:e.cp2x,s?e.cp1y:e.cp2y,s?i.cp2x:i.cp1x,s?i.cp2y:i.cp1y,i.x,i.y)}function se(t,e,i,s,n,o={}){const a=Y(e)?e:[e],r=o.strokeWidth>0&&""!==o.strokeColor;let l,h;for(t.save(),t.font=n.string,function(t,e){e.translation&&t.translate(e.translation[0],e.translation[1]);$(e.rotation)||t.rotate(e.rotation);e.color&&(t.fillStyle=e.color);e.textAlign&&(t.textAlign=e.textAlign);e.textBaseline&&(t.textBaseline=e.textBaseline)}(t,o),l=0;l<a.length;++l)h=a[l],r&&(o.strokeColor&&(t.strokeStyle=o.strokeColor),$(o.strokeWidth)||(t.lineWidth=o.strokeWidth),t.strokeText(h,i,s,o.maxWidth)),t.fillText(h,i,s,o.maxWidth),ne(t,i,s,h,o),s+=n.lineHeight;t.restore()}function ne(t,e,i,s,n){if(n.strikethrough||n.underline){const o=t.measureText(s),a=e-o.actualBoundingBoxLeft,r=e+o.actualBoundingBoxRight,l=i-o.actualBoundingBoxAscent,h=i+o.actualBoundingBoxDescent,c=n.strikethrough?(l+h)/2:h;t.strokeStyle=t.fillStyle,t.beginPath(),t.lineWidth=n.decorationWidth||2,t.moveTo(a,c),t.lineTo(r,c),t.stroke()}}function oe(t,e){const{x:i,y:s,w:n,h:o,radius:a}=e;t.arc(i+a.topLeft,s+a.topLeft,a.topLeft,-kt,_t,!0),t.lineTo(i,s+o-a.bottomLeft),t.arc(i+a.bottomLeft,s+o-a.bottomLeft,a.bottomLeft,_t,kt,!0),t.lineTo(i+n-a.bottomRight,s+o),t.arc(i+n-a.bottomRight,s+o-a.bottomRight,a.bottomRight,kt,0,!0),t.lineTo(i+n,s+a.topRight),t.arc(i+n-a.topRight,s+a.topRight,a.topRight,0,-kt,!0),t.lineTo(i+a.topLeft,s)}function ae(t,e,i){i=i||(i=>t[i]<e);let s,n=t.length-1,o=0;for(;n-o>1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const re=(t,e,i)=>ae(t,i,(s=>t[s][e]<i)),le=(t,e,i)=>ae(t,i,(s=>t[s][e]>=i));function he(t,e,i){let s=0,n=t.length;for(;s<n&&t[s]<e;)s++;for(;n>s&&t[n-1]>i;)n--;return s>0||n<t.length?t.slice(s,n):t}const ce=["push","pop","shift","splice","unshift"];function de(t,e){t._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),ce.forEach((e=>{const i="_onData"+ht(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{"function"==typeof t[i]&&t[i](...e)})),n}})})))}function ue(t,e){const i=t._chartjs;if(!i)return;const s=i.listeners,n=s.indexOf(e);-1!==n&&s.splice(n,1),s.length>0||(ce.forEach((e=>{delete t[e]})),delete t._chartjs)}function fe(t){const e=new Set;let i,s;for(i=0,s=t.length;i<s;++i)e.add(t[i]);return e.size===s?t:Array.from(e)}function ge(){return"undefined"!=typeof window&&"undefined"!=typeof document}function pe(t){let e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e}function me(t,e,i){let s;return"string"==typeof t?(s=parseInt(t,10),-1!==t.indexOf("%")&&(s=s/100*e.parentNode[i])):s=t,s}const xe=t=>window.getComputedStyle(t,null);function be(t,e){return xe(t).getPropertyValue(e)}const _e=["top","right","bottom","left"];function ye(t,e,i){const s={};i=i?"-"+i:"";for(let n=0;n<4;n++){const o=_e[n];s[o]=parseFloat(t[e+"-"+o+i])||0}return s.width=s.left+s.right,s.height=s.top+s.bottom,s}function ve(t,e){const{canvas:i,currentDevicePixelRatio:s}=e,n=xe(i),o="border-box"===n.boxSizing,a=ye(n,"padding"),r=ye(n,"border","width"),{x:l,y:h,box:c}=function(t,e){const i=t.native||t,s=i.touches,n=s&&s.length?s[0]:i,{offsetX:o,offsetY:a}=n;let r,l,h=!1;if(((t,e,i)=>(t>0||e>0)&&(!i||!i.shadowRoot))(o,a,i.target))r=o,l=a;else{const t=e.getBoundingClientRect();r=n.clientX-t.left,l=n.clientY-t.top,h=!0}return{x:r,y:l,box:h}}(t,i),d=a.left+(c&&r.left),u=a.top+(c&&r.top);let{width:f,height:g}=e;return o&&(f-=a.width+r.width,g-=a.height+r.height),{x:Math.round((l-d)/f*i.width/s),y:Math.round((h-u)/g*i.height/s)}}const we=t=>Math.round(10*t)/10;function Me(t,e,i,s){const n=xe(t),o=ye(n,"margin"),a=me(n.maxWidth,t,"clientWidth")||wt,r=me(n.maxHeight,t,"clientHeight")||wt,l=function(t,e,i){let s,n;if(void 0===e||void 0===i){const o=pe(t);if(o){const t=o.getBoundingClientRect(),a=xe(o),r=ye(a,"border","width"),l=ye(a,"padding");e=t.width-l.width-r.width,i=t.height-l.height-r.height,s=me(a.maxWidth,o,"clientWidth"),n=me(a.maxHeight,o,"clientHeight")}else e=t.clientWidth,i=t.clientHeight}return{width:e,height:i,maxWidth:s||wt,maxHeight:n||wt}}(t,e,i);let{width:h,height:c}=l;if("content-box"===n.boxSizing){const t=ye(n,"border","width"),e=ye(n,"padding");h-=e.width+t.width,c-=e.height+t.height}return h=Math.max(0,h-o.width),c=Math.max(0,s?Math.floor(h/s):c-o.height),h=we(Math.min(h,a,l.maxWidth)),c=we(Math.min(c,r,l.maxHeight)),h&&!c&&(c=we(h/2)),{width:h,height:c}}function ke(t,e,i){const s=e||1,n=Math.floor(t.height*s),o=Math.floor(t.width*s);t.height=n/s,t.width=o/s;const a=t.canvas;return a.style&&(i||!a.style.height&&!a.style.width)&&(a.style.height=`${t.height}px`,a.style.width=`${t.width}px`),(t.currentDevicePixelRatio!==s||a.height!==n||a.width!==o)&&(t.currentDevicePixelRatio=s,a.height=n,a.width=o,t.ctx.setTransform(s,0,0,s,0,0),!0)}const Se=function(){let t=!1;try{const e={get passive(){return t=!0,!1}};window.addEventListener("test",null,e),window.removeEventListener("test",null,e)}catch(t){}return t}();function Pe(t,e){const i=be(t,e),s=i&&i.match(/^(\d+)(\.\d+)?px$/);return s?+s[1]:void 0}function De(t,e){return"native"in t?{x:t.x,y:t.y}:ve(t,e)}function Ce(t,e,i,s){const{controller:n,data:o,_sorted:a}=t,r=n._cachedMeta.iScale;if(r&&e===r.axis&&"r"!==e&&a&&o.length){const t=r._reversePixels?le:re;if(!s)return t(o,e,i);if(n._sharedOptions){const s=o[0],n="function"==typeof s.getRange&&s.getRange(e);if(n){const s=t(o,e,i-n),a=t(o,e,i+n);return{lo:s.lo,hi:a.hi}}}}return{lo:0,hi:o.length-1}}function Oe(t,e,i,s,n){const o=t.getSortedVisibleDatasetMetas(),a=i[e];for(let t=0,i=o.length;t<i;++t){const{index:i,data:r}=o[t],{lo:l,hi:h}=Ce(o[t],e,a,n);for(let t=l;t<=h;++t){const e=r[t];e.skip||s(e,i,t)}}}function Ae(t,e,i,s){const n=[];if(!Jt(e,t.chartArea,t._minPadding))return n;return Oe(t,i,e,(function(t,i,o){t.inRange(e.x,e.y,s)&&n.push({element:t,datasetIndex:i,index:o})}),!0),n}function Te(t,e,i,s,n){let o=[];const a=function(t){const e=-1!==t.indexOf("x"),i=-1!==t.indexOf("y");return function(t,s){const n=e?Math.abs(t.x-s.x):0,o=i?Math.abs(t.y-s.y):0;return Math.sqrt(Math.pow(n,2)+Math.pow(o,2))}}(i);let r=Number.POSITIVE_INFINITY;return Oe(t,i,e,(function(i,l,h){const c=i.inRange(e.x,e.y,n);if(s&&!c)return;const d=i.getCenterPoint(n);if(!Jt(d,t.chartArea,t._minPadding)&&!c)return;const u=a(e,d);u<r?(o=[{element:i,datasetIndex:l,index:h}],r=u):u===r&&o.push({element:i,datasetIndex:l,index:h})})),o}function Le(t,e,i,s,n){return Jt(e,t.chartArea,t._minPadding)?"r"!==i||s?Te(t,e,i,s,n):function(t,e,i,s){let n=[];return Oe(t,i,e,(function(t,i,o){const{startAngle:a,endAngle:r}=t.getProps(["startAngle","endAngle"],s),{angle:l}=Bt(t,{x:e.x,y:e.y});Ht(l,a,r)&&n.push({element:t,datasetIndex:i,index:o})})),n}(t,e,i,n):[]}function Re(t,e,i,s){const n=De(e,t),o=[],a=i.axis,r="x"===a?"inXRange":"inYRange";let l=!1;return function(t,e){const i=t.getSortedVisibleDatasetMetas();let s,n,o;for(let t=0,a=i.length;t<a;++t){({index:s,data:n}=i[t]);for(let t=0,i=n.length;t<i;++t)o=n[t],o.skip||e(o,s,t)}}(t,((t,e,i)=>{t[r](n[a],s)&&o.push({element:t,datasetIndex:e,index:i}),t.inRange(n.x,n.y,s)&&(l=!0)})),i.intersect&&!l?[]:o}var Ee={modes:{index(t,e,i,s){const n=De(e,t),o=i.axis||"x",a=i.intersect?Ae(t,n,o,s):Le(t,n,o,!1,s),r=[];return a.length?(t.getSortedVisibleDatasetMetas().forEach((t=>{const e=a[0].index,i=t.data[e];i&&!i.skip&&r.push({element:i,datasetIndex:t.index,index:e})})),r):[]},dataset(t,e,i,s){const n=De(e,t),o=i.axis||"xy";let a=i.intersect?Ae(t,n,o,s):Le(t,n,o,!1,s);if(a.length>0){const e=a[0].datasetIndex,i=t.getDatasetMeta(e).data;a=[];for(let t=0;t<i.length;++t)a.push({element:i[t],datasetIndex:e,index:t})}return a},point:(t,e,i,s)=>Ae(t,De(e,t),i.axis||"xy",s),nearest:(t,e,i,s)=>Le(t,De(e,t),i.axis||"xy",i.intersect,s),x:(t,e,i,s)=>Re(t,e,{axis:"x",intersect:i.intersect},s),y:(t,e,i,s)=>Re(t,e,{axis:"y",intersect:i.intersect},s)}};const Ie=new RegExp(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/),ze=new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/);function Fe(t,e){const i=(""+t).match(Ie);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t}function Be(t,e){const i={},s=U(e),n=s?Object.keys(e):e,o=U(t)?s?i=>K(t[i],t[e[i]]):e=>t[e]:()=>t;for(const t of n)i[t]=+o(t)||0;return i}function Ve(t){return Be(t,{top:"y",right:"x",bottom:"y",left:"x"})}function We(t){return Be(t,["topLeft","topRight","bottomLeft","bottomRight"])}function Ne(t){const e=Ve(t);return e.width=e.left+e.right,e.height=e.top+e.bottom,e}function He(t,e){t=t||{},e=e||bt.font;let i=K(t.size,e.size);"string"==typeof i&&(i=parseInt(i,10));let s=K(t.style,e.style);s&&!(""+s).match(ze)&&(console.warn('Invalid font style specified: "'+s+'"'),s="");const n={family:K(t.family,e.family),lineHeight:Fe(K(t.lineHeight,e.lineHeight),i),size:i,style:s,weight:K(t.weight,e.weight),string:""};return n.string=Ut(n),n}function je(t,e,i,s){let n,o,a,r=!0;for(n=0,o=t.length;n<o;++n)if(a=t[n],void 0!==a&&(void 0!==e&&"function"==typeof a&&(a=a(e),r=!1),void 0!==i&&Y(a)&&(a=a[i%a.length],r=!1),void 0!==a))return s&&!r&&(s.cacheable=!1),a}function $e(t,e,i){const{min:s,max:n}=t,o=Z(e,(n-s)/2),a=(t,e)=>i&&0===t?0:t+e;return{min:a(s,-Math.abs(o)),max:a(n,o)}}function Ye(t,e){return Object.assign(Object.create(t),e)}const Ue=["left","top","right","bottom"];function Xe(t,e){return t.filter((t=>t.pos===e))}function qe(t,e){return t.filter((t=>-1===Ue.indexOf(t.pos)&&t.box.axis===e))}function Ke(t,e){return t.sort(((t,i)=>{const s=e?i:t,n=e?t:i;return s.weight===n.weight?s.index-n.index:s.weight-n.weight}))}function Ge(t,e){const i=function(t){const e={};for(const i of t){const{stack:t,pos:s,stackWeight:n}=i;if(!t||!Ue.includes(s))continue;const o=e[t]||(e[t]={count:0,placed:0,weight:0,size:0});o.count++,o.weight+=n}return e}(t),{vBoxMaxWidth:s,hBoxMaxHeight:n}=e;let o,a,r;for(o=0,a=t.length;o<a;++o){r=t[o];const{fullSize:a}=r.box,l=i[r.stack],h=l&&r.stackWeight/l.weight;r.horizontal?(r.width=h?h*s:a&&e.availableWidth,r.height=n):(r.width=s,r.height=h?h*n:a&&e.availableHeight)}return i}function Ze(t,e,i,s){return Math.max(t[i],e[i])+Math.max(t[s],e[s])}function Je(t,e){t.top=Math.max(t.top,e.top),t.left=Math.max(t.left,e.left),t.bottom=Math.max(t.bottom,e.bottom),t.right=Math.max(t.right,e.right)}function Qe(t,e,i,s){const{pos:n,box:o}=i,a=t.maxPadding;if(!U(n)){i.size&&(t[n]-=i.size);const e=s[i.stack]||{size:0,count:1};e.size=Math.max(e.size,i.horizontal?o.height:o.width),i.size=e.size/e.count,t[n]+=i.size}o.getPadding&&Je(a,o.getPadding());const r=Math.max(0,e.outerWidth-Ze(a,t,"left","right")),l=Math.max(0,e.outerHeight-Ze(a,t,"top","bottom")),h=r!==t.w,c=l!==t.h;return t.w=r,t.h=l,i.horizontal?{same:h,other:c}:{same:c,other:h}}function ti(t,e){const i=e.maxPadding;function s(t){const s={left:0,top:0,right:0,bottom:0};return t.forEach((t=>{s[t]=Math.max(e[t],i[t])})),s}return s(t?["left","right"]:["top","bottom"])}function ei(t,e,i,s){const n=[];let o,a,r,l,h,c;for(o=0,a=t.length,h=0;o<a;++o){r=t[o],l=r.box,l.update(r.width||e.w,r.height||e.h,ti(r.horizontal,e));const{same:a,other:d}=Qe(e,i,r,s);h|=a&&n.length,c=c||d,l.fullSize||n.push(r)}return h&&ei(n,e,i,s)||c}function ii(t,e,i,s,n){t.top=i,t.left=e,t.right=e+s,t.bottom=i+n,t.width=s,t.height=n}function si(t,e,i,s){const n=i.padding;let{x:o,y:a}=e;for(const r of t){const t=r.box,l=s[r.stack]||{count:1,placed:0,weight:1},h=r.stackWeight/l.weight||1;if(r.horizontal){const s=e.w*h,o=l.size||t.height;ct(l.start)&&(a=l.start),t.fullSize?ii(t,n.left,a,i.outerWidth-n.right-n.left,o):ii(t,e.left+l.placed,a,s,o),l.start=a,l.placed+=s,a=t.bottom}else{const s=e.h*h,a=l.size||t.width;ct(l.start)&&(o=l.start),t.fullSize?ii(t,o,n.top,a,i.outerHeight-n.bottom-n.top):ii(t,o,e.top+l.placed,a,s),l.start=o,l.placed+=s,o=t.right}}e.x=o,e.y=a}bt.set("layout",{autoPadding:!0,padding:{top:0,right:0,bottom:0,left:0}});var ni={addBox(t,e){t.boxes||(t.boxes=[]),e.fullSize=e.fullSize||!1,e.position=e.position||"top",e.weight=e.weight||0,e._layers=e._layers||function(){return[{z:0,draw(t){e.draw(t)}}]},t.boxes.push(e)},removeBox(t,e){const i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure(t,e,i){e.fullSize=i.fullSize,e.position=i.position,e.weight=i.weight},update(t,e,i,s){if(!t)return;const n=Ne(t.options.layout.padding),o=Math.max(e-n.width,0),a=Math.max(i-n.height,0),r=function(t){const e=function(t){const e=[];let i,s,n,o,a,r;for(i=0,s=(t||[]).length;i<s;++i)n=t[i],({position:o,options:{stack:a,stackWeight:r=1}}=n),e.push({index:i,box:n,pos:o,horizontal:n.isHorizontal(),weight:n.weight,stack:a&&o+a,stackWeight:r});return e}(t),i=Ke(e.filter((t=>t.box.fullSize)),!0),s=Ke(Xe(e,"left"),!0),n=Ke(Xe(e,"right")),o=Ke(Xe(e,"top"),!0),a=Ke(Xe(e,"bottom")),r=qe(e,"x"),l=qe(e,"y");return{fullSize:i,leftAndTop:s.concat(o),rightAndBottom:n.concat(l).concat(a).concat(r),chartArea:Xe(e,"chartArea"),vertical:s.concat(n).concat(l),horizontal:o.concat(a).concat(r)}}(t.boxes),l=r.vertical,h=r.horizontal;Q(t.boxes,(t=>{"function"==typeof t.beforeLayout&&t.beforeLayout()}));const c=l.reduce(((t,e)=>e.box.options&&!1===e.box.options.display?t:t+1),0)||1,d=Object.freeze({outerWidth:e,outerHeight:i,padding:n,availableWidth:o,availableHeight:a,vBoxMaxWidth:o/2/c,hBoxMaxHeight:a/2}),u=Object.assign({},n);Je(u,Ne(s));const f=Object.assign({maxPadding:u,w:o,h:a,x:n.left,y:n.top},n),g=Ge(l.concat(h),d);ei(r.fullSize,f,d,g),ei(l,f,d,g),ei(h,f,d,g)&&ei(l,f,d,g),function(t){const e=t.maxPadding;function i(i){const s=Math.max(e[i]-t[i],0);return t[i]+=s,s}t.y+=i("top"),t.x+=i("left"),i("right"),i("bottom")}(f),si(r.leftAndTop,f,d,g),f.x+=f.w,f.y+=f.h,si(r.rightAndBottom,f,d,g),t.chartArea={left:f.left,top:f.top,right:f.left+f.w,bottom:f.top+f.h,height:f.h,width:f.w},Q(r.chartArea,(e=>{const i=e.box;Object.assign(i,t.chartArea),i.update(f.w,f.h,{left:0,top:0,right:0,bottom:0})}))}};function oi(t,e=[""],i=t,s,n=(()=>t[0])){ct(s)||(s=mi("_fallback",t));const o={[Symbol.toStringTag]:"Object",_cacheable:!0,_scopes:t,_rootScopes:i,_fallback:s,_getTarget:n,override:n=>oi([n,...t],e,i,s)};return new Proxy(o,{deleteProperty:(e,i)=>(delete e[i],delete e._keys,delete t[0][i],!0),get:(i,s)=>ci(i,s,(()=>function(t,e,i,s){let n;for(const o of e)if(n=mi(li(o,t),i),ct(n))return hi(t,n)?gi(i,s,t,n):n}(s,e,t,i))),getOwnPropertyDescriptor:(t,e)=>Reflect.getOwnPropertyDescriptor(t._scopes[0],e),getPrototypeOf:()=>Reflect.getPrototypeOf(t[0]),has:(t,e)=>xi(t).includes(e),ownKeys:t=>xi(t),set(t,e,i){const s=t._storage||(t._storage=n());return t[e]=s[e]=i,delete t._keys,!0}})}function ai(t,e,i,s){const n={_cacheable:!1,_proxy:t,_context:e,_subProxy:i,_stack:new Set,_descriptors:ri(t,s),setContext:e=>ai(t,e,i,s),override:n=>ai(t.override(n),e,i,s)};return new Proxy(n,{deleteProperty:(e,i)=>(delete e[i],delete t[i],!0),get:(t,e,i)=>ci(t,e,(()=>function(t,e,i){const{_proxy:s,_context:n,_subProxy:o,_descriptors:a}=t;let r=s[e];dt(r)&&a.isScriptable(e)&&(r=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_stack:r}=i;if(r.has(t))throw new Error("Recursion detected: "+Array.from(r).join("->")+"->"+t);r.add(t),e=e(o,a||s),r.delete(t),hi(t,e)&&(e=gi(n._scopes,n,t,e));return e}(e,r,t,i));Y(r)&&r.length&&(r=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_descriptors:r}=i;if(ct(o.index)&&s(t))e=e[o.index%e.length];else if(U(e[0])){const i=e,s=n._scopes.filter((t=>t!==i));e=[];for(const l of i){const i=gi(s,n,t,l);e.push(ai(i,o,a&&a[t],r))}}return e}(e,r,t,a.isIndexable));hi(e,r)&&(r=ai(r,n,o&&o[e],a));return r}(t,e,i))),getOwnPropertyDescriptor:(e,i)=>e._descriptors.allKeys?Reflect.has(t,i)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(t,i),getPrototypeOf:()=>Reflect.getPrototypeOf(t),has:(e,i)=>Reflect.has(t,i),ownKeys:()=>Reflect.ownKeys(t),set:(e,i,s)=>(t[i]=s,delete e[i],!0)})}function ri(t,e={scriptable:!0,indexable:!0}){const{_scriptable:i=e.scriptable,_indexable:s=e.indexable,_allKeys:n=e.allKeys}=t;return{allKeys:n,scriptable:i,indexable:s,isScriptable:dt(i)?i:()=>i,isIndexable:dt(s)?s:()=>s}}const li=(t,e)=>t?t+ht(e):e,hi=(t,e)=>U(e)&&"adapters"!==t&&(null===Object.getPrototypeOf(e)||e.constructor===Object);function ci(t,e,i){if(Object.prototype.hasOwnProperty.call(t,e))return t[e];const s=i();return t[e]=s,s}function di(t,e,i){return dt(t)?t(e,i):t}const ui=(t,e)=>!0===t?e:"string"==typeof t?lt(e,t):void 0;function fi(t,e,i,s,n){for(const o of e){const e=ui(i,o);if(e){t.add(e);const o=di(e._fallback,i,n);if(ct(o)&&o!==i&&o!==s)return o}else if(!1===e&&ct(s)&&i!==s)return null}return!1}function gi(t,e,i,s){const n=e._rootScopes,o=di(e._fallback,i,s),a=[...t,...n],r=new Set;r.add(s);let l=pi(r,a,i,o||i,s);return null!==l&&((!ct(o)||o===i||(l=pi(r,a,o,l,s),null!==l))&&oi(Array.from(r),[""],n,o,(()=>function(t,e,i){const s=t._getTarget();e in s||(s[e]={});const n=s[e];if(Y(n)&&U(i))return i;return n}(e,i,s))))}function pi(t,e,i,s,n){for(;i;)i=fi(t,e,i,s,n);return i}function mi(t,e){for(const i of e){if(!i)continue;const e=i[t];if(ct(e))return e}}function xi(t){let e=t._keys;return e||(e=t._keys=function(t){const e=new Set;for(const i of t)for(const t of Object.keys(i).filter((t=>!t.startsWith("_"))))e.add(t);return Array.from(e)}(t._scopes)),e}const bi=Number.EPSILON||1e-14,_i=(t,e)=>e<t.length&&!t[e].skip&&t[e],yi=t=>"x"===t?"y":"x";function vi(t,e,i,s){const n=t.skip?e:t,o=e,a=i.skip?e:i,r=Vt(o,n),l=Vt(a,o);let h=r/(r+l),c=l/(r+l);h=isNaN(h)?0:h,c=isNaN(c)?0:c;const d=s*h,u=s*c;return{previous:{x:o.x-d*(a.x-n.x),y:o.y-d*(a.y-n.y)},next:{x:o.x+u*(a.x-n.x),y:o.y+u*(a.y-n.y)}}}function wi(t,e="x"){const i=yi(e),s=t.length,n=Array(s).fill(0),o=Array(s);let a,r,l,h=_i(t,0);for(a=0;a<s;++a)if(r=l,l=h,h=_i(t,a+1),l){if(h){const t=h[e]-l[e];n[a]=0!==t?(h[i]-l[i])/t:0}o[a]=r?h?Ct(n[a-1])!==Ct(n[a])?0:(n[a-1]+n[a])/2:n[a-1]:n[a]}!function(t,e,i){const s=t.length;let n,o,a,r,l,h=_i(t,0);for(let c=0;c<s-1;++c)l=h,h=_i(t,c+1),l&&h&&(Lt(e[c],0,bi)?i[c]=i[c+1]=0:(n=i[c]/e[c],o=i[c+1]/e[c],r=Math.pow(n,2)+Math.pow(o,2),r<=9||(a=3/Math.sqrt(r),i[c]=n*a*e[c],i[c+1]=o*a*e[c])))}(t,n,o),function(t,e,i="x"){const s=yi(i),n=t.length;let o,a,r,l=_i(t,0);for(let h=0;h<n;++h){if(a=r,r=l,l=_i(t,h+1),!r)continue;const n=r[i],c=r[s];a&&(o=(n-a[i])/3,r[`cp1${i}`]=n-o,r[`cp1${s}`]=c-o*e[h]),l&&(o=(l[i]-n)/3,r[`cp2${i}`]=n+o,r[`cp2${s}`]=c+o*e[h])}}(t,o,e)}function Mi(t,e,i){return Math.max(Math.min(t,i),e)}function ki(t,e,i,s,n){let o,a,r,l;if(e.spanGaps&&(t=t.filter((t=>!t.skip))),"monotone"===e.cubicInterpolationMode)wi(t,n);else{let i=s?t[t.length-1]:t[0];for(o=0,a=t.length;o<a;++o)r=t[o],l=vi(i,r,t[Math.min(o+1,a-(s?0:1))%a],e.tension),r.cp1x=l.previous.x,r.cp1y=l.previous.y,r.cp2x=l.next.x,r.cp2y=l.next.y,i=r}e.capBezierPoints&&function(t,e){let i,s,n,o,a,r=Jt(t[0],e);for(i=0,s=t.length;i<s;++i)a=o,o=r,r=i<s-1&&Jt(t[i+1],e),o&&(n=t[i],a&&(n.cp1x=Mi(n.cp1x,e.left,e.right),n.cp1y=Mi(n.cp1y,e.top,e.bottom)),r&&(n.cp2x=Mi(n.cp2x,e.left,e.right),n.cp2y=Mi(n.cp2y,e.top,e.bottom)))}(t,i)}const Si=t=>0===t||1===t,Pi=(t,e,i)=>-Math.pow(2,10*(t-=1))*Math.sin((t-e)*yt/i),Di=(t,e,i)=>Math.pow(2,-10*t)*Math.sin((t-e)*yt/i)+1,Ci={linear:t=>t,easeInQuad:t=>t*t,easeOutQuad:t=>-t*(t-2),easeInOutQuad:t=>(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1),easeInCubic:t=>t*t*t,easeOutCubic:t=>(t-=1)*t*t+1,easeInOutCubic:t=>(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2),easeInQuart:t=>t*t*t*t,easeOutQuart:t=>-((t-=1)*t*t*t-1),easeInOutQuart:t=>(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2),easeInQuint:t=>t*t*t*t*t,easeOutQuint:t=>(t-=1)*t*t*t*t+1,easeInOutQuint:t=>(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2),easeInSine:t=>1-Math.cos(t*kt),easeOutSine:t=>Math.sin(t*kt),easeInOutSine:t=>-.5*(Math.cos(_t*t)-1),easeInExpo:t=>0===t?0:Math.pow(2,10*(t-1)),easeOutExpo:t=>1===t?1:1-Math.pow(2,-10*t),easeInOutExpo:t=>Si(t)?t:t<.5?.5*Math.pow(2,10*(2*t-1)):.5*(2-Math.pow(2,-10*(2*t-1))),easeInCirc:t=>t>=1?t:-(Math.sqrt(1-t*t)-1),easeOutCirc:t=>Math.sqrt(1-(t-=1)*t),easeInOutCirc:t=>(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1),easeInElastic:t=>Si(t)?t:Pi(t,.075,.3),easeOutElastic:t=>Si(t)?t:Di(t,.075,.3),easeInOutElastic(t){const e=.1125;return Si(t)?t:t<.5?.5*Pi(2*t,e,.45):.5+.5*Di(2*t-1,e,.45)},easeInBack(t){const e=1.70158;return t*t*((e+1)*t-e)},easeOutBack(t){const e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack(t){let e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:t=>1-Ci.easeOutBounce(1-t),easeOutBounce(t){const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375},easeInOutBounce:t=>t<.5?.5*Ci.easeInBounce(2*t):.5*Ci.easeOutBounce(2*t-1)+.5};function Oi(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:t.y+i*(e.y-t.y)}}function Ai(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:"middle"===s?i<.5?t.y:e.y:"after"===s?i<1?t.y:e.y:i>0?e.y:t.y}}function Ti(t,e,i,s){const n={x:t.cp2x,y:t.cp2y},o={x:e.cp1x,y:e.cp1y},a=Oi(t,n,i),r=Oi(n,o,i),l=Oi(o,e,i),h=Oi(a,r,i),c=Oi(r,l,i);return Oi(h,c,i)}const Li=new Map;function Ri(t,e,i){return function(t,e){e=e||{};const i=t+JSON.stringify(e);let s=Li.get(i);return s||(s=new Intl.NumberFormat(t,e),Li.set(i,s)),s}(e,i).format(t)}function Ei(t,e,i){return t?function(t,e){return{x:i=>t+t+e-i,setWidth(t){e=t},textAlign:t=>"center"===t?t:"right"===t?"left":"right",xPlus:(t,e)=>t-e,leftForLtr:(t,e)=>t-e}}(e,i):{x:t=>t,setWidth(t){},textAlign:t=>t,xPlus:(t,e)=>t+e,leftForLtr:(t,e)=>t}}function Ii(t,e){let i,s;"ltr"!==e&&"rtl"!==e||(i=t.canvas.style,s=[i.getPropertyValue("direction"),i.getPropertyPriority("direction")],i.setProperty("direction",e,"important"),t.prevTextDirection=s)}function zi(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}function Fi(t){return"angle"===t?{between:Ht,compare:Wt,normalize:Nt}:{between:Yt,compare:(t,e)=>t-e,normalize:t=>t}}function Bi({start:t,end:e,count:i,loop:s,style:n}){return{start:t%i,end:e%i,loop:s&&(e-t+1)%i==0,style:n}}function Vi(t,e,i){if(!i)return[t];const{property:s,start:n,end:o}=i,a=e.length,{compare:r,between:l,normalize:h}=Fi(s),{start:c,end:d,loop:u,style:f}=function(t,e,i){const{property:s,start:n,end:o}=i,{between:a,normalize:r}=Fi(s),l=e.length;let h,c,{start:d,end:u,loop:f}=t;if(f){for(d+=l,u+=l,h=0,c=l;h<c&&a(r(e[d%l][s]),n,o);++h)d--,u--;d%=l,u%=l}return u<d&&(u+=l),{start:d,end:u,loop:f,style:t.style}}(t,e,i),g=[];let p,m,x,b=!1,_=null;const y=()=>b||l(n,x,p)&&0!==r(n,x),v=()=>!b||0===r(o,p)||l(o,x,p);for(let t=c,i=c;t<=d;++t)m=e[t%a],m.skip||(p=h(m[s]),p!==x&&(b=l(p,n,o),null===_&&y()&&(_=0===r(p,n)?t:i),null!==_&&v()&&(g.push(Bi({start:_,end:t,loop:u,count:a,style:f})),_=null),i=t,x=p));return null!==_&&g.push(Bi({start:_,end:d,loop:u,count:a,style:f})),g}function Wi(t,e){const i=[],s=t.segments;for(let n=0;n<s.length;n++){const o=Vi(s[n],t.points,e);o.length&&i.push(...o)}return i}function Ni(t,e){const i=t.points,s=t.options.spanGaps,n=i.length;if(!n)return[];const o=!!t._loop,{start:a,end:r}=function(t,e,i,s){let n=0,o=e-1;if(i&&!s)for(;n<e&&!t[n].skip;)n++;for(;n<e&&t[n].skip;)n++;for(n%=e,i&&(o+=n);o>n&&t[o%e].skip;)o--;return o%=e,{start:n,end:o}}(i,n,o,s);if(!0===s)return Hi(t,[{start:a,end:r,loop:o}],i,e);return Hi(t,function(t,e,i,s){const n=t.length,o=[];let a,r=e,l=t[e];for(a=e+1;a<=i;++a){const i=t[a%n];i.skip||i.stop?l.skip||(s=!1,o.push({start:e%n,end:(a-1)%n,loop:s}),e=r=i.stop?a:null):(r=a,l.skip&&(e=a)),l=i}return null!==r&&o.push({start:e%n,end:r%n,loop:s}),o}(i,a,r<a?r+n:r,!!t._fullLoop&&0===a&&r===n-1),i,e)}function Hi(t,e,i,s){return s&&s.setContext&&i?function(t,e,i,s){const n=t._chart.getContext(),o=ji(t.options),{_datasetIndex:a,options:{spanGaps:r}}=t,l=i.length,h=[];let c=o,d=e[0].start,u=d;function f(t,e,s,n){const o=r?-1:1;if(t!==e){for(t+=l;i[t%l].skip;)t-=o;for(;i[e%l].skip;)e+=o;t%l!=e%l&&(h.push({start:t%l,end:e%l,loop:s,style:n}),c=n,d=e%l)}}for(const t of e){d=r?d:t.start;let e,o=i[d%l];for(u=d+1;u<=t.end;u++){const r=i[u%l];e=ji(s.setContext(Ye(n,{type:"segment",p0:o,p1:r,p0DataIndex:(u-1)%l,p1DataIndex:u%l,datasetIndex:a}))),$i(e,c)&&f(d,u-1,t.loop,c),o=r,c=e}d<u-1&&f(d,u-1,t.loop,c)}return h}(t,e,i,s):e}function ji(t){return{backgroundColor:t.backgroundColor,borderCapStyle:t.borderCapStyle,borderDash:t.borderDash,borderDashOffset:t.borderDashOffset,borderJoinStyle:t.borderJoinStyle,borderWidth:t.borderWidth,borderColor:t.borderColor}}function $i(t,e){return e&&JSON.stringify(t)!==JSON.stringify(e)}var Yi=Object.freeze({__proto__:null,easingEffects:Ci,color:W,getHoverColor:N,noop:H,uid:j,isNullOrUndef:$,isArray:Y,isObject:U,isFinite:X,finiteOrDefault:q,valueOrDefault:K,toPercentage:G,toDimension:Z,callback:J,each:Q,_elementsEqual:tt,clone:et,_merger:st,merge:nt,mergeIf:ot,_mergerIf:at,_deprecated:function(t,e,i,s){void 0!==e&&console.warn(t+': "'+i+'" is deprecated. Please use "'+s+'" instead')},resolveObjectKey:lt,_capitalize:ht,defined:ct,isFunction:dt,setsEqual:ut,_isClickEvent:ft,toFontString:Ut,_measureText:Xt,_longestText:qt,_alignPixel:Kt,clearCanvas:Gt,drawPoint:Zt,_isPointInArea:Jt,clipArea:Qt,unclipArea:te,_steppedLineTo:ee,_bezierCurveTo:ie,renderText:se,addRoundedRectPath:oe,_lookup:ae,_lookupByKey:re,_rlookupByKey:le,_filterBetween:he,listenArrayEvents:de,unlistenArrayEvents:ue,_arrayUnique:fe,_createResolver:oi,_attachContext:ai,_descriptors:ri,splineCurve:vi,splineCurveMonotone:wi,_updateBezierControlPoints:ki,_isDomSupported:ge,_getParentNode:pe,getStyle:be,getRelativePosition:ve,getMaximumSize:Me,retinaScale:ke,supportsEventListenerOptions:Se,readUsedSize:Pe,fontString:function(t,e,i){return e+" "+t+"px "+i},requestAnimFrame:t,throttled:e,debounce:i,_toLeftRightCenter:s,_alignStartEnd:n,_textX:o,_pointInLine:Oi,_steppedInterpolation:Ai,_bezierInterpolation:Ti,formatNumber:Ri,toLineHeight:Fe,_readValueToProps:Be,toTRBL:Ve,toTRBLCorners:We,toPadding:Ne,toFont:He,resolve:je,_addGrace:$e,createContext:Ye,PI:_t,TAU:yt,PITAU:vt,INFINITY:wt,RAD_PER_DEG:Mt,HALF_PI:kt,QUARTER_PI:St,TWO_THIRDS_PI:Pt,log10:Dt,sign:Ct,niceNum:Ot,_factorize:At,isNumber:Tt,almostEquals:Lt,almostWhole:Rt,_setMinAndMaxByKey:Et,toRadians:It,toDegrees:zt,_decimalPlaces:Ft,getAngleFromPoint:Bt,distanceBetweenPoints:Vt,_angleDiff:Wt,_normalizeAngle:Nt,_angleBetween:Ht,_limitValue:jt,_int16Range:$t,_isBetween:Yt,getRtlAdapter:Ei,overrideTextDirection:Ii,restoreTextDirection:zi,_boundSegment:Vi,_boundSegments:Wi,_computeSegments:Ni});class Ui{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,i){}removeEventListener(t,e,i){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,i,s){return e=Math.max(0,e||t.width),i=i||t.height,{width:e,height:Math.max(0,s?Math.floor(e/s):i)}}isAttached(t){return!0}updateConfig(t){}}class Xi extends Ui{acquireContext(t){return t&&t.getContext&&t.getContext("2d")||null}updateConfig(t){t.options.animation=!1}}const qi={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},Ki=t=>null===t||""===t;const Gi=!!Se&&{passive:!0};function Zi(t,e,i){t.canvas.removeEventListener(e,i,Gi)}function Ji(t,e){for(const i of t)if(i===e||i.contains(e))return!0}function Qi(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||Ji(i.addedNodes,s),e=e&&!Ji(i.removedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}function ts(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||Ji(i.removedNodes,s),e=e&&!Ji(i.addedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}const es=new Map;let is=0;function ss(){const t=window.devicePixelRatio;t!==is&&(is=t,es.forEach(((e,i)=>{i.currentDevicePixelRatio!==t&&e()})))}function ns(t,i,s){const n=t.canvas,o=n&&pe(n);if(!o)return;const a=e(((t,e)=>{const i=o.clientWidth;s(t,e),i<o.clientWidth&&s()}),window),r=new ResizeObserver((t=>{const e=t[0],i=e.contentRect.width,s=e.contentRect.height;0===i&&0===s||a(i,s)}));return r.observe(o),function(t,e){es.size||window.addEventListener("resize",ss),es.set(t,e)}(t,a),r}function os(t,e,i){i&&i.disconnect(),"resize"===e&&function(t){es.delete(t),es.size||window.removeEventListener("resize",ss)}(t)}function as(t,i,s){const n=t.canvas,o=e((e=>{null!==t.ctx&&s(function(t,e){const i=qi[t.type]||t.type,{x:s,y:n}=ve(t,e);return{type:i,chart:e,native:t,x:void 0!==s?s:null,y:void 0!==n?n:null}}(e,t))}),t,(t=>{const e=t[0];return[e,e.offsetX,e.offsetY]}));return function(t,e,i){t.addEventListener(e,i,Gi)}(n,i,o),o}class rs extends Ui{acquireContext(t,e){const i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){const i=t.style,s=t.getAttribute("height"),n=t.getAttribute("width");if(t.$chartjs={initial:{height:s,width:n,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",i.boxSizing=i.boxSizing||"border-box",Ki(n)){const e=Pe(t,"width");void 0!==e&&(t.width=e)}if(Ki(s))if(""===t.style.height)t.height=t.width/(e||2);else{const e=Pe(t,"height");void 0!==e&&(t.height=e)}}(t,e),i):null}releaseContext(t){const e=t.canvas;if(!e.$chartjs)return!1;const i=e.$chartjs.initial;["height","width"].forEach((t=>{const s=i[t];$(s)?e.removeAttribute(t):e.setAttribute(t,s)}));const s=i.style||{};return Object.keys(s).forEach((t=>{e.style[t]=s[t]})),e.width=e.width,delete e.$chartjs,!0}addEventListener(t,e,i){this.removeEventListener(t,e);const s=t.$proxies||(t.$proxies={}),n={attach:Qi,detach:ts,resize:ns}[e]||as;s[e]=n(t,e,i)}removeEventListener(t,e){const i=t.$proxies||(t.$proxies={}),s=i[e];if(!s)return;({attach:os,detach:os,resize:os}[e]||Zi)(t,e,s),i[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,i,s){return Me(t,e,i,s)}isAttached(t){const e=pe(t);return!(!e||!e.isConnected)}}function ls(t){return!ge()||"undefined"!=typeof OffscreenCanvas&&t instanceof OffscreenCanvas?Xi:rs}var hs=Object.freeze({__proto__:null,_detectPlatform:ls,BasePlatform:Ui,BasicPlatform:Xi,DomPlatform:rs});const cs="transparent",ds={boolean:(t,e,i)=>i>.5?e:t,color(t,e,i){const s=W(t||cs),n=s.valid&&W(e||cs);return n&&n.valid?n.mix(s,i).hexString():e},number:(t,e,i)=>t+(e-t)*i};class us{constructor(t,e,i,s){const n=e[i];s=je([t.to,s,n,t.from]);const o=je([t.from,n,s]);this._active=!0,this._fn=t.fn||ds[t.type||typeof o],this._easing=Ci[t.easing]||Ci.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=i,this._from=o,this._to=s,this._promises=void 0}active(){return this._active}update(t,e,i){if(this._active){this._notify(!1);const s=this._target[this._prop],n=i-this._start,o=this._duration-n;this._start=i,this._duration=Math.floor(Math.max(o,t.duration)),this._total+=n,this._loop=!!t.loop,this._to=je([t.to,e,s,t.from]),this._from=je([t.from,s,e])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(t){const e=t-this._start,i=this._duration,s=this._prop,n=this._from,o=this._loop,a=this._to;let r;if(this._active=n!==a&&(o||e<i),!this._active)return this._target[s]=a,void this._notify(!0);e<0?this._target[s]=n:(r=e/i%2,r=o&&r>1?2-r:r,r=this._easing(Math.min(1,Math.max(0,r))),this._target[s]=this._fn(n,a,r))}wait(){const t=this._promises||(this._promises=[]);return new Promise(((e,i)=>{t.push({res:e,rej:i})}))}_notify(t){const e=t?"res":"rej",i=this._promises||[];for(let t=0;t<i.length;t++)i[t][e]()}}bt.set("animation",{delay:void 0,duration:1e3,easing:"easeOutQuart",fn:void 0,from:void 0,loop:void 0,to:void 0,type:void 0});const fs=Object.keys(bt.animation);bt.describe("animation",{_fallback:!1,_indexable:!1,_scriptable:t=>"onProgress"!==t&&"onComplete"!==t&&"fn"!==t}),bt.set("animations",{colors:{type:"color",properties:["color","borderColor","backgroundColor"]},numbers:{type:"number",properties:["x","y","borderWidth","radius","tension"]}}),bt.describe("animations",{_fallback:"animation"}),bt.set("transitions",{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:"transparent"},visible:{type:"boolean",duration:0}}},hide:{animations:{colors:{to:"transparent"},visible:{type:"boolean",easing:"linear",fn:t=>0|t}}}});class gs{constructor(t,e){this._chart=t,this._properties=new Map,this.configure(e)}configure(t){if(!U(t))return;const e=this._properties;Object.getOwnPropertyNames(t).forEach((i=>{const s=t[i];if(!U(s))return;const n={};for(const t of fs)n[t]=s[t];(Y(s.properties)&&s.properties||[i]).forEach((t=>{t!==i&&e.has(t)||e.set(t,n)}))}))}_animateOptions(t,e){const i=e.options,s=function(t,e){if(!e)return;let i=t.options;if(!i)return void(t.options=e);i.$shared&&(t.options=i=Object.assign({},i,{$shared:!1,$animations:{}}));return i}(t,i);if(!s)return[];const n=this._createAnimations(s,i);return i.$shared&&function(t,e){const i=[],s=Object.keys(e);for(let e=0;e<s.length;e++){const n=t[s[e]];n&&n.active()&&i.push(n.wait())}return Promise.all(i)}(t.options.$animations,i).then((()=>{t.options=i}),(()=>{})),n}_createAnimations(t,e){const i=this._properties,s=[],n=t.$animations||(t.$animations={}),o=Object.keys(e),a=Date.now();let r;for(r=o.length-1;r>=0;--r){const l=o[r];if("$"===l.charAt(0))continue;if("options"===l){s.push(...this._animateOptions(t,e));continue}const h=e[l];let c=n[l];const d=i.get(l);if(c){if(d&&c.active()){c.update(d,h,a);continue}c.cancel()}d&&d.duration?(n[l]=c=new us(d,t,l,h),s.push(c)):t[l]=h}return s}update(t,e){if(0===this._properties.size)return void Object.assign(t,e);const i=this._createAnimations(t,e);return i.length?(a.add(this._chart,i),!0):void 0}}function ps(t,e){const i=t&&t.options||{},s=i.reverse,n=void 0===i.min?e:0,o=void 0===i.max?e:0;return{start:s?o:n,end:s?n:o}}function ms(t,e){const i=[],s=t._getSortedDatasetMetas(e);let n,o;for(n=0,o=s.length;n<o;++n)i.push(s[n].index);return i}function xs(t,e,i,s={}){const n=t.keys,o="single"===s.mode;let a,r,l,h;if(null!==e){for(a=0,r=n.length;a<r;++a){if(l=+n[a],l===i){if(s.all)continue;break}h=t.values[l],X(h)&&(o||0===e||Ct(e)===Ct(h))&&(e+=h)}return e}}function bs(t,e){const i=t&&t.options.stacked;return i||void 0===i&&void 0!==e.stack}function _s(t,e,i){const s=t[e]||(t[e]={});return s[i]||(s[i]={})}function ys(t,e,i,s){for(const n of e.getMatchingVisibleMetas(s).reverse()){const e=t[n.index];if(i&&e>0||!i&&e<0)return n.index}return null}function vs(t,e){const{chart:i,_cachedMeta:s}=t,n=i._stacks||(i._stacks={}),{iScale:o,vScale:a,index:r}=s,l=o.axis,h=a.axis,c=function(t,e,i){return`${t.id}.${e.id}.${i.stack||i.type}`}(o,a,s),d=e.length;let u;for(let t=0;t<d;++t){const i=e[t],{[l]:o,[h]:d}=i;u=(i._stacks||(i._stacks={}))[h]=_s(n,c,o),u[r]=d,u._top=ys(u,a,!0,s.type),u._bottom=ys(u,a,!1,s.type)}}function ws(t,e){const i=t.scales;return Object.keys(i).filter((t=>i[t].axis===e)).shift()}function Ms(t,e){const i=t.controller.index,s=t.vScale&&t.vScale.axis;if(s){e=e||t._parsed;for(const t of e){const e=t._stacks;if(!e||void 0===e[s]||void 0===e[s][i])return;delete e[s][i]}}}const ks=t=>"reset"===t||"none"===t,Ss=(t,e)=>e?t:Object.assign({},t);class Ps{constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.$context=void 0,this._syncList=[],this.initialize()}initialize(){const t=this._cachedMeta;this.configure(),this.linkScales(),t._stacked=bs(t.vScale,t),this.addElements()}updateIndex(t){this.index!==t&&Ms(this._cachedMeta),this.index=t}linkScales(){const t=this.chart,e=this._cachedMeta,i=this.getDataset(),s=(t,e,i,s)=>"x"===t?e:"r"===t?s:i,n=e.xAxisID=K(i.xAxisID,ws(t,"x")),o=e.yAxisID=K(i.yAxisID,ws(t,"y")),a=e.rAxisID=K(i.rAxisID,ws(t,"r")),r=e.indexAxis,l=e.iAxisID=s(r,n,o,a),h=e.vAxisID=s(r,o,n,a);e.xScale=this.getScaleForId(n),e.yScale=this.getScaleForId(o),e.rScale=this.getScaleForId(a),e.iScale=this.getScaleForId(l),e.vScale=this.getScaleForId(h)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){const e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update("reset")}_destroy(){const t=this._cachedMeta;this._data&&ue(this._data,this),t._stacked&&Ms(t)}_dataCheck(){const t=this.getDataset(),e=t.data||(t.data=[]),i=this._data;if(U(e))this._data=function(t){const e=Object.keys(t),i=new Array(e.length);let s,n,o;for(s=0,n=e.length;s<n;++s)o=e[s],i[s]={x:o,y:t[o]};return i}(e);else if(i!==e){if(i){ue(i,this);const t=this._cachedMeta;Ms(t),t._parsed=[]}e&&Object.isExtensible(e)&&de(e,this),this._syncList=[],this._data=e}}addElements(){const t=this._cachedMeta;this._dataCheck(),this.datasetElementType&&(t.dataset=new this.datasetElementType)}buildOrUpdateElements(t){const e=this._cachedMeta,i=this.getDataset();let s=!1;this._dataCheck();const n=e._stacked;e._stacked=bs(e.vScale,e),e.stack!==i.stack&&(s=!0,Ms(e),e.stack=i.stack),this._resyncElements(t),(s||n!==e._stacked)&&vs(this,e._parsed)}configure(){const t=this.chart.config,e=t.datasetScopeKeys(this._type),i=t.getOptionScopes(this.getDataset(),e,!0);this.options=t.createResolver(i,this.getContext()),this._parsing=this.options.parsing,this._cachedDataOpts={}}parse(t,e){const{_cachedMeta:i,_data:s}=this,{iScale:n,_stacked:o}=i,a=n.axis;let r,l,h,c=0===t&&e===s.length||i._sorted,d=t>0&&i._parsed[t-1];if(!1===this._parsing)i._parsed=s,i._sorted=!0,h=s;else{h=Y(s[t])?this.parseArrayData(i,s,t,e):U(s[t])?this.parseObjectData(i,s,t,e):this.parsePrimitiveData(i,s,t,e);const n=()=>null===l[a]||d&&l[a]<d[a];for(r=0;r<e;++r)i._parsed[r+t]=l=h[r],c&&(n()&&(c=!1),d=l);i._sorted=c}o&&vs(this,h)}parsePrimitiveData(t,e,i,s){const{iScale:n,vScale:o}=t,a=n.axis,r=o.axis,l=n.getLabels(),h=n===o,c=new Array(s);let d,u,f;for(d=0,u=s;d<u;++d)f=d+i,c[d]={[a]:h||n.parse(l[f],f),[r]:o.parse(e[f],f)};return c}parseArrayData(t,e,i,s){const{xScale:n,yScale:o}=t,a=new Array(s);let r,l,h,c;for(r=0,l=s;r<l;++r)h=r+i,c=e[h],a[r]={x:n.parse(c[0],h),y:o.parse(c[1],h)};return a}parseObjectData(t,e,i,s){const{xScale:n,yScale:o}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l=new Array(s);let h,c,d,u;for(h=0,c=s;h<c;++h)d=h+i,u=e[d],l[h]={x:n.parse(lt(u,a),d),y:o.parse(lt(u,r),d)};return l}getParsed(t){return this._cachedMeta._parsed[t]}getDataElement(t){return this._cachedMeta.data[t]}applyStack(t,e,i){const s=this.chart,n=this._cachedMeta,o=e[t.axis];return xs({keys:ms(s,!0),values:e._stacks[t.axis]},o,n.index,{mode:i})}updateRangeFromParsed(t,e,i,s){const n=i[e.axis];let o=null===n?NaN:n;const a=s&&i._stacks[e.axis];s&&a&&(s.values=a,o=xs(s,n,this._cachedMeta.index)),t.min=Math.min(t.min,o),t.max=Math.max(t.max,o)}getMinMax(t,e){const i=this._cachedMeta,s=i._parsed,n=i._sorted&&t===i.iScale,o=s.length,a=this._getOtherScale(t),r=((t,e,i)=>t&&!e.hidden&&e._stacked&&{keys:ms(i,!0),values:null})(e,i,this.chart),l={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY},{min:h,max:c}=function(t){const{min:e,max:i,minDefined:s,maxDefined:n}=t.getUserBounds();return{min:s?e:Number.NEGATIVE_INFINITY,max:n?i:Number.POSITIVE_INFINITY}}(a);let d,u;function f(){u=s[d];const e=u[a.axis];return!X(u[t.axis])||h>e||c<e}for(d=0;d<o&&(f()||(this.updateRangeFromParsed(l,t,u,r),!n));++d);if(n)for(d=o-1;d>=0;--d)if(!f()){this.updateRangeFromParsed(l,t,u,r);break}return l}getAllParsedValues(t){const e=this._cachedMeta._parsed,i=[];let s,n,o;for(s=0,n=e.length;s<n;++s)o=e[s][t.axis],X(o)&&i.push(o);return i}getMaxOverflow(){return!1}getLabelAndValue(t){const e=this._cachedMeta,i=e.iScale,s=e.vScale,n=this.getParsed(t);return{label:i?""+i.getLabelForValue(n[i.axis]):"",value:s?""+s.getLabelForValue(n[s.axis]):""}}_update(t){const e=this._cachedMeta;this.update(t||"default"),e._clip=function(t){let e,i,s,n;return U(t)?(e=t.top,i=t.right,s=t.bottom,n=t.left):e=i=s=n=t,{top:e,right:i,bottom:s,left:n,disabled:!1===t}}(K(this.options.clip,function(t,e,i){if(!1===i)return!1;const s=ps(t,i),n=ps(e,i);return{top:n.end,right:s.end,bottom:n.start,left:s.start}}(e.xScale,e.yScale,this.getMaxOverflow())))}update(t){}draw(){const t=this._ctx,e=this.chart,i=this._cachedMeta,s=i.data||[],n=e.chartArea,o=[],a=this._drawStart||0,r=this._drawCount||s.length-a,l=this.options.drawActiveElementsOnTop;let h;for(i.dataset&&i.dataset.draw(t,n,a,r),h=a;h<a+r;++h){const e=s[h];e.hidden||(e.active&&l?o.push(e):e.draw(t,n))}for(h=0;h<o.length;++h)o[h].draw(t,n)}getStyle(t,e){const i=e?"active":"default";return void 0===t&&this._cachedMeta.dataset?this.resolveDatasetElementOptions(i):this.resolveDataElementOptions(t||0,i)}getContext(t,e,i){const s=this.getDataset();let n;if(t>=0&&t<this._cachedMeta.data.length){const e=this._cachedMeta.data[t];n=e.$context||(e.$context=function(t,e,i){return Ye(t,{active:!1,dataIndex:e,parsed:void 0,raw:void 0,element:i,index:e,mode:"default",type:"data"})}(this.getContext(),t,e)),n.parsed=this.getParsed(t),n.raw=s.data[t],n.index=n.dataIndex=t}else n=this.$context||(this.$context=function(t,e){return Ye(t,{active:!1,dataset:void 0,datasetIndex:e,index:e,mode:"default",type:"dataset"})}(this.chart.getContext(),this.index)),n.dataset=s,n.index=n.datasetIndex=this.index;return n.active=!!e,n.mode=i,n}resolveDatasetElementOptions(t){return this._resolveElementOptions(this.datasetElementType.id,t)}resolveDataElementOptions(t,e){return this._resolveElementOptions(this.dataElementType.id,e,t)}_resolveElementOptions(t,e="default",i){const s="active"===e,n=this._cachedDataOpts,o=t+"-"+e,a=n[o],r=this.enableOptionSharing&&ct(i);if(a)return Ss(a,r);const l=this.chart.config,h=l.datasetElementScopeKeys(this._type,t),c=s?[`${t}Hover`,"hover",t,""]:[t,""],d=l.getOptionScopes(this.getDataset(),h),u=Object.keys(bt.elements[t]),f=l.resolveNamedOptions(d,u,(()=>this.getContext(i,s)),c);return f.$shared&&(f.$shared=r,n[o]=Object.freeze(Ss(f,r))),f}_resolveAnimations(t,e,i){const s=this.chart,n=this._cachedDataOpts,o=`animation-${e}`,a=n[o];if(a)return a;let r;if(!1!==s.options.animation){const s=this.chart.config,n=s.datasetAnimationScopeKeys(this._type,e),o=s.getOptionScopes(this.getDataset(),n);r=s.createResolver(o,this.getContext(t,i,e))}const l=new gs(s,r&&r.animations);return r&&r._cacheable&&(n[o]=Object.freeze(l)),l}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||ks(t)||this.chart._animationsDisabled}updateElement(t,e,i,s){ks(s)?Object.assign(t,i):this._resolveAnimations(e,s).update(t,i)}updateSharedOptions(t,e,i){t&&!ks(e)&&this._resolveAnimations(void 0,e).update(t,i)}_setStyle(t,e,i,s){t.active=s;const n=this.getStyle(e,s);this._resolveAnimations(e,i,s).update(t,{options:!s&&this.getSharedOptions(n)||n})}removeHoverStyle(t,e,i){this._setStyle(t,i,"active",!1)}setHoverStyle(t,e,i){this._setStyle(t,i,"active",!0)}_removeDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}_setDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}_resyncElements(t){const e=this._data,i=this._cachedMeta.data;for(const[t,e,i]of this._syncList)this[t](e,i);this._syncList=[];const s=i.length,n=e.length,o=Math.min(n,s);o&&this.parse(0,o),n>s?this._insertElements(s,n-s,t):n<s&&this._removeElements(n,s-n)}_insertElements(t,e,i=!0){const s=this._cachedMeta,n=s.data,o=t+e;let a;const r=t=>{for(t.length+=e,a=t.length-1;a>=o;a--)t[a]=t[a-e]};for(r(n),a=t;a<o;++a)n[a]=new this.dataElementType;this._parsing&&r(s._parsed),this.parse(t,e),i&&this.updateElements(n,t,e,"reset")}updateElements(t,e,i,s){}_removeElements(t,e){const i=this._cachedMeta;if(this._parsing){const s=i._parsed.splice(t,e);i._stacked&&Ms(i,s)}i.data.splice(t,e)}_sync(t){if(this._parsing)this._syncList.push(t);else{const[e,i,s]=t;this[e](i,s)}this.chart._dataChanges.push([this.index,...t])}_onDataPush(){const t=arguments.length;this._sync(["_insertElements",this.getDataset().data.length-t,t])}_onDataPop(){this._sync(["_removeElements",this._cachedMeta.data.length-1,1])}_onDataShift(){this._sync(["_removeElements",0,1])}_onDataSplice(t,e){e&&this._sync(["_removeElements",t,e]);const i=arguments.length-2;i&&this._sync(["_insertElements",t,i])}_onDataUnshift(){this._sync(["_insertElements",0,arguments.length])}}Ps.defaults={},Ps.prototype.datasetElementType=null,Ps.prototype.dataElementType=null;class Ds{constructor(){this.x=void 0,this.y=void 0,this.active=!1,this.options=void 0,this.$animations=void 0}tooltipPosition(t){const{x:e,y:i}=this.getProps(["x","y"],t);return{x:e,y:i}}hasValue(){return Tt(this.x)&&Tt(this.y)}getProps(t,e){const i=this.$animations;if(!e||!i)return this;const s={};return t.forEach((t=>{s[t]=i[t]&&i[t].active()?i[t]._to:this[t]})),s}}Ds.defaults={},Ds.defaultRoutes=void 0;const Cs={values:t=>Y(t)?t:""+t,numeric(t,e,i){if(0===t)return"0";const s=this.chart.options.locale;let n,o=t;if(i.length>1){const e=Math.max(Math.abs(i[0].value),Math.abs(i[i.length-1].value));(e<1e-4||e>1e15)&&(n="scientific"),o=function(t,e){let i=e.length>3?e[2].value-e[1].value:e[1].value-e[0].value;Math.abs(i)>=1&&t!==Math.floor(t)&&(i=t-Math.floor(t));return i}(t,i)}const a=Dt(Math.abs(o)),r=Math.max(Math.min(-1*Math.floor(a),20),0),l={notation:n,minimumFractionDigits:r,maximumFractionDigits:r};return Object.assign(l,this.options.ticks.format),Ri(t,s,l)},logarithmic(t,e,i){if(0===t)return"0";const s=t/Math.pow(10,Math.floor(Dt(t)));return 1===s||2===s||5===s?Cs.numeric.call(this,t,e,i):""}};var Os={formatters:Cs};function As(t,e){const i=t.options.ticks,s=i.maxTicksLimit||function(t){const e=t.options.offset,i=t._tickSize(),s=t._length/i+(e?0:1),n=t._maxLength/i;return Math.floor(Math.min(s,n))}(t),n=i.major.enabled?function(t){const e=[];let i,s;for(i=0,s=t.length;i<s;i++)t[i].major&&e.push(i);return e}(e):[],o=n.length,a=n[0],r=n[o-1],l=[];if(o>s)return function(t,e,i,s){let n,o=0,a=i[0];for(s=Math.ceil(s),n=0;n<t.length;n++)n===a&&(e.push(t[n]),o++,a=i[o*s])}(e,l,n,o/s),l;const h=function(t,e,i){const s=function(t){const e=t.length;let i,s;if(e<2)return!1;for(s=t[0],i=1;i<e;++i)if(t[i]-t[i-1]!==s)return!1;return s}(t),n=e.length/i;if(!s)return Math.max(n,1);const o=At(s);for(let t=0,e=o.length-1;t<e;t++){const e=o[t];if(e>n)return e}return Math.max(n,1)}(n,e,s);if(o>0){let t,i;const s=o>1?Math.round((r-a)/(o-1)):null;for(Ts(e,l,h,$(s)?0:a-s,a),t=0,i=o-1;t<i;t++)Ts(e,l,h,n[t],n[t+1]);return Ts(e,l,h,r,$(s)?e.length:r+s),l}return Ts(e,l,h),l}function Ts(t,e,i,s,n){const o=K(s,0),a=Math.min(K(n,t.length),t.length);let r,l,h,c=0;for(i=Math.ceil(i),n&&(r=n-s,i=r/Math.floor(r/i)),h=o;h<0;)c++,h=Math.round(o+c*i);for(l=Math.max(o,0);l<a;l++)l===h&&(e.push(t[l]),c++,h=Math.round(o+c*i))}bt.set("scale",{display:!0,offset:!1,reverse:!1,beginAtZero:!1,bounds:"ticks",grace:0,grid:{display:!0,lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickLength:8,tickWidth:(t,e)=>e.lineWidth,tickColor:(t,e)=>e.color,offset:!1,borderDash:[],borderDashOffset:0,borderWidth:1},title:{display:!1,text:"",padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:"",padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:Os.formatters.values,minor:{},major:{},align:"center",crossAlign:"near",showLabelBackdrop:!1,backdropColor:"rgba(255, 255, 255, 0.75)",backdropPadding:2}}),bt.route("scale.ticks","color","","color"),bt.route("scale.grid","color","","borderColor"),bt.route("scale.grid","borderColor","","borderColor"),bt.route("scale.title","color","","color"),bt.describe("scale",{_fallback:!1,_scriptable:t=>!t.startsWith("before")&&!t.startsWith("after")&&"callback"!==t&&"parser"!==t,_indexable:t=>"borderDash"!==t&&"tickBorderDash"!==t}),bt.describe("scales",{_fallback:"scale"}),bt.describe("scale.ticks",{_scriptable:t=>"backdropPadding"!==t&&"callback"!==t,_indexable:t=>"backdropPadding"!==t});const Ls=(t,e,i)=>"top"===e||"left"===e?t[e]+i:t[e]-i;function Rs(t,e){const i=[],s=t.length/e,n=t.length;let o=0;for(;o<n;o+=s)i.push(t[Math.floor(o)]);return i}function Es(t,e,i){const s=t.ticks.length,n=Math.min(e,s-1),o=t._startPixel,a=t._endPixel,r=1e-6;let l,h=t.getPixelForTick(n);if(!(i&&(l=1===s?Math.max(h-o,a-h):0===e?(t.getPixelForTick(1)-h)/2:(h-t.getPixelForTick(n-1))/2,h+=n<e?l:-l,h<o-r||h>a+r)))return h}function Is(t){return t.drawTicks?t.tickLength:0}function zs(t,e){if(!t.display)return 0;const i=He(t.font,e),s=Ne(t.padding);return(Y(t.text)?t.text.length:1)*i.lineHeight+s.height}function Fs(t,e,i){let n=s(t);return(i&&"right"!==e||!i&&"right"===e)&&(n=(t=>"left"===t?"right":"right"===t?"left":t)(n)),n}class Bs extends Ds{constructor(t){super(),this.id=t.id,this.type=t.type,this.options=void 0,this.ctx=t.ctx,this.chart=t.chart,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this._margins={left:0,right:0,top:0,bottom:0},this.maxWidth=void 0,this.maxHeight=void 0,this.paddingTop=void 0,this.paddingBottom=void 0,this.paddingLeft=void 0,this.paddingRight=void 0,this.axis=void 0,this.labelRotation=void 0,this.min=void 0,this.max=void 0,this._range=void 0,this.ticks=[],this._gridLineItems=null,this._labelItems=null,this._labelSizes=null,this._length=0,this._maxLength=0,this._longestTextCache={},this._startPixel=void 0,this._endPixel=void 0,this._reversePixels=!1,this._userMax=void 0,this._userMin=void 0,this._suggestedMax=void 0,this._suggestedMin=void 0,this._ticksLength=0,this._borderValue=0,this._cache={},this._dataLimitsCached=!1,this.$context=void 0}init(t){this.options=t.setContext(this.getContext()),this.axis=t.axis,this._userMin=this.parse(t.min),this._userMax=this.parse(t.max),this._suggestedMin=this.parse(t.suggestedMin),this._suggestedMax=this.parse(t.suggestedMax)}parse(t,e){return t}getUserBounds(){let{_userMin:t,_userMax:e,_suggestedMin:i,_suggestedMax:s}=this;return t=q(t,Number.POSITIVE_INFINITY),e=q(e,Number.NEGATIVE_INFINITY),i=q(i,Number.POSITIVE_INFINITY),s=q(s,Number.NEGATIVE_INFINITY),{min:q(t,i),max:q(e,s),minDefined:X(t),maxDefined:X(e)}}getMinMax(t){let e,{min:i,max:s,minDefined:n,maxDefined:o}=this.getUserBounds();if(n&&o)return{min:i,max:s};const a=this.getMatchingVisibleMetas();for(let r=0,l=a.length;r<l;++r)e=a[r].controller.getMinMax(this,t),n||(i=Math.min(i,e.min)),o||(s=Math.max(s,e.max));return i=o&&i>s?s:i,s=n&&i>s?i:s,{min:q(i,q(s,i)),max:q(s,q(i,s))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){const t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){J(this.options.beforeUpdate,[this])}update(t,e,i){const{beginAtZero:s,grace:n,ticks:o}=this.options,a=o.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=i=Object.assign({left:0,right:0,top:0,bottom:0},i),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+i.left+i.right:this.height+i.top+i.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=$e(this,n,s),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();const r=a<this.ticks.length;this._convertTicksToLabels(r?Rs(this.ticks,a):this.ticks),this.configure(),this.beforeCalculateLabelRotation(),this.calculateLabelRotation(),this.afterCalculateLabelRotation(),o.display&&(o.autoSkip||"auto"===o.source)&&(this.ticks=As(this,this.ticks),this._labelSizes=null),r&&this._convertTicksToLabels(this.ticks),this.beforeFit(),this.fit(),this.afterFit(),this.afterUpdate()}configure(){let t,e,i=this.options.reverse;this.isHorizontal()?(t=this.left,e=this.right):(t=this.top,e=this.bottom,i=!i),this._startPixel=t,this._endPixel=e,this._reversePixels=i,this._length=e-t,this._alignToPixels=this.options.alignToPixels}afterUpdate(){J(this.options.afterUpdate,[this])}beforeSetDimensions(){J(this.options.beforeSetDimensions,[this])}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=0,this.right=this.width):(this.height=this.maxHeight,this.top=0,this.bottom=this.height),this.paddingLeft=0,this.paddingTop=0,this.paddingRight=0,this.paddingBottom=0}afterSetDimensions(){J(this.options.afterSetDimensions,[this])}_callHooks(t){this.chart.notifyPlugins(t,this.getContext()),J(this.options[t],[this])}beforeDataLimits(){this._callHooks("beforeDataLimits")}determineDataLimits(){}afterDataLimits(){this._callHooks("afterDataLimits")}beforeBuildTicks(){this._callHooks("beforeBuildTicks")}buildTicks(){return[]}afterBuildTicks(){this._callHooks("afterBuildTicks")}beforeTickToLabelConversion(){J(this.options.beforeTickToLabelConversion,[this])}generateTickLabels(t){const e=this.options.ticks;let i,s,n;for(i=0,s=t.length;i<s;i++)n=t[i],n.label=J(e.callback,[n.value,i,t],this)}afterTickToLabelConversion(){J(this.options.afterTickToLabelConversion,[this])}beforeCalculateLabelRotation(){J(this.options.beforeCalculateLabelRotation,[this])}calculateLabelRotation(){const t=this.options,e=t.ticks,i=this.ticks.length,s=e.minRotation||0,n=e.maxRotation;let o,a,r,l=s;if(!this._isVisible()||!e.display||s>=n||i<=1||!this.isHorizontal())return void(this.labelRotation=s);const h=this._getLabelSizes(),c=h.widest.width,d=h.highest.height,u=jt(this.chart.width-c,0,this.maxWidth);o=t.offset?this.maxWidth/i:u/(i-1),c+6>o&&(o=u/(i-(t.offset?.5:1)),a=this.maxHeight-Is(t.grid)-e.padding-zs(t.title,this.chart.options.font),r=Math.sqrt(c*c+d*d),l=zt(Math.min(Math.asin(jt((h.highest.height+6)/o,-1,1)),Math.asin(jt(a/r,-1,1))-Math.asin(jt(d/r,-1,1)))),l=Math.max(s,Math.min(n,l))),this.labelRotation=l}afterCalculateLabelRotation(){J(this.options.afterCalculateLabelRotation,[this])}beforeFit(){J(this.options.beforeFit,[this])}fit(){const t={width:0,height:0},{chart:e,options:{ticks:i,title:s,grid:n}}=this,o=this._isVisible(),a=this.isHorizontal();if(o){const o=zs(s,e.options.font);if(a?(t.width=this.maxWidth,t.height=Is(n)+o):(t.height=this.maxHeight,t.width=Is(n)+o),i.display&&this.ticks.length){const{first:e,last:s,widest:n,highest:o}=this._getLabelSizes(),r=2*i.padding,l=It(this.labelRotation),h=Math.cos(l),c=Math.sin(l);if(a){const e=i.mirror?0:c*n.width+h*o.height;t.height=Math.min(this.maxHeight,t.height+e+r)}else{const e=i.mirror?0:h*n.width+c*o.height;t.width=Math.min(this.maxWidth,t.width+e+r)}this._calculatePadding(e,s,c,h)}}this._handleMargins(),a?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}_calculatePadding(t,e,i,s){const{ticks:{align:n,padding:o},position:a}=this.options,r=0!==this.labelRotation,l="top"!==a&&"x"===this.axis;if(this.isHorizontal()){const a=this.getPixelForTick(0)-this.left,h=this.right-this.getPixelForTick(this.ticks.length-1);let c=0,d=0;r?l?(c=s*t.width,d=i*e.height):(c=i*t.height,d=s*e.width):"start"===n?d=e.width:"end"===n?c=t.width:(c=t.width/2,d=e.width/2),this.paddingLeft=Math.max((c-a+o)*this.width/(this.width-a),0),this.paddingRight=Math.max((d-h+o)*this.width/(this.width-h),0)}else{let i=e.height/2,s=t.height/2;"start"===n?(i=0,s=t.height):"end"===n&&(i=e.height,s=0),this.paddingTop=i+o,this.paddingBottom=s+o}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){J(this.options.afterFit,[this])}isHorizontal(){const{axis:t,position:e}=this.options;return"top"===e||"bottom"===e||"x"===t}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){let e,i;for(this.beforeTickToLabelConversion(),this.generateTickLabels(t),e=0,i=t.length;e<i;e++)$(t[e].label)&&(t.splice(e,1),i--,e--);this.afterTickToLabelConversion()}_getLabelSizes(){let t=this._labelSizes;if(!t){const e=this.options.ticks.sampleSize;let i=this.ticks;e<i.length&&(i=Rs(i,e)),this._labelSizes=t=this._computeLabelSizes(i,i.length)}return t}_computeLabelSizes(t,e){const{ctx:i,_longestTextCache:s}=this,n=[],o=[];let a,r,l,h,c,d,u,f,g,p,m,x=0,b=0;for(a=0;a<e;++a){if(h=t[a].label,c=this._resolveTickFontOptions(a),i.font=d=c.string,u=s[d]=s[d]||{data:{},gc:[]},f=c.lineHeight,g=p=0,$(h)||Y(h)){if(Y(h))for(r=0,l=h.length;r<l;++r)m=h[r],$(m)||Y(m)||(g=Xt(i,u.data,u.gc,g,m),p+=f)}else g=Xt(i,u.data,u.gc,g,h),p=f;n.push(g),o.push(p),x=Math.max(g,x),b=Math.max(p,b)}!function(t,e){Q(t,(t=>{const i=t.gc,s=i.length/2;let n;if(s>e){for(n=0;n<s;++n)delete t.data[i[n]];i.splice(0,s)}}))}(s,e);const _=n.indexOf(x),y=o.indexOf(b),v=t=>({width:n[t]||0,height:o[t]||0});return{first:v(0),last:v(e-1),widest:v(_),highest:v(y),widths:n,heights:o}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);const e=this._startPixel+t*this._length;return $t(this._alignToPixels?Kt(this.chart,e,0):e)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this.ticks||[];if(t>=0&&t<e.length){const i=e[t];return i.$context||(i.$context=function(t,e,i){return Ye(t,{tick:i,index:e,type:"tick"})}(this.getContext(),t,i))}return this.$context||(this.$context=Ye(this.chart.getContext(),{scale:this,type:"scale"}))}_tickSize(){const t=this.options.ticks,e=It(this.labelRotation),i=Math.abs(Math.cos(e)),s=Math.abs(Math.sin(e)),n=this._getLabelSizes(),o=t.autoSkipPadding||0,a=n?n.widest.width+o:0,r=n?n.highest.height+o:0;return this.isHorizontal()?r*i>a*s?a/i:r/s:r*s<a*i?r/i:a/s}_isVisible(){const t=this.options.display;return"auto"!==t?!!t:this.getMatchingVisibleMetas().length>0}_computeGridLineItems(t){const e=this.axis,i=this.chart,s=this.options,{grid:n,position:o}=s,a=n.offset,r=this.isHorizontal(),l=this.ticks.length+(a?1:0),h=Is(n),c=[],d=n.setContext(this.getContext()),u=d.drawBorder?d.borderWidth:0,f=u/2,g=function(t){return Kt(i,t,u)};let p,m,x,b,_,y,v,w,M,k,S,P;if("top"===o)p=g(this.bottom),y=this.bottom-h,w=p-f,k=g(t.top)+f,P=t.bottom;else if("bottom"===o)p=g(this.top),k=t.top,P=g(t.bottom)-f,y=p+f,w=this.top+h;else if("left"===o)p=g(this.right),_=this.right-h,v=p-f,M=g(t.left)+f,S=t.right;else if("right"===o)p=g(this.left),M=t.left,S=g(t.right)-f,_=p+f,v=this.left+h;else if("x"===e){if("center"===o)p=g((t.top+t.bottom)/2+.5);else if(U(o)){const t=Object.keys(o)[0],e=o[t];p=g(this.chart.scales[t].getPixelForValue(e))}k=t.top,P=t.bottom,y=p+f,w=y+h}else if("y"===e){if("center"===o)p=g((t.left+t.right)/2);else if(U(o)){const t=Object.keys(o)[0],e=o[t];p=g(this.chart.scales[t].getPixelForValue(e))}_=p-f,v=_-h,M=t.left,S=t.right}const D=K(s.ticks.maxTicksLimit,l),C=Math.max(1,Math.ceil(l/D));for(m=0;m<l;m+=C){const t=n.setContext(this.getContext(m)),e=t.lineWidth,s=t.color,o=n.borderDash||[],l=t.borderDashOffset,h=t.tickWidth,d=t.tickColor,u=t.tickBorderDash||[],f=t.tickBorderDashOffset;x=Es(this,m,a),void 0!==x&&(b=Kt(i,x,e),r?_=v=M=S=b:y=w=k=P=b,c.push({tx1:_,ty1:y,tx2:v,ty2:w,x1:M,y1:k,x2:S,y2:P,width:e,color:s,borderDash:o,borderDashOffset:l,tickWidth:h,tickColor:d,tickBorderDash:u,tickBorderDashOffset:f}))}return this._ticksLength=l,this._borderValue=p,c}_computeLabelItems(t){const e=this.axis,i=this.options,{position:s,ticks:n}=i,o=this.isHorizontal(),a=this.ticks,{align:r,crossAlign:l,padding:h,mirror:c}=n,d=Is(i.grid),u=d+h,f=c?-h:u,g=-It(this.labelRotation),p=[];let m,x,b,_,y,v,w,M,k,S,P,D,C="middle";if("top"===s)v=this.bottom-f,w=this._getXAxisLabelAlignment();else if("bottom"===s)v=this.top+f,w=this._getXAxisLabelAlignment();else if("left"===s){const t=this._getYAxisLabelAlignment(d);w=t.textAlign,y=t.x}else if("right"===s){const t=this._getYAxisLabelAlignment(d);w=t.textAlign,y=t.x}else if("x"===e){if("center"===s)v=(t.top+t.bottom)/2+u;else if(U(s)){const t=Object.keys(s)[0],e=s[t];v=this.chart.scales[t].getPixelForValue(e)+u}w=this._getXAxisLabelAlignment()}else if("y"===e){if("center"===s)y=(t.left+t.right)/2-u;else if(U(s)){const t=Object.keys(s)[0],e=s[t];y=this.chart.scales[t].getPixelForValue(e)}w=this._getYAxisLabelAlignment(d).textAlign}"y"===e&&("start"===r?C="top":"end"===r&&(C="bottom"));const O=this._getLabelSizes();for(m=0,x=a.length;m<x;++m){b=a[m],_=b.label;const t=n.setContext(this.getContext(m));M=this.getPixelForTick(m)+n.labelOffset,k=this._resolveTickFontOptions(m),S=k.lineHeight,P=Y(_)?_.length:1;const e=P/2,i=t.color,r=t.textStrokeColor,h=t.textStrokeWidth;let d;if(o?(y=M,D="top"===s?"near"===l||0!==g?-P*S+S/2:"center"===l?-O.highest.height/2-e*S+S:-O.highest.height+S/2:"near"===l||0!==g?S/2:"center"===l?O.highest.height/2-e*S:O.highest.height-P*S,c&&(D*=-1)):(v=M,D=(1-P)*S/2),t.showLabelBackdrop){const e=Ne(t.backdropPadding),i=O.heights[m],s=O.widths[m];let n=v+D-e.top,o=y-e.left;switch(C){case"middle":n-=i/2;break;case"bottom":n-=i}switch(w){case"center":o-=s/2;break;case"right":o-=s}d={left:o,top:n,width:s+e.width,height:i+e.height,color:t.backdropColor}}p.push({rotation:g,label:_,font:k,color:i,strokeColor:r,strokeWidth:h,textOffset:D,textAlign:w,textBaseline:C,translation:[y,v],backdrop:d})}return p}_getXAxisLabelAlignment(){const{position:t,ticks:e}=this.options;if(-It(this.labelRotation))return"top"===t?"left":"right";let i="center";return"start"===e.align?i="left":"end"===e.align&&(i="right"),i}_getYAxisLabelAlignment(t){const{position:e,ticks:{crossAlign:i,mirror:s,padding:n}}=this.options,o=t+n,a=this._getLabelSizes().widest.width;let r,l;return"left"===e?s?(l=this.right+n,"near"===i?r="left":"center"===i?(r="center",l+=a/2):(r="right",l+=a)):(l=this.right-o,"near"===i?r="right":"center"===i?(r="center",l-=a/2):(r="left",l=this.left)):"right"===e?s?(l=this.left+n,"near"===i?r="right":"center"===i?(r="center",l-=a/2):(r="left",l-=a)):(l=this.left+o,"near"===i?r="left":"center"===i?(r="center",l+=a/2):(r="right",l=this.right)):r="right",{textAlign:r,x:l}}_computeLabelArea(){if(this.options.ticks.mirror)return;const t=this.chart,e=this.options.position;return"left"===e||"right"===e?{top:0,left:this.left,bottom:t.height,right:this.right}:"top"===e||"bottom"===e?{top:this.top,left:0,bottom:this.bottom,right:t.width}:void 0}drawBackground(){const{ctx:t,options:{backgroundColor:e},left:i,top:s,width:n,height:o}=this;e&&(t.save(),t.fillStyle=e,t.fillRect(i,s,n,o),t.restore())}getLineWidthForValue(t){const e=this.options.grid;if(!this._isVisible()||!e.display)return 0;const i=this.ticks.findIndex((e=>e.value===t));if(i>=0){return e.setContext(this.getContext(i)).lineWidth}return 0}drawGrid(t){const e=this.options.grid,i=this.ctx,s=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t));let n,o;const a=(t,e,s)=>{s.width&&s.color&&(i.save(),i.lineWidth=s.width,i.strokeStyle=s.color,i.setLineDash(s.borderDash||[]),i.lineDashOffset=s.borderDashOffset,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),i.restore())};if(e.display)for(n=0,o=s.length;n<o;++n){const t=s[n];e.drawOnChartArea&&a({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},t),e.drawTicks&&a({x:t.tx1,y:t.ty1},{x:t.tx2,y:t.ty2},{color:t.tickColor,width:t.tickWidth,borderDash:t.tickBorderDash,borderDashOffset:t.tickBorderDashOffset})}}drawBorder(){const{chart:t,ctx:e,options:{grid:i}}=this,s=i.setContext(this.getContext()),n=i.drawBorder?s.borderWidth:0;if(!n)return;const o=i.setContext(this.getContext(0)).lineWidth,a=this._borderValue;let r,l,h,c;this.isHorizontal()?(r=Kt(t,this.left,n)-n/2,l=Kt(t,this.right,o)+o/2,h=c=a):(h=Kt(t,this.top,n)-n/2,c=Kt(t,this.bottom,o)+o/2,r=l=a),e.save(),e.lineWidth=s.borderWidth,e.strokeStyle=s.borderColor,e.beginPath(),e.moveTo(r,h),e.lineTo(l,c),e.stroke(),e.restore()}drawLabels(t){if(!this.options.ticks.display)return;const e=this.ctx,i=this._computeLabelArea();i&&Qt(e,i);const s=this._labelItems||(this._labelItems=this._computeLabelItems(t));let n,o;for(n=0,o=s.length;n<o;++n){const t=s[n],i=t.font,o=t.label;t.backdrop&&(e.fillStyle=t.backdrop.color,e.fillRect(t.backdrop.left,t.backdrop.top,t.backdrop.width,t.backdrop.height)),se(e,o,0,t.textOffset,i,t)}i&&te(e)}drawTitle(){const{ctx:t,options:{position:e,title:i,reverse:s}}=this;if(!i.display)return;const o=He(i.font),a=Ne(i.padding),r=i.align;let l=o.lineHeight/2;"bottom"===e||"center"===e||U(e)?(l+=a.bottom,Y(i.text)&&(l+=o.lineHeight*(i.text.length-1))):l+=a.top;const{titleX:h,titleY:c,maxWidth:d,rotation:u}=function(t,e,i,s){const{top:o,left:a,bottom:r,right:l,chart:h}=t,{chartArea:c,scales:d}=h;let u,f,g,p=0;const m=r-o,x=l-a;if(t.isHorizontal()){if(f=n(s,a,l),U(i)){const t=Object.keys(i)[0],s=i[t];g=d[t].getPixelForValue(s)+m-e}else g="center"===i?(c.bottom+c.top)/2+m-e:Ls(t,i,e);u=l-a}else{if(U(i)){const t=Object.keys(i)[0],s=i[t];f=d[t].getPixelForValue(s)-x+e}else f="center"===i?(c.left+c.right)/2-x+e:Ls(t,i,e);g=n(s,r,o),p="left"===i?-kt:kt}return{titleX:f,titleY:g,maxWidth:u,rotation:p}}(this,l,e,r);se(t,i.text,0,0,o,{color:i.color,maxWidth:d,rotation:u,textAlign:Fs(r,e,s),textBaseline:"middle",translation:[h,c]})}draw(t){this._isVisible()&&(this.drawBackground(),this.drawGrid(t),this.drawBorder(),this.drawTitle(),this.drawLabels(t))}_layers(){const t=this.options,e=t.ticks&&t.ticks.z||0,i=K(t.grid&&t.grid.z,-1);return this._isVisible()&&this.draw===Bs.prototype.draw?[{z:i,draw:t=>{this.drawBackground(),this.drawGrid(t),this.drawTitle()}},{z:i+1,draw:()=>{this.drawBorder()}},{z:e,draw:t=>{this.drawLabels(t)}}]:[{z:e,draw:t=>{this.draw(t)}}]}getMatchingVisibleMetas(t){const e=this.chart.getSortedVisibleDatasetMetas(),i=this.axis+"AxisID",s=[];let n,o;for(n=0,o=e.length;n<o;++n){const o=e[n];o[i]!==this.id||t&&o.type!==t||s.push(o)}return s}_resolveTickFontOptions(t){return He(this.options.ticks.setContext(this.getContext(t)).font)}_maxDigits(){const t=this._resolveTickFontOptions(0).lineHeight;return(this.isHorizontal()?this.width:this.height)/t}}class Vs{constructor(t,e,i){this.type=t,this.scope=e,this.override=i,this.items=Object.create(null)}isForType(t){return Object.prototype.isPrototypeOf.call(this.type.prototype,t.prototype)}register(t){const e=Object.getPrototypeOf(t);let i;(function(t){return"id"in t&&"defaults"in t})(e)&&(i=this.register(e));const s=this.items,n=t.id,o=this.scope+"."+n;if(!n)throw new Error("class does not have id: "+t);return n in s||(s[n]=t,function(t,e,i){const s=nt(Object.create(null),[i?bt.get(i):{},bt.get(e),t.defaults]);bt.set(e,s),t.defaultRoutes&&function(t,e){Object.keys(e).forEach((i=>{const s=i.split("."),n=s.pop(),o=[t].concat(s).join("."),a=e[i].split("."),r=a.pop(),l=a.join(".");bt.route(o,n,l,r)}))}(e,t.defaultRoutes);t.descriptors&&bt.describe(e,t.descriptors)}(t,o,i),this.override&&bt.override(t.id,t.overrides)),o}get(t){return this.items[t]}unregister(t){const e=this.items,i=t.id,s=this.scope;i in e&&delete e[i],s&&i in bt[s]&&(delete bt[s][i],this.override&&delete gt[i])}}var Ws=new class{constructor(){this.controllers=new Vs(Ps,"datasets",!0),this.elements=new Vs(Ds,"elements"),this.plugins=new Vs(Object,"plugins"),this.scales=new Vs(Bs,"scales"),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...t){this._each("register",t)}remove(...t){this._each("unregister",t)}addControllers(...t){this._each("register",t,this.controllers)}addElements(...t){this._each("register",t,this.elements)}addPlugins(...t){this._each("register",t,this.plugins)}addScales(...t){this._each("register",t,this.scales)}getController(t){return this._get(t,this.controllers,"controller")}getElement(t){return this._get(t,this.elements,"element")}getPlugin(t){return this._get(t,this.plugins,"plugin")}getScale(t){return this._get(t,this.scales,"scale")}removeControllers(...t){this._each("unregister",t,this.controllers)}removeElements(...t){this._each("unregister",t,this.elements)}removePlugins(...t){this._each("unregister",t,this.plugins)}removeScales(...t){this._each("unregister",t,this.scales)}_each(t,e,i){[...e].forEach((e=>{const s=i||this._getRegistryForType(e);i||s.isForType(e)||s===this.plugins&&e.id?this._exec(t,s,e):Q(e,(e=>{const s=i||this._getRegistryForType(e);this._exec(t,s,e)}))}))}_exec(t,e,i){const s=ht(t);J(i["before"+s],[],i),e[t](i),J(i["after"+s],[],i)}_getRegistryForType(t){for(let e=0;e<this._typedRegistries.length;e++){const i=this._typedRegistries[e];if(i.isForType(t))return i}return this.plugins}_get(t,e,i){const s=e.get(t);if(void 0===s)throw new Error('"'+t+'" is not a registered '+i+".");return s}};class Ns{constructor(){this._init=[]}notify(t,e,i,s){"beforeInit"===e&&(this._init=this._createDescriptors(t,!0),this._notify(this._init,t,"install"));const n=s?this._descriptors(t).filter(s):this._descriptors(t),o=this._notify(n,t,e,i);return"afterDestroy"===e&&(this._notify(n,t,"stop"),this._notify(this._init,t,"uninstall")),o}_notify(t,e,i,s){s=s||{};for(const n of t){const t=n.plugin;if(!1===J(t[i],[e,s,n.options],t)&&s.cancelable)return!1}return!0}invalidate(){$(this._cache)||(this._oldCache=this._cache,this._cache=void 0)}_descriptors(t){if(this._cache)return this._cache;const e=this._cache=this._createDescriptors(t);return this._notifyStateChanges(t),e}_createDescriptors(t,e){const i=t&&t.config,s=K(i.options&&i.options.plugins,{}),n=function(t){const e=[],i=Object.keys(Ws.plugins.items);for(let t=0;t<i.length;t++)e.push(Ws.getPlugin(i[t]));const s=t.plugins||[];for(let t=0;t<s.length;t++){const i=s[t];-1===e.indexOf(i)&&e.push(i)}return e}(i);return!1!==s||e?function(t,e,i,s){const n=[],o=t.getContext();for(let a=0;a<e.length;a++){const r=e[a],l=Hs(i[r.id],s);null!==l&&n.push({plugin:r,options:js(t.config,r,l,o)})}return n}(t,n,s,e):[]}_notifyStateChanges(t){const e=this._oldCache||[],i=this._cache,s=(t,e)=>t.filter((t=>!e.some((e=>t.plugin.id===e.plugin.id))));this._notify(s(e,i),t,"stop"),this._notify(s(i,e),t,"start")}}function Hs(t,e){return e||!1!==t?!0===t?{}:t:null}function js(t,e,i,s){const n=t.pluginScopeKeys(e),o=t.getOptionScopes(i,n);return t.createResolver(o,s,[""],{scriptable:!1,indexable:!1,allKeys:!0})}function $s(t,e){const i=bt.datasets[t]||{};return((e.datasets||{})[t]||{}).indexAxis||e.indexAxis||i.indexAxis||"x"}function Ys(t,e){return"x"===t||"y"===t?t:e.axis||("top"===(i=e.position)||"bottom"===i?"x":"left"===i||"right"===i?"y":void 0)||t.charAt(0).toLowerCase();var i}function Us(t){const e=t.options||(t.options={});e.plugins=K(e.plugins,{}),e.scales=function(t,e){const i=gt[t.type]||{scales:{}},s=e.scales||{},n=$s(t.type,e),o=Object.create(null),a=Object.create(null);return Object.keys(s).forEach((t=>{const e=s[t];if(!U(e))return console.error(`Invalid scale configuration for scale: ${t}`);if(e._proxy)return console.warn(`Ignoring resolver passed as options for scale: ${t}`);const r=Ys(t,e),l=function(t,e){return t===e?"_index_":"_value_"}(r,n),h=i.scales||{};o[r]=o[r]||t,a[t]=ot(Object.create(null),[{axis:r},e,h[r],h[l]])})),t.data.datasets.forEach((i=>{const n=i.type||t.type,r=i.indexAxis||$s(n,e),l=(gt[n]||{}).scales||{};Object.keys(l).forEach((t=>{const e=function(t,e){let i=t;return"_index_"===t?i=e:"_value_"===t&&(i="x"===e?"y":"x"),i}(t,r),n=i[e+"AxisID"]||o[e]||e;a[n]=a[n]||Object.create(null),ot(a[n],[{axis:e},s[n],l[t]])}))})),Object.keys(a).forEach((t=>{const e=a[t];ot(e,[bt.scales[e.type],bt.scale])})),a}(t,e)}function Xs(t){return(t=t||{}).datasets=t.datasets||[],t.labels=t.labels||[],t}const qs=new Map,Ks=new Set;function Gs(t,e){let i=qs.get(t);return i||(i=e(),qs.set(t,i),Ks.add(i)),i}const Zs=(t,e,i)=>{const s=lt(e,i);void 0!==s&&t.add(s)};class Js{constructor(t){this._config=function(t){return(t=t||{}).data=Xs(t.data),Us(t),t}(t),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=Xs(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){const t=this._config;this.clearCache(),Us(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return Gs(t,(()=>[[`datasets.${t}`,""]]))}datasetAnimationScopeKeys(t,e){return Gs(`${t}.transition.${e}`,(()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,""]]))}datasetElementScopeKeys(t,e){return Gs(`${t}-${e}`,(()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,""]]))}pluginScopeKeys(t){const e=t.id;return Gs(`${this.type}-plugin-${e}`,(()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]]))}_cachedScopes(t,e){const i=this._scopeCache;let s=i.get(t);return s&&!e||(s=new Map,i.set(t,s)),s}getOptionScopes(t,e,i){const{options:s,type:n}=this,o=this._cachedScopes(t,i),a=o.get(e);if(a)return a;const r=new Set;e.forEach((e=>{t&&(r.add(t),e.forEach((e=>Zs(r,t,e)))),e.forEach((t=>Zs(r,s,t))),e.forEach((t=>Zs(r,gt[n]||{},t))),e.forEach((t=>Zs(r,bt,t))),e.forEach((t=>Zs(r,pt,t)))}));const l=Array.from(r);return 0===l.length&&l.push(Object.create(null)),Ks.has(e)&&o.set(e,l),l}chartOptionScopes(){const{options:t,type:e}=this;return[t,gt[e]||{},bt.datasets[e]||{},{type:e},bt,pt]}resolveNamedOptions(t,e,i,s=[""]){const n={$shared:!0},{resolver:o,subPrefixes:a}=Qs(this._resolverCache,t,s);let r=o;if(function(t,e){const{isScriptable:i,isIndexable:s}=ri(t);for(const n of e){const e=i(n),o=s(n),a=(o||e)&&t[n];if(e&&(dt(a)||tn(a))||o&&Y(a))return!0}return!1}(o,e)){n.$shared=!1;r=ai(o,i=dt(i)?i():i,this.createResolver(t,i,a))}for(const t of e)n[t]=r[t];return n}createResolver(t,e,i=[""],s){const{resolver:n}=Qs(this._resolverCache,t,i);return U(e)?ai(n,e,void 0,s):n}}function Qs(t,e,i){let s=t.get(e);s||(s=new Map,t.set(e,s));const n=i.join();let o=s.get(n);if(!o){o={resolver:oi(e,i),subPrefixes:i.filter((t=>!t.toLowerCase().includes("hover")))},s.set(n,o)}return o}const tn=t=>U(t)&&Object.getOwnPropertyNames(t).reduce(((e,i)=>e||dt(t[i])),!1);const en=["top","bottom","left","right","chartArea"];function sn(t,e){return"top"===t||"bottom"===t||-1===en.indexOf(t)&&"x"===e}function nn(t,e){return function(i,s){return i[t]===s[t]?i[e]-s[e]:i[t]-s[t]}}function on(t){const e=t.chart,i=e.options.animation;e.notifyPlugins("afterRender"),J(i&&i.onComplete,[t],e)}function an(t){const e=t.chart,i=e.options.animation;J(i&&i.onProgress,[t],e)}function rn(t){return ge()&&"string"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}const ln={},hn=t=>{const e=rn(t);return Object.values(ln).filter((t=>t.canvas===e)).pop()};function cn(t,e,i){const s=Object.keys(t);for(const n of s){const s=+n;if(s>=e){const o=t[n];delete t[n],(i>0||s>e)&&(t[s+i]=o)}}}class dn{constructor(t,e){const s=this.config=new Js(e),n=rn(t),o=hn(n);if(o)throw new Error("Canvas is already in use. Chart with ID '"+o.id+"' must be destroyed before the canvas can be reused.");const r=s.createResolver(s.chartOptionScopes(),this.getContext());this.platform=new(s.platform||ls(n)),this.platform.updateConfig(s);const l=this.platform.acquireContext(n,r.aspectRatio),h=l&&l.canvas,c=h&&h.height,d=h&&h.width;this.id=j(),this.ctx=l,this.canvas=h,this.width=d,this.height=c,this._options=r,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new Ns,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=i((t=>this.update(t)),r.resizeDelay||0),this._dataChanges=[],ln[this.id]=this,l&&h?(a.listen(this,"complete",on),a.listen(this,"progress",an),this._initialize(),this.attached&&this.update()):console.error("Failed to create chart: can't acquire context from the given item")}get aspectRatio(){const{options:{aspectRatio:t,maintainAspectRatio:e},width:i,height:s,_aspectRatio:n}=this;return $(t)?e&&n?n:s?i/s:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}_initialize(){return this.notifyPlugins("beforeInit"),this.options.responsive?this.resize():ke(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins("afterInit"),this}clear(){return Gt(this.canvas,this.ctx),this}stop(){return a.stop(this),this}resize(t,e){a.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){const i=this.options,s=this.canvas,n=i.maintainAspectRatio&&this.aspectRatio,o=this.platform.getMaximumSize(s,t,e,n),a=i.devicePixelRatio||this.platform.getDevicePixelRatio(),r=this.width?"resize":"attach";this.width=o.width,this.height=o.height,this._aspectRatio=this.aspectRatio,ke(this,a,!0)&&(this.notifyPlugins("resize",{size:o}),J(i.onResize,[this,o],this),this.attached&&this._doResize(r)&&this.render())}ensureScalesHaveIDs(){Q(this.options.scales||{},((t,e)=>{t.id=e}))}buildOrUpdateScales(){const t=this.options,e=t.scales,i=this.scales,s=Object.keys(i).reduce(((t,e)=>(t[e]=!1,t)),{});let n=[];e&&(n=n.concat(Object.keys(e).map((t=>{const i=e[t],s=Ys(t,i),n="r"===s,o="x"===s;return{options:i,dposition:n?"chartArea":o?"bottom":"left",dtype:n?"radialLinear":o?"category":"linear"}})))),Q(n,(e=>{const n=e.options,o=n.id,a=Ys(o,n),r=K(n.type,e.dtype);void 0!==n.position&&sn(n.position,a)===sn(e.dposition)||(n.position=e.dposition),s[o]=!0;let l=null;if(o in i&&i[o].type===r)l=i[o];else{l=new(Ws.getScale(r))({id:o,type:r,ctx:this.ctx,chart:this}),i[l.id]=l}l.init(n,t)})),Q(s,((t,e)=>{t||delete i[e]})),Q(i,(t=>{ni.configure(this,t,t.options),ni.addBox(this,t)}))}_updateMetasets(){const t=this._metasets,e=this.data.datasets.length,i=t.length;if(t.sort(((t,e)=>t.index-e.index)),i>e){for(let t=e;t<i;++t)this._destroyDatasetMeta(t);t.splice(e,i-e)}this._sortedMetasets=t.slice(0).sort(nn("order","index"))}_removeUnreferencedMetasets(){const{_metasets:t,data:{datasets:e}}=this;t.length>e.length&&delete this._stacks,t.forEach(((t,i)=>{0===e.filter((e=>e===t._dataset)).length&&this._destroyDatasetMeta(i)}))}buildOrUpdateControllers(){const t=[],e=this.data.datasets;let i,s;for(this._removeUnreferencedMetasets(),i=0,s=e.length;i<s;i++){const s=e[i];let n=this.getDatasetMeta(i);const o=s.type||this.config.type;if(n.type&&n.type!==o&&(this._destroyDatasetMeta(i),n=this.getDatasetMeta(i)),n.type=o,n.indexAxis=s.indexAxis||$s(o,this.options),n.order=s.order||0,n.index=i,n.label=""+s.label,n.visible=this.isDatasetVisible(i),n.controller)n.controller.updateIndex(i),n.controller.linkScales();else{const e=Ws.getController(o),{datasetElementType:s,dataElementType:a}=bt.datasets[o];Object.assign(e.prototype,{dataElementType:Ws.getElement(a),datasetElementType:s&&Ws.getElement(s)}),n.controller=new e(this,i),t.push(n.controller)}}return this._updateMetasets(),t}_resetElements(){Q(this.data.datasets,((t,e)=>{this.getDatasetMeta(e).controller.reset()}),this)}reset(){this._resetElements(),this.notifyPlugins("reset")}update(t){const e=this.config;e.update();const i=this._options=e.createResolver(e.chartOptionScopes(),this.getContext()),s=this._animationsDisabled=!i.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),!1===this.notifyPlugins("beforeUpdate",{mode:t,cancelable:!0}))return;const n=this.buildOrUpdateControllers();this.notifyPlugins("beforeElementsUpdate");let o=0;for(let t=0,e=this.data.datasets.length;t<e;t++){const{controller:e}=this.getDatasetMeta(t),i=!s&&-1===n.indexOf(e);e.buildOrUpdateElements(i),o=Math.max(+e.getMaxOverflow(),o)}o=this._minPadding=i.layout.autoPadding?o:0,this._updateLayout(o),s||Q(n,(t=>{t.reset()})),this._updateDatasets(t),this.notifyPlugins("afterUpdate",{mode:t}),this._layers.sort(nn("z","_idx"));const{_active:a,_lastEvent:r}=this;r?this._eventHandler(r,!0):a.length&&this._updateHoverStyles(a,a,!0),this.render()}_updateScales(){Q(this.scales,(t=>{ni.removeBox(this,t)})),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){const t=this.options,e=new Set(Object.keys(this._listeners)),i=new Set(t.events);ut(e,i)&&!!this._responsiveListeners===t.responsive||(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){const{_hiddenIndices:t}=this,e=this._getUniformDataChanges()||[];for(const{method:i,start:s,count:n}of e){cn(t,s,"_removeElements"===i?-n:n)}}_getUniformDataChanges(){const t=this._dataChanges;if(!t||!t.length)return;this._dataChanges=[];const e=this.data.datasets.length,i=e=>new Set(t.filter((t=>t[0]===e)).map(((t,e)=>e+","+t.splice(1).join(",")))),s=i(0);for(let t=1;t<e;t++)if(!ut(s,i(t)))return;return Array.from(s).map((t=>t.split(","))).map((t=>({method:t[1],start:+t[2],count:+t[3]})))}_updateLayout(t){if(!1===this.notifyPlugins("beforeLayout",{cancelable:!0}))return;ni.update(this,this.width,this.height,t);const e=this.chartArea,i=e.width<=0||e.height<=0;this._layers=[],Q(this.boxes,(t=>{i&&"chartArea"===t.position||(t.configure&&t.configure(),this._layers.push(...t._layers()))}),this),this._layers.forEach(((t,e)=>{t._idx=e})),this.notifyPlugins("afterLayout")}_updateDatasets(t){if(!1!==this.notifyPlugins("beforeDatasetsUpdate",{mode:t,cancelable:!0})){for(let t=0,e=this.data.datasets.length;t<e;++t)this.getDatasetMeta(t).controller.configure();for(let e=0,i=this.data.datasets.length;e<i;++e)this._updateDataset(e,dt(t)?t({datasetIndex:e}):t);this.notifyPlugins("afterDatasetsUpdate",{mode:t})}}_updateDataset(t,e){const i=this.getDatasetMeta(t),s={meta:i,index:t,mode:e,cancelable:!0};!1!==this.notifyPlugins("beforeDatasetUpdate",s)&&(i.controller._update(e),s.cancelable=!1,this.notifyPlugins("afterDatasetUpdate",s))}render(){!1!==this.notifyPlugins("beforeRender",{cancelable:!0})&&(a.has(this)?this.attached&&!a.running(this)&&a.start(this):(this.draw(),on({chart:this})))}draw(){let t;if(this._resizeBeforeDraw){const{width:t,height:e}=this._resizeBeforeDraw;this._resize(t,e),this._resizeBeforeDraw=null}if(this.clear(),this.width<=0||this.height<=0)return;if(!1===this.notifyPlugins("beforeDraw",{cancelable:!0}))return;const e=this._layers;for(t=0;t<e.length&&e[t].z<=0;++t)e[t].draw(this.chartArea);for(this._drawDatasets();t<e.length;++t)e[t].draw(this.chartArea);this.notifyPlugins("afterDraw")}_getSortedDatasetMetas(t){const e=this._sortedMetasets,i=[];let s,n;for(s=0,n=e.length;s<n;++s){const n=e[s];t&&!n.visible||i.push(n)}return i}getSortedVisibleDatasetMetas(){return this._getSortedDatasetMetas(!0)}_drawDatasets(){if(!1===this.notifyPlugins("beforeDatasetsDraw",{cancelable:!0}))return;const t=this.getSortedVisibleDatasetMetas();for(let e=t.length-1;e>=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}_drawDataset(t){const e=this.ctx,i=t._clip,s=!i.disabled,n=this.chartArea,o={meta:t,index:t.index,cancelable:!0};!1!==this.notifyPlugins("beforeDatasetDraw",o)&&(s&&Qt(e,{left:!1===i.left?0:n.left-i.left,right:!1===i.right?this.width:n.right+i.right,top:!1===i.top?0:n.top-i.top,bottom:!1===i.bottom?this.height:n.bottom+i.bottom}),t.controller.draw(),s&&te(e),o.cancelable=!1,this.notifyPlugins("afterDatasetDraw",o))}getElementsAtEventForMode(t,e,i,s){const n=Ee.modes[e];return"function"==typeof n?n(this,t,i,s):[]}getDatasetMeta(t){const e=this.data.datasets[t],i=this._metasets;let s=i.filter((t=>t&&t._dataset===e)).pop();return s||(s={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},i.push(s)),s}getContext(){return this.$context||(this.$context=Ye(null,{chart:this,type:"chart"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const i=this.getDatasetMeta(t);return"boolean"==typeof i.hidden?!i.hidden:!e.hidden}setDatasetVisibility(t,e){this.getDatasetMeta(t).hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,i){const s=i?"show":"hide",n=this.getDatasetMeta(t),o=n.controller._resolveAnimations(void 0,s);ct(e)?(n.data[e].hidden=!i,this.update()):(this.setDatasetVisibility(t,i),o.update(n,{visible:i}),this.update((e=>e.datasetIndex===t?s:void 0)))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){const e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),a.remove(this),t=0,e=this.data.datasets.length;t<e;++t)this._destroyDatasetMeta(t)}destroy(){this.notifyPlugins("beforeDestroy");const{canvas:t,ctx:e}=this;this._stop(),this.config.clearCache(),t&&(this.unbindEvents(),Gt(t,e),this.platform.releaseContext(e),this.canvas=null,this.ctx=null),this.notifyPlugins("destroy"),delete ln[this.id],this.notifyPlugins("afterDestroy")}toBase64Image(...t){return this.canvas.toDataURL(...t)}bindEvents(){this.bindUserEvents(),this.options.responsive?this.bindResponsiveEvents():this.attached=!0}bindUserEvents(){const t=this._listeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(t,e,i)=>{t.offsetX=e,t.offsetY=i,this._eventHandler(t)};Q(this.options.events,(t=>i(t,s)))}bindResponsiveEvents(){this._responsiveListeners||(this._responsiveListeners={});const t=this._responsiveListeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(i,s)=>{t[i]&&(e.removeEventListener(this,i,s),delete t[i])},n=(t,e)=>{this.canvas&&this.resize(t,e)};let o;const a=()=>{s("attach",a),this.attached=!0,this.resize(),i("resize",n),i("detach",o)};o=()=>{this.attached=!1,s("resize",n),this._stop(),this._resize(0,0),i("attach",a)},e.isAttached(this.canvas)?a():o()}unbindEvents(){Q(this._listeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._listeners={},Q(this._responsiveListeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._responsiveListeners=void 0}updateHoverStyle(t,e,i){const s=i?"set":"remove";let n,o,a,r;for("dataset"===e&&(n=this.getDatasetMeta(t[0].datasetIndex),n.controller["_"+s+"DatasetHoverStyle"]()),a=0,r=t.length;a<r;++a){o=t[a];const e=o&&this.getDatasetMeta(o.datasetIndex).controller;e&&e[s+"HoverStyle"](o.element,o.datasetIndex,o.index)}}getActiveElements(){return this._active||[]}setActiveElements(t){const e=this._active||[],i=t.map((({datasetIndex:t,index:e})=>{const i=this.getDatasetMeta(t);if(!i)throw new Error("No dataset found at index "+t);return{datasetIndex:t,element:i.data[e],index:e}}));!tt(i,e)&&(this._active=i,this._lastEvent=null,this._updateHoverStyles(i,e))}notifyPlugins(t,e,i){return this._plugins.notify(this,t,e,i)}_updateHoverStyles(t,e,i){const s=this.options.hover,n=(t,e)=>t.filter((t=>!e.some((e=>t.datasetIndex===e.datasetIndex&&t.index===e.index)))),o=n(e,t),a=i?t:n(t,e);o.length&&this.updateHoverStyle(o,s.mode,!1),a.length&&s.mode&&this.updateHoverStyle(a,s.mode,!0)}_eventHandler(t,e){const i={event:t,replay:e,cancelable:!0,inChartArea:Jt(t,this.chartArea,this._minPadding)},s=e=>(e.options.events||this.options.events).includes(t.native.type);if(!1===this.notifyPlugins("beforeEvent",i,s))return;const n=this._handleEvent(t,e,i.inChartArea);return i.cancelable=!1,this.notifyPlugins("afterEvent",i,s),(n||i.changed)&&this.render(),this}_handleEvent(t,e,i){const{_active:s=[],options:n}=this,o=e,a=this._getActiveElements(t,s,i,o),r=ft(t),l=function(t,e,i,s){return i&&"mouseout"!==t.type?s?e:t:null}(t,this._lastEvent,i,r);i&&(this._lastEvent=null,J(n.onHover,[t,a,this],this),r&&J(n.onClick,[t,a,this],this));const h=!tt(a,s);return(h||e)&&(this._active=a,this._updateHoverStyles(a,s,e)),this._lastEvent=l,h}_getActiveElements(t,e,i,s){if("mouseout"===t.type)return[];if(!i)return e;const n=this.options.hover;return this.getElementsAtEventForMode(t,n.mode,n,s)}}const un=()=>Q(dn.instances,(t=>t._plugins.invalidate())),fn=!0;function gn(){throw new Error("This method is not implemented: Check that a complete date adapter is provided.")}Object.defineProperties(dn,{defaults:{enumerable:fn,value:bt},instances:{enumerable:fn,value:ln},overrides:{enumerable:fn,value:gt},registry:{enumerable:fn,value:Ws},version:{enumerable:fn,value:"3.7.1"},getChart:{enumerable:fn,value:hn},register:{enumerable:fn,value:(...t)=>{Ws.add(...t),un()}},unregister:{enumerable:fn,value:(...t)=>{Ws.remove(...t),un()}}});class pn{constructor(t){this.options=t||{}}formats(){return gn()}parse(t,e){return gn()}format(t,e){return gn()}add(t,e,i){return gn()}diff(t,e,i){return gn()}startOf(t,e,i){return gn()}endOf(t,e){return gn()}}pn.override=function(t){Object.assign(pn.prototype,t)};var mn={_date:pn};function xn(t){const e=t.iScale,i=function(t,e){if(!t._cache.$bar){const i=t.getMatchingVisibleMetas(e);let s=[];for(let e=0,n=i.length;e<n;e++)s=s.concat(i[e].controller.getAllParsedValues(t));t._cache.$bar=fe(s.sort(((t,e)=>t-e)))}return t._cache.$bar}(e,t.type);let s,n,o,a,r=e._length;const l=()=>{32767!==o&&-32768!==o&&(ct(a)&&(r=Math.min(r,Math.abs(o-a)||r)),a=o)};for(s=0,n=i.length;s<n;++s)o=e.getPixelForValue(i[s]),l();for(a=void 0,s=0,n=e.ticks.length;s<n;++s)o=e.getPixelForTick(s),l();return r}function bn(t,e,i,s){return Y(t)?function(t,e,i,s){const n=i.parse(t[0],s),o=i.parse(t[1],s),a=Math.min(n,o),r=Math.max(n,o);let l=a,h=r;Math.abs(a)>Math.abs(r)&&(l=r,h=a),e[i.axis]=h,e._custom={barStart:l,barEnd:h,start:n,end:o,min:a,max:r}}(t,e,i,s):e[i.axis]=i.parse(t,s),e}function _n(t,e,i,s){const n=t.iScale,o=t.vScale,a=n.getLabels(),r=n===o,l=[];let h,c,d,u;for(h=i,c=i+s;h<c;++h)u=e[h],d={},d[n.axis]=r||n.parse(a[h],h),l.push(bn(u,d,o,h));return l}function yn(t){return t&&void 0!==t.barStart&&void 0!==t.barEnd}function vn(t,e,i,s){let n=e.borderSkipped;const o={};if(!n)return void(t.borderSkipped=o);const{start:a,end:r,reverse:l,top:h,bottom:c}=function(t){let e,i,s,n,o;return t.horizontal?(e=t.base>t.x,i="left",s="right"):(e=t.base<t.y,i="bottom",s="top"),e?(n="end",o="start"):(n="start",o="end"),{start:i,end:s,reverse:e,top:n,bottom:o}}(t);"middle"===n&&i&&(t.enableBorderRadius=!0,(i._top||0)===s?n=h:(i._bottom||0)===s?n=c:(o[wn(c,a,r,l)]=!0,n=h)),o[wn(n,a,r,l)]=!0,t.borderSkipped=o}function wn(t,e,i,s){var n,o,a;return s?(a=i,t=Mn(t=(n=t)===(o=e)?a:n===a?o:n,i,e)):t=Mn(t,e,i),t}function Mn(t,e,i){return"start"===t?e:"end"===t?i:t}function kn(t,{inflateAmount:e},i){t.inflateAmount="auto"===e?1===i?.33:0:e}class Sn extends Ps{parsePrimitiveData(t,e,i,s){return _n(t,e,i,s)}parseArrayData(t,e,i,s){return _n(t,e,i,s)}parseObjectData(t,e,i,s){const{iScale:n,vScale:o}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l="x"===n.axis?a:r,h="x"===o.axis?a:r,c=[];let d,u,f,g;for(d=i,u=i+s;d<u;++d)g=e[d],f={},f[n.axis]=n.parse(lt(g,l),d),c.push(bn(lt(g,h),f,o,d));return c}updateRangeFromParsed(t,e,i,s){super.updateRangeFromParsed(t,e,i,s);const n=i._custom;n&&e===this._cachedMeta.vScale&&(t.min=Math.min(t.min,n.min),t.max=Math.max(t.max,n.max))}getMaxOverflow(){return 0}getLabelAndValue(t){const e=this._cachedMeta,{iScale:i,vScale:s}=e,n=this.getParsed(t),o=n._custom,a=yn(o)?"["+o.start+", "+o.end+"]":""+s.getLabelForValue(n[s.axis]);return{label:""+i.getLabelForValue(n[i.axis]),value:a}}initialize(){this.enableOptionSharing=!0,super.initialize();this._cachedMeta.stack=this.getDataset().stack}update(t){const e=this._cachedMeta;this.updateElements(e.data,0,e.data.length,t)}updateElements(t,e,i,s){const n="reset"===s,{index:o,_cachedMeta:{vScale:a}}=this,r=a.getBasePixel(),l=a.isHorizontal(),h=this._getRuler(),c=this.resolveDataElementOptions(e,s),d=this.getSharedOptions(c),u=this.includeOptions(s,d);this.updateSharedOptions(d,s,c);for(let c=e;c<e+i;c++){const e=this.getParsed(c),i=n||$(e[a.axis])?{base:r,head:r}:this._calculateBarValuePixels(c),f=this._calculateBarIndexPixels(c,h),g=(e._stacks||{})[a.axis],p={horizontal:l,base:i.base,enableBorderRadius:!g||yn(e._custom)||o===g._top||o===g._bottom,x:l?i.head:f.center,y:l?f.center:i.head,height:l?f.size:Math.abs(i.size),width:l?Math.abs(i.size):f.size};u&&(p.options=d||this.resolveDataElementOptions(c,t[c].active?"active":s));const m=p.options||t[c].options;vn(p,m,g,o),kn(p,m,h.ratio),this.updateElement(t[c],c,p,s)}}_getStacks(t,e){const i=this._cachedMeta.iScale,s=i.getMatchingVisibleMetas(this._type),n=i.options.stacked,o=s.length,a=[];let r,l;for(r=0;r<o;++r)if(l=s[r],l.controller.options.grouped){if(void 0!==e){const t=l.controller.getParsed(e)[l.controller._cachedMeta.vScale.axis];if($(t)||isNaN(t))continue}if((!1===n||-1===a.indexOf(l.stack)||void 0===n&&void 0===l.stack)&&a.push(l.stack),l.index===t)break}return a.length||a.push(void 0),a}_getStackCount(t){return this._getStacks(void 0,t).length}_getStackIndex(t,e,i){const s=this._getStacks(t,i),n=void 0!==e?s.indexOf(e):-1;return-1===n?s.length-1:n}_getRuler(){const t=this.options,e=this._cachedMeta,i=e.iScale,s=[];let n,o;for(n=0,o=e.data.length;n<o;++n)s.push(i.getPixelForValue(this.getParsed(n)[i.axis],n));const a=t.barThickness;return{min:a||xn(e),pixels:s,start:i._startPixel,end:i._endPixel,stackCount:this._getStackCount(),scale:i,grouped:t.grouped,ratio:a?1:t.categoryPercentage*t.barPercentage}}_calculateBarValuePixels(t){const{_cachedMeta:{vScale:e,_stacked:i},options:{base:s,minBarLength:n}}=this,o=s||0,a=this.getParsed(t),r=a._custom,l=yn(r);let h,c,d=a[e.axis],u=0,f=i?this.applyStack(e,a,i):d;f!==d&&(u=f-d,f=d),l&&(d=r.barStart,f=r.barEnd-r.barStart,0!==d&&Ct(d)!==Ct(r.barEnd)&&(u=0),u+=d);const g=$(s)||l?u:s;let p=e.getPixelForValue(g);if(h=this.chart.getDataVisibility(t)?e.getPixelForValue(u+f):p,c=h-p,Math.abs(c)<n&&(c=function(t,e,i){return 0!==t?Ct(t):(e.isHorizontal()?1:-1)*(e.min>=i?1:-1)}(c,e,o)*n,d===o&&(p-=c/2),h=p+c),p===e.getPixelForValue(o)){const t=Ct(c)*e.getLineWidthForValue(o)/2;p+=t,c-=t}return{size:c,base:p,head:h,center:h+c/2}}_calculateBarIndexPixels(t,e){const i=e.scale,s=this.options,n=s.skipNull,o=K(s.maxBarThickness,1/0);let a,r;if(e.grouped){const i=n?this._getStackCount(t):e.stackCount,l="flex"===s.barThickness?function(t,e,i,s){const n=e.pixels,o=n[t];let a=t>0?n[t-1]:null,r=t<n.length-1?n[t+1]:null;const l=i.categoryPercentage;null===a&&(a=o-(null===r?e.end-e.start:r-o)),null===r&&(r=o+o-a);const h=o-(o-Math.min(a,r))/2*l;return{chunk:Math.abs(r-a)/2*l/s,ratio:i.barPercentage,start:h}}(t,e,s,i):function(t,e,i,s){const n=i.barThickness;let o,a;return $(n)?(o=e.min*i.categoryPercentage,a=i.barPercentage):(o=n*s,a=1),{chunk:o/s,ratio:a,start:e.pixels[t]-o/2}}(t,e,s,i),h=this._getStackIndex(this.index,this._cachedMeta.stack,n?t:void 0);a=l.start+l.chunk*h+l.chunk/2,r=Math.min(o,l.chunk*l.ratio)}else a=i.getPixelForValue(this.getParsed(t)[i.axis],t),r=Math.min(o,e.min*e.ratio);return{base:a-r/2,head:a+r/2,center:a,size:r}}draw(){const t=this._cachedMeta,e=t.vScale,i=t.data,s=i.length;let n=0;for(;n<s;++n)null!==this.getParsed(n)[e.axis]&&i[n].draw(this._ctx)}}Sn.id="bar",Sn.defaults={datasetElementType:!1,dataElementType:"bar",categoryPercentage:.8,barPercentage:.9,grouped:!0,animations:{numbers:{type:"number",properties:["x","y","base","width","height"]}}},Sn.overrides={scales:{_index_:{type:"category",offset:!0,grid:{offset:!0}},_value_:{type:"linear",beginAtZero:!0}}};class Pn extends Ps{initialize(){this.enableOptionSharing=!0,super.initialize()}parsePrimitiveData(t,e,i,s){const n=super.parsePrimitiveData(t,e,i,s);for(let t=0;t<n.length;t++)n[t]._custom=this.resolveDataElementOptions(t+i).radius;return n}parseArrayData(t,e,i,s){const n=super.parseArrayData(t,e,i,s);for(let t=0;t<n.length;t++){const s=e[i+t];n[t]._custom=K(s[2],this.resolveDataElementOptions(t+i).radius)}return n}parseObjectData(t,e,i,s){const n=super.parseObjectData(t,e,i,s);for(let t=0;t<n.length;t++){const s=e[i+t];n[t]._custom=K(s&&s.r&&+s.r,this.resolveDataElementOptions(t+i).radius)}return n}getMaxOverflow(){const t=this._cachedMeta.data;let e=0;for(let i=t.length-1;i>=0;--i)e=Math.max(e,t[i].size(this.resolveDataElementOptions(i))/2);return e>0&&e}getLabelAndValue(t){const e=this._cachedMeta,{xScale:i,yScale:s}=e,n=this.getParsed(t),o=i.getLabelForValue(n.x),a=s.getLabelForValue(n.y),r=n._custom;return{label:e.label,value:"("+o+", "+a+(r?", "+r:"")+")"}}update(t){const e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a}=this._cachedMeta,r=this.resolveDataElementOptions(e,s),l=this.getSharedOptions(r),h=this.includeOptions(s,l),c=o.axis,d=a.axis;for(let r=e;r<e+i;r++){const e=t[r],i=!n&&this.getParsed(r),l={},u=l[c]=n?o.getPixelForDecimal(.5):o.getPixelForValue(i[c]),f=l[d]=n?a.getBasePixel():a.getPixelForValue(i[d]);l.skip=isNaN(u)||isNaN(f),h&&(l.options=this.resolveDataElementOptions(r,e.active?"active":s),n&&(l.options.radius=0)),this.updateElement(e,r,l,s)}this.updateSharedOptions(l,s,r)}resolveDataElementOptions(t,e){const i=this.getParsed(t);let s=super.resolveDataElementOptions(t,e);s.$shared&&(s=Object.assign({},s,{$shared:!1}));const n=s.radius;return"active"!==e&&(s.radius=0),s.radius+=K(i&&i._custom,n),s}}Pn.id="bubble",Pn.defaults={datasetElementType:!1,dataElementType:"point",animations:{numbers:{type:"number",properties:["x","y","borderWidth","radius"]}}},Pn.overrides={scales:{x:{type:"linear"},y:{type:"linear"}},plugins:{tooltip:{callbacks:{title:()=>""}}}};class Dn extends Ps{constructor(t,e){super(t,e),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(t,e){const i=this.getDataset().data,s=this._cachedMeta;if(!1===this._parsing)s._parsed=i;else{let n,o,a=t=>+i[t];if(U(i[t])){const{key:t="value"}=this._parsing;a=e=>+lt(i[e],t)}for(n=t,o=t+e;n<o;++n)s._parsed[n]=a(n)}}_getRotation(){return It(this.options.rotation-90)}_getCircumference(){return It(this.options.circumference)}_getRotationExtents(){let t=yt,e=-yt;for(let i=0;i<this.chart.data.datasets.length;++i)if(this.chart.isDatasetVisible(i)){const s=this.chart.getDatasetMeta(i).controller,n=s._getRotation(),o=s._getCircumference();t=Math.min(t,n),e=Math.max(e,n+o)}return{rotation:t,circumference:e-t}}update(t){const e=this.chart,{chartArea:i}=e,s=this._cachedMeta,n=s.data,o=this.getMaxBorderWidth()+this.getMaxOffset(n)+this.options.spacing,a=Math.max((Math.min(i.width,i.height)-o)/2,0),r=Math.min(G(this.options.cutout,a),1),l=this._getRingWeight(this.index),{circumference:h,rotation:c}=this._getRotationExtents(),{ratioX:d,ratioY:u,offsetX:f,offsetY:g}=function(t,e,i){let s=1,n=1,o=0,a=0;if(e<yt){const r=t,l=r+e,h=Math.cos(r),c=Math.sin(r),d=Math.cos(l),u=Math.sin(l),f=(t,e,s)=>Ht(t,r,l,!0)?1:Math.max(e,e*i,s,s*i),g=(t,e,s)=>Ht(t,r,l,!0)?-1:Math.min(e,e*i,s,s*i),p=f(0,h,d),m=f(kt,c,u),x=g(_t,h,d),b=g(_t+kt,c,u);s=(p-x)/2,n=(m-b)/2,o=-(p+x)/2,a=-(m+b)/2}return{ratioX:s,ratioY:n,offsetX:o,offsetY:a}}(c,h,r),p=(i.width-o)/d,m=(i.height-o)/u,x=Math.max(Math.min(p,m)/2,0),b=Z(this.options.radius,x),_=(b-Math.max(b*r,0))/this._getVisibleDatasetWeightTotal();this.offsetX=f*b,this.offsetY=g*b,s.total=this.calculateTotal(),this.outerRadius=b-_*this._getRingWeightOffset(this.index),this.innerRadius=Math.max(this.outerRadius-_*l,0),this.updateElements(n,0,n.length,t)}_circumference(t,e){const i=this.options,s=this._cachedMeta,n=this._getCircumference();return e&&i.animation.animateRotate||!this.chart.getDataVisibility(t)||null===s._parsed[t]||s.data[t].hidden?0:this.calculateCircumference(s._parsed[t]*n/yt)}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=o.chartArea,r=o.options.animation,l=(a.left+a.right)/2,h=(a.top+a.bottom)/2,c=n&&r.animateScale,d=c?0:this.innerRadius,u=c?0:this.outerRadius,f=this.resolveDataElementOptions(e,s),g=this.getSharedOptions(f),p=this.includeOptions(s,g);let m,x=this._getRotation();for(m=0;m<e;++m)x+=this._circumference(m,n);for(m=e;m<e+i;++m){const e=this._circumference(m,n),i=t[m],o={x:l+this.offsetX,y:h+this.offsetY,startAngle:x,endAngle:x+e,circumference:e,outerRadius:u,innerRadius:d};p&&(o.options=g||this.resolveDataElementOptions(m,i.active?"active":s)),x+=e,this.updateElement(i,m,o,s)}this.updateSharedOptions(g,s,f)}calculateTotal(){const t=this._cachedMeta,e=t.data;let i,s=0;for(i=0;i<e.length;i++){const n=t._parsed[i];null===n||isNaN(n)||!this.chart.getDataVisibility(i)||e[i].hidden||(s+=Math.abs(n))}return s}calculateCircumference(t){const e=this._cachedMeta.total;return e>0&&!isNaN(t)?yt*(Math.abs(t)/e):0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=Ri(e._parsed[t],i.options.locale);return{label:s[t]||"",value:n}}getMaxBorderWidth(t){let e=0;const i=this.chart;let s,n,o,a,r;if(!t)for(s=0,n=i.data.datasets.length;s<n;++s)if(i.isDatasetVisible(s)){o=i.getDatasetMeta(s),t=o.data,a=o.controller;break}if(!t)return 0;for(s=0,n=t.length;s<n;++s)r=a.resolveDataElementOptions(s),"inner"!==r.borderAlign&&(e=Math.max(e,r.borderWidth||0,r.hoverBorderWidth||0));return e}getMaxOffset(t){let e=0;for(let i=0,s=t.length;i<s;++i){const t=this.resolveDataElementOptions(i);e=Math.max(e,t.offset||0,t.hoverOffset||0)}return e}_getRingWeightOffset(t){let e=0;for(let i=0;i<t;++i)this.chart.isDatasetVisible(i)&&(e+=this._getRingWeight(i));return e}_getRingWeight(t){return Math.max(K(this.chart.data.datasets[t].weight,1),0)}_getVisibleDatasetWeightTotal(){return this._getRingWeightOffset(this.chart.data.datasets.length)||1}}Dn.id="doughnut",Dn.defaults={datasetElementType:!1,dataElementType:"arc",animation:{animateRotate:!0,animateScale:!1},animations:{numbers:{type:"number",properties:["circumference","endAngle","innerRadius","outerRadius","startAngle","x","y","offset","borderWidth","spacing"]}},cutout:"50%",rotation:0,circumference:360,radius:"100%",spacing:0,indexAxis:"r"},Dn.descriptors={_scriptable:t=>"spacing"!==t,_indexable:t=>"spacing"!==t},Dn.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label(t){let e=t.label;const i=": "+t.formattedValue;return Y(e)?(e=e.slice(),e[0]+=i):e+=i,e}}}}};class Cn extends Ps{initialize(){this.enableOptionSharing=!0,super.initialize()}update(t){const e=this._cachedMeta,{dataset:i,data:s=[],_dataset:n}=e,o=this.chart._animationsDisabled;let{start:a,count:r}=function(t,e,i){const s=e.length;let n=0,o=s;if(t._sorted){const{iScale:a,_parsed:r}=t,l=a.axis,{min:h,max:c,minDefined:d,maxDefined:u}=a.getUserBounds();d&&(n=jt(Math.min(re(r,a.axis,h).lo,i?s:re(e,l,a.getPixelForValue(h)).lo),0,s-1)),o=u?jt(Math.max(re(r,a.axis,c).hi+1,i?0:re(e,l,a.getPixelForValue(c)).hi+1),n,s)-n:s-n}return{start:n,count:o}}(e,s,o);this._drawStart=a,this._drawCount=r,function(t){const{xScale:e,yScale:i,_scaleRanges:s}=t,n={xmin:e.min,xmax:e.max,ymin:i.min,ymax:i.max};if(!s)return t._scaleRanges=n,!0;const o=s.xmin!==e.min||s.xmax!==e.max||s.ymin!==i.min||s.ymax!==i.max;return Object.assign(s,n),o}(e)&&(a=0,r=s.length),i._chart=this.chart,i._datasetIndex=this.index,i._decimated=!!n._decimated,i.points=s;const l=this.resolveDatasetElementOptions(t);this.options.showLine||(l.borderWidth=0),l.segment=this.options.segment,this.updateElement(i,void 0,{animated:!o,options:l},t),this.updateElements(s,a,r,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a,_stacked:r,_dataset:l}=this._cachedMeta,h=this.resolveDataElementOptions(e,s),c=this.getSharedOptions(h),d=this.includeOptions(s,c),u=o.axis,f=a.axis,{spanGaps:g,segment:p}=this.options,m=Tt(g)?g:Number.POSITIVE_INFINITY,x=this.chart._animationsDisabled||n||"none"===s;let b=e>0&&this.getParsed(e-1);for(let h=e;h<e+i;++h){const e=t[h],i=this.getParsed(h),g=x?e:{},_=$(i[f]),y=g[u]=o.getPixelForValue(i[u],h),v=g[f]=n||_?a.getBasePixel():a.getPixelForValue(r?this.applyStack(a,i,r):i[f],h);g.skip=isNaN(y)||isNaN(v)||_,g.stop=h>0&&i[u]-b[u]>m,p&&(g.parsed=i,g.raw=l.data[h]),d&&(g.options=c||this.resolveDataElementOptions(h,e.active?"active":s)),x||this.updateElement(e,h,g,s),b=i}this.updateSharedOptions(c,s,h)}getMaxOverflow(){const t=this._cachedMeta,e=t.dataset,i=e.options&&e.options.borderWidth||0,s=t.data||[];if(!s.length)return i;const n=s[0].size(this.resolveDataElementOptions(0)),o=s[s.length-1].size(this.resolveDataElementOptions(s.length-1));return Math.max(i,n,o)/2}draw(){const t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}}Cn.id="line",Cn.defaults={datasetElementType:"line",dataElementType:"point",showLine:!0,spanGaps:!1},Cn.overrides={scales:{_index_:{type:"category"},_value_:{type:"linear"}}};class On extends Ps{constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=Ri(e._parsed[t].r,i.options.locale);return{label:s[t]||"",value:n}}update(t){const e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}_updateRadius(){const t=this.chart,e=t.chartArea,i=t.options,s=Math.min(e.right-e.left,e.bottom-e.top),n=Math.max(s/2,0),o=(n-Math.max(i.cutoutPercentage?n/100*i.cutoutPercentage:1,0))/t.getVisibleDatasetCount();this.outerRadius=n-o*this.index,this.innerRadius=this.outerRadius-o}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=this.getDataset(),r=o.options.animation,l=this._cachedMeta.rScale,h=l.xCenter,c=l.yCenter,d=l.getIndexAngle(0)-.5*_t;let u,f=d;const g=360/this.countVisibleElements();for(u=0;u<e;++u)f+=this._computeAngle(u,s,g);for(u=e;u<e+i;u++){const e=t[u];let i=f,p=f+this._computeAngle(u,s,g),m=o.getDataVisibility(u)?l.getDistanceFromCenterForValue(a.data[u]):0;f=p,n&&(r.animateScale&&(m=0),r.animateRotate&&(i=p=d));const x={x:h,y:c,innerRadius:0,outerRadius:m,startAngle:i,endAngle:p,options:this.resolveDataElementOptions(u,e.active?"active":s)};this.updateElement(e,u,x,s)}}countVisibleElements(){const t=this.getDataset(),e=this._cachedMeta;let i=0;return e.data.forEach(((e,s)=>{!isNaN(t.data[s])&&this.chart.getDataVisibility(s)&&i++})),i}_computeAngle(t,e,i){return this.chart.getDataVisibility(t)?It(this.resolveDataElementOptions(t,e).angle||i):0}}On.id="polarArea",On.defaults={dataElementType:"arc",animation:{animateRotate:!0,animateScale:!0},animations:{numbers:{type:"number",properties:["x","y","startAngle","endAngle","innerRadius","outerRadius"]}},indexAxis:"r",startAngle:0},On.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label:t=>t.chart.data.labels[t.dataIndex]+": "+t.formattedValue}}},scales:{r:{type:"radialLinear",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}};class An extends Dn{}An.id="pie",An.defaults={cutout:0,rotation:0,circumference:360,radius:"100%"};class Tn extends Ps{getLabelAndValue(t){const e=this._cachedMeta.vScale,i=this.getParsed(t);return{label:e.getLabels()[t],value:""+e.getLabelForValue(i[e.axis])}}update(t){const e=this._cachedMeta,i=e.dataset,s=e.data||[],n=e.iScale.getLabels();if(i.points=s,"resize"!==t){const e=this.resolveDatasetElementOptions(t);this.options.showLine||(e.borderWidth=0);const o={_loop:!0,_fullLoop:n.length===s.length,options:e};this.updateElement(i,void 0,o,t)}this.updateElements(s,0,s.length,t)}updateElements(t,e,i,s){const n=this.getDataset(),o=this._cachedMeta.rScale,a="reset"===s;for(let r=e;r<e+i;r++){const e=t[r],i=this.resolveDataElementOptions(r,e.active?"active":s),l=o.getPointPositionForValue(r,n.data[r]),h=a?o.xCenter:l.x,c=a?o.yCenter:l.y,d={x:h,y:c,angle:l.angle,skip:isNaN(h)||isNaN(c),options:i};this.updateElement(e,r,d,s)}}}Tn.id="radar",Tn.defaults={datasetElementType:"line",dataElementType:"point",indexAxis:"r",showLine:!0,elements:{line:{fill:"start"}}},Tn.overrides={aspectRatio:1,scales:{r:{type:"radialLinear"}}};class Ln extends Cn{}Ln.id="scatter",Ln.defaults={showLine:!1,fill:!1},Ln.overrides={interaction:{mode:"point"},plugins:{tooltip:{callbacks:{title:()=>"",label:t=>"("+t.label+", "+t.formattedValue+")"}}},scales:{x:{type:"linear"},y:{type:"linear"}}};var Rn=Object.freeze({__proto__:null,BarController:Sn,BubbleController:Pn,DoughnutController:Dn,LineController:Cn,PolarAreaController:On,PieController:An,RadarController:Tn,ScatterController:Ln});function En(t,e,i){const{startAngle:s,pixelMargin:n,x:o,y:a,outerRadius:r,innerRadius:l}=e;let h=n/r;t.beginPath(),t.arc(o,a,r,s-h,i+h),l>n?(h=n/l,t.arc(o,a,l,i+h,s-h,!0)):t.arc(o,a,n,i+kt,s-kt),t.closePath(),t.clip()}function In(t,e,i,s){const n=Be(t.options.borderRadius,["outerStart","outerEnd","innerStart","innerEnd"]);const o=(i-e)/2,a=Math.min(o,s*e/2),r=t=>{const e=(i-Math.min(o,t))*s/2;return jt(t,0,Math.min(o,e))};return{outerStart:r(n.outerStart),outerEnd:r(n.outerEnd),innerStart:jt(n.innerStart,0,a),innerEnd:jt(n.innerEnd,0,a)}}function zn(t,e,i,s){return{x:i+t*Math.cos(e),y:s+t*Math.sin(e)}}function Fn(t,e,i,s,n){const{x:o,y:a,startAngle:r,pixelMargin:l,innerRadius:h}=e,c=Math.max(e.outerRadius+s+i-l,0),d=h>0?h+s+i+l:0;let u=0;const f=n-r;if(s){const t=((h>0?h-s:0)+(c>0?c-s:0))/2;u=(f-(0!==t?f*t/(t+s):f))/2}const g=(f-Math.max(.001,f*c-i/_t)/c)/2,p=r+g+u,m=n-g-u,{outerStart:x,outerEnd:b,innerStart:_,innerEnd:y}=In(e,d,c,m-p),v=c-x,w=c-b,M=p+x/v,k=m-b/w,S=d+_,P=d+y,D=p+_/S,C=m-y/P;if(t.beginPath(),t.arc(o,a,c,M,k),b>0){const e=zn(w,k,o,a);t.arc(e.x,e.y,b,k,m+kt)}const O=zn(P,m,o,a);if(t.lineTo(O.x,O.y),y>0){const e=zn(P,C,o,a);t.arc(e.x,e.y,y,m+kt,C+Math.PI)}if(t.arc(o,a,d,m-y/d,p+_/d,!0),_>0){const e=zn(S,D,o,a);t.arc(e.x,e.y,_,D+Math.PI,p-kt)}const A=zn(v,p,o,a);if(t.lineTo(A.x,A.y),x>0){const e=zn(v,M,o,a);t.arc(e.x,e.y,x,p-kt,M)}t.closePath()}function Bn(t,e,i,s,n){const{options:o}=e,{borderWidth:a,borderJoinStyle:r}=o,l="inner"===o.borderAlign;a&&(l?(t.lineWidth=2*a,t.lineJoin=r||"round"):(t.lineWidth=a,t.lineJoin=r||"bevel"),e.fullCircles&&function(t,e,i){const{x:s,y:n,startAngle:o,pixelMargin:a,fullCircles:r}=e,l=Math.max(e.outerRadius-a,0),h=e.innerRadius+a;let c;for(i&&En(t,e,o+yt),t.beginPath(),t.arc(s,n,h,o+yt,o,!0),c=0;c<r;++c)t.stroke();for(t.beginPath(),t.arc(s,n,l,o,o+yt),c=0;c<r;++c)t.stroke()}(t,e,l),l&&En(t,e,n),Fn(t,e,i,s,n),t.stroke())}class Vn extends Ds{constructor(t){super(),this.options=void 0,this.circumference=void 0,this.startAngle=void 0,this.endAngle=void 0,this.innerRadius=void 0,this.outerRadius=void 0,this.pixelMargin=0,this.fullCircles=0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.getProps(["x","y"],i),{angle:n,distance:o}=Bt(s,{x:t,y:e}),{startAngle:a,endAngle:r,innerRadius:l,outerRadius:h,circumference:c}=this.getProps(["startAngle","endAngle","innerRadius","outerRadius","circumference"],i),d=this.options.spacing/2,u=K(c,r-a)>=yt||Ht(n,a,r),f=Yt(o,l+d,h+d);return u&&f}getCenterPoint(t){const{x:e,y:i,startAngle:s,endAngle:n,innerRadius:o,outerRadius:a}=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius","circumference"],t),{offset:r,spacing:l}=this.options,h=(s+n)/2,c=(o+a+l+r)/2;return{x:e+Math.cos(h)*c,y:i+Math.sin(h)*c}}tooltipPosition(t){return this.getCenterPoint(t)}draw(t){const{options:e,circumference:i}=this,s=(e.offset||0)/2,n=(e.spacing||0)/2;if(this.pixelMargin="inner"===e.borderAlign?.33:0,this.fullCircles=i>yt?Math.floor(i/yt):0,0===i||this.innerRadius<0||this.outerRadius<0)return;t.save();let o=0;if(s){o=s/2;const e=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(e)*o,Math.sin(e)*o),this.circumference>=_t&&(o=s)}t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor;const a=function(t,e,i,s){const{fullCircles:n,startAngle:o,circumference:a}=e;let r=e.endAngle;if(n){Fn(t,e,i,s,o+yt);for(let e=0;e<n;++e)t.fill();isNaN(a)||(r=o+a%yt,a%yt==0&&(r+=yt))}return Fn(t,e,i,s,r),t.fill(),r}(t,this,o,n);Bn(t,this,o,n,a),t.restore()}}function Wn(t,e,i=e){t.lineCap=K(i.borderCapStyle,e.borderCapStyle),t.setLineDash(K(i.borderDash,e.borderDash)),t.lineDashOffset=K(i.borderDashOffset,e.borderDashOffset),t.lineJoin=K(i.borderJoinStyle,e.borderJoinStyle),t.lineWidth=K(i.borderWidth,e.borderWidth),t.strokeStyle=K(i.borderColor,e.borderColor)}function Nn(t,e,i){t.lineTo(i.x,i.y)}function Hn(t,e,i={}){const s=t.length,{start:n=0,end:o=s-1}=i,{start:a,end:r}=e,l=Math.max(n,a),h=Math.min(o,r),c=n<a&&o<a||n>r&&o>r;return{count:s,start:l,loop:e.loop,ilen:h<l&&!c?s+h-l:h-l}}function jn(t,e,i,s){const{points:n,options:o}=e,{count:a,start:r,loop:l,ilen:h}=Hn(n,i,s),c=function(t){return t.stepped?ee:t.tension||"monotone"===t.cubicInterpolationMode?ie:Nn}(o);let d,u,f,{move:g=!0,reverse:p}=s||{};for(d=0;d<=h;++d)u=n[(r+(p?h-d:d))%a],u.skip||(g?(t.moveTo(u.x,u.y),g=!1):c(t,f,u,p,o.stepped),f=u);return l&&(u=n[(r+(p?h:0))%a],c(t,f,u,p,o.stepped)),!!l}function $n(t,e,i,s){const n=e.points,{count:o,start:a,ilen:r}=Hn(n,i,s),{move:l=!0,reverse:h}=s||{};let c,d,u,f,g,p,m=0,x=0;const b=t=>(a+(h?r-t:t))%o,_=()=>{f!==g&&(t.lineTo(m,g),t.lineTo(m,f),t.lineTo(m,p))};for(l&&(d=n[b(0)],t.moveTo(d.x,d.y)),c=0;c<=r;++c){if(d=n[b(c)],d.skip)continue;const e=d.x,i=d.y,s=0|e;s===u?(i<f?f=i:i>g&&(g=i),m=(x*m+e)/++x):(_(),t.lineTo(e,i),u=s,x=0,f=g=i),p=i}_()}function Yn(t){const e=t.options,i=e.borderDash&&e.borderDash.length;return!(t._decimated||t._loop||e.tension||"monotone"===e.cubicInterpolationMode||e.stepped||i)?$n:jn}Vn.id="arc",Vn.defaults={borderAlign:"center",borderColor:"#fff",borderJoinStyle:void 0,borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0},Vn.defaultRoutes={backgroundColor:"backgroundColor"};const Un="function"==typeof Path2D;function Xn(t,e,i,s){Un&&!e.options.segment?function(t,e,i,s){let n=e._path;n||(n=e._path=new Path2D,e.path(n,i,s)&&n.closePath()),Wn(t,e.options),t.stroke(n)}(t,e,i,s):function(t,e,i,s){const{segments:n,options:o}=e,a=Yn(e);for(const r of n)Wn(t,o,r.style),t.beginPath(),a(t,e,r,{start:i,end:i+s-1})&&t.closePath(),t.stroke()}(t,e,i,s)}class qn extends Ds{constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){const i=this.options;if((i.tension||"monotone"===i.cubicInterpolationMode)&&!i.stepped&&!this._pointsUpdated){const s=i.spanGaps?this._loop:this._fullLoop;ki(this._points,i,t,s,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=Ni(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,i=t.length;return i&&e[t[i-1].end]}interpolate(t,e){const i=this.options,s=t[e],n=this.points,o=Wi(this,{property:e,start:s,end:s});if(!o.length)return;const a=[],r=function(t){return t.stepped?Ai:t.tension||"monotone"===t.cubicInterpolationMode?Ti:Oi}(i);let l,h;for(l=0,h=o.length;l<h;++l){const{start:h,end:c}=o[l],d=n[h],u=n[c];if(d===u){a.push(d);continue}const f=r(d,u,Math.abs((s-d[e])/(u[e]-d[e])),i.stepped);f[e]=t[e],a.push(f)}return 1===a.length?a[0]:a}pathSegment(t,e,i){return Yn(this)(t,this,e,i)}path(t,e,i){const s=this.segments,n=Yn(this);let o=this._loop;e=e||0,i=i||this.points.length-e;for(const a of s)o&=n(t,this,a,{start:e,end:e+i-1});return!!o}draw(t,e,i,s){const n=this.options||{};(this.points||[]).length&&n.borderWidth&&(t.save(),Xn(t,this,i,s),t.restore()),this.animated&&(this._pointsUpdated=!1,this._path=void 0)}}function Kn(t,e,i,s){const n=t.options,{[i]:o}=t.getProps([i],s);return Math.abs(e-o)<n.radius+n.hitRadius}qn.id="line",qn.defaults={borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderWidth:3,capBezierPoints:!0,cubicInterpolationMode:"default",fill:!1,spanGaps:!1,stepped:!1,tension:0},qn.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"},qn.descriptors={_scriptable:!0,_indexable:t=>"borderDash"!==t&&"fill"!==t};class Gn extends Ds{constructor(t){super(),this.options=void 0,this.parsed=void 0,this.skip=void 0,this.stop=void 0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.options,{x:n,y:o}=this.getProps(["x","y"],i);return Math.pow(t-n,2)+Math.pow(e-o,2)<Math.pow(s.hitRadius+s.radius,2)}inXRange(t,e){return Kn(this,t,"x",e)}inYRange(t,e){return Kn(this,t,"y",e)}getCenterPoint(t){const{x:e,y:i}=this.getProps(["x","y"],t);return{x:e,y:i}}size(t){let e=(t=t||this.options||{}).radius||0;e=Math.max(e,e&&t.hoverRadius||0);return 2*(e+(e&&t.borderWidth||0))}draw(t,e){const i=this.options;this.skip||i.radius<.1||!Jt(this,e,this.size(i)/2)||(t.strokeStyle=i.borderColor,t.lineWidth=i.borderWidth,t.fillStyle=i.backgroundColor,Zt(t,i,this.x,this.y))}getRange(){const t=this.options||{};return t.radius+t.hitRadius}}function Zn(t,e){const{x:i,y:s,base:n,width:o,height:a}=t.getProps(["x","y","base","width","height"],e);let r,l,h,c,d;return t.horizontal?(d=a/2,r=Math.min(i,n),l=Math.max(i,n),h=s-d,c=s+d):(d=o/2,r=i-d,l=i+d,h=Math.min(s,n),c=Math.max(s,n)),{left:r,top:h,right:l,bottom:c}}function Jn(t,e,i,s){return t?0:jt(e,i,s)}function Qn(t){const e=Zn(t),i=e.right-e.left,s=e.bottom-e.top,n=function(t,e,i){const s=t.options.borderWidth,n=t.borderSkipped,o=Ve(s);return{t:Jn(n.top,o.top,0,i),r:Jn(n.right,o.right,0,e),b:Jn(n.bottom,o.bottom,0,i),l:Jn(n.left,o.left,0,e)}}(t,i/2,s/2),o=function(t,e,i){const{enableBorderRadius:s}=t.getProps(["enableBorderRadius"]),n=t.options.borderRadius,o=We(n),a=Math.min(e,i),r=t.borderSkipped,l=s||U(n);return{topLeft:Jn(!l||r.top||r.left,o.topLeft,0,a),topRight:Jn(!l||r.top||r.right,o.topRight,0,a),bottomLeft:Jn(!l||r.bottom||r.left,o.bottomLeft,0,a),bottomRight:Jn(!l||r.bottom||r.right,o.bottomRight,0,a)}}(t,i/2,s/2);return{outer:{x:e.left,y:e.top,w:i,h:s,radius:o},inner:{x:e.left+n.l,y:e.top+n.t,w:i-n.l-n.r,h:s-n.t-n.b,radius:{topLeft:Math.max(0,o.topLeft-Math.max(n.t,n.l)),topRight:Math.max(0,o.topRight-Math.max(n.t,n.r)),bottomLeft:Math.max(0,o.bottomLeft-Math.max(n.b,n.l)),bottomRight:Math.max(0,o.bottomRight-Math.max(n.b,n.r))}}}}function to(t,e,i,s){const n=null===e,o=null===i,a=t&&!(n&&o)&&Zn(t,s);return a&&(n||Yt(e,a.left,a.right))&&(o||Yt(i,a.top,a.bottom))}function eo(t,e){t.rect(e.x,e.y,e.w,e.h)}function io(t,e,i={}){const s=t.x!==i.x?-e:0,n=t.y!==i.y?-e:0,o=(t.x+t.w!==i.x+i.w?e:0)-s,a=(t.y+t.h!==i.y+i.h?e:0)-n;return{x:t.x+s,y:t.y+n,w:t.w+o,h:t.h+a,radius:t.radius}}Gn.id="point",Gn.defaults={borderWidth:1,hitRadius:1,hoverBorderWidth:1,hoverRadius:4,pointStyle:"circle",radius:3,rotation:0},Gn.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};class so extends Ds{constructor(t){super(),this.options=void 0,this.horizontal=void 0,this.base=void 0,this.width=void 0,this.height=void 0,this.inflateAmount=void 0,t&&Object.assign(this,t)}draw(t){const{inflateAmount:e,options:{borderColor:i,backgroundColor:s}}=this,{inner:n,outer:o}=Qn(this),a=(r=o.radius).topLeft||r.topRight||r.bottomLeft||r.bottomRight?oe:eo;var r;t.save(),o.w===n.w&&o.h===n.h||(t.beginPath(),a(t,io(o,e,n)),t.clip(),a(t,io(n,-e,o)),t.fillStyle=i,t.fill("evenodd")),t.beginPath(),a(t,io(n,e)),t.fillStyle=s,t.fill(),t.restore()}inRange(t,e,i){return to(this,t,e,i)}inXRange(t,e){return to(this,t,null,e)}inYRange(t,e){return to(this,null,t,e)}getCenterPoint(t){const{x:e,y:i,base:s,horizontal:n}=this.getProps(["x","y","base","horizontal"],t);return{x:n?(e+s)/2:e,y:n?i:(i+s)/2}}getRange(t){return"x"===t?this.width/2:this.height/2}}so.id="bar",so.defaults={borderSkipped:"start",borderWidth:0,borderRadius:0,inflateAmount:"auto",pointStyle:void 0},so.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};var no=Object.freeze({__proto__:null,ArcElement:Vn,LineElement:qn,PointElement:Gn,BarElement:so});function oo(t){if(t._decimated){const e=t._data;delete t._decimated,delete t._data,Object.defineProperty(t,"data",{value:e})}}function ao(t){t.data.datasets.forEach((t=>{oo(t)}))}var ro={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:(t,e,i)=>{if(!i.enabled)return void ao(t);const s=t.width;t.data.datasets.forEach(((e,n)=>{const{_data:o,indexAxis:a}=e,r=t.getDatasetMeta(n),l=o||e.data;if("y"===je([a,t.options.indexAxis]))return;if("line"!==r.type)return;const h=t.scales[r.xAxisID];if("linear"!==h.type&&"time"!==h.type)return;if(t.options.parsing)return;let{start:c,count:d}=function(t,e){const i=e.length;let s,n=0;const{iScale:o}=t,{min:a,max:r,minDefined:l,maxDefined:h}=o.getUserBounds();return l&&(n=jt(re(e,o.axis,a).lo,0,i-1)),s=h?jt(re(e,o.axis,r).hi+1,n,i)-n:i-n,{start:n,count:s}}(r,l);if(d<=(i.threshold||4*s))return void oo(e);let u;switch($(o)&&(e._data=l,delete e.data,Object.defineProperty(e,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),i.algorithm){case"lttb":u=function(t,e,i,s,n){const o=n.samples||s;if(o>=i)return t.slice(e,e+i);const a=[],r=(i-2)/(o-2);let l=0;const h=e+i-1;let c,d,u,f,g,p=e;for(a[l++]=t[p],c=0;c<o-2;c++){let s,n=0,o=0;const h=Math.floor((c+1)*r)+1+e,m=Math.min(Math.floor((c+2)*r)+1,i)+e,x=m-h;for(s=h;s<m;s++)n+=t[s].x,o+=t[s].y;n/=x,o/=x;const b=Math.floor(c*r)+1+e,_=Math.min(Math.floor((c+1)*r)+1,i)+e,{x:y,y:v}=t[p];for(u=f=-1,s=b;s<_;s++)f=.5*Math.abs((y-n)*(t[s].y-v)-(y-t[s].x)*(o-v)),f>u&&(u=f,d=t[s],g=s);a[l++]=d,p=g}return a[l++]=t[h],a}(l,c,d,s,i);break;case"min-max":u=function(t,e,i,s){let n,o,a,r,l,h,c,d,u,f,g=0,p=0;const m=[],x=e+i-1,b=t[e].x,_=t[x].x-b;for(n=e;n<e+i;++n){o=t[n],a=(o.x-b)/_*s,r=o.y;const e=0|a;if(e===l)r<u?(u=r,h=n):r>f&&(f=r,c=n),g=(p*g+o.x)/++p;else{const i=n-1;if(!$(h)&&!$(c)){const e=Math.min(h,c),s=Math.max(h,c);e!==d&&e!==i&&m.push({...t[e],x:g}),s!==d&&s!==i&&m.push({...t[s],x:g})}n>0&&i!==d&&m.push(t[i]),m.push(o),l=e,p=0,u=f=r,h=c=d=n}}return m}(l,c,d,s);break;default:throw new Error(`Unsupported decimation algorithm '${i.algorithm}'`)}e._decimated=u}))},destroy(t){ao(t)}};function lo(t,e,i){const s=function(t){const e=t.options,i=e.fill;let s=K(i&&i.target,i);return void 0===s&&(s=!!e.backgroundColor),!1!==s&&null!==s&&(!0===s?"origin":s)}(t);if(U(s))return!isNaN(s.value)&&s;let n=parseFloat(s);return X(n)&&Math.floor(n)===n?("-"!==s[0]&&"+"!==s[0]||(n=e+n),!(n===e||n<0||n>=i)&&n):["origin","start","end","stack","shape"].indexOf(s)>=0&&s}class ho{constructor(t){this.x=t.x,this.y=t.y,this.radius=t.radius}pathSegment(t,e,i){const{x:s,y:n,radius:o}=this;return e=e||{start:0,end:yt},t.arc(s,n,o,e.end,e.start,!0),!i.bounds}interpolate(t){const{x:e,y:i,radius:s}=this,n=t.angle;return{x:e+Math.cos(n)*s,y:i+Math.sin(n)*s,angle:n}}}function co(t){return(t.scale||{}).getPointPositionForValue?function(t){const{scale:e,fill:i}=t,s=e.options,n=e.getLabels().length,o=[],a=s.reverse?e.max:e.min,r=s.reverse?e.min:e.max;let l,h,c;if(c="start"===i?a:"end"===i?r:U(i)?i.value:e.getBaseValue(),s.grid.circular)return h=e.getPointPositionForValue(0,a),new ho({x:h.x,y:h.y,radius:e.getDistanceFromCenterForValue(c)});for(l=0;l<n;++l)o.push(e.getPointPositionForValue(l,c));return o}(t):function(t){const{scale:e={},fill:i}=t;let s,n=null;return"start"===i?n=e.bottom:"end"===i?n=e.top:U(i)?n=e.getPixelForValue(i.value):e.getBasePixel&&(n=e.getBasePixel()),X(n)?(s=e.isHorizontal(),{x:s?n:null,y:s?null:n}):null}(t)}function uo(t,e,i){for(;e>t;e--){const t=i[e];if(!isNaN(t.x)&&!isNaN(t.y))break}return e}function fo(t,e,i){const s=[];for(let n=0;n<i.length;n++){const o=i[n],{first:a,last:r,point:l}=go(o,e,"x");if(!(!l||a&&r))if(a)s.unshift(l);else if(t.push(l),!r)break}t.push(...s)}function go(t,e,i){const s=t.interpolate(e,i);if(!s)return{};const n=s[i],o=t.segments,a=t.points;let r=!1,l=!1;for(let t=0;t<o.length;t++){const e=o[t],s=a[e.start][i],h=a[e.end][i];if(Yt(n,s,h)){r=n===s,l=n===h;break}}return{first:r,last:l,point:s}}function po(t){const{chart:e,fill:i,line:s}=t;if(X(i))return function(t,e){const i=t.getDatasetMeta(e);return i&&t.isDatasetVisible(e)?i.dataset:null}(e,i);if("stack"===i)return function(t){const{scale:e,index:i,line:s}=t,n=[],o=s.segments,a=s.points,r=function(t,e){const i=[],s=t.getMatchingVisibleMetas("line");for(let t=0;t<s.length;t++){const n=s[t];if(n.index===e)break;n.hidden||i.unshift(n.dataset)}return i}(e,i);r.push(mo({x:null,y:e.bottom},s));for(let t=0;t<o.length;t++){const e=o[t];for(let t=e.start;t<=e.end;t++)fo(n,a[t],r)}return new qn({points:n,options:{}})}(t);if("shape"===i)return!0;const n=co(t);return n instanceof ho?n:mo(n,s)}function mo(t,e){let i=[],s=!1;return Y(t)?(s=!0,i=t):i=function(t,e){const{x:i=null,y:s=null}=t||{},n=e.points,o=[];return e.segments.forEach((({start:t,end:e})=>{e=uo(t,e,n);const a=n[t],r=n[e];null!==s?(o.push({x:a.x,y:s}),o.push({x:r.x,y:s})):null!==i&&(o.push({x:i,y:a.y}),o.push({x:i,y:r.y}))})),o}(t,e),i.length?new qn({points:i,options:{tension:0},_loop:s,_fullLoop:s}):null}function xo(t,e,i){let s=t[e].fill;const n=[e];let o;if(!i)return s;for(;!1!==s&&-1===n.indexOf(s);){if(!X(s))return s;if(o=t[s],!o)return!1;if(o.visible)return s;n.push(s),s=o.fill}return!1}function bo(t,e,i){const{segments:s,points:n}=e;let o=!0,a=!1;t.beginPath();for(const r of s){const{start:s,end:l}=r,h=n[s],c=n[uo(s,l,n)];o?(t.moveTo(h.x,h.y),o=!1):(t.lineTo(h.x,i),t.lineTo(h.x,h.y)),a=!!e.pathSegment(t,r,{move:a}),a?t.closePath():t.lineTo(c.x,i)}t.lineTo(e.first().x,i),t.closePath(),t.clip()}function _o(t,e,i,s){if(s)return;let n=e[t],o=i[t];return"angle"===t&&(n=Nt(n),o=Nt(o)),{property:t,start:n,end:o}}function yo(t,e,i,s){return t&&e?s(t[i],e[i]):t?t[i]:e?e[i]:0}function vo(t,e,i){const{top:s,bottom:n}=e.chart.chartArea,{property:o,start:a,end:r}=i||{};"x"===o&&(t.beginPath(),t.rect(a,s,r-a,n-s),t.clip())}function wo(t,e,i,s){const n=e.interpolate(i,s);n&&t.lineTo(n.x,n.y)}function Mo(t,e){const{line:i,target:s,property:n,color:o,scale:a}=e,r=function(t,e,i){const s=t.segments,n=t.points,o=e.points,a=[];for(const t of s){let{start:s,end:r}=t;r=uo(s,r,n);const l=_o(i,n[s],n[r],t.loop);if(!e.segments){a.push({source:t,target:l,start:n[s],end:n[r]});continue}const h=Wi(e,l);for(const e of h){const s=_o(i,o[e.start],o[e.end],e.loop),r=Vi(t,n,s);for(const t of r)a.push({source:t,target:e,start:{[i]:yo(l,s,"start",Math.max)},end:{[i]:yo(l,s,"end",Math.min)}})}}return a}(i,s,n);for(const{source:e,target:l,start:h,end:c}of r){const{style:{backgroundColor:r=o}={}}=e,d=!0!==s;t.save(),t.fillStyle=r,vo(t,a,d&&_o(n,h,c)),t.beginPath();const u=!!i.pathSegment(t,e);let f;if(d){u?t.closePath():wo(t,s,c,n);const e=!!s.pathSegment(t,l,{move:u,reverse:!0});f=u&&e,f||wo(t,s,h,n)}t.closePath(),t.fill(f?"evenodd":"nonzero"),t.restore()}}function ko(t,e,i){const s=po(e),{line:n,scale:o,axis:a}=e,r=n.options,l=r.fill,h=r.backgroundColor,{above:c=h,below:d=h}=l||{};s&&n.points.length&&(Qt(t,i),function(t,e){const{line:i,target:s,above:n,below:o,area:a,scale:r}=e,l=i._loop?"angle":e.axis;t.save(),"x"===l&&o!==n&&(bo(t,s,a.top),Mo(t,{line:i,target:s,color:n,scale:r,property:l}),t.restore(),t.save(),bo(t,s,a.bottom)),Mo(t,{line:i,target:s,color:o,scale:r,property:l}),t.restore()}(t,{line:n,target:s,above:c,below:d,area:i,scale:o,axis:a}),te(t))}var So={id:"filler",afterDatasetsUpdate(t,e,i){const s=(t.data.datasets||[]).length,n=[];let o,a,r,l;for(a=0;a<s;++a)o=t.getDatasetMeta(a),r=o.dataset,l=null,r&&r.options&&r instanceof qn&&(l={visible:t.isDatasetVisible(a),index:a,fill:lo(r,a,s),chart:t,axis:o.controller.options.indexAxis,scale:o.vScale,line:r}),o.$filler=l,n.push(l);for(a=0;a<s;++a)l=n[a],l&&!1!==l.fill&&(l.fill=xo(n,a,i.propagate))},beforeDraw(t,e,i){const s="beforeDraw"===i.drawTime,n=t.getSortedVisibleDatasetMetas(),o=t.chartArea;for(let e=n.length-1;e>=0;--e){const i=n[e].$filler;i&&(i.line.updateControlPoints(o,i.axis),s&&ko(t.ctx,i,o))}},beforeDatasetsDraw(t,e,i){if("beforeDatasetsDraw"!==i.drawTime)return;const s=t.getSortedVisibleDatasetMetas();for(let e=s.length-1;e>=0;--e){const i=s[e].$filler;i&&ko(t.ctx,i,t.chartArea)}},beforeDatasetDraw(t,e,i){const s=e.meta.$filler;s&&!1!==s.fill&&"beforeDatasetDraw"===i.drawTime&&ko(t.ctx,s,t.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}};const Po=(t,e)=>{let{boxHeight:i=e,boxWidth:s=e}=t;return t.usePointStyle&&(i=Math.min(i,e),s=Math.min(s,e)),{boxWidth:s,boxHeight:i,itemHeight:Math.max(e,i)}};class Do extends Ds{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,i){this.maxWidth=t,this.maxHeight=e,this._margins=i,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){const t=this.options.labels||{};let e=J(t.generateLabels,[this.chart],this)||[];t.filter&&(e=e.filter((e=>t.filter(e,this.chart.data)))),t.sort&&(e=e.sort(((e,i)=>t.sort(e,i,this.chart.data)))),this.options.reverse&&e.reverse(),this.legendItems=e}fit(){const{options:t,ctx:e}=this;if(!t.display)return void(this.width=this.height=0);const i=t.labels,s=He(i.font),n=s.size,o=this._computeTitleHeight(),{boxWidth:a,itemHeight:r}=Po(i,n);let l,h;e.font=s.string,this.isHorizontal()?(l=this.maxWidth,h=this._fitRows(o,n,a,r)+10):(h=this.maxHeight,l=this._fitCols(o,n,a,r)+10),this.width=Math.min(l,t.maxWidth||this.maxWidth),this.height=Math.min(h,t.maxHeight||this.maxHeight)}_fitRows(t,e,i,s){const{ctx:n,maxWidth:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.lineWidths=[0],h=s+a;let c=t;n.textAlign="left",n.textBaseline="middle";let d=-1,u=-h;return this.legendItems.forEach(((t,f)=>{const g=i+e/2+n.measureText(t.text).width;(0===f||l[l.length-1]+g+2*a>o)&&(c+=h,l[l.length-(f>0?0:1)]=0,u+=h,d++),r[f]={left:0,top:u,row:d,width:g,height:s},l[l.length-1]+=g+a})),c}_fitCols(t,e,i,s){const{ctx:n,maxHeight:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.columnSizes=[],h=o-t;let c=a,d=0,u=0,f=0,g=0;return this.legendItems.forEach(((t,o)=>{const p=i+e/2+n.measureText(t.text).width;o>0&&u+s+2*a>h&&(c+=d+a,l.push({width:d,height:u}),f+=d+a,g++,d=u=0),r[o]={left:f,top:u,col:g,width:p,height:s},d=Math.max(d,p),u+=s+a})),c+=d,l.push({width:d,height:u}),c}adjustHitBoxes(){if(!this.options.display)return;const t=this._computeTitleHeight(),{legendHitBoxes:e,options:{align:i,labels:{padding:s},rtl:o}}=this,a=Ei(o,this.left,this.width);if(this.isHorizontal()){let o=0,r=n(i,this.left+s,this.right-this.lineWidths[o]);for(const l of e)o!==l.row&&(o=l.row,r=n(i,this.left+s,this.right-this.lineWidths[o])),l.top+=this.top+t+s,l.left=a.leftForLtr(a.x(r),l.width),r+=l.width+s}else{let o=0,r=n(i,this.top+t+s,this.bottom-this.columnSizes[o].height);for(const l of e)l.col!==o&&(o=l.col,r=n(i,this.top+t+s,this.bottom-this.columnSizes[o].height)),l.top=r,l.left+=this.left+s,l.left=a.leftForLtr(a.x(l.left),l.width),r+=l.height+s}}isHorizontal(){return"top"===this.options.position||"bottom"===this.options.position}draw(){if(this.options.display){const t=this.ctx;Qt(t,this),this._draw(),te(t)}}_draw(){const{options:t,columnSizes:e,lineWidths:i,ctx:s}=this,{align:a,labels:r}=t,l=bt.color,h=Ei(t.rtl,this.left,this.width),c=He(r.font),{color:d,padding:u}=r,f=c.size,g=f/2;let p;this.drawTitle(),s.textAlign=h.textAlign("left"),s.textBaseline="middle",s.lineWidth=.5,s.font=c.string;const{boxWidth:m,boxHeight:x,itemHeight:b}=Po(r,f),_=this.isHorizontal(),y=this._computeTitleHeight();p=_?{x:n(a,this.left+u,this.right-i[0]),y:this.top+u+y,line:0}:{x:this.left+u,y:n(a,this.top+y+u,this.bottom-e[0].height),line:0},Ii(this.ctx,t.textDirection);const v=b+u;this.legendItems.forEach(((w,M)=>{s.strokeStyle=w.fontColor||d,s.fillStyle=w.fontColor||d;const k=s.measureText(w.text).width,S=h.textAlign(w.textAlign||(w.textAlign=r.textAlign)),P=m+g+k;let D=p.x,C=p.y;h.setWidth(this.width),_?M>0&&D+P+u>this.right&&(C=p.y+=v,p.line++,D=p.x=n(a,this.left+u,this.right-i[p.line])):M>0&&C+v>this.bottom&&(D=p.x=D+e[p.line].width+u,p.line++,C=p.y=n(a,this.top+y+u,this.bottom-e[p.line].height));!function(t,e,i){if(isNaN(m)||m<=0||isNaN(x)||x<0)return;s.save();const n=K(i.lineWidth,1);if(s.fillStyle=K(i.fillStyle,l),s.lineCap=K(i.lineCap,"butt"),s.lineDashOffset=K(i.lineDashOffset,0),s.lineJoin=K(i.lineJoin,"miter"),s.lineWidth=n,s.strokeStyle=K(i.strokeStyle,l),s.setLineDash(K(i.lineDash,[])),r.usePointStyle){const o={radius:m*Math.SQRT2/2,pointStyle:i.pointStyle,rotation:i.rotation,borderWidth:n},a=h.xPlus(t,m/2);Zt(s,o,a,e+g)}else{const o=e+Math.max((f-x)/2,0),a=h.leftForLtr(t,m),r=We(i.borderRadius);s.beginPath(),Object.values(r).some((t=>0!==t))?oe(s,{x:a,y:o,w:m,h:x,radius:r}):s.rect(a,o,m,x),s.fill(),0!==n&&s.stroke()}s.restore()}(h.x(D),C,w),D=o(S,D+m+g,_?D+P:this.right,t.rtl),function(t,e,i){se(s,i.text,t,e+b/2,c,{strikethrough:i.hidden,textAlign:h.textAlign(i.textAlign)})}(h.x(D),C,w),_?p.x+=P+u:p.y+=v})),zi(this.ctx,t.textDirection)}drawTitle(){const t=this.options,e=t.title,i=He(e.font),o=Ne(e.padding);if(!e.display)return;const a=Ei(t.rtl,this.left,this.width),r=this.ctx,l=e.position,h=i.size/2,c=o.top+h;let d,u=this.left,f=this.width;if(this.isHorizontal())f=Math.max(...this.lineWidths),d=this.top+c,u=n(t.align,u,this.right-f);else{const e=this.columnSizes.reduce(((t,e)=>Math.max(t,e.height)),0);d=c+n(t.align,this.top,this.bottom-e-t.labels.padding-this._computeTitleHeight())}const g=n(l,u,u+f);r.textAlign=a.textAlign(s(l)),r.textBaseline="middle",r.strokeStyle=e.color,r.fillStyle=e.color,r.font=i.string,se(r,e.text,g,d,i)}_computeTitleHeight(){const t=this.options.title,e=He(t.font),i=Ne(t.padding);return t.display?e.lineHeight+i.height:0}_getLegendItemAt(t,e){let i,s,n;if(Yt(t,this.left,this.right)&&Yt(e,this.top,this.bottom))for(n=this.legendHitBoxes,i=0;i<n.length;++i)if(s=n[i],Yt(t,s.left,s.left+s.width)&&Yt(e,s.top,s.top+s.height))return this.legendItems[i];return null}handleEvent(t){const e=this.options;if(!function(t,e){if("mousemove"===t&&(e.onHover||e.onLeave))return!0;if(e.onClick&&("click"===t||"mouseup"===t))return!0;return!1}(t.type,e))return;const i=this._getLegendItemAt(t.x,t.y);if("mousemove"===t.type){const o=this._hoveredItem,a=(n=i,null!==(s=o)&&null!==n&&s.datasetIndex===n.datasetIndex&&s.index===n.index);o&&!a&&J(e.onLeave,[t,o,this],this),this._hoveredItem=i,i&&!a&&J(e.onHover,[t,i,this],this)}else i&&J(e.onClick,[t,i,this],this);var s,n}}var Co={id:"legend",_element:Do,start(t,e,i){const s=t.legend=new Do({ctx:t.ctx,options:i,chart:t});ni.configure(t,s,i),ni.addBox(t,s)},stop(t){ni.removeBox(t,t.legend),delete t.legend},beforeUpdate(t,e,i){const s=t.legend;ni.configure(t,s,i),s.options=i},afterUpdate(t){const e=t.legend;e.buildLabels(),e.adjustHitBoxes()},afterEvent(t,e){e.replay||t.legend.handleEvent(e.event)},defaults:{display:!0,position:"top",align:"center",fullSize:!0,reverse:!1,weight:1e3,onClick(t,e,i){const s=e.datasetIndex,n=i.chart;n.isDatasetVisible(s)?(n.hide(s),e.hidden=!0):(n.show(s),e.hidden=!1)},onHover:null,onLeave:null,labels:{color:t=>t.chart.options.color,boxWidth:40,padding:10,generateLabels(t){const e=t.data.datasets,{labels:{usePointStyle:i,pointStyle:s,textAlign:n,color:o}}=t.legend.options;return t._getSortedDatasetMetas().map((t=>{const a=t.controller.getStyle(i?0:void 0),r=Ne(a.borderWidth);return{text:e[t.index].label,fillStyle:a.backgroundColor,fontColor:o,hidden:!t.visible,lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:(r.width+r.height)/4,strokeStyle:a.borderColor,pointStyle:s||a.pointStyle,rotation:a.rotation,textAlign:n||a.textAlign,borderRadius:0,datasetIndex:t.index}}),this)}},title:{color:t=>t.chart.options.color,display:!1,position:"center",text:""}},descriptors:{_scriptable:t=>!t.startsWith("on"),labels:{_scriptable:t=>!["generateLabels","filter","sort"].includes(t)}}};class Oo extends Ds{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){const i=this.options;if(this.left=0,this.top=0,!i.display)return void(this.width=this.height=this.right=this.bottom=0);this.width=this.right=t,this.height=this.bottom=e;const s=Y(i.text)?i.text.length:1;this._padding=Ne(i.padding);const n=s*He(i.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=n:this.width=n}isHorizontal(){const t=this.options.position;return"top"===t||"bottom"===t}_drawArgs(t){const{top:e,left:i,bottom:s,right:o,options:a}=this,r=a.align;let l,h,c,d=0;return this.isHorizontal()?(h=n(r,i,o),c=e+t,l=o-i):("left"===a.position?(h=i+t,c=n(r,s,e),d=-.5*_t):(h=o-t,c=n(r,e,s),d=.5*_t),l=s-e),{titleX:h,titleY:c,maxWidth:l,rotation:d}}draw(){const t=this.ctx,e=this.options;if(!e.display)return;const i=He(e.font),n=i.lineHeight/2+this._padding.top,{titleX:o,titleY:a,maxWidth:r,rotation:l}=this._drawArgs(n);se(t,e.text,0,0,i,{color:e.color,maxWidth:r,rotation:l,textAlign:s(e.align),textBaseline:"middle",translation:[o,a]})}}var Ao={id:"title",_element:Oo,start(t,e,i){!function(t,e){const i=new Oo({ctx:t.ctx,options:e,chart:t});ni.configure(t,i,e),ni.addBox(t,i),t.titleBlock=i}(t,i)},stop(t){const e=t.titleBlock;ni.removeBox(t,e),delete t.titleBlock},beforeUpdate(t,e,i){const s=t.titleBlock;ni.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"bold"},fullSize:!0,padding:10,position:"top",text:"",weight:2e3},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const To=new WeakMap;var Lo={id:"subtitle",start(t,e,i){const s=new Oo({ctx:t.ctx,options:i,chart:t});ni.configure(t,s,i),ni.addBox(t,s),To.set(t,s)},stop(t){ni.removeBox(t,To.get(t)),To.delete(t)},beforeUpdate(t,e,i){const s=To.get(t);ni.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"normal"},fullSize:!0,padding:0,position:"top",text:"",weight:1500},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Ro={average(t){if(!t.length)return!1;let e,i,s=0,n=0,o=0;for(e=0,i=t.length;e<i;++e){const i=t[e].element;if(i&&i.hasValue()){const t=i.tooltipPosition();s+=t.x,n+=t.y,++o}}return{x:s/o,y:n/o}},nearest(t,e){if(!t.length)return!1;let i,s,n,o=e.x,a=e.y,r=Number.POSITIVE_INFINITY;for(i=0,s=t.length;i<s;++i){const s=t[i].element;if(s&&s.hasValue()){const t=Vt(e,s.getCenterPoint());t<r&&(r=t,n=s)}}if(n){const t=n.tooltipPosition();o=t.x,a=t.y}return{x:o,y:a}}};function Eo(t,e){return e&&(Y(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function Io(t){return("string"==typeof t||t instanceof String)&&t.indexOf("\n")>-1?t.split("\n"):t}function zo(t,e){const{element:i,datasetIndex:s,index:n}=e,o=t.getDatasetMeta(s).controller,{label:a,value:r}=o.getLabelAndValue(n);return{chart:t,label:a,parsed:o.getParsed(n),raw:t.data.datasets[s].data[n],formattedValue:r,dataset:o.getDataset(),dataIndex:n,datasetIndex:s,element:i}}function Fo(t,e){const i=t.chart.ctx,{body:s,footer:n,title:o}=t,{boxWidth:a,boxHeight:r}=e,l=He(e.bodyFont),h=He(e.titleFont),c=He(e.footerFont),d=o.length,u=n.length,f=s.length,g=Ne(e.padding);let p=g.height,m=0,x=s.reduce(((t,e)=>t+e.before.length+e.lines.length+e.after.length),0);if(x+=t.beforeBody.length+t.afterBody.length,d&&(p+=d*h.lineHeight+(d-1)*e.titleSpacing+e.titleMarginBottom),x){p+=f*(e.displayColors?Math.max(r,l.lineHeight):l.lineHeight)+(x-f)*l.lineHeight+(x-1)*e.bodySpacing}u&&(p+=e.footerMarginTop+u*c.lineHeight+(u-1)*e.footerSpacing);let b=0;const _=function(t){m=Math.max(m,i.measureText(t).width+b)};return i.save(),i.font=h.string,Q(t.title,_),i.font=l.string,Q(t.beforeBody.concat(t.afterBody),_),b=e.displayColors?a+2+e.boxPadding:0,Q(s,(t=>{Q(t.before,_),Q(t.lines,_),Q(t.after,_)})),b=0,i.font=c.string,Q(t.footer,_),i.restore(),m+=g.width,{width:m,height:p}}function Bo(t,e,i,s){const{x:n,width:o}=i,{width:a,chartArea:{left:r,right:l}}=t;let h="center";return"center"===s?h=n<=(r+l)/2?"left":"right":n<=o/2?h="left":n>=a-o/2&&(h="right"),function(t,e,i,s){const{x:n,width:o}=s,a=i.caretSize+i.caretPadding;return"left"===t&&n+o+a>e.width||"right"===t&&n-o-a<0||void 0}(h,t,e,i)&&(h="center"),h}function Vo(t,e,i){const s=i.yAlign||e.yAlign||function(t,e){const{y:i,height:s}=e;return i<s/2?"top":i>t.height-s/2?"bottom":"center"}(t,i);return{xAlign:i.xAlign||e.xAlign||Bo(t,e,i,s),yAlign:s}}function Wo(t,e,i,s){const{caretSize:n,caretPadding:o,cornerRadius:a}=t,{xAlign:r,yAlign:l}=i,h=n+o,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=We(a);let g=function(t,e){let{x:i,width:s}=t;return"right"===e?i-=s:"center"===e&&(i-=s/2),i}(e,r);const p=function(t,e,i){let{y:s,height:n}=t;return"top"===e?s+=i:s-="bottom"===e?n+i:n/2,s}(e,l,h);return"center"===l?"left"===r?g+=h:"right"===r&&(g-=h):"left"===r?g-=Math.max(c,u)+n:"right"===r&&(g+=Math.max(d,f)+n),{x:jt(g,0,s.width-e.width),y:jt(p,0,s.height-e.height)}}function No(t,e,i){const s=Ne(i.padding);return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-s.right:t.x+s.left}function Ho(t){return Eo([],Io(t))}function jo(t,e){const i=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return i?t.override(i):t}class $o extends Ds{constructor(t){super(),this.opacity=0,this._active=[],this._eventPosition=void 0,this._size=void 0,this._cachedAnimations=void 0,this._tooltipItems=[],this.$animations=void 0,this.$context=void 0,this.chart=t.chart||t._chart,this._chart=this.chart,this.options=t.options,this.dataPoints=void 0,this.title=void 0,this.beforeBody=void 0,this.body=void 0,this.afterBody=void 0,this.footer=void 0,this.xAlign=void 0,this.yAlign=void 0,this.x=void 0,this.y=void 0,this.height=void 0,this.width=void 0,this.caretX=void 0,this.caretY=void 0,this.labelColors=void 0,this.labelPointStyles=void 0,this.labelTextColors=void 0}initialize(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}_resolveAnimations(){const t=this._cachedAnimations;if(t)return t;const e=this.chart,i=this.options.setContext(this.getContext()),s=i.enabled&&e.options.animation&&i.animations,n=new gs(this.chart,s);return s._cacheable&&(this._cachedAnimations=Object.freeze(n)),n}getContext(){return this.$context||(this.$context=(t=this.chart.getContext(),e=this,i=this._tooltipItems,Ye(t,{tooltip:e,tooltipItems:i,type:"tooltip"})));var t,e,i}getTitle(t,e){const{callbacks:i}=e,s=i.beforeTitle.apply(this,[t]),n=i.title.apply(this,[t]),o=i.afterTitle.apply(this,[t]);let a=[];return a=Eo(a,Io(s)),a=Eo(a,Io(n)),a=Eo(a,Io(o)),a}getBeforeBody(t,e){return Ho(e.callbacks.beforeBody.apply(this,[t]))}getBody(t,e){const{callbacks:i}=e,s=[];return Q(t,(t=>{const e={before:[],lines:[],after:[]},n=jo(i,t);Eo(e.before,Io(n.beforeLabel.call(this,t))),Eo(e.lines,n.label.call(this,t)),Eo(e.after,Io(n.afterLabel.call(this,t))),s.push(e)})),s}getAfterBody(t,e){return Ho(e.callbacks.afterBody.apply(this,[t]))}getFooter(t,e){const{callbacks:i}=e,s=i.beforeFooter.apply(this,[t]),n=i.footer.apply(this,[t]),o=i.afterFooter.apply(this,[t]);let a=[];return a=Eo(a,Io(s)),a=Eo(a,Io(n)),a=Eo(a,Io(o)),a}_createItems(t){const e=this._active,i=this.chart.data,s=[],n=[],o=[];let a,r,l=[];for(a=0,r=e.length;a<r;++a)l.push(zo(this.chart,e[a]));return t.filter&&(l=l.filter(((e,s,n)=>t.filter(e,s,n,i)))),t.itemSort&&(l=l.sort(((e,s)=>t.itemSort(e,s,i)))),Q(l,(e=>{const i=jo(t.callbacks,e);s.push(i.labelColor.call(this,e)),n.push(i.labelPointStyle.call(this,e)),o.push(i.labelTextColor.call(this,e))})),this.labelColors=s,this.labelPointStyles=n,this.labelTextColors=o,this.dataPoints=l,l}update(t,e){const i=this.options.setContext(this.getContext()),s=this._active;let n,o=[];if(s.length){const t=Ro[i.position].call(this,s,this._eventPosition);o=this._createItems(i),this.title=this.getTitle(o,i),this.beforeBody=this.getBeforeBody(o,i),this.body=this.getBody(o,i),this.afterBody=this.getAfterBody(o,i),this.footer=this.getFooter(o,i);const e=this._size=Fo(this,i),a=Object.assign({},t,e),r=Vo(this.chart,i,a),l=Wo(i,a,r,this.chart);this.xAlign=r.xAlign,this.yAlign=r.yAlign,n={opacity:1,x:l.x,y:l.y,width:e.width,height:e.height,caretX:t.x,caretY:t.y}}else 0!==this.opacity&&(n={opacity:0});this._tooltipItems=o,this.$context=void 0,n&&this._resolveAnimations().update(this,n),t&&i.external&&i.external.call(this,{chart:this.chart,tooltip:this,replay:e})}drawCaret(t,e,i,s){const n=this.getCaretPosition(t,i,s);e.lineTo(n.x1,n.y1),e.lineTo(n.x2,n.y2),e.lineTo(n.x3,n.y3)}getCaretPosition(t,e,i){const{xAlign:s,yAlign:n}=this,{caretSize:o,cornerRadius:a}=i,{topLeft:r,topRight:l,bottomLeft:h,bottomRight:c}=We(a),{x:d,y:u}=t,{width:f,height:g}=e;let p,m,x,b,_,y;return"center"===n?(_=u+g/2,"left"===s?(p=d,m=p-o,b=_+o,y=_-o):(p=d+f,m=p+o,b=_-o,y=_+o),x=p):(m="left"===s?d+Math.max(r,h)+o:"right"===s?d+f-Math.max(l,c)-o:this.caretX,"top"===n?(b=u,_=b-o,p=m-o,x=m+o):(b=u+g,_=b+o,p=m+o,x=m-o),y=b),{x1:p,x2:m,x3:x,y1:b,y2:_,y3:y}}drawTitle(t,e,i){const s=this.title,n=s.length;let o,a,r;if(n){const l=Ei(i.rtl,this.x,this.width);for(t.x=No(this,i.titleAlign,i),e.textAlign=l.textAlign(i.titleAlign),e.textBaseline="middle",o=He(i.titleFont),a=i.titleSpacing,e.fillStyle=i.titleColor,e.font=o.string,r=0;r<n;++r)e.fillText(s[r],l.x(t.x),t.y+o.lineHeight/2),t.y+=o.lineHeight+a,r+1===n&&(t.y+=i.titleMarginBottom-a)}}_drawColorBox(t,e,i,s,n){const o=this.labelColors[i],a=this.labelPointStyles[i],{boxHeight:r,boxWidth:l,boxPadding:h}=n,c=He(n.bodyFont),d=No(this,"left",n),u=s.x(d),f=r<c.lineHeight?(c.lineHeight-r)/2:0,g=e.y+f;if(n.usePointStyle){const e={radius:Math.min(l,r)/2,pointStyle:a.pointStyle,rotation:a.rotation,borderWidth:1},i=s.leftForLtr(u,l)+l/2,h=g+r/2;t.strokeStyle=n.multiKeyBackground,t.fillStyle=n.multiKeyBackground,Zt(t,e,i,h),t.strokeStyle=o.borderColor,t.fillStyle=o.backgroundColor,Zt(t,e,i,h)}else{t.lineWidth=o.borderWidth||1,t.strokeStyle=o.borderColor,t.setLineDash(o.borderDash||[]),t.lineDashOffset=o.borderDashOffset||0;const e=s.leftForLtr(u,l-h),i=s.leftForLtr(s.xPlus(u,1),l-h-2),a=We(o.borderRadius);Object.values(a).some((t=>0!==t))?(t.beginPath(),t.fillStyle=n.multiKeyBackground,oe(t,{x:e,y:g,w:l,h:r,radius:a}),t.fill(),t.stroke(),t.fillStyle=o.backgroundColor,t.beginPath(),oe(t,{x:i,y:g+1,w:l-2,h:r-2,radius:a}),t.fill()):(t.fillStyle=n.multiKeyBackground,t.fillRect(e,g,l,r),t.strokeRect(e,g,l,r),t.fillStyle=o.backgroundColor,t.fillRect(i,g+1,l-2,r-2))}t.fillStyle=this.labelTextColors[i]}drawBody(t,e,i){const{body:s}=this,{bodySpacing:n,bodyAlign:o,displayColors:a,boxHeight:r,boxWidth:l,boxPadding:h}=i,c=He(i.bodyFont);let d=c.lineHeight,u=0;const f=Ei(i.rtl,this.x,this.width),g=function(i){e.fillText(i,f.x(t.x+u),t.y+d/2),t.y+=d+n},p=f.textAlign(o);let m,x,b,_,y,v,w;for(e.textAlign=o,e.textBaseline="middle",e.font=c.string,t.x=No(this,p,i),e.fillStyle=i.bodyColor,Q(this.beforeBody,g),u=a&&"right"!==p?"center"===o?l/2+h:l+2+h:0,_=0,v=s.length;_<v;++_){for(m=s[_],x=this.labelTextColors[_],e.fillStyle=x,Q(m.before,g),b=m.lines,a&&b.length&&(this._drawColorBox(e,t,_,f,i),d=Math.max(c.lineHeight,r)),y=0,w=b.length;y<w;++y)g(b[y]),d=c.lineHeight;Q(m.after,g)}u=0,d=c.lineHeight,Q(this.afterBody,g),t.y-=n}drawFooter(t,e,i){const s=this.footer,n=s.length;let o,a;if(n){const r=Ei(i.rtl,this.x,this.width);for(t.x=No(this,i.footerAlign,i),t.y+=i.footerMarginTop,e.textAlign=r.textAlign(i.footerAlign),e.textBaseline="middle",o=He(i.footerFont),e.fillStyle=i.footerColor,e.font=o.string,a=0;a<n;++a)e.fillText(s[a],r.x(t.x),t.y+o.lineHeight/2),t.y+=o.lineHeight+i.footerSpacing}}drawBackground(t,e,i,s){const{xAlign:n,yAlign:o}=this,{x:a,y:r}=t,{width:l,height:h}=i,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=We(s.cornerRadius);e.fillStyle=s.backgroundColor,e.strokeStyle=s.borderColor,e.lineWidth=s.borderWidth,e.beginPath(),e.moveTo(a+c,r),"top"===o&&this.drawCaret(t,e,i,s),e.lineTo(a+l-d,r),e.quadraticCurveTo(a+l,r,a+l,r+d),"center"===o&&"right"===n&&this.drawCaret(t,e,i,s),e.lineTo(a+l,r+h-f),e.quadraticCurveTo(a+l,r+h,a+l-f,r+h),"bottom"===o&&this.drawCaret(t,e,i,s),e.lineTo(a+u,r+h),e.quadraticCurveTo(a,r+h,a,r+h-u),"center"===o&&"left"===n&&this.drawCaret(t,e,i,s),e.lineTo(a,r+c),e.quadraticCurveTo(a,r,a+c,r),e.closePath(),e.fill(),s.borderWidth>0&&e.stroke()}_updateAnimationTarget(t){const e=this.chart,i=this.$animations,s=i&&i.x,n=i&&i.y;if(s||n){const i=Ro[t.position].call(this,this._active,this._eventPosition);if(!i)return;const o=this._size=Fo(this,t),a=Object.assign({},i,this._size),r=Vo(e,t,a),l=Wo(t,a,r,e);s._to===l.x&&n._to===l.y||(this.xAlign=r.xAlign,this.yAlign=r.yAlign,this.width=o.width,this.height=o.height,this.caretX=i.x,this.caretY=i.y,this._resolveAnimations().update(this,l))}}draw(t){const e=this.options.setContext(this.getContext());let i=this.opacity;if(!i)return;this._updateAnimationTarget(e);const s={width:this.width,height:this.height},n={x:this.x,y:this.y};i=Math.abs(i)<.001?0:i;const o=Ne(e.padding),a=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&a&&(t.save(),t.globalAlpha=i,this.drawBackground(n,t,s,e),Ii(t,e.textDirection),n.y+=o.top,this.drawTitle(n,t,e),this.drawBody(n,t,e),this.drawFooter(n,t,e),zi(t,e.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){const i=this._active,s=t.map((({datasetIndex:t,index:e})=>{const i=this.chart.getDatasetMeta(t);if(!i)throw new Error("Cannot find a dataset at index "+t);return{datasetIndex:t,element:i.data[e],index:e}})),n=!tt(i,s),o=this._positionChanged(s,e);(n||o)&&(this._active=s,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}handleEvent(t,e,i=!0){if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;const s=this.options,n=this._active||[],o=this._getActiveElements(t,n,e,i),a=this._positionChanged(o,t),r=e||!tt(o,n)||a;return r&&(this._active=o,(s.enabled||s.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),r}_getActiveElements(t,e,i,s){const n=this.options;if("mouseout"===t.type)return[];if(!s)return e;const o=this.chart.getElementsAtEventForMode(t,n.mode,n,i);return n.reverse&&o.reverse(),o}_positionChanged(t,e){const{caretX:i,caretY:s,options:n}=this,o=Ro[n.position].call(this,t,e);return!1!==o&&(i!==o.x||s!==o.y)}}$o.positioners=Ro;var Yo={id:"tooltip",_element:$o,positioners:Ro,afterInit(t,e,i){i&&(t.tooltip=new $o({chart:t,options:i}))},beforeUpdate(t,e,i){t.tooltip&&t.tooltip.initialize(i)},reset(t,e,i){t.tooltip&&t.tooltip.initialize(i)},afterDraw(t){const e=t.tooltip,i={tooltip:e};!1!==t.notifyPlugins("beforeTooltipDraw",i)&&(e&&e.draw(t.ctx),t.notifyPlugins("afterTooltipDraw",i))},afterEvent(t,e){if(t.tooltip){const i=e.replay;t.tooltip.handleEvent(e.event,i,e.inChartArea)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(t,e)=>e.bodyFont.size,boxWidth:(t,e)=>e.bodyFont.size,multiKeyBackground:"#fff",displayColors:!0,boxPadding:0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:{beforeTitle:H,title(t){if(t.length>0){const e=t[0],i=e.chart.data.labels,s=i?i.length:0;if(this&&this.options&&"dataset"===this.options.mode)return e.dataset.label||"";if(e.label)return e.label;if(s>0&&e.dataIndex<s)return i[e.dataIndex]}return""},afterTitle:H,beforeBody:H,beforeLabel:H,label(t){if(this&&this.options&&"dataset"===this.options.mode)return t.label+": "+t.formattedValue||t.formattedValue;let e=t.dataset.label||"";e&&(e+=": ");const i=t.formattedValue;return $(i)||(e+=i),e},labelColor(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{borderColor:e.borderColor,backgroundColor:e.backgroundColor,borderWidth:e.borderWidth,borderDash:e.borderDash,borderDashOffset:e.borderDashOffset,borderRadius:0}},labelTextColor(){return this.options.bodyColor},labelPointStyle(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{pointStyle:e.pointStyle,rotation:e.rotation}},afterLabel:H,afterBody:H,beforeFooter:H,footer:H,afterFooter:H}},defaultRoutes:{bodyFont:"font",footerFont:"font",titleFont:"font"},descriptors:{_scriptable:t=>"filter"!==t&&"itemSort"!==t&&"external"!==t,_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:"animation"}},additionalOptionScopes:["interaction"]},Uo=Object.freeze({__proto__:null,Decimation:ro,Filler:So,Legend:Co,SubTitle:Lo,Title:Ao,Tooltip:Yo});function Xo(t,e,i,s){const n=t.indexOf(e);if(-1===n)return((t,e,i,s)=>("string"==typeof e?(i=t.push(e)-1,s.unshift({index:i,label:e})):isNaN(e)&&(i=null),i))(t,e,i,s);return n!==t.lastIndexOf(e)?i:n}class qo extends Bs{constructor(t){super(t),this._startValue=void 0,this._valueRange=0,this._addedLabels=[]}init(t){const e=this._addedLabels;if(e.length){const t=this.getLabels();for(const{index:i,label:s}of e)t[i]===s&&t.splice(i,1);this._addedLabels=[]}super.init(t)}parse(t,e){if($(t))return null;const i=this.getLabels();return((t,e)=>null===t?null:jt(Math.round(t),0,e))(e=isFinite(e)&&i[e]===t?e:Xo(i,t,K(e,t),this._addedLabels),i.length-1)}determineDataLimits(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let{min:i,max:s}=this.getMinMax(!0);"ticks"===this.options.bounds&&(t||(i=0),e||(s=this.getLabels().length-1)),this.min=i,this.max=s}buildTicks(){const t=this.min,e=this.max,i=this.options.offset,s=[];let n=this.getLabels();n=0===t&&e===n.length-1?n:n.slice(t,e+1),this._valueRange=Math.max(n.length-(i?0:1),1),this._startValue=this.min-(i?.5:0);for(let i=t;i<=e;i++)s.push({value:i});return s}getLabelForValue(t){const e=this.getLabels();return t>=0&&t<e.length?e[t]:t}configure(){super.configure(),this.isHorizontal()||(this._reversePixels=!this._reversePixels)}getPixelForValue(t){return"number"!=typeof t&&(t=this.parse(t)),null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}getBasePixel(){return this.bottom}}function Ko(t,e,{horizontal:i,minRotation:s}){const n=It(s),o=(i?Math.sin(n):Math.cos(n))||.001,a=.75*e*(""+t).length;return Math.min(e/o,a)}qo.id="category",qo.defaults={ticks:{callback:qo.prototype.getLabelForValue}};class Go extends Bs{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._endValue=void 0,this._valueRange=0}parse(t,e){return $(t)||("number"==typeof t||t instanceof Number)&&!isFinite(+t)?null:+t}handleTickRangeOptions(){const{beginAtZero:t}=this.options,{minDefined:e,maxDefined:i}=this.getUserBounds();let{min:s,max:n}=this;const o=t=>s=e?s:t,a=t=>n=i?n:t;if(t){const t=Ct(s),e=Ct(n);t<0&&e<0?a(0):t>0&&e>0&&o(0)}if(s===n){let e=1;(n>=Number.MAX_SAFE_INTEGER||s<=Number.MIN_SAFE_INTEGER)&&(e=Math.abs(.05*n)),a(n+e),t||o(s-e)}this.min=s,this.max=n}getTickLimit(){const t=this.options.ticks;let e,{maxTicksLimit:i,stepSize:s}=t;return s?(e=Math.ceil(this.max/s)-Math.floor(this.min/s)+1,e>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${s} would result generating up to ${e} ticks. Limiting to 1000.`),e=1e3)):(e=this.computeTickLimit(),i=i||11),i&&(e=Math.min(i,e)),e}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){const t=this.options,e=t.ticks;let i=this.getTickLimit();i=Math.max(2,i);const s=function(t,e){const i=[],{bounds:s,step:n,min:o,max:a,precision:r,count:l,maxTicks:h,maxDigits:c,includeBounds:d}=t,u=n||1,f=h-1,{min:g,max:p}=e,m=!$(o),x=!$(a),b=!$(l),_=(p-g)/(c+1);let y,v,w,M,k=Ot((p-g)/f/u)*u;if(k<1e-14&&!m&&!x)return[{value:g},{value:p}];M=Math.ceil(p/k)-Math.floor(g/k),M>f&&(k=Ot(M*k/f/u)*u),$(r)||(y=Math.pow(10,r),k=Math.ceil(k*y)/y),"ticks"===s?(v=Math.floor(g/k)*k,w=Math.ceil(p/k)*k):(v=g,w=p),m&&x&&n&&Rt((a-o)/n,k/1e3)?(M=Math.round(Math.min((a-o)/k,h)),k=(a-o)/M,v=o,w=a):b?(v=m?o:v,w=x?a:w,M=l-1,k=(w-v)/M):(M=(w-v)/k,M=Lt(M,Math.round(M),k/1e3)?Math.round(M):Math.ceil(M));const S=Math.max(Ft(k),Ft(v));y=Math.pow(10,$(r)?S:r),v=Math.round(v*y)/y,w=Math.round(w*y)/y;let P=0;for(m&&(d&&v!==o?(i.push({value:o}),v<o&&P++,Lt(Math.round((v+P*k)*y)/y,o,Ko(o,_,t))&&P++):v<o&&P++);P<M;++P)i.push({value:Math.round((v+P*k)*y)/y});return x&&d&&w!==a?i.length&&Lt(i[i.length-1].value,a,Ko(a,_,t))?i[i.length-1].value=a:i.push({value:a}):x&&w!==a||i.push({value:w}),i}({maxTicks:i,bounds:t.bounds,min:t.min,max:t.max,precision:e.precision,step:e.stepSize,count:e.count,maxDigits:this._maxDigits(),horizontal:this.isHorizontal(),minRotation:e.minRotation||0,includeBounds:!1!==e.includeBounds},this._range||this);return"ticks"===t.bounds&&Et(s,this,"value"),t.reverse?(s.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),s}configure(){const t=this.ticks;let e=this.min,i=this.max;if(super.configure(),this.options.offset&&t.length){const s=(i-e)/Math.max(t.length-1,1)/2;e-=s,i+=s}this._startValue=e,this._endValue=i,this._valueRange=i-e}getLabelForValue(t){return Ri(t,this.chart.options.locale,this.options.ticks.format)}}class Zo extends Go{determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=X(t)?t:0,this.max=X(e)?e:1,this.handleTickRangeOptions()}computeTickLimit(){const t=this.isHorizontal(),e=t?this.width:this.height,i=It(this.options.ticks.minRotation),s=(t?Math.sin(i):Math.cos(i))||.001,n=this._resolveTickFontOptions(0);return Math.ceil(e/Math.min(40,n.lineHeight/s))}getPixelForValue(t){return null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getValueForPixel(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange}}function Jo(t){return 1===t/Math.pow(10,Math.floor(Dt(t)))}Zo.id="linear",Zo.defaults={ticks:{callback:Os.formatters.numeric}};class Qo extends Bs{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._valueRange=0}parse(t,e){const i=Go.prototype.parse.apply(this,[t,e]);if(0!==i)return X(i)&&i>0?i:null;this._zero=!0}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=X(t)?Math.max(0,t):null,this.max=X(e)?Math.max(0,e):null,this.options.beginAtZero&&(this._zero=!0),this.handleTickRangeOptions()}handleTickRangeOptions(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let i=this.min,s=this.max;const n=e=>i=t?i:e,o=t=>s=e?s:t,a=(t,e)=>Math.pow(10,Math.floor(Dt(t))+e);i===s&&(i<=0?(n(1),o(10)):(n(a(i,-1)),o(a(s,1)))),i<=0&&n(a(s,-1)),s<=0&&o(a(i,1)),this._zero&&this.min!==this._suggestedMin&&i===a(this.min,0)&&n(a(i,-1)),this.min=i,this.max=s}buildTicks(){const t=this.options,e=function(t,e){const i=Math.floor(Dt(e.max)),s=Math.ceil(e.max/Math.pow(10,i)),n=[];let o=q(t.min,Math.pow(10,Math.floor(Dt(e.min)))),a=Math.floor(Dt(o)),r=Math.floor(o/Math.pow(10,a)),l=a<0?Math.pow(10,Math.abs(a)):1;do{n.push({value:o,major:Jo(o)}),++r,10===r&&(r=1,++a,l=a>=0?1:l),o=Math.round(r*Math.pow(10,a)*l)/l}while(a<i||a===i&&r<s);const h=q(t.max,o);return n.push({value:h,major:Jo(o)}),n}({min:this._userMin,max:this._userMax},this);return"ticks"===t.bounds&&Et(e,this,"value"),t.reverse?(e.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),e}getLabelForValue(t){return void 0===t?"0":Ri(t,this.chart.options.locale,this.options.ticks.format)}configure(){const t=this.min;super.configure(),this._startValue=Dt(t),this._valueRange=Dt(this.max)-Dt(t)}getPixelForValue(t){return void 0!==t&&0!==t||(t=this.min),null===t||isNaN(t)?NaN:this.getPixelForDecimal(t===this.min?0:(Dt(t)-this._startValue)/this._valueRange)}getValueForPixel(t){const e=this.getDecimalForPixel(t);return Math.pow(10,this._startValue+e*this._valueRange)}}function ta(t){const e=t.ticks;if(e.display&&t.display){const t=Ne(e.backdropPadding);return K(e.font&&e.font.size,bt.font.size)+t.height}return 0}function ea(t,e,i,s,n){return t===s||t===n?{start:e-i/2,end:e+i/2}:t<s||t>n?{start:e-i,end:e}:{start:e,end:e+i}}function ia(t){const e={l:t.left+t._padding.left,r:t.right-t._padding.right,t:t.top+t._padding.top,b:t.bottom-t._padding.bottom},i=Object.assign({},e),s=[],n=[],o=t._pointLabels.length,a=t.options.pointLabels,r=a.centerPointLabels?_t/o:0;for(let d=0;d<o;d++){const o=a.setContext(t.getPointLabelContext(d));n[d]=o.padding;const u=t.getPointPosition(d,t.drawingArea+n[d],r),f=He(o.font),g=(l=t.ctx,h=f,c=Y(c=t._pointLabels[d])?c:[c],{w:qt(l,h.string,c),h:c.length*h.lineHeight});s[d]=g;const p=Nt(t.getIndexAngle(d)+r),m=Math.round(zt(p));sa(i,e,p,ea(m,u.x,g.w,0,180),ea(m,u.y,g.h,90,270))}var l,h,c;t.setCenterPoint(e.l-i.l,i.r-e.r,e.t-i.t,i.b-e.b),t._pointLabelItems=function(t,e,i){const s=[],n=t._pointLabels.length,o=t.options,a=ta(o)/2,r=t.drawingArea,l=o.pointLabels.centerPointLabels?_t/n:0;for(let o=0;o<n;o++){const n=t.getPointPosition(o,r+a+i[o],l),h=Math.round(zt(Nt(n.angle+kt))),c=e[o],d=aa(n.y,c.h,h),u=na(h),f=oa(n.x,c.w,u);s.push({x:n.x,y:d,textAlign:u,left:f,top:d,right:f+c.w,bottom:d+c.h})}return s}(t,s,n)}function sa(t,e,i,s,n){const o=Math.abs(Math.sin(i)),a=Math.abs(Math.cos(i));let r=0,l=0;s.start<e.l?(r=(e.l-s.start)/o,t.l=Math.min(t.l,e.l-r)):s.end>e.r&&(r=(s.end-e.r)/o,t.r=Math.max(t.r,e.r+r)),n.start<e.t?(l=(e.t-n.start)/a,t.t=Math.min(t.t,e.t-l)):n.end>e.b&&(l=(n.end-e.b)/a,t.b=Math.max(t.b,e.b+l))}function na(t){return 0===t||180===t?"center":t<180?"left":"right"}function oa(t,e,i){return"right"===i?t-=e:"center"===i&&(t-=e/2),t}function aa(t,e,i){return 90===i||270===i?t-=e/2:(i>270||i<90)&&(t-=e),t}function ra(t,e,i,s){const{ctx:n}=t;if(i)n.arc(t.xCenter,t.yCenter,e,0,yt);else{let i=t.getPointPosition(0,e);n.moveTo(i.x,i.y);for(let o=1;o<s;o++)i=t.getPointPosition(o,e),n.lineTo(i.x,i.y)}}Qo.id="logarithmic",Qo.defaults={ticks:{callback:Os.formatters.logarithmic,major:{enabled:!0}}};class la extends Go{constructor(t){super(t),this.xCenter=void 0,this.yCenter=void 0,this.drawingArea=void 0,this._pointLabels=[],this._pointLabelItems=[]}setDimensions(){const t=this._padding=Ne(ta(this.options)/2),e=this.width=this.maxWidth-t.width,i=this.height=this.maxHeight-t.height;this.xCenter=Math.floor(this.left+e/2+t.left),this.yCenter=Math.floor(this.top+i/2+t.top),this.drawingArea=Math.floor(Math.min(e,i)/2)}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!1);this.min=X(t)&&!isNaN(t)?t:0,this.max=X(e)&&!isNaN(e)?e:0,this.handleTickRangeOptions()}computeTickLimit(){return Math.ceil(this.drawingArea/ta(this.options))}generateTickLabels(t){Go.prototype.generateTickLabels.call(this,t),this._pointLabels=this.getLabels().map(((t,e)=>{const i=J(this.options.pointLabels.callback,[t,e],this);return i||0===i?i:""})).filter(((t,e)=>this.chart.getDataVisibility(e)))}fit(){const t=this.options;t.display&&t.pointLabels.display?ia(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(t,e,i,s){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((i-s)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,i,s))}getIndexAngle(t){return Nt(t*(yt/(this._pointLabels.length||1))+It(this.options.startAngle||0))}getDistanceFromCenterForValue(t){if($(t))return NaN;const e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if($(t))return NaN;const e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){const e=this._pointLabels||[];if(t>=0&&t<e.length){const i=e[t];return function(t,e,i){return Ye(t,{label:i,index:e,type:"pointLabel"})}(this.getContext(),t,i)}}getPointPosition(t,e,i=0){const s=this.getIndexAngle(t)-kt+i;return{x:Math.cos(s)*e+this.xCenter,y:Math.sin(s)*e+this.yCenter,angle:s}}getPointPositionForValue(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))}getBasePosition(t){return this.getPointPositionForValue(t||0,this.getBaseValue())}getPointLabelPosition(t){const{left:e,top:i,right:s,bottom:n}=this._pointLabelItems[t];return{left:e,top:i,right:s,bottom:n}}drawBackground(){const{backgroundColor:t,grid:{circular:e}}=this.options;if(t){const i=this.ctx;i.save(),i.beginPath(),ra(this,this.getDistanceFromCenterForValue(this._endValue),e,this._pointLabels.length),i.closePath(),i.fillStyle=t,i.fill(),i.restore()}}drawGrid(){const t=this.ctx,e=this.options,{angleLines:i,grid:s}=e,n=this._pointLabels.length;let o,a,r;if(e.pointLabels.display&&function(t,e){const{ctx:i,options:{pointLabels:s}}=t;for(let n=e-1;n>=0;n--){const e=s.setContext(t.getPointLabelContext(n)),o=He(e.font),{x:a,y:r,textAlign:l,left:h,top:c,right:d,bottom:u}=t._pointLabelItems[n],{backdropColor:f}=e;if(!$(f)){const t=Ne(e.backdropPadding);i.fillStyle=f,i.fillRect(h-t.left,c-t.top,d-h+t.width,u-c+t.height)}se(i,t._pointLabels[n],a,r+o.lineHeight/2,o,{color:e.color,textAlign:l,textBaseline:"middle"})}}(this,n),s.display&&this.ticks.forEach(((t,e)=>{if(0!==e){a=this.getDistanceFromCenterForValue(t.value);!function(t,e,i,s){const n=t.ctx,o=e.circular,{color:a,lineWidth:r}=e;!o&&!s||!a||!r||i<0||(n.save(),n.strokeStyle=a,n.lineWidth=r,n.setLineDash(e.borderDash),n.lineDashOffset=e.borderDashOffset,n.beginPath(),ra(t,i,o,s),n.closePath(),n.stroke(),n.restore())}(this,s.setContext(this.getContext(e-1)),a,n)}})),i.display){for(t.save(),o=n-1;o>=0;o--){const s=i.setContext(this.getPointLabelContext(o)),{color:n,lineWidth:l}=s;l&&n&&(t.lineWidth=l,t.strokeStyle=n,t.setLineDash(s.borderDash),t.lineDashOffset=s.borderDashOffset,a=this.getDistanceFromCenterForValue(e.ticks.reverse?this.min:this.max),r=this.getPointPosition(o,a),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(r.x,r.y),t.stroke())}t.restore()}}drawBorder(){}drawLabels(){const t=this.ctx,e=this.options,i=e.ticks;if(!i.display)return;const s=this.getIndexAngle(0);let n,o;t.save(),t.translate(this.xCenter,this.yCenter),t.rotate(s),t.textAlign="center",t.textBaseline="middle",this.ticks.forEach(((s,a)=>{if(0===a&&!e.reverse)return;const r=i.setContext(this.getContext(a)),l=He(r.font);if(n=this.getDistanceFromCenterForValue(this.ticks[a].value),r.showLabelBackdrop){t.font=l.string,o=t.measureText(s.label).width,t.fillStyle=r.backdropColor;const e=Ne(r.backdropPadding);t.fillRect(-o/2-e.left,-n-l.size/2-e.top,o+e.width,l.size+e.height)}se(t,s.label,0,-n,l,{color:r.color})})),t.restore()}drawTitle(){}}la.id="radialLinear",la.defaults={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,lineWidth:1,borderDash:[],borderDashOffset:0},grid:{circular:!1},startAngle:0,ticks:{showLabelBackdrop:!0,callback:Os.formatters.numeric},pointLabels:{backdropColor:void 0,backdropPadding:2,display:!0,font:{size:10},callback:t=>t,padding:5,centerPointLabels:!1}},la.defaultRoutes={"angleLines.color":"borderColor","pointLabels.color":"color","ticks.color":"color"},la.descriptors={angleLines:{_fallback:"grid"}};const ha={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ca=Object.keys(ha);function da(t,e){return t-e}function ua(t,e){if($(e))return null;const i=t._adapter,{parser:s,round:n,isoWeekday:o}=t._parseOpts;let a=e;return"function"==typeof s&&(a=s(a)),X(a)||(a="string"==typeof s?i.parse(a,s):i.parse(a)),null===a?null:(n&&(a="week"!==n||!Tt(o)&&!0!==o?i.startOf(a,n):i.startOf(a,"isoWeek",o)),+a)}function fa(t,e,i,s){const n=ca.length;for(let o=ca.indexOf(t);o<n-1;++o){const t=ha[ca[o]],n=t.steps?t.steps:Number.MAX_SAFE_INTEGER;if(t.common&&Math.ceil((i-e)/(n*t.size))<=s)return ca[o]}return ca[n-1]}function ga(t,e,i){if(i){if(i.length){const{lo:s,hi:n}=ae(i,e);t[i[s]>=e?i[s]:i[n]]=!0}}else t[e]=!0}function pa(t,e,i){const s=[],n={},o=e.length;let a,r;for(a=0;a<o;++a)r=e[a],n[r]=a,s.push({value:r,major:!1});return 0!==o&&i?function(t,e,i,s){const n=t._adapter,o=+n.startOf(e[0].value,s),a=e[e.length-1].value;let r,l;for(r=o;r<=a;r=+n.add(r,1,s))l=i[r],l>=0&&(e[l].major=!0);return e}(t,s,n,i):s}class ma extends Bs{constructor(t){super(t),this._cache={data:[],labels:[],all:[]},this._unit="day",this._majorUnit=void 0,this._offsets={},this._normalized=!1,this._parseOpts=void 0}init(t,e){const i=t.time||(t.time={}),s=this._adapter=new mn._date(t.adapters.date);ot(i.displayFormats,s.formats()),this._parseOpts={parser:i.parser,round:i.round,isoWeekday:i.isoWeekday},super.init(t),this._normalized=e.normalized}parse(t,e){return void 0===t?null:ua(this,t)}beforeLayout(){super.beforeLayout(),this._cache={data:[],labels:[],all:[]}}determineDataLimits(){const t=this.options,e=this._adapter,i=t.time.unit||"day";let{min:s,max:n,minDefined:o,maxDefined:a}=this.getUserBounds();function r(t){o||isNaN(t.min)||(s=Math.min(s,t.min)),a||isNaN(t.max)||(n=Math.max(n,t.max))}o&&a||(r(this._getLabelBounds()),"ticks"===t.bounds&&"labels"===t.ticks.source||r(this.getMinMax(!1))),s=X(s)&&!isNaN(s)?s:+e.startOf(Date.now(),i),n=X(n)&&!isNaN(n)?n:+e.endOf(Date.now(),i)+1,this.min=Math.min(s,n-1),this.max=Math.max(s+1,n)}_getLabelBounds(){const t=this.getLabelTimestamps();let e=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],i=t[t.length-1]),{min:e,max:i}}buildTicks(){const t=this.options,e=t.time,i=t.ticks,s="labels"===i.source?this.getLabelTimestamps():this._generate();"ticks"===t.bounds&&s.length&&(this.min=this._userMin||s[0],this.max=this._userMax||s[s.length-1]);const n=this.min,o=he(s,n,this.max);return this._unit=e.unit||(i.autoSkip?fa(e.minUnit,this.min,this.max,this._getLabelCapacity(n)):function(t,e,i,s,n){for(let o=ca.length-1;o>=ca.indexOf(i);o--){const i=ca[o];if(ha[i].common&&t._adapter.diff(n,s,i)>=e-1)return i}return ca[i?ca.indexOf(i):0]}(this,o.length,e.minUnit,this.min,this.max)),this._majorUnit=i.major.enabled&&"year"!==this._unit?function(t){for(let e=ca.indexOf(t)+1,i=ca.length;e<i;++e)if(ha[ca[e]].common)return ca[e]}(this._unit):void 0,this.initOffsets(s),t.reverse&&o.reverse(),pa(this,o,this._majorUnit)}initOffsets(t){let e,i,s=0,n=0;this.options.offset&&t.length&&(e=this.getDecimalForValue(t[0]),s=1===t.length?1-e:(this.getDecimalForValue(t[1])-e)/2,i=this.getDecimalForValue(t[t.length-1]),n=1===t.length?i:(i-this.getDecimalForValue(t[t.length-2]))/2);const o=t.length<3?.5:.25;s=jt(s,0,o),n=jt(n,0,o),this._offsets={start:s,end:n,factor:1/(s+1+n)}}_generate(){const t=this._adapter,e=this.min,i=this.max,s=this.options,n=s.time,o=n.unit||fa(n.minUnit,e,i,this._getLabelCapacity(e)),a=K(n.stepSize,1),r="week"===o&&n.isoWeekday,l=Tt(r)||!0===r,h={};let c,d,u=e;if(l&&(u=+t.startOf(u,"isoWeek",r)),u=+t.startOf(u,l?"day":o),t.diff(i,e,o)>1e5*a)throw new Error(e+" and "+i+" are too far apart with stepSize of "+a+" "+o);const f="data"===s.ticks.source&&this.getDataTimestamps();for(c=u,d=0;c<i;c=+t.add(c,a,o),d++)ga(h,c,f);return c!==i&&"ticks"!==s.bounds&&1!==d||ga(h,c,f),Object.keys(h).sort(((t,e)=>t-e)).map((t=>+t))}getLabelForValue(t){const e=this._adapter,i=this.options.time;return i.tooltipFormat?e.format(t,i.tooltipFormat):e.format(t,i.displayFormats.datetime)}_tickFormatFunction(t,e,i,s){const n=this.options,o=n.time.displayFormats,a=this._unit,r=this._majorUnit,l=a&&o[a],h=r&&o[r],c=i[e],d=r&&h&&c&&c.major,u=this._adapter.format(t,s||(d?h:l)),f=n.ticks.callback;return f?J(f,[u,e,i],this):u}generateTickLabels(t){let e,i,s;for(e=0,i=t.length;e<i;++e)s=t[e],s.label=this._tickFormatFunction(s.value,e,t)}getDecimalForValue(t){return null===t?NaN:(t-this.min)/(this.max-this.min)}getPixelForValue(t){const e=this._offsets,i=this.getDecimalForValue(t);return this.getPixelForDecimal((e.start+i)*e.factor)}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return this.min+i*(this.max-this.min)}_getLabelSize(t){const e=this.options.ticks,i=this.ctx.measureText(t).width,s=It(this.isHorizontal()?e.maxRotation:e.minRotation),n=Math.cos(s),o=Math.sin(s),a=this._resolveTickFontOptions(0).size;return{w:i*n+a*o,h:i*o+a*n}}_getLabelCapacity(t){const e=this.options.time,i=e.displayFormats,s=i[e.unit]||i.millisecond,n=this._tickFormatFunction(t,0,pa(this,[t],this._majorUnit),s),o=this._getLabelSize(n),a=Math.floor(this.isHorizontal()?this.width/o.w:this.height/o.h)-1;return a>0?a:1}getDataTimestamps(){let t,e,i=this._cache.data||[];if(i.length)return i;const s=this.getMatchingVisibleMetas();if(this._normalized&&s.length)return this._cache.data=s[0].controller.getAllParsedValues(this);for(t=0,e=s.length;t<e;++t)i=i.concat(s[t].controller.getAllParsedValues(this));return this._cache.data=this.normalize(i)}getLabelTimestamps(){const t=this._cache.labels||[];let e,i;if(t.length)return t;const s=this.getLabels();for(e=0,i=s.length;e<i;++e)t.push(ua(this,s[e]));return this._cache.labels=this._normalized?t:this.normalize(t)}normalize(t){return fe(t.sort(da))}}function xa(t,e,i){let s,n,o,a,r=0,l=t.length-1;i?(e>=t[r].pos&&e<=t[l].pos&&({lo:r,hi:l}=re(t,"pos",e)),({pos:s,time:o}=t[r]),({pos:n,time:a}=t[l])):(e>=t[r].time&&e<=t[l].time&&({lo:r,hi:l}=re(t,"time",e)),({time:s,pos:o}=t[r]),({time:n,pos:a}=t[l]));const h=n-s;return h?o+(a-o)*(e-s)/h:o}ma.id="time",ma.defaults={bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{source:"auto",major:{enabled:!1}}};class ba extends ma{constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=xa(e,this.min),this._tableRange=xa(e,this.max)-this._minPos,super.initOffsets(t)}buildLookupTable(t){const{min:e,max:i}=this,s=[],n=[];let o,a,r,l,h;for(o=0,a=t.length;o<a;++o)l=t[o],l>=e&&l<=i&&s.push(l);if(s.length<2)return[{time:e,pos:0},{time:i,pos:1}];for(o=0,a=s.length;o<a;++o)h=s[o+1],r=s[o-1],l=s[o],Math.round((h+r)/2)!==l&&n.push({time:l,pos:o/(a-1)});return n}_getTimestampsForTable(){let t=this._cache.all||[];if(t.length)return t;const e=this.getDataTimestamps(),i=this.getLabelTimestamps();return t=e.length&&i.length?this.normalize(e.concat(i)):e.length?e:i,t=this._cache.all=t,t}getDecimalForValue(t){return(xa(this._table,t)-this._minPos)/this._tableRange}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return xa(this._table,i*this._tableRange+this._minPos,!0)}}ba.id="timeseries",ba.defaults=ma.defaults;var _a=Object.freeze({__proto__:null,CategoryScale:qo,LinearScale:Zo,LogarithmicScale:Qo,RadialLinearScale:la,TimeScale:ma,TimeSeriesScale:ba});return dn.register(Rn,_a,no,Uo),dn.helpers={...Yi},dn._adapters=mn,dn.Animation=us,dn.Animations=gs,dn.animator=a,dn.controllers=Ws.controllers.items,dn.DatasetController=Ps,dn.Element=Ds,dn.elements=no,dn.Interaction=Ee,dn.layouts=ni,dn.platforms=hs,dn.Scale=Bs,dn.Ticks=Os,Object.assign(dn,Rn,_a,no,Uo,hs),dn.Chart=dn,"undefined"!=typeof window&&(window.Chart=dn),dn}));
includes/mycred-addons-upgrader.php DELETED
@@ -1,365 +0,0 @@
1
- <?php
2
- if ( ! defined( 'myCRED_VERSION' ) ) exit;
3
-
4
-
5
- if ( ! class_exists( 'myCRED_Addons_Upgrader' ) ) :
6
- Class myCRED_Addons_Upgrader {
7
-
8
- /**
9
- * Construct
10
- */
11
- public function __construct() {
12
-
13
- add_action( 'admin_menu', array( $this, 'mycred_upgrader_menu' ) );
14
- add_action( 'admin_notices', array( $this, 'mycred_update_notice') );
15
- add_action( 'admin_init', array( $this, 'admin_init') );
16
- add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_transient' ), 99 );
17
- add_filter( 'update_bulk_plugins_complete_actions', array( $this, 'update_actions' ), 99, 2 );
18
-
19
- }
20
-
21
- /**
22
- * Register upgrader menu
23
- */
24
- public function mycred_upgrader_menu() {
25
-
26
- add_submenu_page(
27
- 'options.php',
28
- 'Update',
29
- 'Update',
30
- 'manage_options',
31
- 'mycred-update',
32
- array( $this, 'mycred_addons_update' )
33
- );
34
-
35
- }
36
-
37
- public function mycred_update_notice() {
38
-
39
- $all_installed_plugins = get_plugins();
40
- $mycred_installed_addons = $this->get_installed_mycred_addons( $all_installed_plugins );
41
-
42
- if ( ! empty( $mycred_installed_addons ) ) {
43
-
44
- $is_upgrade_done = get_option( 'mycred_addons_upgrade' );
45
-
46
- if ( false === $is_upgrade_done ) :?>
47
- <div class="notice notice-warning is-dismissible">
48
- <h2 style="margin-bottom: 8px;">myCred Addons Update Required</h2>
49
- <p style="margin-bottom: 8px;">From myCred version 2.3.1 and onwards, you will be able to use our latest license management system that allows you to run your add-ons more smoothly. Please update your add-ons immediately for a better experience!<br /><a href="https://mycred.me/blog/why-do-you-need-to-update-your-mycred-addons/" target="_blank">Why am I seeing this notice?</a></p>
50
- <a href="<?php echo admin_url('options.php?page=mycred-update'); ?>" class="button button-primary button-large">Update Addons Now</a>
51
- <a class="button button-large" href="<?php echo add_query_arg( 'mycred_addons_upgrader', 'mycred-addons-updated', home_url( $_SERVER['REQUEST_URI'] ) ) ?>">I have already updated</a>
52
- <br>
53
- <br>
54
- </div>
55
- <?php endif;
56
-
57
- }
58
-
59
- }
60
-
61
- public function admin_init() {
62
-
63
- global $pagenow;
64
- if ( $pagenow == 'options.php' && isset( $_GET['page'] ) && $_GET['page'] == 'mycred-update' ) {
65
- remove_all_actions( 'admin_notices' );
66
- }
67
-
68
- if ( isset( $_GET['mycred_addons_upgrader'] ) && $_GET['mycred_addons_upgrader'] == 'mycred-addons-updated' ) {
69
-
70
- update_option( 'mycred_addons_upgrade', 'done' );
71
- wp_redirect( remove_query_arg( 'mycred_addons_upgrader', home_url( $_SERVER['REQUEST_URI'] ) ) );
72
-
73
- }
74
-
75
- }
76
-
77
- public function update_transient( $data ) {
78
-
79
- if ( empty( $data->checked ) ) return $data;
80
-
81
- if ( isset( $_GET['mautype'] ) && isset( $_GET['plugins'] ) ) {
82
-
83
- $addons = explode( ',', $_GET['plugins'] );
84
-
85
- if ( ! empty( $addons ) && is_array( $addons ) ) {
86
-
87
- $all_installed_plugins = get_plugins();
88
- $mycred_installed_addons = $this->get_installed_mycred_addons( $all_installed_plugins );
89
- $mycred_addons_detail = (array) $this->get_addons_detail( $mycred_installed_addons );
90
-
91
- foreach ( $addons as $key => $addon ) {
92
-
93
- $addon_slug = explode( '/', $addon );
94
-
95
- if ( ! empty( $addon_slug[0] ) && ! empty( $mycred_addons_detail[ $addon_slug[0] ] ) ) {
96
-
97
- $data->response[ $addon ] = $mycred_addons_detail[ $addon_slug[0] ];
98
-
99
- if ( ! empty( $data->response[ $addon ]->package ) ) {
100
-
101
- $data->response[ $addon ]->package = add_query_arg(
102
- array(
103
- 'site' => site_url(),
104
- 'api-key' => md5( get_bloginfo( 'url' ) ),
105
- 'slug' => $data->response[ $addon ]->slug
106
- ),
107
- $data->response[ $addon ]->package
108
- );
109
-
110
- $data->no_update[ $addon ] = $data->response[ $addon ];
111
-
112
- }
113
-
114
- }
115
-
116
- }
117
-
118
- }
119
-
120
- }
121
-
122
- return $data;
123
- }
124
-
125
- public function update_actions( $update_actions, $plugin_info ) {
126
-
127
- if ( isset( $_GET['mautype'] ) && $_GET['mautype'] == true ) {
128
-
129
- $update_actions['plugins_page'] = sprintf(
130
- '<a href="%s" target="_parent">%s</a>',
131
- self_admin_url( 'options.php?page=mycred-update' ),
132
- __( 'Go to myCred Addons Update page' )
133
- );
134
-
135
- $update_actions['updates_page'] = sprintf(
136
- '<a href="%s" target="_parent">%s</a>',
137
- self_admin_url( 'plugins.php' ),
138
- __( 'Go to Plugins page' )
139
- );
140
-
141
- }
142
-
143
- update_option( 'mycred_addons_upgrade', 'done' );
144
-
145
- return $update_actions;
146
-
147
- }
148
-
149
-
150
- public function mycred_addons_update() {
151
-
152
- $all_installed_plugins = get_plugins();
153
- $mycred_installed_addons = $this->get_installed_mycred_addons( $all_installed_plugins );
154
- $mycred_addons_detail = (array) $this->get_addons_detail( $mycred_installed_addons );
155
-
156
- if ( isset( $_POST['mycred_addons_update'] ) ) {
157
-
158
- delete_site_transient('update_plugins');
159
-
160
- $title = __( 'myCred Addons Update' );
161
-
162
- wp_enqueue_script( 'updates' );
163
- $url = self_admin_url( 'update.php?action=update-selected&amp;mautype=true&amp;plugins=' . urlencode( implode( ',', $_POST['mycred_addons_update'] ) ) );
164
- $url = wp_nonce_url( $url, 'bulk-update-plugins' );
165
-
166
- ?>
167
- <div class="wrap">
168
- <h1><?php echo esc_html( $title ); ?></h1>
169
- <div class="notice notice-warning">
170
- <h2 id="mycred-addons-update-msg-title">Please wait for a while! <span class="is-active spinner" style="margin:-6px 10px 0;float: none;"></span></h2>
171
- <p>After updating addons, you are required to get a new license key from myCred.me (Dashboard).</p>
172
- <p><span style="color:#d63638;font-weight: bold;">Note:</span> If you're facing issues while updating your addons, you can manually update them from <a href="https://mycred.me/redirect-to-membership/" target="_blank">myCred.me (Dashboard).</a><br /><a href="https://mycred.me/blog/why-do-you-need-to-update-your-mycred-addons/" target="_blank">Why am I seeing this notice?</a></p>
173
- <a href="https://mycred.me/redirect-to-membership/" target="_blank" class="button button-primary button-large">Get your Updated License Key</a>
174
- <br>
175
- <br>
176
- </div>
177
- <iframe id="mycred-addons-update-frame" src="<?php echo $url; ?>" style="width: 100%; height:100%; min-height:850px;"></iframe>
178
- </div>
179
- <script type="text/javascript">
180
-
181
- jQuery('#mycred-addons-update-frame').on('load', function(){
182
- jQuery('#mycred-addons-update-msg-title').hide();
183
- });
184
-
185
- </script>
186
- <?php
187
- }
188
- else { ?>
189
- <div class="wrap">
190
- <h1>myCred Addons Update</h1>
191
- <form method="post" name="upgrade-plugins" class="upgrade">
192
- <p>
193
- <input id="upgrade-plugins" class="button" type="submit" value="Update Plugins" name="upgrade">
194
- </p>
195
- <table class="widefat updates-table" id="update-plugins-table">
196
- <thead>
197
- <tr>
198
- <td class="manage-column check-column"><input type="checkbox" id="plugins-select-all"></td>
199
- <td class="manage-column"><label for="plugins-select-all">Select All</label></td>
200
- </tr>
201
- </thead>
202
- <tbody class="plugins">
203
- <?php
204
-
205
- $count = 0;
206
-
207
- foreach ( $mycred_installed_addons as $key => $value ) :
208
-
209
- $addon_slug = explode( '/', $value );
210
-
211
- if ( ! isset( $mycred_addons_detail[ $addon_slug[0] ] ) ) continue;
212
-
213
- $addon = $mycred_addons_detail[ $addon_slug[0] ];
214
-
215
- if ( version_compare( $all_installed_plugins[ $value ]['Version'], $addon->new_version, '>=' ) ) continue;
216
-
217
- $count++;
218
-
219
- ?>
220
- <tr>
221
- <td class="check-column">
222
- <input type="checkbox" name="mycred_addons_update[]" id="checkbox_<?php echo $addon_slug[0]; ?>" value="<?php echo $value; ?>">
223
- <label for="checkbox_<?php echo $addon_slug[0]; ?>" class="screen-reader-text">Select myCred</label>
224
- </td>
225
- <td class="plugin-title">
226
- <p>
227
- <img src="https://mycred.me/wp-content/uploads/2013/02/mycred-token-icon-100x100.png" alt="">
228
- <strong><?php echo $addon->name; ?></strong> You have version <?php echo $all_installed_plugins[ $value ]['Version']; ?> installed. Update to <?php echo $addon->new_version ?>.
229
- <br>Compatibility with WordPress <?php echo $addon->tested ?>: 100% (according to its author)<br>Improved license system.
230
- </p>
231
- </td>
232
- </tr>
233
- <?php endforeach; ?>
234
- <?php if ( $count == 0 ): ?>
235
- <tr>
236
- <td colspan="2">Empty</td>
237
- </tr>
238
- <?php endif ?>
239
- </tbody>
240
- <tfoot>
241
- <tr>
242
- <td class="manage-column check-column"><input type="checkbox" id="plugins-select-all-2"></td>
243
- <td class="manage-column"><label for="plugins-select-all-2">Select All</label></td>
244
- </tr>
245
- </tfoot>
246
- </table>
247
- <p>
248
- <input id="upgrade-plugins-2" class="button" type="submit" value="Update Plugins" name="upgrade">
249
- </p>
250
- </form>
251
- </div>
252
- <?php
253
- }
254
-
255
- }
256
-
257
- public function get_installed_mycred_addons( $installed_plugins ) {
258
-
259
- $mycred_addons = array(
260
- 'mycred-2co/mycred-2co.php',
261
- 'mycred-coinbase/mycred-coinbase.php',
262
- 'mycred-coinpayment/mycred-coinpayment.php',
263
- 'mycred-compropago/mycred-compropago.php',
264
- 'mycred-payfast/mycred-payfast.php',
265
- 'mycred-paymentwall/mycred-paymentwall.php',
266
- 'mycred-payza/mycred-payza.php',
267
- 'mycred-robokassa/mycred-robokassa.php',
268
- 'mycred-stripe/mycred-stripe.php',
269
- 'mycred-wepay/mycred-wepay.php',
270
- 'mycred-cashcred-paypal/mycred-cashcred-paypal.php',
271
- 'mycred-cashcred-stripe/mycred-cashcred-stripe.php',
272
- 'mycred-anniversary-pro/mycred-anniversary-pro.php',
273
- 'mycred-birthday-plus/myCred-birthday-plus.php',
274
- 'mycred-bp-charges/mycred-bp-charges.php',
275
- 'mycred-cashcred-paystack/mycred-cashcred-paystack.php',
276
- 'mycred-coupons-plus/mycred-coupons-plus.php',
277
- 'mycred-daily-login-rewards/mycred-daily-login-rewards.php',
278
- 'mycred-dokan/mycred-dokan.php',
279
- 'mycred-email-digest/mycred-email-digest.php',
280
- 'mycred-expiration-addon/mycred-expiration-addon.php',
281
- 'mycred-beaver-builder/mycred-beaver-builder.php',
282
- 'mycred-userpro/mycred-userpro.php',
283
- 'mycred-usersultra/mycred-usersultra.php',
284
- 'mycred-vc/mycred-vc.php',
285
- 'mycred-gateway-edd/mycred-gateway-edd.php',
286
- 'mycred-gateway-jigoshop/mycred-gateway-jigoshop.php',
287
- 'mycred-gateway-fundraising/mycred-gateway-fundraising.php',
288
- 'mycred-level-cred/mycred-level-cred.php',
289
- 'mycred-notice-plus/mycred-notice-plus.php',
290
- 'mycred-pacman/mycred-pacman.php',
291
- 'mycred-paystack/mycred-paystack.php',
292
- 'mycred-points-cap/mycred-points-cap.php',
293
- 'mycred-progress-bar/mycred-progress-bar.php',
294
- 'mycred-progress-map/mycred-progress-map.php',
295
- 'mycred-reset-points/mycred-reset-points.php',
296
- 'mycred-rest/mycred-rest.php',
297
- 'mycred-sms-payments/mycred-sms-payments.php',
298
- 'mycred-social-proof/mycred-social-proof.php',
299
- 'mycred-social-shares/mycred-social-shares.php',
300
- 'mycred-transfer-plus/mycred-transfer-plus.php',
301
- 'mycred-videos/mycred-videos.php',
302
- 'mycred-jwplayer/mycred-jwplayer.php',
303
- 'mycred-wc-vendor/mycred-wc-vendors-addon.php',
304
- 'mycred-wheel-of-fortune/mycred-wheel-of-fortune.php',
305
- 'mycred-woocommerce-plus/mycred-woocommerce-plus.php',
306
- 'mycred-zapier/mycred-zapier.php'
307
- );
308
-
309
- return array_intersect( $mycred_addons, array_keys( $installed_plugins ) );
310
-
311
- }
312
-
313
- public function get_addons_detail( $installed_addons ) {
314
-
315
- $transient_key = md5( implode( ",", $installed_addons ) );
316
- $plugins_data = get_site_transient( $transient_key );
317
-
318
- if ( false === $plugins_data ) {
319
-
320
- $addons = array();
321
-
322
- foreach ( $installed_addons as $key => $addon ) {
323
-
324
- $addon_file = explode( '/', $addon );
325
-
326
- if ( ! empty( $addon_file[0] ) ) array_push( $addons, $addon_file[0] );
327
-
328
- }
329
-
330
- $plugins_data = new stdClass();
331
- $request_args = array(
332
- 'body' => array(
333
- 'site' => site_url(),
334
- 'api-key' => md5( get_bloginfo( 'url' ) ),
335
- 'addons' => $addons
336
- ),
337
- 'timeout' => 12
338
- );
339
-
340
- // Start checking for an update
341
- $response = wp_remote_post( 'https://license.mycred.me/wp-json/license/get-new-plugins', $request_args );
342
-
343
- if ( ! is_wp_error( $response ) ) {
344
-
345
- $response_data = json_decode( $response['body'] );
346
-
347
- if ( ! empty( $response_data->status ) && $response_data->status == 'success' ) {
348
-
349
- $plugins_data = $response_data->data;
350
- set_site_transient( $transient_key, $plugins_data, 5 * HOUR_IN_SECONDS );
351
-
352
- }
353
-
354
- }
355
-
356
- }
357
-
358
- return $plugins_data;
359
-
360
- }
361
-
362
- }
363
- endif;
364
-
365
- new myCRED_Addons_Upgrader();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/shortcodes/mycred_video.php CHANGED
@@ -21,15 +21,15 @@ if (! function_exists('mycred_render_shortcode_video') ) :
21
  extract(
22
  shortcode_atts(
23
  array(
24
- 'id' => null,
25
- 'width' => 560,
26
- 'height' => 315,
27
- 'amount' => '',
28
- 'logic' => '',
29
- 'interval' => '',
30
- 'streaming' => '',
31
- 'duration' => '',
32
- 'ctype' => MYCRED_DEFAULT_TYPE_KEY
33
  ), $atts, MYCRED_SLUG . '_video'
34
  )
35
  );
@@ -114,7 +114,7 @@ if (! function_exists('mycred_render_shortcode_video') ) :
114
  ?>
115
  <div class="row mycred-video-wrapper youtube-video">
116
  <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
117
- <iframe id="mycred_vvideo_v<?php echo $video_id; ?>" class="mycred-video mycred-youtube-video" data-vid="<?php echo $video_id; ?>" src="<?php echo esc_url($url); ?>" width="<?php echo $width; ?>" height="<?php echo $height; ?>" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
118
  </div>
119
  </div>
120
  <?php
21
  extract(
22
  shortcode_atts(
23
  array(
24
+ 'id' => null,
25
+ 'width' => 560,
26
+ 'height' => 315,
27
+ 'amount' => '',
28
+ 'logic' => '',
29
+ 'interval' => '',
30
+ 'streaming' => '',
31
+ 'duration' => '',
32
+ 'ctype' => MYCRED_DEFAULT_TYPE_KEY
33
  ), $atts, MYCRED_SLUG . '_video'
34
  )
35
  );
114
  ?>
115
  <div class="row mycred-video-wrapper youtube-video">
116
  <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
117
+ <iframe id="mycred_vvideo_v<?php echo esc_attr($video_id); ?>" class="mycred-video mycred-youtube-video" data-vid="<?php echo esc_attr($video_id); ?>" src="<?php echo esc_url($url); ?>" width="<?php echo esc_attr($width); ?>" height="<?php echo esc_attr($height); ?>" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
118
  </div>
119
  </div>
120
  <?php