@pipsend/charts 2.3.10 → 2.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @license
3
- * Pipsend Charts v2.3.10
3
+ * Pipsend Charts v2.3.11
4
4
  * Copyright (c) 2026 Pipsend
5
5
  * Licensed under MIT License
6
6
  * Built on TradingView Lightweight Charts™ (Apache 2.0)
@@ -19723,6 +19723,8 @@
19723
19723
  this._private__pointerId = null;
19724
19724
  this._private__pressOrigin = null;
19725
19725
  this._private__pressedLine = null;
19726
+ /** Whether the gesture in flight came from a finger rather than a mouse. */
19727
+ this._private__pressWasTouch = false;
19726
19728
  /** Distance from the pointer to the dragged line when the press landed. */
19727
19729
  this._private__grabOffset = 0;
19728
19730
  /** Latest pointer position in pane coordinates, or null when off the panes. */
@@ -19787,8 +19789,18 @@
19787
19789
  this._private__applyCursor();
19788
19790
  }
19789
19791
  _private__onPointerDown(event) {
19790
- const line = this._private__hoveredId === null ? null : this._private__lines.get(this._private__hoveredId) ?? null;
19792
+ // Hover belongs to the mouse. Touch leaves whatever the last press marked
19793
+ // still marked, so trusting it here grabbed that line again wherever the
19794
+ // next tap landed: every press resolves itself instead.
19795
+ this._private__pressWasTouch = event.pointerType !== 'mouse';
19796
+ let line = this._private__pressWasTouch || this._private__hoveredId === null
19797
+ ? null
19798
+ : this._private__lines.get(this._private__hoveredId) ?? null;
19799
+ if (line === null) {
19800
+ line = this._private__resolveHitAt(event);
19801
+ }
19791
19802
  if (!line) {
19803
+ this._private__clearTouchHover();
19792
19804
  return;
19793
19805
  }
19794
19806
  this._private__pressOrigin = { _internal_x: event.clientX, _internal_y: event.clientY };
@@ -19827,6 +19839,7 @@
19827
19839
  }
19828
19840
  _private__onPointerUp(event) {
19829
19841
  const dragged = this._private__dragging;
19842
+ const wasTouch = this._private__pressWasTouch;
19830
19843
  const pressed = this._private__pressedLine;
19831
19844
  const origin = this._private__pressOrigin;
19832
19845
  this._private__releasePointer();
@@ -19848,12 +19861,24 @@
19848
19861
  dragged.click();
19849
19862
  }
19850
19863
  }
19864
+ this._private__clearTouchHover(wasTouch);
19851
19865
  this._private__applyCursor();
19852
19866
  return;
19853
19867
  }
19854
19868
  if (pressed !== null && !moved && pressed.isClickable()) {
19855
19869
  pressed.click();
19856
19870
  }
19871
+ this._private__clearTouchHover(wasTouch);
19872
+ }
19873
+ /** A finger leaves nothing hovered behind it, the way lifting a mouse does. */
19874
+ _private__clearTouchHover(wasTouch = this._private__pressWasTouch) {
19875
+ if (!wasTouch || this._private__hoveredId === null) {
19876
+ return;
19877
+ }
19878
+ const line = this._private__lines.get(this._private__hoveredId) ?? null;
19879
+ this._private__setHovered(null);
19880
+ this._private__setHoveredPart(line, null);
19881
+ this._private__applyCursor();
19857
19882
  }
19858
19883
  /**
19859
19884
  * Abort an in-flight gesture: the line goes back to where it was and no
@@ -19899,9 +19924,38 @@
19899
19924
  return paneY === null ? null : line.priceAt(paneY - this._private__grabOffset);
19900
19925
  }
19901
19926
  /** The pointer's position inside the line's pane, in pane coordinates. */
