text: /**
   *
   *  Events generator for Stock tools
   *
   *  (c) 2009-2020 Paweł Fus
   *
   *  License: www.highcharts.com/license
   *
   *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
   *
   * */
  'use strict';
  import H from '../parts/Globals.js';
  import NavigationBindings from '../annotations/navigationBindings.js';
  import U from '../parts/Utilities.js';
  var correctFloat = U.correctFloat, defined = U.defined, extend = U.extend, fireEvent = U.fireEvent, isNumber = U.isNumber, merge = U.merge, pick = U.pick, uniqueKey = U.uniqueKey;
  var bindingsUtils = NavigationBindings.prototype.utils, PREFIX = 'highcharts-';
  /* eslint-disable no-invalid-this, valid-jsdoc */
  /**
   * Generates function which will add a flag series using modal in GUI.
   * Method fires an event "showPopup" with config:
   * `{type, options, callback}`.
   *
   * Example: NavigationBindings.utils.addFlagFromForm('url(...)') - will
   * generate function that shows modal in GUI.
   *
   * @private
   * @function bindingsUtils.addFlagFromForm
   *
   * @param {Highcharts.FlagsShapeValue} type
   *        Type of flag series, e.g. "squarepin"
   *
   * @return {Function}
   *         Callback to be used in `start` callback
   */
  bindingsUtils.addFlagFromForm = function (type) {
      return function (e) {
          var navigation = this, chart = navigation.chart, toolbar = chart.stockTools, getFieldType = bindingsUtils.getFieldType, point = bindingsUtils.attractToPoint(e, chart), pointConfig = {
              x: point.x,
              y: point.y
          }, seriesOptions = {
              type: 'flags',
              onSeries: point.series.id,
              shape: type,
              data: [pointConfig],
              point: {
                  events: {
                      click: function () {
                          var point = this, options = point.options;
                          fireEvent(navigation, 'showPopup', {
                              point: point,
                              formType: 'annotation-toolbar',
                              options: {
                                  langKey: 'flags',
                                  type: 'flags',
                                  title: [
                                      options.title,
                                      getFieldType(options.title)
                                  ],
                                  name: [
                                      options.name,
                                      getFieldType(options.name)
                                  ]
                              },
                              onSubmit: function (updated) {
                                  if (updated.actionType === 'remove') {
                                      point.remove();
                                  }
                                  else {
                                      point.update(navigation.fieldsToOptions(updated.fields, {}));
                                  }
                              }
                          });
                      }
                  }
              }
          };
          if (!toolbar || !toolbar.guiEnabled) {
              chart.addSeries(seriesOptions);
          }
          fireEvent(navigation, 'showPopup', {
              formType: 'flag',
              // Enabled options:
              options: {
                  langKey: 'flags',
                  type: 'flags',
                  title: ['A', getFieldType('A')],
                  name: ['Flag A', getFieldType('Flag A')]
              },
              // Callback on submit:
              onSubmit: function (data) {
                  navigation.fieldsToOptions(data.fields, seriesOptions.data[0]);
                  chart.addSeries(seriesOptions);
              }
          });
      };
  };
  bindingsUtils.manageIndicators = function (data) {
      var navigation = this, chart = navigation.chart, seriesConfig = {
          linkedTo: data.linkedTo,
          type: data.type
      }, indicatorsWithVolume = [
          'ad',
          'cmf',
          'mfi',
          'vbp',
          'vwap'
      ], indicatorsWithAxes = [
          'ad',
          'atr',
          'cci',
          'cmf',
          'macd',
          'mfi',
          'roc',
          'rsi',
          'ao',
          'aroon',
          'aroonoscillator',
          'trix',
          'apo',
          'dpo',
          'ppo',
          'natr',
          'williamsr',
          'stochastic',
          'slowstochastic',
          'linearRegression',
          'linearRegressionSlope',
          'linearRegressionIntercept',
          'linearRegressionAngle'
      ], yAxis, series;
      if (data.actionType === 'edit') {
          navigation.fieldsToOptions(data.fields, seriesConfig);
          series = chart.get(data.seriesId);
          if (series) {
              series.update(seriesConfig, false);
          }
      }
      else if (data.actionType === 'remove') {
          series = chart.get(data.seriesId);
          if (series) {
              yAxis = series.yAxis;
              if (series.linkedSeries) {
                  series.linkedSeries.forEach(function (linkedSeries) {
                      linkedSeries.remove(false);
                  });
              }
              series.remove(false);
              if (indicatorsWithAxes.indexOf(series.type) >= 0) {
                  yAxis.remove(false);
                  navigation.resizeYAxes();
              }
          }
      }
      else {
          seriesConfig.id = uniqueKey();
          navigation.fieldsToOptions(data.fields, seriesConfig);
          if (indicatorsWithAxes.indexOf(data.type) >= 0) {
              yAxis = chart.addAxis({
                  id: uniqueKey(),
                  offset: 0,
                  opposite: true,
                  title: {
                      text: ''
                  },
                  tickPixelInterval: 40,
                  showLastLabel: false,
                  labels: {
                      align: 'left',
                      y: -2
                  }
              }, false, false);
              seriesConfig.yAxis = yAxis.options.id;
              navigation.resizeYAxes();
          }
          else {
              seriesConfig.yAxis = chart.get(data.linkedTo).options.yAxis;
          }
          if (indicatorsWithVolume.indexOf(data.type) >= 0) {
              seriesConfig.params.volumeSeriesID = chart.series.filter(function (series) {
                  return series.options.type === 'column';
              })[0].options.id;
          }
          chart.addSeries(seriesConfig, false);
      }
      fireEvent(navigation, 'deselectButton', {
          button: navigation.selectedButtonElement
      });
      chart.redraw();
  };
  /**
   * Update height for an annotation. Height is calculated as a difference
   * between last point in `typeOptions` and current position. It's a value,
   * not pixels height.
   *
   * @private
   * @function bindingsUtils.updateHeight
   *
   * @param {Highcharts.PointerEventObject} e
   *        normalized browser event
   *
   * @param {Highcharts.Annotation} annotation
   *        Annotation to be updated
   *
   * @return {void}
   */
  bindingsUtils.updateHeight = function (e, annotation) {
      annotation.update({
          typeOptions: {
              height: this.chart.pointer.getCoordinates(e).yAxis[0].value -
                  annotation.options.typeOptions.points[1].y
          }
      });
  };
  // @todo
  // Consider using getHoverData(), but always kdTree (columns?)
  bindingsUtils.attractToPoint = function (e, chart) {
      var coords = chart.pointer.getCoordinates(e), x = coords.xAxis[0].value, y = coords.yAxis[0].value, distX = Number.MAX_VALUE, closestPoint;
      chart.series.forEach(function (series) {
          series.points.forEach(function (point) {
              if (point && distX > Math.abs(point.x - x)) {
                  distX = Math.abs(point.x - x);
                  closestPoint = point;
              }
          });
      });
      return {
          x: closestPoint.x,
          y: closestPoint.y,
          below: y < closestPoint.y,
          series: closestPoint.series,
          xAxis: closestPoint.series.xAxis.index || 0,
          yAxis: closestPoint.series.yAxis.index || 0
      };
  };
  /**
   * Shorthand to check if given yAxis comes from navigator.
   *
   * @private
   * @function bindingsUtils.isNotNavigatorYAxis
   *
   * @param {Highcharts.Axis} axis
   * Axis to check.
   *
   * @return {boolean}
   * True, if axis comes from navigator.
   */
  bindingsUtils.isNotNavigatorYAxis = function (axis) {
      return axis.userOptions.className !== PREFIX + 'navigator-yaxis';
  };
  /**
   * Update each point after specified index, most of the annotations use
   * this. For example crooked line: logic behind updating each point is the
   * same, only index changes when adding an annotation.
   *
   * Example: NavigationBindings.utils.updateNthPoint(1) - will generate
   * function that updates all consecutive points except point with index=0.
   *
   * @private
   * @function bindingsUtils.updateNthPoint
   *
   * @param {number} startIndex
   *        Index from each point should udpated
   *
   * @return {Function}
   *         Callback to be used in steps array
   */
  bindingsUtils.updateNthPoint = function (startIndex) {
      return function (e, annotation) {
          var options = annotation.options.typeOptions, coords = this.chart.pointer.getCoordinates(e), x = coords.xAxis[0].value, y = coords.yAxis[0].value;
          options.points.forEach(function (point, index) {
              if (index >= startIndex) {
                  point.x = x;
                  point.y = y;
              }
          });
          annotation.update({
              typeOptions: {
                  points: options.points
              }
          });
      };
  };
  // Extends NavigationBindigs to support indicators and resizers:
  extend(NavigationBindings.prototype, {
      /* eslint-disable valid-jsdoc */
      /**
       * Get current positions for all yAxes. If new axis does not have position,
       * returned is default height and last available top place.
       *
       * @private
       * @function Highcharts.NavigationBindings#getYAxisPositions
       *
       * @param {Array<Highcharts.Axis>} yAxes
       *        Array of yAxes available in the chart.
       *
       * @param {number} plotHeight
       *        Available height in the chart.
       *
       * @param {number} defaultHeight
       *        Default height in percents.
       *
       * @return {Array}
       *         An array of calculated positions in percentages.
       *         Format: `{top: Number, height: Number}`
       */
      getYAxisPositions: function (yAxes, plotHeight, defaultHeight) {
          var positions, allAxesHeight = 0;
          /** @private */
          function isPercentage(prop) {
              return defined(prop) && !isNumber(prop) && prop.match('%');
          }
          positions = yAxes.map(function (yAxis) {
              var height = isPercentage(yAxis.options.height) ?
                  parseFloat(yAxis.options.height) / 100 :
                  yAxis.height / plotHeight, top = isPercentage(yAxis.options.top) ?
                  parseFloat(yAxis.options.top) / 100 :
                  correctFloat(yAxis.top - yAxis.chart.plotTop) / plotHeight;
              // New yAxis does not contain "height" info yet
              if (!isNumber(height)) {
                  height = defaultHeight / 100;
              }
              allAxesHeight = correctFloat(allAxesHeight + height);
              return {
                  height: height * 100,
                  top: top * 100
              };
          });
          positions.allAxesHeight = allAxesHeight;
          return positions;
      },
      /**
       * Get current resize options for each yAxis. Note that each resize is
       * linked to the next axis, except the last one which shouldn't affect
       * axes in the navigator. Because indicator can be removed with it's yAxis
       * in the middle of yAxis array, we need to bind closest yAxes back.
       *
       * @private
       * @function Highcharts.NavigationBindings#getYAxisResizers
       *
       * @param {Array<Highcharts.Axis>} yAxes
       *        Array of yAxes available in the chart
       *
       * @return {Array<object>}
       *         An array of resizer options.
       *         Format: `{enabled: Boolean, controlledAxis: { next: [String]}}`
       */
      getYAxisResizers: function (yAxes) {
          var resizers = [];
          yAxes.forEach(function (_yAxis, index) {
              var nextYAxis = yAxes[index + 1];
              // We have next axis, bind them:
              if (nextYAxis) {
                  resizers[index] = {
                      enabled: true,
                      controlledAxis: {
                          next: [
                              pick(nextYAxis.options.id, nextYAxis.options.index)
                          ]
                      }
                  };
              }
              else {
                  // Remove binding:
                  resizers[index] = {
                      enabled: false
                  };
              }
          });
          return resizers;
      },
      /**
       * Resize all yAxes (except navigator) to fit the plotting height. Method
       * checks if new axis is added, then shrinks other main axis up to 5 panes.
       * If added is more thatn 5 panes, it rescales all other axes to fit new
       * yAxis.
       *
       * If axis is removed, and we have more than 5 panes, rescales all other
       * axes. If chart has less than 5 panes, first pane receives all extra
       * space.
       *
       * @private
       * @function Highcharts.NavigationBindings#resizeYAxes
       * @param {number} [defaultHeight]
       * Default height for yAxis
       * @return {void}
       */
      resizeYAxes: function (defaultHeight) {
          defaultHeight = defaultHeight || 20; // in %, but as a number
          var chart = this.chart, 
          // Only non-navigator axes
          yAxes = chart.yAxis.filter(bindingsUtils.isNotNavigatorYAxis), plotHeight = chart.plotHeight, allAxesLength = yAxes.length, 
          // Gather current heights (in %)
          positions = this.getYAxisPositions(yAxes, plotHeight, defaultHeight), resizers = this.getYAxisResizers(yAxes), allAxesHeight = positions.allAxesHeight, changedSpace = defaultHeight;
          // More than 100%
          if (allAxesHeight > 1) {
              // Simple case, add new panes up to 5
              if (allAxesLength < 6) {
                  // Added axis, decrease first pane's height:
                  positions[0].height = correctFloat(positions[0].height - changedSpace);
                  // And update all other "top" positions:
                  positions = this.recalculateYAxisPositions(positions, changedSpace);
              }
              else {
                  // We have more panes, rescale all others to gain some space,
                  // This is new height for upcoming yAxis:
                  defaultHeight = 100 / allAxesLength;
                  // This is how much we need to take from each other yAxis:
                  changedSpace = defaultHeight / (allAxesLength - 1);
                  // Now update all positions:
                  positions = this.recalculateYAxisPositions(positions, changedSpace, true, -1);
              }
              // Set last position manually:
              positions[allAxesLength - 1] = {
                  top: correctFloat(100 - defaultHeight),
                  height: defaultHeight
              };
          }
          else {
              // Less than 100%
              changedSpace = correctFloat(1 - allAxesHeight) * 100;
              // Simple case, return first pane it's space:
              if (allAxesLength < 5) {
                  positions[0].height = correctFloat(positions[0].height + changedSpace);
                  positions = this.recalculateYAxisPositions(positions, changedSpace);
              }
              else {
                  // There were more panes, return to each pane a bit of space:
                  changedSpace /= allAxesLength;
                  // Removed axis, add extra space to the first pane:
                  // And update all other positions:
                  positions = this.recalculateYAxisPositions(positions, changedSpace, true, 1);
              }
          }
          positions.forEach(function (position, index) {
              // if (index === 0) debugger;
              yAxes[index].update({
                  height: position.height + '%',
                  top: position.top + '%',
                  resize: resizers[index]
              }, false);
          });
      },
      /**
       * Utility to modify calculated positions according to the remaining/needed
       * space. Later, these positions are used in `yAxis.update({ top, height })`
       *
       * @private
       * @function Highcharts.NavigationBindings#recalculateYAxisPositions
       * @param {Array<Highcharts.Dictionary<number>>} positions
       * Default positions of all yAxes.
       * @param {number} changedSpace
       * How much space should be added or removed.
       * @param {boolean} modifyHeight
       * Update only `top` or both `top` and `height`.
       * @param {number} adder
       * `-1` or `1`, to determine whether we should add or remove space.
       *
       * @return {Array<object>}
       *         Modified positions,
       */
      recalculateYAxisPositions: function (positions, changedSpace, modifyHeight, adder) {
          positions.forEach(function (position, index) {
              var prevPosition = positions[index - 1];
              position.top = !prevPosition ? 0 :
                  correctFloat(prevPosition.height + prevPosition.top);
              if (modifyHeight) {
                  position.height = correctFloat(position.height + adder * changedSpace);
              }
          });
          return positions;
      }
      /* eslint-enable valid-jsdoc */
  });
  /**
   * @type         {Highcharts.Dictionary<Highcharts.NavigationBindingsOptionsObject>}
   * @since        7.0.0
   * @optionparent navigation.bindings
   */
  var stockToolsBindings = {
      // Line type annotations:
      /**
       * A segment annotation bindings. Includes `start` and one event in `steps`
       * array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-segment", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
       */
      segment: {
          /** @ignore-option */
          className: 'highcharts-segment',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'segment',
                  type: 'crookedLine',
                  typeOptions: {
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  }
              }, navigation.annotationsOptions, navigation.bindings.segment.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1)
          ]
      },
      /**
       * A segment with an arrow annotation bindings. Includes `start` and one
       * event in `steps` array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-arrow-segment", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
       */
      arrowSegment: {
          /** @ignore-option */
          className: 'highcharts-arrow-segment',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'arrowSegment',
                  type: 'crookedLine',
                  typeOptions: {
                      line: {
                          markerEnd: 'arrow'
                      },
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  }
              }, navigation.annotationsOptions, navigation.bindings.arrowSegment.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1)
          ]
      },
      /**
       * A ray annotation bindings. Includes `start` and one event in `steps`
       * array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-ray", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
       */
      ray: {
          /** @ignore-option */
          className: 'highcharts-ray',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'ray',
                  type: 'crookedLine',
                  typeOptions: {
                      type: 'ray',
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  }
              }, navigation.annotationsOptions, navigation.bindings.ray.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1)
          ]
      },
      /**
       * A ray with an arrow annotation bindings. Includes `start` and one event
       * in `steps` array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-arrow-ray", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
       */
      arrowRay: {
          /** @ignore-option */
          className: 'highcharts-arrow-ray',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'arrowRay',
                  type: 'infinityLine',
                  typeOptions: {
                      type: 'ray',
                      line: {
                          markerEnd: 'arrow'
                      },
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  }
              }, navigation.annotationsOptions, navigation.bindings.arrowRay.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1)
          ]
      },
      /**
       * A line annotation. Includes `start` and one event in `steps` array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-infinity-line", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
       */
      infinityLine: {
          /** @ignore-option */
          className: 'highcharts-infinity-line',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'infinityLine',
                  type: 'infinityLine',
                  typeOptions: {
                      type: 'line',
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  }
              }, navigation.annotationsOptions, navigation.bindings.infinityLine.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1)
          ]
      },
      /**
       * A line with arrow annotation. Includes `start` and one event in `steps`
       * array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-arrow-infinity-line", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
       */
      arrowInfinityLine: {
          /** @ignore-option */
          className: 'highcharts-arrow-infinity-line',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'arrowInfinityLine',
                  type: 'infinityLine',
                  typeOptions: {
                      type: 'line',
                      line: {
                          markerEnd: 'arrow'
                      },
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  }
              }, navigation.annotationsOptions, navigation.bindings.arrowInfinityLine.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1)
          ]
      },
      /**
       * A horizontal line annotation. Includes `start` event.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-horizontal-line", "start": function() {}, "annotationsOptions": {}}
       */
      horizontalLine: {
          /** @ignore-option */
          className: 'highcharts-horizontal-line',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'horizontalLine',
                  type: 'infinityLine',
                  draggable: 'y',
                  typeOptions: {
                      type: 'horizontalLine',
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  }
              }, navigation.annotationsOptions, navigation.bindings.horizontalLine.annotationsOptions);
              this.chart.addAnnotation(options);
          }
      },
      /**
       * A vertical line annotation. Includes `start` event.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-vertical-line", "start": function() {}, "annotationsOptions": {}}
       */
      verticalLine: {
          /** @ignore-option */
          className: 'highcharts-vertical-line',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'verticalLine',
                  type: 'infinityLine',
                  draggable: 'x',
                  typeOptions: {
                      type: 'verticalLine',
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  }
              }, navigation.annotationsOptions, navigation.bindings.verticalLine.annotationsOptions);
              this.chart.addAnnotation(options);
          }
      },
      /**
       * Crooked line (three points) annotation bindings. Includes `start` and two
       * events in `steps` (for second and third points in crooked line) array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-crooked3", "start": function() {}, "steps": [function() {}, function() {}], "annotationsOptions": {}}
       */
      // Crooked Line type annotations:
      crooked3: {
          /** @ignore-option */
          className: 'highcharts-crooked3',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'crooked3',
                  type: 'crookedLine',
                  typeOptions: {
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  }
              }, navigation.annotationsOptions, navigation.bindings.crooked3.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1),
              bindingsUtils.updateNthPoint(2)
          ]
      },
      /**
       * Crooked line (five points) annotation bindings. Includes `start` and four
       * events in `steps` (for all consequent points in crooked line) array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-crooked3", "start": function() {}, "steps": [function() {}, function() {}, function() {}, function() {}], "annotationsOptions": {}}
       */
      crooked5: {
          /** @ignore-option */
          className: 'highcharts-crooked5',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'crookedLine',
                  type: 'crookedLine',
                  typeOptions: {
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  }
              }, navigation.annotationsOptions, navigation.bindings.crooked5.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1),
              bindingsUtils.updateNthPoint(2),
              bindingsUtils.updateNthPoint(3),
              bindingsUtils.updateNthPoint(4)
          ]
      },
      /**
       * Elliott wave (three points) annotation bindings. Includes `start` and two
       * events in `steps` (for second and third points) array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-elliott3", "start": function() {}, "steps": [function() {}, function() {}], "annotationsOptions": {}}
       */
      elliott3: {
          /** @ignore-option */
          className: 'highcharts-elliott3',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'elliott3',
                  type: 'elliottWave',
                  typeOptions: {
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  },
                  labelOptions: {
                      style: {
                          color: '#666666'
                      }
                  }
              }, navigation.annotationsOptions, navigation.bindings.elliott3.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1),
              bindingsUtils.updateNthPoint(2),
              bindingsUtils.updateNthPoint(3)
          ]
      },
      /**
       * Elliott wave (five points) annotation bindings. Includes `start` and four
       * event in `steps` (for all consequent points in Elliott wave) array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-elliott3", "start": function() {}, "steps": [function() {}, function() {}, function() {}, function() {}], "annotationsOptions": {}}
       */
      elliott5: {
          /** @ignore-option */
          className: 'highcharts-elliott5',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'elliott5',
                  type: 'elliottWave',
                  typeOptions: {
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  },
                  labelOptions: {
                      style: {
                          color: '#666666'
                      }
                  }
              }, navigation.annotationsOptions, navigation.bindings.elliott5.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1),
              bindingsUtils.updateNthPoint(2),
              bindingsUtils.updateNthPoint(3),
              bindingsUtils.updateNthPoint(4),
              bindingsUtils.updateNthPoint(5)
          ]
      },
      /**
       * A measure (x-dimension) annotation bindings. Includes `start` and one
       * event in `steps` array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-measure-x", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
       */
      measureX: {
          /** @ignore-option */
          className: 'highcharts-measure-x',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'measure',
                  type: 'measure',
                  typeOptions: {
                      selectType: 'x',
                      point: {
                          x: coords.xAxis[0].value,
                          y: coords.yAxis[0].value,
                          xAxis: 0,
                          yAxis: 0
                      },
                      crosshairX: {
                          strokeWidth: 1,
                          stroke: '#000000'
                      },
                      crosshairY: {
                          enabled: false,
                          strokeWidth: 0,
                          stroke: '#000000'
                      },
                      background: {
                          width: 0,
                          height: 0,
                          strokeWidth: 0,
                          stroke: '#ffffff'
                      }
                  },
                  labelOptions: {
                      style: {
                          color: '#666666'
                      }
                  }
              }, navigation.annotationsOptions, navigation.bindings.measureX.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateRectSize
          ]
      },
      /**
       * A measure (y-dimension) annotation bindings. Includes `start` and one
       * event in `steps` array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-measure-y", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
       */
      measureY: {
          /** @ignore-option */
          className: 'highcharts-measure-y',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'measure',
                  type: 'measure',
                  typeOptions: {
                      selectType: 'y',
                      point: {
                          x: coords.xAxis[0].value,
                          y: coords.yAxis[0].value,
                          xAxis: 0,
                          yAxis: 0
                      },
                      crosshairX: {
                          enabled: false,
                          strokeWidth: 0,
                          stroke: '#000000'
                      },
                      crosshairY: {
                          strokeWidth: 1,
                          stroke: '#000000'
                      },
                      background: {
                          width: 0,
                          height: 0,
                          strokeWidth: 0,
                          stroke: '#ffffff'
                      }
                  },
                  labelOptions: {
                      style: {
                          color: '#666666'
                      }
                  }
              }, navigation.annotationsOptions, navigation.bindings.measureY.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateRectSize
          ]
      },
      /**
       * A measure (xy-dimension) annotation bindings. Includes `start` and one
       * event in `steps` array.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-measure-xy", "start": function() {}, "steps": [function() {}], "annotationsOptions": {}}
       */
      measureXY: {
          /** @ignore-option */
          className: 'highcharts-measure-xy',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'measure',
                  type: 'measure',
                  typeOptions: {
                      selectType: 'xy',
                      point: {
                          x: coords.xAxis[0].value,
                          y: coords.yAxis[0].value,
                          xAxis: 0,
                          yAxis: 0
                      },
                      background: {
                          width: 0,
                          height: 0,
                          strokeWidth: 10
                      },
                      crosshairX: {
                          strokeWidth: 1,
                          stroke: '#000000'
                      },
                      crosshairY: {
                          strokeWidth: 1,
                          stroke: '#000000'
                      }
                  },
                  labelOptions: {
                      style: {
                          color: '#666666'
                      }
                  }
              }, navigation.annotationsOptions, navigation.bindings.measureXY.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateRectSize
          ]
      },
      // Advanced type annotations:
      /**
       * A fibonacci annotation bindings. Includes `start` and two events in
       * `steps` array (updates second point, then height).
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-fibonacci", "start": function() {}, "steps": [function() {}, function() {}], "annotationsOptions": {}}
       */
      fibonacci: {
          /** @ignore-option */
          className: 'highcharts-fibonacci',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'fibonacci',
                  type: 'fibonacci',
                  typeOptions: {
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  },
                  labelOptions: {
                      style: {
                          color: '#666666'
                      }
                  }
              }, navigation.annotationsOptions, navigation.bindings.fibonacci.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1),
              bindingsUtils.updateHeight
          ]
      },
      /**
       * A parallel channel (tunnel) annotation bindings. Includes `start` and
       * two events in `steps` array (updates second point, then height).
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-parallel-channel", "start": function() {}, "steps": [function() {}, function() {}], "annotationsOptions": {}}
       */
      parallelChannel: {
          /** @ignore-option */
          className: 'highcharts-parallel-channel',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'parallelChannel',
                  type: 'tunnel',
                  typeOptions: {
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }]
                  }
              }, navigation.annotationsOptions, navigation.bindings.parallelChannel.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1),
              bindingsUtils.updateHeight
          ]
      },
      /**
       * An Andrew's pitchfork annotation bindings. Includes `start` and two
       * events in `steps` array (sets second and third control points).
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-pitchfork", "start": function() {}, "steps": [function() {}, function() {}], "annotationsOptions": {}}
       */
      pitchfork: {
          /** @ignore-option */
          className: 'highcharts-pitchfork',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var coords = this.chart.pointer.getCoordinates(e), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'pitchfork',
                  type: 'pitchfork',
                  typeOptions: {
                      points: [{
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value,
                              controlPoint: {
                                  style: {
                                      fill: 'red'
                                  }
                              }
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }, {
                              x: coords.xAxis[0].value,
                              y: coords.yAxis[0].value
                          }],
                      innerBackground: {
                          fill: 'rgba(100, 170, 255, 0.8)'
                      }
                  },
                  shapeOptions: {
                      strokeWidth: 2
                  }
              }, navigation.annotationsOptions, navigation.bindings.pitchfork.annotationsOptions);
              return this.chart.addAnnotation(options);
          },
          /** @ignore-option */
          steps: [
              bindingsUtils.updateNthPoint(1),
              bindingsUtils.updateNthPoint(2)
          ]
      },
      // Labels with arrow and auto increments
      /**
       * A vertical counter annotation bindings. Includes `start` event. On click,
       * finds the closest point and marks it with a numeric annotation -
       * incrementing counter on each add.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-vertical-counter", "start": function() {}, "annotationsOptions": {}}
       */
      verticalCounter: {
          /** @ignore-option */
          className: 'highcharts-vertical-counter',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var closestPoint = bindingsUtils.attractToPoint(e, this.chart), navigation = this.chart.options.navigation, verticalCounter = !defined(this.verticalCounter) ? 0 :
                  this.verticalCounter, options = merge({
                  langKey: 'verticalCounter',
                  type: 'verticalLine',
                  typeOptions: {
                      point: {
                          x: closestPoint.x,
                          y: closestPoint.y,
                          xAxis: closestPoint.xAxis,
                          yAxis: closestPoint.yAxis
                      },
                      label: {
                          offset: closestPoint.below ? 40 : -40,
                          text: verticalCounter.toString()
                      }
                  },
                  labelOptions: {
                      style: {
                          color: '#666666',
                          fontSize: '11px'
                      }
                  },
                  shapeOptions: {
                      stroke: 'rgba(0, 0, 0, 0.75)',
                      strokeWidth: 1
                  }
              }, navigation.annotationsOptions, navigation.bindings.verticalCounter.annotationsOptions), annotation;
              annotation = this.chart.addAnnotation(options);
              verticalCounter++;
              annotation.options.events.click.call(annotation, {});
          }
      },
      /**
       * A vertical arrow annotation bindings. Includes `start` event. On click,
       * finds the closest point and marks it with an arrow and a label with
       * value.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-vertical-label", "start": function() {}, "annotationsOptions": {}}
       */
      verticalLabel: {
          /** @ignore-option */
          className: 'highcharts-vertical-label',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var closestPoint = bindingsUtils.attractToPoint(e, this.chart), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'verticalLabel',
                  type: 'verticalLine',
                  typeOptions: {
                      point: {
                          x: closestPoint.x,
                          y: closestPoint.y,
                          xAxis: closestPoint.xAxis,
                          yAxis: closestPoint.yAxis
                      },
                      label: {
                          offset: closestPoint.below ? 40 : -40
                      }
                  },
                  labelOptions: {
                      style: {
                          color: '#666666',
                          fontSize: '11px'
                      }
                  },
                  shapeOptions: {
                      stroke: 'rgba(0, 0, 0, 0.75)',
                      strokeWidth: 1
                  }
              }, navigation.annotationsOptions, navigation.bindings.verticalLabel.annotationsOptions), annotation;
              annotation = this.chart.addAnnotation(options);
              annotation.options.events.click.call(annotation, {});
          }
      },
      /**
       * A vertical arrow annotation bindings. Includes `start` event. On click,
       * finds the closest point and marks it with an arrow. Green arrow when
       * pointing from above, red when pointing from below the point.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-vertical-arrow", "start": function() {}, "annotationsOptions": {}}
       */
      verticalArrow: {
          /** @ignore-option */
          className: 'highcharts-vertical-arrow',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          start: function (e) {
              var closestPoint = bindingsUtils.attractToPoint(e, this.chart), navigation = this.chart.options.navigation, options = merge({
                  langKey: 'verticalArrow',
                  type: 'verticalLine',
                  typeOptions: {
                      point: {
                          x: closestPoint.x,
                          y: closestPoint.y,
                          xAxis: closestPoint.xAxis,
                          yAxis: closestPoint.yAxis
                      },
                      label: {
                          offset: closestPoint.below ? 40 : -40,
                          format: ' '
                      },
                      connector: {
                          fill: 'none',
                          stroke: closestPoint.below ? 'red' : 'green'
                      }
                  },
                  shapeOptions: {
                      stroke: 'rgba(0, 0, 0, 0.75)',
                      strokeWidth: 1
                  }
              }, navigation.annotationsOptions, navigation.bindings.verticalArrow.annotationsOptions), annotation;
              annotation = this.chart.addAnnotation(options);
              annotation.options.events.click.call(annotation, {});
          }
      },
      // Flag types:
      /**
       * A flag series bindings. Includes `start` event. On click, finds the
       * closest point and marks it with a flag with `'circlepin'` shape.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-flag-circlepin", "start": function() {}}
       */
      flagCirclepin: {
          /** @ignore-option */
          className: 'highcharts-flag-circlepin',
          /** @ignore-option */
          start: bindingsUtils.addFlagFromForm('circlepin')
      },
      /**
       * A flag series bindings. Includes `start` event. On click, finds the
       * closest point and marks it with a flag with `'diamondpin'` shape.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-flag-diamondpin", "start": function() {}}
       */
      flagDiamondpin: {
          /** @ignore-option */
          className: 'highcharts-flag-diamondpin',
          /** @ignore-option */
          start: bindingsUtils.addFlagFromForm('flag')
      },
      /**
       * A flag series bindings. Includes `start` event.
       * On click, finds the closest point and marks it with a flag with
       * `'squarepin'` shape.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-flag-squarepin", "start": function() {}}
       */
      flagSquarepin: {
          /** @ignore-option */
          className: 'highcharts-flag-squarepin',
          /** @ignore-option */
          start: bindingsUtils.addFlagFromForm('squarepin')
      },
      /**
       * A flag series bindings. Includes `start` event.
       * On click, finds the closest point and marks it with a flag without pin
       * shape.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-flag-simplepin", "start": function() {}}
       */
      flagSimplepin: {
          /** @ignore-option */
          className: 'highcharts-flag-simplepin',
          /** @ignore-option */
          start: bindingsUtils.addFlagFromForm('nopin')
      },
      // Other tools:
      /**
       * Enables zooming in xAxis on a chart. Includes `start` event which
       * changes [chart.zoomType](#chart.zoomType).
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-zoom-x", "init": function() {}}
       */
      zoomX: {
          /** @ignore-option */
          className: 'highcharts-zoom-x',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          init: function (button) {
              this.chart.update({
                  chart: {
                      zoomType: 'x'
                  }
              });
              fireEvent(this, 'deselectButton', { button: button });
          }
      },
      /**
       * Enables zooming in yAxis on a chart. Includes `start` event which
       * changes [chart.zoomType](#chart.zoomType).
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-zoom-y", "init": function() {}}
       */
      zoomY: {
          /** @ignore-option */
          className: 'highcharts-zoom-y',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          init: function (button) {
              this.chart.update({
                  chart: {
                      zoomType: 'y'
                  }
              });
              fireEvent(this, 'deselectButton', { button: button });
          }
      },
      /**
       * Enables zooming in xAxis and yAxis on a chart. Includes `start` event
       * which changes [chart.zoomType](#chart.zoomType).
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-zoom-xy", "init": function() {}}
       */
      zoomXY: {
          /** @ignore-option */
          className: 'highcharts-zoom-xy',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          init: function (button) {
              this.chart.update({
                  chart: {
                      zoomType: 'xy'
                  }
              });
              fireEvent(this, 'deselectButton', { button: button });
          }
      },
      /**
       * Changes main series to `'line'` type.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-series-type-line", "init": function() {}}
       */
      seriesTypeLine: {
          /** @ignore-option */
          className: 'highcharts-series-type-line',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          init: function (button) {
              this.chart.series[0].update({
                  type: 'line',
                  useOhlcData: true
              });
              fireEvent(this, 'deselectButton', { button: button });
          }
      },
      /**
       * Changes main series to `'ohlc'` type.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-series-type-ohlc", "init": function() {}}
       */
      seriesTypeOhlc: {
          /** @ignore-option */
          className: 'highcharts-series-type-ohlc',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          init: function (button) {
              this.chart.series[0].update({
                  type: 'ohlc'
              });
              fireEvent(this, 'deselectButton', { button: button });
          }
      },
      /**
       * Changes main series to `'candlestick'` type.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-series-type-candlestick", "init": function() {}}
       */
      seriesTypeCandlestick: {
          /** @ignore-option */
          className: 'highcharts-series-type-candlestick',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          init: function (button) {
              this.chart.series[0].update({
                  type: 'candlestick'
              });
              fireEvent(this, 'deselectButton', { button: button });
          }
      },
      /**
       * Displays chart in fullscreen.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-full-screen", "init": function() {}}
       */
      fullScreen: {
          /** @ignore-option */
          className: 'highcharts-full-screen',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          init: function (button) {
              this.chart.fullscreen.toggle();
              fireEvent(this, 'deselectButton', { button: button });
          }
      },
      /**
       * Hides/shows two price indicators:
       * - last price in the dataset
       * - last price in the selected range
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-current-price-indicator", "init": function() {}}
       */
      currentPriceIndicator: {
          /** @ignore-option */
          className: 'highcharts-current-price-indicator',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          init: function (button) {
              var chart = this.chart, series = chart.series[0], options = series.options, lastVisiblePrice = (options.lastVisiblePrice &&
                  options.lastVisiblePrice.enabled), lastPrice = options.lastPrice && options.lastPrice.enabled, gui = chart.stockTools, iconsURL = gui.getIconsURL();
              if (gui && gui.guiEnabled) {
                  if (lastPrice) {
                      button.firstChild.style['background-image'] =
                          'url("' + iconsURL +
                              'current-price-show.svg")';
                  }
                  else {
                      button.firstChild.style['background-image'] =
                          'url("' + iconsURL +
                              'current-price-hide.svg")';
                  }
              }
              series.update({
                  // line
                  lastPrice: {
                      enabled: !lastPrice,
                      color: 'red'
                  },
                  // label
                  lastVisiblePrice: {
                      enabled: !lastVisiblePrice,
                      label: {
                          enabled: true
                      }
                  }
              });
              fireEvent(this, 'deselectButton', { button: button });
          }
      },
      /**
       * Indicators bindings. Includes `init` event to show a popup.
       *
       * Note: In order to show base series from the chart in the popup's
       * dropdown each series requires
       * [series.id](https://api.highcharts.com/highstock/series.line.id) to be
       * defined.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-indicators", "init": function() {}}
       */
      indicators: {
          /** @ignore-option */
          className: 'highcharts-indicators',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          init: function () {
              var navigation = this;
              fireEvent(navigation, 'showPopup', {
                  formType: 'indicators',
                  options: {},
                  // Callback on submit:
                  onSubmit: function (data) {
                      navigation.utils.manageIndicators.call(navigation, data);
                  }
              });
          }
      },
      /**
       * Hides/shows all annotations on a chart.
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-toggle-annotations", "init": function() {}}
       */
      toggleAnnotations: {
          /** @ignore-option */
          className: 'highcharts-toggle-annotations',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          init: function (button) {
              var chart = this.chart, gui = chart.stockTools, iconsURL = gui.getIconsURL();
              this.toggledAnnotations = !this.toggledAnnotations;
              (chart.annotations || []).forEach(function (annotation) {
                  annotation.setVisibility(!this.toggledAnnotations);
              }, this);
              if (gui && gui.guiEnabled) {
                  if (this.toggledAnnotations) {
                      button.firstChild.style['background-image'] =
                          'url("' + iconsURL +
                              'annotations-hidden.svg")';
                  }
                  else {
                      button.firstChild.style['background-image'] =
                          'url("' + iconsURL +
                              'annotations-visible.svg")';
                  }
              }
              fireEvent(this, 'deselectButton', { button: button });
          }
      },
      /**
       * Save a chart in localStorage under `highcharts-chart` key.
       * Stored items:
       * - annotations
       * - indicators (with yAxes)
       * - flags
       *
       * @type    {Highcharts.NavigationBindingsOptionsObject}
       * @product highstock
       * @default {"className": "highcharts-save-chart", "init": function() {}}
       */
      saveChart: {
          /** @ignore-option */
          className: 'highcharts-save-chart',
          // eslint-disable-next-line valid-jsdoc
          /** @ignore-option */
          init: function (button) {
              var navigation = this, chart = navigation.chart, annotations = [], indicators = [], flags = [], yAxes = [];
              chart.annotations.forEach(function (annotation, index) {
                  annotations[index] = annotation.userOptions;
              });
              chart.series.forEach(function (series) {
                  if (series.is('sma')) {
                      indicators.push(series.userOptions);
                  }
                  else if (series.type === 'flags') {
                      flags.push(series.userOptions);
                  }
              });
              chart.yAxis.forEach(function (yAxis) {
                  if (bindingsUtils.isNotNavigatorYAxis(yAxis)) {
                      yAxes.push(yAxis.options);
                  }
              });
              H.win.localStorage.setItem(PREFIX + 'chart', JSON.stringify({
                  annotations: annotations,
                  indicators: indicators,
                  flags: flags,
                  yAxes: yAxes
              }));
              fireEvent(this, 'deselectButton', { button: button });
          }
      }
  };
  H.setOptions({
      navigation: {
          bindings: stockToolsBindings
      }
  });
  NavigationBindings.prototype.utils = merge(bindingsUtils, NavigationBindings.prototype.utils);
  