19902
- _private__paneY(line, event) {
19927
+ /**
19928
+ * The hovered id comes from the crosshair, which touch never moves before it
19929
+ * presses, so the press resolves the target itself.
19930
+ */
19931
+ _private__resolveHitAt(event) {
19932
+ for (const line of this._private__lines.values()) {
19933
+ if (!line.hitTestAt) {
19934
+ continue;
19935
+ }
19936
+ const paneElement = this._private__paneElementOf(line);
19937
+ if (paneElement === null) {
19938
+ continue;
19939
+ }
19940
+ const rect = paneElement.getBoundingClientRect();
19941
+ // A fingertip is far coarser than a pointer, so its targets are widened.
19942
+ const slop = event.pointerType === 'mouse' ? 0 : 12 /* Constants.TouchSlopPx */;
19943
+ const hit = this._private__splitHit(line.hitTestAt(event.clientX - rect.left, event.clientY - rect.top, slop));
19944
+ if (hit === null) {
19945
+ continue;
19946
+ }
19947
+ this._private__setHovered(line.id());
19948
+ this._private__setHoveredPart(line, hit._internal_part);
19949
+ return line;
19950
+ }
19951
+ return null;
19952
+ }
19953
+ _private__paneElementOf(line) {
19903
19954
  const pane = this._private__chart.panes()[line.paneIndex()];
19904
- const paneElement = pane ? pane.getHTMLElement() : null;
19955
+ return pane ? pane.getHTMLElement() : null;
19956
+ }
19957
+ _private__paneY(line, event) {
19958
+ const paneElement = this._private__paneElementOf(line);
19905
19959
  if (paneElement) {
19906
19960
  return event.clientY - paneElement.getBoundingClientRect().top;
19907
19961
  }
@@ -20018,6 +20072,7 @@
20018
20072
  * line. Hit testing comes from the engine — the line's id travels as the price
20019
20073
  * line's `externalId` — so the hit area matches what is drawn.
20020
20074
  */
20075
+ const HIT_TOLERANCE_PX$1 = 8;
20021
20076
  class DraggablePriceLine {
20022
20077
  constructor(chart, series, options) {
20023
20078
  this._private__priceLine = null;
@@ -20070,6 +20125,14 @@
20070
20125
  color: hovered ? this._private__options.hoverColor : this._private__originalColor,
20071
20126
  });
20072
20127
  }
20128
+ /**
20129
+ * The engine draws this one, so there is no pane view to ask: a press within
20130
+ * the line's own grab strip counts as a hit.
20131
+ */
20132
+ hitTestAt(x, y, slop = 0) {
20133
+ const coord = this._private__series.priceToCoordinate(this._private__options.price);
20134
+ return coord !== null && Math.abs(y - coord) <= HIT_TOLERANCE_PX$1 + slop ? this._private__id : null;
20135
+ }
20073
20136
  priceAt(paneY) {
20074
20137
  const price = this._private__series.coordinateToPrice(paneY);
20075
20138
  return price === null ? null : price;
@@ -20612,22 +20675,27 @@
20612
20675
  _internal_setData(data) {
20613
20676
  this._private__data = data;
20614
20677
  }
20615
- _internal_hitTest(x, y) {
20678
+ /**
20679
+ * `slop` widens every target by the same amount, for input coarser than a
20680
+ * mouse pointer.
20681
+ */
20682
+ _internal_hitTest(x, y, slop = 0) {
20616
20683
  // The close button sits on top of the label, which sits on top of the
20617
20684
  // line, so the narrowest target is tested first.
20618
20685
  for (const layout of this._private__layouts) {
20619
- if (layout._internal_closable && x >= layout._internal_closeLeft && x <= layout._internal_closeRight &&
20620
- Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2) {
20686
+ if (layout._internal_closable && x >= layout._internal_closeLeft - slop && x <= layout._internal_closeRight + slop &&
20687
+ Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2 + slop) {
20621
20688
  return { _internal_level: layout._internal_level, _internal_part: 'close' };
20622
20689
  }
20623
20690
  }
20624
20691
  for (const layout of this._private__layouts) {
20625
- if (x >= layout._internal_pillLeft && x <= layout._internal_pillRight && Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2) {
20692
+ if (x >= layout._internal_pillLeft - slop && x <= layout._internal_pillRight + slop &&
20693
+ Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2 + slop) {
20626
20694
  return { _internal_level: layout._internal_level, _internal_part: 'body' };
20627
20695
  }
20628
20696
  }
20629
20697
  for (const layout of this._private__layouts) {
20630
- if (Math.abs(y - layout._internal_y) <= 8 /* Constants.LineHitTolerance */) {
20698
+ if (Math.abs(y - layout._internal_y) <= 8 /* Constants.LineHitTolerance */ + slop) {
20631
20699
  return { _internal_level: layout._internal_level, _internal_part: 'line' };
20632
20700
  }
20633
20701
  }
@@ -20864,8 +20932,8 @@
20864
20932
  zOrder() {
20865
20933
  return 'top';
20866
20934
  }
20867
- _internal_hitTest(x, y) {
20868
- return this._private__data === null ? null : this._private__renderer._internal_hitTest(x, y);
20935
+ _internal_hitTest(x, y, slop = 0) {
20936
+ return this._private__data === null ? null : this._private__renderer._internal_hitTest(x, y, slop);
20869
20937
  }
20870
20938
  }
20871
20939
 
@@ -21016,6 +21084,13 @@
21016
21084
  * of jumping to sit under it — which matters most when the label has been
21017
21085
  * fanned away from its own line.
21018
21086
  */
21087
+ hitTestAt(x, y, slop = 0) {
21088
+ const hit = this._private__paneView._internal_hitTest(x, y, slop);
21089
+ if (hit === null) {
21090
+ return null;
21091
+ }
21092
+ return this._private__levelOptions(hit._internal_level) === null ? null : `${this._private__id}#${hit._internal_level}:${hit._internal_part}`;
21093
+ }
21019
21094
  dragAnchorY() {
21020
21095
  if (this._private__dragLevel === null) {
21021
21096
  return null;
@@ -30086,6 +30161,7 @@
30086
30161
  this._private__mouseMoveHandler = null;
30087
30162
  this._private__pointerDownHandler = null;
30088
30163
  this._private__pointerUpHandler = null;
30164
+ this._private__pointerMoveHandler = null;
30089
30165
  this._private__pointerCancelHandler = null;
30090
30166
  this._private__lostCaptureHandler = null;
30091
30167
  this._private__windowPointerUpHandler = null;
@@ -30660,10 +30736,12 @@
30660
30736
  if (chartElement) {
30661
30737
  this._private__pointerDownHandler = (event) => this._private__handlePointerDown(event);
30662
30738
  this._private__pointerUpHandler = (event) => this._private__handlePointerUp(event);
30739
+ this._private__pointerMoveHandler = (event) => this._private__handlePointerMove(event);
30663
30740
  this._private__pointerCancelHandler = (event) => this._private__handlePointerUp(event);
30664
30741
  this._private__lostCaptureHandler = (event) => this._private__handleLostPointerCapture(event);
30665
30742
  chartElement.addEventListener('pointerdown', this._private__pointerDownHandler);
30666
30743
  chartElement.addEventListener('pointerup', this._private__pointerUpHandler);
30744
+ chartElement.addEventListener('pointermove', this._private__pointerMoveHandler);
30667
30745
  chartElement.addEventListener('pointercancel', this._private__pointerCancelHandler);
30668
30746
  chartElement.addEventListener('lostpointercapture', this._private__lostCaptureHandler);
30669
30747
  }
@@ -30698,6 +30776,10 @@
30698
30776
  chartElement.removeEventListener('pointerup', this._private__pointerUpHandler);
30699
30777
  this._private__pointerUpHandler = null;
30700
30778
  }
30779
+ if (this._private__pointerMoveHandler) {
30780
+ chartElement.removeEventListener('pointermove', this._private__pointerMoveHandler);
30781
+ this._private__pointerMoveHandler = null;
30782
+ }
30701
30783
  if (this._private__pointerCancelHandler) {
30702
30784
  chartElement.removeEventListener('pointercancel', this._private__pointerCancelHandler);
30703
30785
  this._private__pointerCancelHandler = null;
@@ -30847,6 +30929,36 @@
30847
30929
  // mouse events, and those are what drive the crosshair the drag reads.
30848
30930
  this._private__disableChartInteractions();
30849
30931
  }
30932
+ /**
30933
+ * The drag reads the crosshair, which touch never moves: its move handler
30934
+ * only tries to pan, and the drag has just turned panning off. So touch is
30935
+ * driven straight from the pointer instead.
30936
+ */
30937
+ _private__handlePointerMove(event) {
30938
+ if (!this._private__isDragging || this._private__draggedToolId === null || event.pointerType === 'mouse') {
30939
+ return;
30940
+ }
30941
+ if (this._private__pointerId !== null && event.pointerId !== this._private__pointerId) {
30942
+ return;
30943
+ }
30944
+ const tool = this._private__tools.get(this._private__draggedToolId);
30945
+ if (!tool) {
30946
+ return;
30947
+ }
30948
+ const paneElement = this._private__paneElementOf(tool);
30949
+ if (paneElement === null) {
30950
+ return;
30951
+ }
30952
+ const rect = paneElement.getBoundingClientRect();
30953
+ const series = tool.series();
30954
+ const price = series.coordinateToPrice((event.clientY - rect.top));
30955
+ const time = timeFromCoordinate(this._private__chart, series, event.clientX - rect.left);
30956
+ if (price === null || time === null) {
30957
+ return;
30958
+ }
30959
+ tool.updateDrag(time, price);
30960
+ event.preventDefault();
30961
+ }
30850
30962
  _private__handlePointerUp(event) {
30851
30963
  if (!this._private__isDragging || this._private__draggedToolId === null) {
30852
30964
  return;
@@ -31020,7 +31132,7 @@
31020
31132
  * Returns the current version as a string. For example `'1.0.0'`.
31021
31133
  */
31022
31134
  function version() {
31023
- return "2.3.10";
31135
+ return "2.3.11";
31024
31136
  }
31025
31137
 
31026
31138
  var PipsendChartsModule = /*#__PURE__*/Object.freeze({
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @license
3
- * Pipsend Charts v2.3.10
3
+ * Pipsend Charts v2.3.11
4
4
  * Copyright (c) 2026 Pipsend
5
5
  * Licensed under MIT License
6
6
  * Built on TradingView Lightweight Charts™ (Apache 2.0)
@@ -19720,6 +19720,8 @@ class TradingLineController {
19720
19720
  this._private__pointerId = null;
19721
19721
  this._private__pressOrigin = null;
19722
19722
  this._private__pressedLine = null;
19723
+ /** Whether the gesture in flight came from a finger rather than a mouse. */
19724
+ this._private__pressWasTouch = false;
19723
19725
  /** Distance from the pointer to the dragged line when the press landed. */
19724
19726
  this._private__grabOffset = 0;
19725
19727
  /** Latest pointer position in pane coordinates, or null when off the panes. */
@@ -19784,8 +19786,18 @@ class TradingLineController {
19784
19786
  this._private__applyCursor();
19785
19787
  }
19786
19788
  _private__onPointerDown(event) {
19787
- const line = this._private__hoveredId === null ? null : this._private__lines.get(this._private__hoveredId) ?? null;
19789
+ // Hover belongs to the mouse. Touch leaves whatever the last press marked
19790
+ // still marked, so trusting it here grabbed that line again wherever the
19791
+ // next tap landed: every press resolves itself instead.
19792
+ this._private__pressWasTouch = event.pointerType !== 'mouse';
19793
+ let line = this._private__pressWasTouch || this._private__hoveredId === null
19794
+ ? null
19795
+ : this._private__lines.get(this._private__hoveredId) ?? null;
19796
+ if (line === null) {
19797
+ line = this._private__resolveHitAt(event);
19798
+ }
19788
19799
  if (!line) {
19800
+ this._private__clearTouchHover();
19789
19801
  return;
19790
19802
  }
19791
19803
  this._private__pressOrigin = { _internal_x: event.clientX, _internal_y: event.clientY };
@@ -19824,6 +19836,7 @@ class TradingLineController {
19824
19836
  }
19825
19837
  _private__onPointerUp(event) {
19826
19838
  const dragged = this._private__dragging;
19839
+ const wasTouch = this._private__pressWasTouch;
19827
19840
  const pressed = this._private__pressedLine;
19828
19841
  const origin = this._private__pressOrigin;
19829
19842
  this._private__releasePointer();
@@ -19845,12 +19858,24 @@ class TradingLineController {
19845
19858
  dragged.click();
19846
19859
  }
19847
19860
  }
19861
+ this._private__clearTouchHover(wasTouch);
19848
19862
  this._private__applyCursor();
19849
19863
  return;
19850
19864
  }
19851
19865
  if (pressed !== null && !moved && pressed.isClickable()) {
19852
19866
  pressed.click();
19853
19867
  }
19868
+ this._private__clearTouchHover(wasTouch);
19869
+ }
19870
+ /** A finger leaves nothing hovered behind it, the way lifting a mouse does. */
19871
+ _private__clearTouchHover(wasTouch = this._private__pressWasTouch) {
19872
+ if (!wasTouch || this._private__hoveredId === null) {
19873
+ return;
19874
+ }
19875
+ const line = this._private__lines.get(this._private__hoveredId) ?? null;
19876
+ this._private__setHovered(null);
19877
+ this._private__setHoveredPart(line, null);
19878
+ this._private__applyCursor();
19854
19879
  }
19855
19880
  /**
19856
19881
  * Abort an in-flight gesture: the line goes back to where it was and no
@@ -19896,9 +19921,38 @@ class TradingLineController {
19896
19921
  return paneY === null ? null : line.priceAt(paneY - this._private__grabOffset);
19897
19922
  }
19898
19923
  /** The pointer's position inside the line's pane, in pane coordinates. */
19899
- _private__paneY(line, event) {
19924
+ /**
19925
+ * The hovered id comes from the crosshair, which touch never moves before it
19926
+ * presses, so the press resolves the target itself.
19927
+ */
19928
+ _private__resolveHitAt(event) {
19929
+ for (const line of this._private__lines.values()) {
19930
+ if (!line.hitTestAt) {
19931
+ continue;
19932
+ }
19933
+ const paneElement = this._private__paneElementOf(line);
19934
+ if (paneElement === null) {
19935
+ continue;
19936
+ }
19937
+ const rect = paneElement.getBoundingClientRect();
19938
+ // A fingertip is far coarser than a pointer, so its targets are widened.
19939
+ const slop = event.pointerType === 'mouse' ? 0 : 12 /* Constants.TouchSlopPx */;
19940
+ const hit = this._private__splitHit(line.hitTestAt(event.clientX - rect.left, event.clientY - rect.top, slop));
19941
+ if (hit === null) {
19942
+ continue;
19943
+ }
19944
+ this._private__setHovered(line.id());
19945
+ this._private__setHoveredPart(line, hit._internal_part);
19946
+ return line;
19947
+ }
19948
+ return null;
19949
+ }
19950
+ _private__paneElementOf(line) {
19900
19951
  const pane = this._private__chart.panes()[line.paneIndex()];
19901
- const paneElement = pane ? pane.getHTMLElement() : null;
19952
+ return pane ? pane.getHTMLElement() : null;
19953
+ }
19954
+ _private__paneY(line, event) {
19955
+ const paneElement = this._private__paneElementOf(line);
19902
19956
  if (paneElement) {
19903
19957
  return event.clientY - paneElement.getBoundingClientRect().top;
19904
19958
  }
@@ -20015,6 +20069,7 @@ let nextLineId = 0;
20015
20069
  * line. Hit testing comes from the engine — the line's id travels as the price
20016
20070
  * line's `externalId` — so the hit area matches what is drawn.
20017
20071
  */
20072
+ const HIT_TOLERANCE_PX$1 = 8;
20018
20073
  class DraggablePriceLine {
20019
20074
  constructor(chart, series, options) {
20020
20075
  this._private__priceLine = null;
@@ -20067,6 +20122,14 @@ class DraggablePriceLine {
20067
20122
  color: hovered ? this._private__options.hoverColor : this._private__originalColor,
20068
20123
  });
20069
20124
  }
20125
+ /**
20126
+ * The engine draws this one, so there is no pane view to ask: a press within
20127
+ * the line's own grab strip counts as a hit.
20128
+ */
20129
+ hitTestAt(x, y, slop = 0) {
20130
+ const coord = this._private__series.priceToCoordinate(this._private__options.price);
20131
+ return coord !== null && Math.abs(y - coord) <= HIT_TOLERANCE_PX$1 + slop ? this._private__id : null;
20132
+ }
20070
20133
  priceAt(paneY) {
20071
20134
  const price = this._private__series.coordinateToPrice(paneY);
20072
20135
  return price === null ? null : price;
@@ -20609,22 +20672,27 @@ class PositionLineRenderer {
20609
20672
  _internal_setData(data) {
20610
20673
  this._private__data = data;
20611
20674
  }
20612
- _internal_hitTest(x, y) {
20675
+ /**
20676
+ * `slop` widens every target by the same amount, for input coarser than a
20677
+ * mouse pointer.
20678
+ */
20679
+ _internal_hitTest(x, y, slop = 0) {
20613
20680
  // The close button sits on top of the label, which sits on top of the
20614
20681
  // line, so the narrowest target is tested first.
20615
20682
  for (const layout of this._private__layouts) {
20616
- if (layout._internal_closable && x >= layout._internal_closeLeft && x <= layout._internal_closeRight &&
20617
- Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2) {
20683
+ if (layout._internal_closable && x >= layout._internal_closeLeft - slop && x <= layout._internal_closeRight + slop &&
20684
+ Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2 + slop) {
20618
20685
  return { _internal_level: layout._internal_level, _internal_part: 'close' };
20619
20686
  }
20620
20687
  }
20621
20688
  for (const layout of this._private__layouts) {
20622
- if (x >= layout._internal_pillLeft && x <= layout._internal_pillRight && Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2) {
20689
+ if (x >= layout._internal_pillLeft - slop && x <= layout._internal_pillRight + slop &&
20690
+ Math.abs(y - layout._internal_labelY) <= layout._internal_height / 2 + slop) {
20623
20691
  return { _internal_level: layout._internal_level, _internal_part: 'body' };
20624
20692
  }
20625
20693
  }
20626
20694
  for (const layout of this._private__layouts) {
20627
- if (Math.abs(y - layout._internal_y) <= 8 /* Constants.LineHitTolerance */) {
20695
+ if (Math.abs(y - layout._internal_y) <= 8 /* Constants.LineHitTolerance */ + slop) {
20628
20696
  return { _internal_level: layout._internal_level, _internal_part: 'line' };
20629
20697
  }
20630
20698
  }
@@ -20861,8 +20929,8 @@ class PositionLinePaneView {
20861
20929
  zOrder() {
20862
20930
  return 'top';
20863
20931
  }
20864
- _internal_hitTest(x, y) {
20865
- return this._private__data === null ? null : this._private__renderer._internal_hitTest(x, y);
20932
+ _internal_hitTest(x, y, slop = 0) {
20933
+ return this._private__data === null ? null : this._private__renderer._internal_hitTest(x, y, slop);
20866
20934
  }
20867
20935
  }
20868
20936
 
@@ -21013,6 +21081,13 @@ class PositionLine {
21013
21081
  * of jumping to sit under it — which matters most when the label has been
21014
21082
  * fanned away from its own line.
21015
21083
  */
21084
+ hitTestAt(x, y, slop = 0) {
21085
+ const hit = this._private__paneView._internal_hitTest(x, y, slop);
21086
+ if (hit === null) {
21087
+ return null;
21088
+ }
21089
+ return this._private__levelOptions(hit._internal_level) === null ? null : `${this._private__id}#${hit._internal_level}:${hit._internal_part}`;
21090
+ }
21016
21091
  dragAnchorY() {
21017
21092
  if (this._private__dragLevel === null) {
21018
21093
  return null;
@@ -30083,6 +30158,7 @@ class DrawingToolsManager {
30083
30158
  this._private__mouseMoveHandler = null;
30084
30159
  this._private__pointerDownHandler = null;
30085
30160
  this._private__pointerUpHandler = null;
30161
+ this._private__pointerMoveHandler = null;
30086
30162
  this._private__pointerCancelHandler = null;
30087
30163
  this._private__lostCaptureHandler = null;
30088
30164
  this._private__windowPointerUpHandler = null;
@@ -30657,10 +30733,12 @@ class DrawingToolsManager {
30657
30733
  if (chartElement) {
30658
30734
  this._private__pointerDownHandler = (event) => this._private__handlePointerDown(event);
30659
30735
  this._private__pointerUpHandler = (event) => this._private__handlePointerUp(event);
30736
+ this._private__pointerMoveHandler = (event) => this._private__handlePointerMove(event);
30660
30737
  this._private__pointerCancelHandler = (event) => this._private__handlePointerUp(event);
30661
30738
  this._private__lostCaptureHandler = (event) => this._private__handleLostPointerCapture(event);
30662
30739
  chartElement.addEventListener('pointerdown', this._private__pointerDownHandler);
30663
30740
  chartElement.addEventListener('pointerup', this._private__pointerUpHandler);
30741
+ chartElement.addEventListener('pointermove', this._private__pointerMoveHandler);
30664
30742
  chartElement.addEventListener('pointercancel', this._private__pointerCancelHandler);
30665
30743
  chartElement.addEventListener('lostpointercapture', this._private__lostCaptureHandler);
30666
30744
  }
@@ -30695,6 +30773,10 @@ class DrawingToolsManager {
30695
30773
  chartElement.removeEventListener('pointerup', this._private__pointerUpHandler);
30696
30774
  this._private__pointerUpHandler = null;
30697
30775
  }
30776
+ if (this._private__pointerMoveHandler) {
30777
+ chartElement.removeEventListener('pointermove', this._private__pointerMoveHandler);
30778
+ this._private__pointerMoveHandler = null;
30779
+ }
30698
30780
  if (this._private__pointerCancelHandler) {
30699
30781
  chartElement.removeEventListener('pointercancel', this._private__pointerCancelHandler);
30700
30782
  this._private__pointerCancelHandler = null;
@@ -30844,6 +30926,36 @@ class DrawingToolsManager {
30844
30926
  // mouse events, and those are what drive the crosshair the drag reads.
30845
30927
  this._private__disableChartInteractions();
30846
30928
  }
30929
+ /**
30930
+ * The drag reads the crosshair, which touch never moves: its move handler
30931
+ * only tries to pan, and the drag has just turned panning off. So touch is
30932
+ * driven straight from the pointer instead.
30933
+ */
30934
+ _private__handlePointerMove(event) {
30935
+ if (!this._private__isDragging || this._private__draggedToolId === null || event.pointerType === 'mouse') {
30936
+ return;
30937
+ }
30938
+ if (this._private__pointerId !== null && event.pointerId !== this._private__pointerId) {
30939
+ return;
30940
+ }
30941
+ const tool = this._private__tools.get(this._private__draggedToolId);
30942
+ if (!tool) {
30943
+ return;
30944
+ }
30945
+ const paneElement = this._private__paneElementOf(tool);
30946
+ if (paneElement === null) {
30947
+ return;
30948
+ }
30949
+ const rect = paneElement.getBoundingClientRect();
30950
+ const series = tool.series();
30951
+ const price = series.coordinateToPrice((event.clientY - rect.top));
30952
+ const time = timeFromCoordinate(this._private__chart, series, event.clientX - rect.left);
30953
+ if (price === null || time === null) {
30954
+ return;
30955
+ }
30956
+ tool.updateDrag(time, price);
30957
+ event.preventDefault();
30958
+ }
30847
30959
  _private__handlePointerUp(event) {
30848
30960
  if (!this._private__isDragging || this._private__draggedToolId === null) {
30849
30961
  return;
@@ -31017,7 +31129,7 @@ const customSeriesDefaultOptions = {
31017
31129
  * Returns the current version as a string. For example `'1.0.0'`.
31018
31130
  */
31019
31131
  function version() {
31020
- return "2.3.10";
31132
+ return "2.3.11";
31021
31133
  }
31022
31134
 
31023
31135
  export { areaSeries as AreaSeries, ArrowTool, barSeries as BarSeries, baselineSeries as BaselineSeries, BrushTool, candlestickSeries as CandlestickSeries, CircleTool, ColorType, CrossLineTool, CrosshairMode, DEFAULT_SESSIONS, DraggablePriceLine, DrawingToolsManager, EXTENDED_FIBONACCI_RATIOS, FibonacciCalculator, FibonacciExtensionTool, FibonacciFanTool, FibonacciTool, GanttTool, histogramSeries as HistogramSeries, HorizontalLineTool, InteractiveLineManager, LastPriceAnimationMode, lineSeries as LineSeries, LineStyle, LineType, MismatchDirection, ParallelChannelTool, PitchforkTool, PolygonTool, PositionCalculator, PositionLine, PositionMarkersManager, PositionTool, PriceLineSource, PriceScaleMode, RectangleTool, RulerCalculator, RulerTool, STANDARD_FIBONACCI_RATIOS, TextTool, TickMarkType, TrackingModeExitMode, TradingSessionsIndicator, TrendLineTool, VerticalLineTool, VolumeProfileIndicator, applyADX, applyATR, applyBollingerBands, applyCCI, applyDonchianChannels, applyEMA, applyHeikinAshi, applyIchimoku, applyKeltnerChannels, applyMACD, applyMFI, applyOBV, applyParabolicSAR, applyPivotPoints, applyRSI, applySMA, applyStochastic, applySuperTrend, applyVWAP, applyVolume, applyWMA, applyWilliamsR, calculateHeikinAshi, calculatePipConfig, coordinateFromTime, createArrowTool, createBrushTool, createChart, createChartEx, createCircleTool, createCrossLineTool, createFibonacciExtensionTool, createFibonacciFanTool, createFibonacciTool, createGanttTool, createHorizontalLineTool, createImageWatermark, createInteractiveLineManager, createOptionsChart, createParallelChannelTool, createPitchforkTool, createPolygonTool, createPositionLine, createPositionMarkers, createPositionTool, createRectangleTool, createRulerTool, createSeriesMarkers, createTextTool, createTextWatermark, createTradingLine, createTradingSessionsIndicator, createTrendLineTool, createUpDownMarkers, createVerticalLineTool, createVolumeProfileIndicator, createYieldCurveChart, customSeriesDefaultOptions, defaultHorzScaleBehavior, getPipConfig, hideSeriesPaint, isBusinessDay, isUTCTimestamp, setSeriesVolumes, setVolumeProfileData, timeFromCoordinate, version };