@tradecanvas/chart 1.1.0 → 1.3.0

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.
Files changed (52) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +100 -26
  3. package/dist/Chart.d.ts +45 -0
  4. package/dist/Chart.d.ts.map +1 -1
  5. package/dist/DataManager.d.ts.map +1 -1
  6. package/dist/DragDropImporter-BazeSQPD.cjs +2 -0
  7. package/dist/DragDropImporter-BazeSQPD.cjs.map +1 -0
  8. package/dist/{DragDropImporter-CLtRQjKD.js → DragDropImporter-cURSpfUb.js} +390 -253
  9. package/dist/DragDropImporter-cURSpfUb.js.map +1 -0
  10. package/dist/charts/IndicatorPriceRange.d.ts +7 -3
  11. package/dist/charts/IndicatorPriceRange.d.ts.map +1 -1
  12. package/dist/index.cjs +1 -1
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.ts +4 -3
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +29 -29
  17. package/dist/index.js.map +1 -1
  18. package/dist/interaction/verticalPanGate.d.ts +22 -0
  19. package/dist/interaction/verticalPanGate.d.ts.map +1 -0
  20. package/dist/layout/LayoutManager.d.ts +3 -0
  21. package/dist/layout/LayoutManager.d.ts.map +1 -1
  22. package/dist/layout/priceAxisWidth.d.ts +22 -0
  23. package/dist/layout/priceAxisWidth.d.ts.map +1 -0
  24. package/dist/widget/ChartWidget.d.ts +24 -1
  25. package/dist/widget/ChartWidget.d.ts.map +1 -1
  26. package/dist/widget/WidgetDrawingSidebar.d.ts.map +1 -1
  27. package/dist/widget/WidgetHotkeySheet.d.ts +4 -2
  28. package/dist/widget/WidgetHotkeySheet.d.ts.map +1 -1
  29. package/dist/widget/WidgetLoadingOverlay.d.ts +43 -0
  30. package/dist/widget/WidgetLoadingOverlay.d.ts.map +1 -0
  31. package/dist/widget/WidgetObjectTree.d.ts +1 -1
  32. package/dist/widget/WidgetObjectTree.d.ts.map +1 -1
  33. package/dist/widget/WidgetSettings.d.ts +3 -1
  34. package/dist/widget/WidgetSettings.d.ts.map +1 -1
  35. package/dist/widget/WidgetToolbar.d.ts +4 -1
  36. package/dist/widget/WidgetToolbar.d.ts.map +1 -1
  37. package/dist/widget/WidgetWatchlist.d.ts +4 -1
  38. package/dist/widget/WidgetWatchlist.d.ts.map +1 -1
  39. package/dist/widget/i18n.d.ts +70 -0
  40. package/dist/widget/i18n.d.ts.map +1 -0
  41. package/dist/widget/icons.d.ts.map +1 -1
  42. package/dist/widget/index.cjs +2554 -2380
  43. package/dist/widget/index.cjs.map +1 -1
  44. package/dist/widget/index.js +725 -258
  45. package/dist/widget/index.js.map +1 -1
  46. package/dist/widget/types.d.ts +10 -0
  47. package/dist/widget/types.d.ts.map +1 -1
  48. package/dist/widget/widgetConfig.d.ts.map +1 -1
  49. package/package.json +6 -3
  50. package/dist/DragDropImporter-CLtRQjKD.js.map +0 -1
  51. package/dist/DragDropImporter-pPS0fl5H.cjs +0 -2
  52. package/dist/DragDropImporter-pPS0fl5H.cjs.map +0 -1
@@ -1,84 +1,96 @@
1
- import { DARK_THEME as e, DEFAULT_PANEL_HEIGHT as t, LIGHT_THEME as n, LayerType as r, MIN_PANEL_HEIGHT as i, PRICE_AXIS_WIDTH as a, TIME_AXIS_HEIGHT as o, computePriceLimits as s, mergeBar as c, setLocale as l, timeframeToMs as u } from "@tradecanvas/commons";
2
- import { AlertDragHandler as d, AlertManager as f, Animator as p, AreaRenderer as m, AxisDragHandler as h, BarCountdown as ee, BarRenderer as te, BaselineRenderer as ne, CandlestickRenderer as g, ChartLegend as re, ChartStateManager as _, CompareRenderer as ie, CrosshairHandler as ae, CrosshairTooltip as oe, CurrentPriceLine as se, DataExporter as v, DepthHeatmapRenderer as ce, DrawingManager as le, DrawingRenderer as ue, EquivolumeRenderer as de, EventBus as fe, GridRenderer as pe, HLCAreaRenderer as me, HollowCandleRenderer as he, IndicatorEngine as y, InteractionManager as ge, KagiRenderer as _e, KeyboardHandler as ve, LineRenderer as ye, LineWithMarkersRenderer as be, MarketProfileRenderer as xe, MeasureOverlay as Se, PanHandler as Ce, PaneResizeHandler as we, PeriodLevelsRenderer as Te, PinnedTooltip as Ee, PivotMarkersRenderer as De, PointAndFigureRenderer as Oe, PriceAxis as ke, RenderEngine as Ae, RenkoRenderer as b, ReplayManager as x, Screenshot as S, SessionBreaks as C, SessionShading as je, SignalMarkerManager as Me, StepLineRenderer as Ne, StreamManager as Pe, TimeAxis as Fe, TradeZoneManager as Ie, TradingManager as Le, TradingRenderer as Re, UndoRedoManager as ze, Viewport as Be, VolumeCandleRenderer as Ve, VolumeProfileRenderer as He, VolumeRenderer as Ue, Watermark as We, ZoomHandler as Ge, findDominantSwing as Ke, registerBuiltInDrawingTools as qe, registerBuiltInIndicators as w, toHeikinAshi as Je, toKagi as Ye, toLineBreak as Xe, toPointAndFigure as Ze, toRangeBars as Qe, toRenko as $e, xToBarIndex as et } from "@tradecanvas/core";
1
+ import { DARK_THEME as e, DEFAULT_PANEL_HEIGHT as t, LIGHT_THEME as n, LayerType as r, MIN_PANEL_HEIGHT as i, PRICE_AXIS_WIDTH as a, TIME_AXIS_HEIGHT as o, autoPricePrecision as s, computePriceLimits as c, formatPrice as l, mergeBar as u, setLocale as d, timeframeToMs as f } from "@tradecanvas/commons";
2
+ import { AlertDragHandler as p, AlertManager as m, Animator as ee, AreaRenderer as te, AxisDragHandler as ne, BarCountdown as re, BarRenderer as ie, BaselineRenderer as ae, CandlestickRenderer as h, ChartLegend as oe, ChartStateManager as g, CompareRenderer as se, CrosshairHandler as ce, CrosshairTooltip as le, CurrentPriceLine as ue, DataExporter as _, DepthHeatmapRenderer as de, DrawingManager as fe, DrawingRenderer as pe, EquivolumeRenderer as me, EventBus as he, GridRenderer as ge, HLCAreaRenderer as _e, HollowCandleRenderer as ve, IndicatorEngine as v, InteractionManager as ye, KagiRenderer as be, KeyboardHandler as xe, LineRenderer as Se, LineWithMarkersRenderer as Ce, MarketProfileRenderer as we, MeasureOverlay as Te, PanHandler as Ee, PaneResizeHandler as De, PeriodLevelsRenderer as Oe, PinnedTooltip as ke, PivotMarkersRenderer as Ae, PointAndFigureRenderer as je, PriceAxis as Me, RenderEngine as Ne, RenkoRenderer as y, ReplayManager as b, Screenshot as x, SelectionBoxOverlay as Pe, SessionBreaks as Fe, SessionShading as Ie, SignalMarkerManager as Le, StepLineRenderer as Re, StreamManager as ze, TimeAxis as Be, TradeZoneManager as Ve, TradingManager as He, TradingRenderer as Ue, UndoRedoManager as We, Viewport as Ge, VolumeCandleRenderer as Ke, VolumeProfileRenderer as qe, VolumeRenderer as Je, Watermark as Ye, ZoomHandler as Xe, barTimeStep as Ze, findDominantSwing as Qe, registerBuiltInDrawingTools as $e, registerBuiltInIndicators as S, timestampToBarIndex as C, toHeikinAshi as et, toKagi as tt, toLineBreak as nt, toPointAndFigure as rt, toRangeBars as it, toRenko as at, xToBarIndex as ot } from "@tradecanvas/core";
3
3
  //#region src/charts/ChartTypeStrategy.ts
4
- function tt(e) {
4
+ function st(e) {
5
5
  switch (e) {
6
6
  case "candlestick":
7
7
  case "heikinAshi":
8
8
  case "lineBreak":
9
- case "rangeBars": return new g();
10
- case "line": return new ye();
11
- case "area": return new m();
12
- case "bar": return new te();
13
- case "hollowCandle": return new he();
14
- case "baseline": return new ne();
15
- case "renko": return new b();
16
- case "kagi": return new _e();
17
- case "pointAndFigure": return new Oe();
18
- case "volumeCandles": return new Ve();
19
- case "equivolume": return new de();
20
- case "hlcArea": return new me();
21
- case "stepLine": return new Ne();
22
- case "lineWithMarkers": return new be();
23
- default: return new g();
9
+ case "rangeBars": return new h();
10
+ case "line": return new Se();
11
+ case "area": return new te();
12
+ case "bar": return new ie();
13
+ case "hollowCandle": return new ve();
14
+ case "baseline": return new ae();
15
+ case "renko": return new y();
16
+ case "kagi": return new be();
17
+ case "pointAndFigure": return new je();
18
+ case "volumeCandles": return new Ke();
19
+ case "equivolume": return new me();
20
+ case "hlcArea": return new _e();
21
+ case "stepLine": return new Re();
22
+ case "lineWithMarkers": return new Ce();
23
+ default: return new h();
24
24
  }
25
25
  }
26
- function nt(e, t) {
26
+ function ct(e, t) {
27
27
  if (t.length === 0) return t;
28
28
  switch (e) {
29
- case "heikinAshi": return Je(t);
30
- case "renko": return $e(t, {
29
+ case "heikinAshi": return et(t);
30
+ case "renko": return at(t, {
31
31
  brickSize: 0,
32
32
  useATR: !0,
33
33
  atrPeriod: 14
34
34
  });
35
- case "lineBreak": return Xe(t, 3);
36
- case "kagi": return Ye(t, 4);
37
- case "pointAndFigure": return Ze(t, T(t) * .01, 3);
38
- case "rangeBars": return Qe(t, { rangeSize: T(t) * .005 });
35
+ case "lineBreak": return nt(t, 3);
36
+ case "kagi": return tt(t, 4);
37
+ case "pointAndFigure": return rt(t, w(t) * .01, 3);
38
+ case "rangeBars": return it(t, { rangeSize: w(t) * .005 });
39
39
  default: return t;
40
40
  }
41
41
  }
42
- function T(e) {
42
+ function w(e) {
43
43
  let t = 0;
44
44
  for (let n of e) t += n.close;
45
45
  return t / e.length;
46
46
  }
47
- function rt(e, t) {
47
+ function lt(e, t) {
48
48
  let n = t?.(e);
49
- return n ? n.createRenderer() : tt(e);
49
+ return n ? n.createRenderer() : st(e);
50
50
  }
51
- function it(e, t, n) {
51
+ function ut(e, t, n) {
52
52
  if (t.length === 0) return t;
53
53
  let r = n?.(e);
54
- return r?.transform ? r.transform(t) : nt(e, t);
54
+ return r?.transform ? r.transform(t) : ct(e, t);
55
55
  }
56
56
  //#endregion
57
57
  //#region src/charts/IndicatorPriceRange.ts
58
- var E = {
58
+ var T = {
59
59
  min: 0,
60
60
  max: 100
61
- }, D = .1;
62
- function at(e, t, n) {
63
- if (!e) return { ...E };
64
- let r = Infinity, i = -Infinity, a = 0;
65
- for (let [, o] of e.values) {
66
- if (a >= t && a <= n) for (let e in o) {
67
- let t = o[e];
68
- t !== void 0 && Number.isFinite(t) && (t < r && (r = t), t > i && (i = t));
61
+ }, E = .1;
62
+ function dt(e, t, n) {
63
+ if (!e) return { ...T };
64
+ let r = Infinity, i = -Infinity;
65
+ if (e.series) {
66
+ let a = Math.min(n, e.series.length - 1);
67
+ for (let n = Math.max(0, t); n <= a; n++) {
68
+ let t = e.series[n];
69
+ if (t) for (let e in t) {
70
+ let n = t[e];
71
+ n !== void 0 && Number.isFinite(n) && (n < r && (r = n), n > i && (i = n));
72
+ }
73
+ }
74
+ } else {
75
+ let a = 0;
76
+ for (let [, o] of e.values) {
77
+ if (a >= t && a <= n) for (let e in o) {
78
+ let t = o[e];
79
+ t !== void 0 && Number.isFinite(t) && (t < r && (r = t), t > i && (i = t));
80
+ }
81
+ a++;
69
82
  }
70
- a++;
71
83
  }
72
- if (r === Infinity) return { ...E };
73
- let o = i - r || 1;
84
+ if (r === Infinity) return { ...T };
85
+ let a = i - r || 1;
74
86
  return {
75
- min: r - o * D,
76
- max: i + o * D
87
+ min: r - a * E,
88
+ max: i + a * E
77
89
  };
78
90
  }
79
91
  //#endregion
80
92
  //#region src/state/AutoSaveScheduler.ts
81
- var ot = class {
93
+ var ft = class {
82
94
  timer = null;
83
95
  delayMs = 0;
84
96
  key = null;
@@ -108,12 +120,15 @@ var ot = class {
108
120
  };
109
121
  //#endregion
110
122
  //#region src/DataManager.ts
111
- function O(e) {
123
+ function D(e) {
112
124
  if (!e || typeof e.time != "number") return !1;
113
125
  let { open: t, high: n, low: r, close: i } = e;
114
126
  return !(!isFinite(t) || !isFinite(n) || !isFinite(r) || !isFinite(i) || t < 0 || n < 0 || r < 0 || i < 0 || n < r || e.volume !== void 0 && (!isFinite(e.volume) || e.volume < 0));
115
127
  }
116
- function k(e) {
128
+ function pt(e) {
129
+ return e.volume !== void 0 && e.high >= e.open && e.high >= e.close && e.low <= e.open && e.low <= e.close;
130
+ }
131
+ function O(e) {
117
132
  return {
118
133
  ...e,
119
134
  high: Math.max(e.open, e.high, e.low, e.close),
@@ -121,20 +136,25 @@ function k(e) {
121
136
  volume: e.volume === void 0 ? 0 : Math.max(0, e.volume)
122
137
  };
123
138
  }
124
- var A = class {
139
+ var k = class {
125
140
  data = [];
126
141
  getData() {
127
142
  return this.data;
128
143
  }
129
144
  setData(e) {
130
- this.data = e.filter(O).map(k);
145
+ let t = [];
146
+ for (let n = 0; n < e.length; n++) {
147
+ let r = e[n];
148
+ D(r) && t.push(pt(r) ? r : O(r));
149
+ }
150
+ this.data = t;
131
151
  }
132
152
  appendBar(e) {
133
- O(e) && this.data.push(k(e));
153
+ D(e) && this.data.push(O(e));
134
154
  }
135
155
  updateLastBar(e) {
136
- if (!O(e)) return;
137
- let t = k(e);
156
+ if (!D(e)) return;
157
+ let t = O(e);
138
158
  if (this.data.length === 0) {
139
159
  this.data.push(t);
140
160
  return;
@@ -142,7 +162,7 @@ var A = class {
142
162
  this.data[this.data.length - 1] = t;
143
163
  }
144
164
  updateLastBarFromTick(e) {
145
- this.data.length !== 0 && (!isFinite(e.price) || e.price < 0 || e.volume !== void 0 && (!isFinite(e.volume) || e.volume < 0) || (this.data[this.data.length - 1] = c(this.data[this.data.length - 1], e)));
165
+ this.data.length !== 0 && (!isFinite(e.price) || e.price < 0 || e.volume !== void 0 && (!isFinite(e.volume) || e.volume < 0) || (this.data[this.data.length - 1] = u(this.data[this.data.length - 1], e)));
146
166
  }
147
167
  getLength() {
148
168
  return this.data.length;
@@ -150,7 +170,7 @@ var A = class {
150
170
  clear() {
151
171
  this.data = [];
152
172
  }
153
- }, j = class {
173
+ }, A = class {
154
174
  theme;
155
175
  constructor(t) {
156
176
  !t || t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t };
@@ -161,10 +181,11 @@ var A = class {
161
181
  setTheme(t) {
162
182
  t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t };
163
183
  }
164
- }, M = 200, N = 80, P = class {
184
+ }, j = 200, M = 80, N = class {
165
185
  panels = [];
166
186
  containerWidth = 0;
167
187
  containerHeight = 0;
188
+ priceAxisWidth = a;
168
189
  resize(e, t) {
169
190
  this.containerWidth = e, this.containerHeight = t;
170
191
  }
@@ -173,8 +194,8 @@ var A = class {
173
194
  this.panels.push({
174
195
  id: e,
175
196
  position: n,
176
- size: r ?? (a ? M : t),
177
- minSize: a ? N : i,
197
+ size: r ?? (a ? j : t),
198
+ minSize: a ? M : i,
178
199
  content: {
179
200
  type: "indicator",
180
201
  indicatorInstanceId: e
@@ -188,108 +209,144 @@ var A = class {
188
209
  let r = this.panels.find((t) => t.id === e);
189
210
  if (r) {
190
211
  let e = r.position === "left" || r.position === "right", a = n === "left" || n === "right";
191
- r.position = n, e !== a && (r.size = a ? M : t, r.minSize = a ? N : i);
212
+ r.position = n, e !== a && (r.size = a ? j : t, r.minSize = a ? M : i);
192
213
  }
193
214
  }
194
215
  setPanelSize(e, t) {
195
216
  let n = this.panels.find((t) => t.id === e);
196
217
  n && (n.size = Math.max(n.minSize, t));
197
218
  }
219
+ setPriceAxisWidth(e) {
220
+ this.priceAxisWidth = e;
221
+ }
198
222
  getPanels() {
199
223
  return this.panels;
200
224
  }
201
225
  resolve() {
202
- let e = this.panels.filter((e) => e.position === "left"), t = this.panels.filter((e) => e.position === "right"), n = this.panels.filter((e) => e.position === "top"), r = this.panels.filter((e) => e.position === "bottom"), i = e.reduce((e, t) => e + t.size, 0), s = t.reduce((e, t) => e + t.size, 0), c = n.reduce((e, t) => e + t.size, 0), l = r.reduce((e, t) => e + t.size, 0), u = {
226
+ let e = this.panels.filter((e) => e.position === "left"), t = this.panels.filter((e) => e.position === "right"), n = this.panels.filter((e) => e.position === "top"), r = this.panels.filter((e) => e.position === "bottom"), i = e.reduce((e, t) => e + t.size, 0), a = t.reduce((e, t) => e + t.size, 0), s = n.reduce((e, t) => e + t.size, 0), c = r.reduce((e, t) => e + t.size, 0), l = {
203
227
  x: i,
204
- y: c,
205
- width: Math.max(0, this.containerWidth - i - s - a),
206
- height: Math.max(0, this.containerHeight - c - l - o)
207
- }, d = [], f = [], p = 0;
208
- for (let t of e) d.push({
228
+ y: s,
229
+ width: Math.max(0, this.containerWidth - i - a - this.priceAxisWidth),
230
+ height: Math.max(0, this.containerHeight - s - c - o)
231
+ }, u = [], d = [], f = 0;
232
+ for (let t of e) u.push({
209
233
  config: t,
210
234
  rect: {
211
- x: p,
235
+ x: f,
212
236
  y: 0,
213
237
  width: t.size,
214
238
  height: this.containerHeight - o
215
239
  }
216
- }), f.push({
240
+ }), d.push({
217
241
  panelId: t.id,
218
242
  rect: {
219
- x: p + t.size - 2,
243
+ x: f + t.size - 2,
220
244
  y: 0,
221
245
  width: 4,
222
246
  height: this.containerHeight
223
247
  },
224
248
  orientation: "vertical"
225
- }), p += t.size;
226
- let m = 0;
227
- for (let e of n) d.push({
249
+ }), f += t.size;
250
+ let p = 0;
251
+ for (let e of n) u.push({
228
252
  config: e,
229
253
  rect: {
230
254
  x: i,
231
- y: m,
232
- width: u.width,
255
+ y: p,
256
+ width: l.width,
233
257
  height: e.size
234
258
  }
235
- }), f.push({
259
+ }), d.push({
236
260
  panelId: e.id,
237
261
  rect: {
238
262
  x: i,
239
- y: m + e.size - 2,
240
- width: u.width,
263
+ y: p + e.size - 2,
264
+ width: l.width,
241
265
  height: 4
242
266
  },
243
267
  orientation: "horizontal"
244
- }), m += e.size;
245
- m = u.y + u.height;
246
- for (let e of r) d.push({
268
+ }), p += e.size;
269
+ p = l.y + l.height;
270
+ for (let e of r) u.push({
247
271
  config: e,
248
272
  rect: {
249
273
  x: i,
250
- y: m,
251
- width: u.width,
274
+ y: p,
275
+ width: l.width,
252
276
  height: e.size
253
277
  }
254
- }), f.push({
278
+ }), d.push({
255
279
  panelId: e.id,
256
280
  rect: {
257
281
  x: i,
258
- y: m - 2,
259
- width: u.width,
282
+ y: p - 2,
283
+ width: l.width,
260
284
  height: 4
261
285
  },
262
286
  orientation: "horizontal"
263
- }), m += e.size;
264
- p = i + u.width + a;
265
- for (let e of t) d.push({
287
+ }), p += e.size;
288
+ f = i + l.width + this.priceAxisWidth;
289
+ for (let e of t) u.push({
266
290
  config: e,
267
291
  rect: {
268
- x: p,
292
+ x: f,
269
293
  y: 0,
270
294
  width: e.size,
271
295
  height: this.containerHeight - o
272
296
  }
273
- }), f.push({
297
+ }), d.push({
274
298
  panelId: e.id,
275
299
  rect: {
276
- x: p - 2,
300
+ x: f - 2,
277
301
  y: 0,
278
302
  width: 4,
279
303
  height: this.containerHeight
280
304
  },
281
305
  orientation: "vertical"
282
- }), p += e.size;
306
+ }), f += e.size;
283
307
  return {
284
- mainChartRect: u,
285
- panels: d,
286
- dividers: f
308
+ mainChartRect: l,
309
+ panels: u,
310
+ dividers: d
287
311
  };
288
312
  }
289
313
  getMainChartRect() {
290
314
  return this.resolve().mainChartRect;
291
315
  }
292
- }, st = 1;
316
+ }, mt = 14, ht = 14, gt = 22, P = 4;
317
+ function _t(e) {
318
+ let { min: t, max: n, lastPrice: r, locale: i, fontFamily: o, fontSizeSmall: c, measure: u } = e, d = s(t, n), f = e.tagPrecision ?? d, p = r === null ? [t, n] : [
319
+ t,
320
+ n,
321
+ r
322
+ ], m = a;
323
+ for (let e of p) {
324
+ if (!Number.isFinite(e)) continue;
325
+ let t = l(e, d, i), n = l(e, f, i);
326
+ m = Math.max(m, u(t, `500 ${c}px ${o}`) + mt, u(n, `bold 11px ${o}`) + ht, u(n, `600 ${c}px ${o}`) + gt);
327
+ }
328
+ return m <= a ? a : Math.ceil(m / P) * P;
329
+ }
330
+ function vt(e, t) {
331
+ return t > e || t <= e - 12 ? t : e;
332
+ }
333
+ var yt = class {
334
+ netY = 0;
335
+ travelX = 0;
336
+ engaged = !1;
337
+ reset() {
338
+ this.netY = 0, this.travelX = 0, this.engaged = !1;
339
+ }
340
+ step(e, t, n) {
341
+ if (this.engaged) return !0;
342
+ if (this.netY += t, this.travelX += Math.abs(e), !n) this.engaged = !0;
343
+ else {
344
+ let e = Math.abs(this.netY);
345
+ this.engaged = e > 24 && e >= this.travelX * .5;
346
+ }
347
+ return this.engaged;
348
+ }
349
+ }, bt = 1;
293
350
  function F(e, t) {
294
351
  return e.filter((e) => (e.descriptor.layer ?? "overlay") === t);
295
352
  }
@@ -304,16 +361,16 @@ function I(e) {
304
361
  //#endregion
305
362
  //#region src/plugins/registry.ts
306
363
  var L = /* @__PURE__ */ new Map();
307
- function ct(e) {
364
+ function xt(e) {
308
365
  L.set(I(e), e);
309
366
  }
310
- function lt(e) {
367
+ function St(e) {
311
368
  return L.delete(e);
312
369
  }
313
370
  function R() {
314
371
  return [...L.values()];
315
372
  }
316
- function ut() {
373
+ function Ct() {
317
374
  L.clear();
318
375
  }
319
376
  //#endregion
@@ -358,7 +415,7 @@ var z = class {
358
415
  positionModify: (e, t) => e.modifyPosition(t),
359
416
  positionClose: (e, t) => e.closePosition(t)
360
417
  };
361
- function dt(e, t) {
418
+ function wt(e, t) {
362
419
  let n = [], r = (e) => t.setOrders(e.data ?? []), i = (e) => t.setPositions(e.data ?? []), a = (e) => t.onError(e.data ?? { message: "Execution error" });
363
420
  e.on("orders", r), e.on("positions", i), e.on("error", a), n.push(() => e.off("orders", r), () => e.off("positions", i), () => e.off("error", a));
364
421
  for (let r of Object.keys(B)) {
@@ -376,8 +433,8 @@ function dt(e, t) {
376
433
  }
377
434
  //#endregion
378
435
  //#region src/Chart.ts
379
- var ft = 6, pt = class {
380
- static version = "1.1.0";
436
+ var Tt = class {
437
+ static version = "1.3.0";
381
438
  engine;
382
439
  viewport;
383
440
  dataManager;
@@ -398,6 +455,8 @@ var ft = 6, pt = class {
398
455
  resolvedLayoutCache = null;
399
456
  panelInfoCache = null;
400
457
  renderScheduled = !1;
458
+ priceAxisWidth = a;
459
+ measureCtx;
401
460
  containerSizeCache = null;
402
461
  containerSizeCacheTime = 0;
403
462
  lastEmittedRange = null;
@@ -420,9 +479,12 @@ var ft = 6, pt = class {
420
479
  signalMarkerManager;
421
480
  tradeZoneManager;
422
481
  measureOverlay;
482
+ selectionBoxOverlay = new Pe();
423
483
  replayManager;
484
+ replayBarUnsub = null;
485
+ replaySeeking = !1;
424
486
  undoRedoManager;
425
- autoSaveScheduler = new ot((e) => this.saveState(e));
487
+ autoSaveScheduler = new ft((e) => this.saveState(e));
426
488
  animator;
427
489
  crosshairTooltip;
428
490
  pinnedTooltip;
@@ -438,11 +500,12 @@ var ft = 6, pt = class {
438
500
  container;
439
501
  currentPriceLine;
440
502
  numberLocale;
503
+ defaultAutoScale;
441
504
  keyboardHandler = null;
442
505
  onWindowKeyDown = null;
443
506
  currentSymbol = "";
444
507
  constructor(e, t) {
445
- this.container = e, this.options = t, this.numberLocale = t.numberLocale ?? "en-US";
508
+ this.container = e, this.options = t, this.numberLocale = t.numberLocale ?? "en-US", this.defaultAutoScale = t.autoScale !== !1;
446
509
  let n = t.features ?? {};
447
510
  this.features = {
448
511
  drawings: n.drawings ?? !0,
@@ -450,12 +513,13 @@ var ft = 6, pt = class {
450
513
  drawingMagnet: n.drawingMagnet ?? !0,
451
514
  drawingUndoRedo: n.drawingUndoRedo ?? !0,
452
515
  trading: n.trading ?? !0,
453
- tradingContextMenu: n.tradingContextMenu ?? !0,
516
+ tradingContextMenu: n.tradingContextMenu ?? !1,
454
517
  indicators: n.indicators ?? !0,
455
518
  indicatorIds: n.indicatorIds ?? [],
456
519
  panning: n.panning ?? !0,
457
520
  zooming: n.zooming ?? !0,
458
521
  crosshair: n.crosshair ?? !0,
522
+ crosshairTooltip: n.crosshairTooltip ?? !0,
459
523
  keyboard: n.keyboard ?? !0,
460
524
  priceAxis: n.priceAxis ?? !0,
461
525
  timeAxis: n.timeAxis ?? !0,
@@ -474,36 +538,48 @@ var ft = 6, pt = class {
474
538
  logScale: n.logScale ?? !0,
475
539
  timeframes: n.timeframes ?? [],
476
540
  defaultTimeframeFavorites: n.defaultTimeframeFavorites ?? []
477
- }, e.style.position = "relative", e.style.overflow = "hidden", e.tabIndex = 0, e.style.outline = "none", this.dataManager = new A(), this.themeManager = new j(t.theme), this.layoutManager = new P(), this.indicatorEngine = new y(), this.pluginManager = new z(this.indicatorEngine, { plugins: t.plugins }), this.eventBus = new fe(), w(this.indicatorEngine), this.drawingManager = new le(), qe(this.drawingManager), this.drawingRenderer = new ue(this.drawingManager), this.drawingManager.setRequestRender(() => {
541
+ }, e.style.position = "relative", e.style.overflow = "hidden", e.tabIndex = 0, e.style.outline = "none", this.dataManager = new k(), this.themeManager = new A(t.theme), this.layoutManager = new N(), this.indicatorEngine = new v(), this.pluginManager = new z(this.indicatorEngine, { plugins: t.plugins }), this.eventBus = new he(), S(this.indicatorEngine), this.drawingManager = new fe(), $e(this.drawingManager), this.drawingRenderer = new pe(this.drawingManager), this.drawingManager.setRequestRender(() => {
478
542
  this.syncRenderContext(), this.engine.requestRender(r.Overlay), this.scheduleAutoSave();
479
543
  }), this.drawingManager.setEventCallback((e, t) => {
480
544
  this.eventBus.emit(e, t);
481
- }), this.undoRedoManager = new ze(), this.drawingManager.setUndoRedoManager(this.undoRedoManager), this.drawingManager.setDataGetter(() => this.dataManager.getData()), this.drawingManager.setDisplayDataGetter(() => this.getDisplayData()), t.crosshair?.mode === "magnet" && this.drawingManager.setMagnetMode("magnet"), this.tradingManager = new Le({
545
+ }), this.undoRedoManager = new We(), this.drawingManager.setUndoRedoManager(this.undoRedoManager), this.drawingManager.setDataGetter(() => this.dataManager.getData()), this.drawingManager.setDisplayDataGetter(() => this.getDisplayData()), t.crosshair?.mode === "magnet" && this.drawingManager.setMagnetMode("magnet"), this.tradingManager = new He({
482
546
  enabled: this.features.trading,
483
547
  contextMenu: { enabled: this.features.tradingContextMenu }
484
- }), this.tradingRenderer = new Re(this.tradingManager), this.tradingManager.setContainer(e), this.tradingManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradingManager.setEventCallback((e, t) => {
548
+ }), this.tradingRenderer = new Ue(this.tradingManager), this.tradingManager.setContainer(e), this.tradingManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradingManager.setEventCallback((e, t) => {
485
549
  this.eventBus.emit(e, t);
486
- }), this.engine = new Ae(e);
550
+ }), this.engine = new Ne(e);
487
551
  let i = this.engine.dprManager.getContainerSize();
488
- if (this.viewport = new Be(i.width, i.height, t.minBarSpacing ?? 2, t.maxBarSpacing ?? 30, t.rightMargin ?? 5), this.layoutManager.resize(i.width, i.height), this.engine.onContainerResize = (e) => {
552
+ if (this.viewport = new Ge(i.width, i.height, t.minBarSpacing ?? 2, t.maxBarSpacing ?? 30, t.rightMargin ?? 5), this.viewport.setPanLimits({
553
+ freePan: t.freePan ?? !0,
554
+ minVisibleBars: t.panLimits?.minVisibleBars ?? 3
555
+ }), this.layoutManager.resize(i.width, i.height), this.engine.onContainerResize = (e) => {
489
556
  if (e.width <= 0 || e.height <= 0) return;
490
557
  let t = this.viewport.isAtEnd();
491
558
  this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(t);
492
- }, this.chartRenderer = this.createChartRenderer(t.chartType), this.gridRenderer = new pe(), t.grid?.visible === !1 && this.gridRenderer.setVisible(!1), this.priceAxis = new ke(), this.priceAxis.setLocale(this.numberLocale), this.timeAxis = new Fe(), this.crosshairHandler = new ae(), this.crosshairHandler.setLocale(this.numberLocale), t.crosshair?.mode && this.crosshairHandler.setMode(t.crosshair.mode), this.crosshairHandler.setCallback((e, t) => {
559
+ }, this.chartRenderer = this.createChartRenderer(t.chartType), this.gridRenderer = new ge(), t.grid?.visible === !1 && this.gridRenderer.setVisible(!1), this.priceAxis = new Me(), this.priceAxis.setLocale(this.numberLocale), this.timeAxis = new Be(), this.crosshairHandler = new ce(), this.crosshairHandler.setLocale(this.numberLocale), t.crosshair?.mode && this.crosshairHandler.setMode(t.crosshair.mode), this.crosshairHandler.setCallback((e, t) => {
493
560
  if (e !== null && t) {
494
561
  let n = this.dataManager.getData(), r = e < n.length ? n[e] : void 0;
495
- this.chartLegend.setHoverBar(r ?? null), r && this.crosshairTooltip.show(t, r, this.themeManager.getTheme(), this.cachedContainerSize()), this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), r ?? null, e, this.themeManager.getTheme()), this.eventBus.emit("crosshairMove", {
562
+ if (this.chartLegend.setHoverBar(r ?? null), r && this.features.crosshairTooltip) {
563
+ let i = this.viewport.getState();
564
+ this.crosshairTooltip.show(t, r, this.themeManager.getTheme(), this.cachedContainerSize(), {
565
+ prevClose: e > 0 ? n[e - 1]?.close : void 0,
566
+ priceRange: i.priceRange,
567
+ plot: i.chartRect,
568
+ barStepMs: Ze(n)
569
+ });
570
+ }
571
+ this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), r ?? null, e, this.themeManager.getTheme()), this.eventBus.emit("crosshairMove", {
496
572
  point: t,
497
573
  bar: r,
498
574
  barIndex: e
499
575
  });
500
576
  } else this.crosshairTooltip.hide(), this.chartLegend.setHoverBar(null);
501
- }), this.chartLegend = new re(), this.chartLegend.setChartType(t.chartType), this.watermark = new We(), t.watermark && this.watermark.setConfig(t.watermark), this.volumeRenderer = new Ue(), this.volumeProfile = new He(), this.marketProfile = new xe(), this.depthHeatmap = new ce(), this.periodLevels = new Te(), this.pivotMarkers = new De(), this.barCountdown = new ee(), this.sessionBreaks = new C(), this.sessionShading = new je(), this.compareRenderer = new ie(), t.sessionBreaks ? this.sessionBreaks.setConfig({
577
+ }), this.chartLegend = new oe(), this.chartLegend.setChartType(t.chartType), this.chartLegend.setLocale(this.numberLocale), this.watermark = new Ye(), t.watermark && this.watermark.setConfig(t.watermark), this.volumeRenderer = new Je(), this.volumeProfile = new qe(), this.marketProfile = new we(), this.depthHeatmap = new de(), this.periodLevels = new Oe(), this.pivotMarkers = new Ae(), this.barCountdown = new re(), this.sessionBreaks = new Fe(), this.sessionBreaks.setLocale(this.numberLocale), this.sessionShading = new Ie(), this.compareRenderer = new se(), t.sessionBreaks ? this.sessionBreaks.setConfig({
502
578
  visible: t.sessionBreaks.visible ?? !0,
503
579
  color: t.sessionBreaks.color,
504
580
  lineStyle: t.sessionBreaks.lineStyle,
505
581
  lineWidth: t.sessionBreaks.lineWidth
506
- }) : t.features?.sessionBreaks !== !1 && this.sessionBreaks.setVisible(!0), t.logScale && this.viewport.setLogScale(!0), this.animator = new p(), this.crosshairTooltip = new oe(), this.crosshairTooltip.create(e), this.pinnedTooltip = new Ee(), this.pinnedTooltip.create(e), this.keyboardHandler = new ve({
582
+ }) : t.features?.sessionBreaks !== !1 && this.sessionBreaks.setVisible(!0), t.logScale && this.viewport.setLogScale(!0), this.animator = new ee(), this.crosshairTooltip = new le(), this.crosshairTooltip.create(e), this.crosshairTooltip.setLocale(this.numberLocale), this.pinnedTooltip = new ke(), this.pinnedTooltip.create(e), this.keyboardHandler = new xe({
507
583
  scrollBars: (e) => {
508
584
  let t = this.viewport.getState().barWidth + this.viewport.getState().barSpacing;
509
585
  this.viewport.scrollBy(e * t), this.updateViewportAndRender();
@@ -523,7 +599,7 @@ var ft = 6, pt = class {
523
599
  if (!this.keyboardHandler) return;
524
600
  let t = document.activeElement;
525
601
  t && t !== this.container && !this.container.contains(t) || t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable) || this.keyboardHandler.handleKey(e) && e.preventDefault();
526
- }, window.addEventListener("keydown", this.onWindowKeyDown), this.currentPriceLine = new se(), this.alertManager = new f(), this.alertManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.alertManager.on("triggered", (e) => {
602
+ }, window.addEventListener("keydown", this.onWindowKeyDown), this.currentPriceLine = new ue(), this.currentPriceLine.setLocale(this.numberLocale), this.priceAxis.setReservedPriceProvider(() => this.currentPriceLine.isVisible() ? this.currentPriceLine.getPrice() : null), this.alertManager = new m(), this.alertManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.alertManager.on("triggered", (e) => {
527
603
  let t = {
528
604
  id: e.id,
529
605
  price: e.price,
@@ -555,7 +631,7 @@ var ft = 6, pt = class {
555
631
  message: e.message,
556
632
  triggered: e.triggered
557
633
  });
558
- }), this.signalMarkerManager = new Me(), this.signalMarkerManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.signalMarkerManager.setDataGetter(() => this.dataManager.getData()), this.signalMarkerManager.on("added", (e) => {
634
+ }), this.signalMarkerManager = new Le(), this.signalMarkerManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.signalMarkerManager.setDataGetter(() => this.dataManager.getData()), this.signalMarkerManager.on("added", (e) => {
559
635
  this.eventBus.emit("signalMarkerAdd", {
560
636
  id: e.id,
561
637
  source: e.source,
@@ -563,26 +639,24 @@ var ft = 6, pt = class {
563
639
  });
564
640
  }), this.signalMarkerManager.on("removed", (e) => {
565
641
  this.eventBus.emit("signalMarkerRemove", { id: e });
566
- }), this.tradeZoneManager = new Ie(), this.tradeZoneManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradeZoneManager.setDataGetter(() => this.dataManager.getData()), this.tradeZoneManager.on("added", (e) => {
642
+ }), this.tradeZoneManager = new Ve(), this.tradeZoneManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradeZoneManager.setDataGetter(() => this.dataManager.getData()), this.tradeZoneManager.on("added", (e) => {
567
643
  this.eventBus.emit("tradeZoneAdd", {
568
644
  id: e.id,
569
645
  direction: e.direction
570
646
  });
571
647
  }), this.tradeZoneManager.on("removed", (e) => {
572
648
  this.eventBus.emit("tradeZoneRemove", { id: e });
573
- }), this.replayManager = new x(), this.measureOverlay = new Se(), this.interactionManager = new ge(e), this.features.panning) {
574
- let e = 0;
575
- this.interactionManager.setPanHandler(new Ce((t, n) => {
576
- t && this.viewport.scrollBy(t), n && (e += n, (this.options.autoScale === !1 || Math.abs(e) > ft) && (this.options.autoScale = !1, this.viewport.panPriceRange(n))), this.updateViewportAndRender();
577
- }, () => {
578
- e = 0;
579
- }));
649
+ }), this.replayManager = new b(), this.measureOverlay = new Te(), this.interactionManager = new ye(e), this.features.panning) {
650
+ let e = new yt();
651
+ this.interactionManager.setPanHandler(new Ee((t, n) => {
652
+ t && this.viewport.scrollBy(t), e.step(t, n, this.options.autoScale !== !1) && n && (this.options.autoScale = !1, this.viewport.panPriceRange(n)), this.updateViewportAndRender();
653
+ }, () => e.reset()));
580
654
  }
581
655
  if (this.features.zooming) {
582
- this.interactionManager.setZoomHandler(new Ge((e, t) => {
656
+ this.interactionManager.setZoomHandler(new Xe((e, t) => {
583
657
  this.viewport.zoom(e, t), this.updateViewportAndRender();
584
658
  }));
585
- let e = new h((e) => {
659
+ let e = new ne((e) => {
586
660
  this.options.autoScale = !1, this.viewport.scalePriceRange(e), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
587
661
  }, (e) => {
588
662
  let t = this.viewport.getState().chartRect.width;
@@ -599,10 +673,10 @@ var ft = 6, pt = class {
599
673
  ...this.viewport.getState(),
600
674
  data: this.getDisplayData()
601
675
  })), this.features.alerts) {
602
- let e = new d(this.alertManager, () => this.viewport.getState());
676
+ let e = new p(this.alertManager, () => this.viewport.getState());
603
677
  this.interactionManager.setAlertDragHandler(e);
604
678
  }
605
- let a = new we();
679
+ let a = new De();
606
680
  a.configure(() => this.getResolvedLayout(), (e, t) => this.setPanelSize(e, t)), this.interactionManager.setPaneResizeHandler(a), this.interactionManager.setAltClickHandler((e) => {
607
681
  let t = this.getDisplayData();
608
682
  if (t.length === 0) return;
@@ -614,7 +688,7 @@ var ft = 6, pt = class {
614
688
  x: e.x,
615
689
  y: e.y
616
690
  }), t.length === 0) return;
617
- let n = et(e.x, this.viewport.getState());
691
+ let n = ot(e.x, this.viewport.getState());
618
692
  n < 0 || n >= t.length || this.eventBus.emit("barClick", {
619
693
  bar: t[n],
620
694
  barIndex: n,
@@ -636,27 +710,58 @@ var ft = 6, pt = class {
636
710
  end: () => {
637
711
  this.measureOverlay.end();
638
712
  }
639
- }), this.interactionManager.setOverlayDirtyCallback(() => {
640
- this.engine.requestRender(r.Overlay), this.engine.requestRender(r.UI);
713
+ });
714
+ let o = (e) => {
715
+ let t = this.viewport.getState().chartRect;
716
+ return {
717
+ x: Math.max(t.x, Math.min(t.x + t.width, e.x)),
718
+ y: Math.max(t.y, Math.min(t.y + t.height, e.y))
719
+ };
720
+ };
721
+ this.interactionManager.setBoxSelectHandlers({
722
+ begin: (e) => this.selectionBoxOverlay.begin(o(e)),
723
+ move: (e) => this.selectionBoxOverlay.update(o(e)),
724
+ end: () => {
725
+ let e = this.selectionBoxOverlay.end();
726
+ if (!e || !this.features.drawings) return;
727
+ let t = {
728
+ ...this.viewport.getState(),
729
+ data: this.getDisplayData()
730
+ };
731
+ e.isClick ? this.drawingManager.toggleSelectionAt({
732
+ x: e.x1,
733
+ y: e.y1
734
+ }, t) : this.drawingManager.selectInRect(e, t), this.engine.requestRender(r.Overlay);
735
+ },
736
+ cancel: () => this.selectionBoxOverlay.cancel()
737
+ }), this.interactionManager.setOverlayDirtyCallback((e) => {
738
+ this.engine.requestRender(e ? r.Hover : r.Overlay);
641
739
  }), this.interactionManager.attach(), this.syncRenderContext(), this.engine.start();
642
740
  }
643
741
  setData(e) {
644
- this.dataManager.setData(e), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.sessionBreaks.invalidateCache(), this.alertManager.clearLastValues(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), e.length > 0 && this.currentPriceLine.setPrice(e[e.length - 1].close), this.updateViewportAndRender(!0), this.eventBus.emit("dataUpdate", { length: e.length });
742
+ this.dataManager.setData(e), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.sessionBreaks.invalidateCache(), this.options.autoScale = this.defaultAutoScale, this.alertManager.clearLastValues(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), e.length > 0 && this.currentPriceLine.setPrice(e[e.length - 1].close), this.updateViewportAndRender(!0), this.eventBus.emit("dataUpdate", { length: e.length });
645
743
  }
646
744
  appendBar(e) {
647
- this.dataManager.appendBar(e), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.autoScrollOnNewBar && this.viewport.scrollToEnd(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.updateViewportAndRender();
745
+ let t = this.autoScrollOnNewBar && this.viewport.isAtEnd();
746
+ this.dataManager.appendBar(e);
747
+ let n = this.dataManager.getData();
748
+ this.crosshairHandler.setData(n), this.displayDataCache = null, this.indicatorEngine.recalculateFrom(n, n.length - 2), this.updateViewportAndRender(t);
648
749
  }
649
750
  appendBars(e) {
650
- if (e.length !== 0) {
651
- for (let t of e) this.dataManager.appendBar(t);
652
- this.displayDataCache = null, this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.crosshairHandler.setData(this.dataManager.getData()), this.updateViewportAndRender(this.viewport.isAtEnd());
653
- }
751
+ if (e.length === 0) return;
752
+ let t = this.viewport.isAtEnd(), n = this.dataManager.getLength() - 1;
753
+ for (let t of e) this.dataManager.appendBar(t);
754
+ this.displayDataCache = null, this.indicatorEngine.recalculateFrom(this.dataManager.getData(), n), this.crosshairHandler.setData(this.dataManager.getData()), this.updateViewportAndRender(t);
654
755
  }
655
756
  updateLastBar(e) {
656
- this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.scheduleRender();
757
+ this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null);
758
+ let t = this.dataManager.getData();
759
+ this.indicatorEngine.recalculateFrom(t, t.length - 1), this.scheduleRender();
657
760
  }
658
761
  updateLastBarFromTick(e) {
659
- this.dataManager.updateLastBarFromTick(e), this.currentPriceLine.setPrice(e.price), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.scheduleRender();
762
+ this.dataManager.updateLastBarFromTick(e), this.currentPriceLine.setPrice(e.price), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null);
763
+ let t = this.dataManager.getData();
764
+ this.indicatorEngine.recalculateFrom(t, t.length - 1), this.scheduleRender();
660
765
  }
661
766
  setChartType(e) {
662
767
  this.options.chartType = e, this.chartRenderer = this.createChartRenderer(e), this.chartLegend.setChartType(e), this.displayDataCache = null, this.updateViewportAndRender(!0);
@@ -686,8 +791,8 @@ var ft = 6, pt = class {
686
791
  return this.pluginManager;
687
792
  }
688
793
  static indicators() {
689
- let e = new y();
690
- return w(e), e.getAvailableIndicators();
794
+ let e = new v();
795
+ return S(e), e.getAvailableIndicators();
691
796
  }
692
797
  setPanelPosition(e, t) {
693
798
  this.layoutManager.setPanelPosition(e, t), this.engine.requestRender();
@@ -726,7 +831,7 @@ var ft = 6, pt = class {
726
831
  }
727
832
  autoFib() {
728
833
  if (!this.features.drawings) return null;
729
- let e = this.getDisplayData(), t = this.viewport.getState(), n = Ke(e, t.visibleRange.from, t.visibleRange.to);
834
+ let e = this.getDisplayData(), t = this.viewport.getState(), n = Qe(e, t.visibleRange.from, t.visibleRange.to);
730
835
  return n ? this.addDrawing({
731
836
  type: "fibRetracement",
732
837
  anchors: [n[0], n[1]]
@@ -781,21 +886,21 @@ var ft = 6, pt = class {
781
886
  exportVisibleData(e = "csv", t) {
782
887
  let n = this.viewport.getState(), r = this.dataManager.getData(), i = Math.max(0, n.visibleRange.from), a = Math.min(r.length - 1, n.visibleRange.to), o = r.slice(i, a + 1);
783
888
  if (e === "json") {
784
- let e = v.toJSON(o);
785
- v.download(e, t ?? "chart-data.json", "application/json");
889
+ let e = _.toJSON(o);
890
+ _.download(e, t ?? "chart-data.json", "application/json");
786
891
  } else {
787
- let e = v.toCSV(o);
788
- v.download(e, t ?? "chart-data.csv", "text/csv");
892
+ let e = _.toCSV(o);
893
+ _.download(e, t ?? "chart-data.csv", "text/csv");
789
894
  }
790
895
  }
791
896
  exportAllData(e = "csv", t) {
792
897
  let n = this.dataManager.getData();
793
898
  if (e === "json") {
794
- let e = v.toJSON(n);
795
- v.download(e, t ?? "chart-data.json", "application/json");
899
+ let e = _.toJSON(n);
900
+ _.download(e, t ?? "chart-data.json", "application/json");
796
901
  } else {
797
- let e = v.toCSV(n);
798
- v.download(e, t ?? "chart-data.csv", "text/csv");
902
+ let e = _.toCSV(n);
903
+ _.download(e, t ?? "chart-data.csv", "text/csv");
799
904
  }
800
905
  }
801
906
  setAutoSave(e, t = 5e3) {
@@ -893,26 +998,33 @@ var ft = 6, pt = class {
893
998
  this.features.trading && this.tradingManager.setConfig(e);
894
999
  }
895
1000
  async connect(e) {
896
- this.disconnectStream(), this.streamManager = new Pe(), this.streamManager.on("snapshot", (e) => {
1001
+ this.disconnectStream(), this.streamManager = new ze(), this.streamManager.on("snapshot", (e) => {
897
1002
  this.setData(e);
898
1003
  }), this.streamManager.on("barClose", (e) => {
899
- this.dataManager.appendBar(e), this.crosshairHandler.setData(this.dataManager.getData()), this.autoScrollOnNewBar && this.viewport.scrollToEnd(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.updateViewportAndRender();
1004
+ let t = this.autoScrollOnNewBar && this.viewport.isAtEnd();
1005
+ this.dataManager.appendBar(e);
1006
+ let n = this.dataManager.getData();
1007
+ this.crosshairHandler.setData(n), this.displayDataCache = null, this.indicatorEngine.recalculateFrom(n, n.length - 2), this.updateViewportAndRender(t);
900
1008
  }), this.streamManager.on("barUpdate", (e) => {
901
- this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close), this.indicatorEngine.recalculateAll(this.dataManager.getData()), this.scheduleRender();
902
- }), this.streamManager.on("priceChange", ({ price: e }) => {
903
- this.tradingManager.setCurrentPrice(e), this.currentPriceLine.setPrice(e), this.engine.requestRender(r.Overlay), this.engine.requestRender(r.UI);
1009
+ this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close);
1010
+ let t = this.dataManager.getData();
1011
+ this.indicatorEngine.recalculateFrom(t, t.length - 1), this.scheduleRender();
1012
+ }), this.streamManager.on("priceChange", ({ price: e, previousClose: t }) => {
1013
+ this.tradingManager.setCurrentPrice(e), this.currentPriceLine.setPrice(e, t ?? void 0), this.engine.requestRender(r.Overlay);
904
1014
  }), this.streamManager.on("connectionChange", (e) => {
905
1015
  this.eventBus.emit("dataUpdate", { connection: e });
906
1016
  }), this.streamManager.on("error", (e) => {
907
1017
  this.eventBus.emit("dataUpdate", { error: e.message });
908
- }), this.autoScrollOnNewBar = e.autoScroll !== !1, this.currentSymbol = e.symbol, await this.streamManager.connect(e);
909
- let t = u(e.timeframe);
910
- this.barCountdown.setTimeframeMs(t), this.countdownInterval && clearInterval(this.countdownInterval), this.countdownInterval = setInterval(() => {
911
- this.barCountdown.isVisible() && this.engine.requestRender(r.UI);
1018
+ }), this.autoScrollOnNewBar = e.autoScroll !== !1, this.currentSymbol = e.symbol;
1019
+ let t = this.streamManager;
1020
+ if (await t.connect(e), this.streamManager !== t) return;
1021
+ let n = f(e.timeframe);
1022
+ this.barCountdown.setTimeframeMs(n), this.countdownInterval && clearInterval(this.countdownInterval), this.countdownInterval = setInterval(() => {
1023
+ this.barCountdown.isVisible() && this.engine.requestRender(r.Hover);
912
1024
  }, 1e3);
913
1025
  }
914
1026
  async switchStream(e, t) {
915
- this.streamManager && (this.currentSymbol = e, await this.streamManager.switchTo(e, t));
1027
+ this.streamManager && (this.currentSymbol = e, this.barCountdown.setTimeframeMs(f(t)), await this.streamManager.switchTo(e, t));
916
1028
  }
917
1029
  async setTimeframe(e) {
918
1030
  if (!this.streamManager) throw Error("No active stream. Call connect() first.");
@@ -923,7 +1035,7 @@ var ft = 6, pt = class {
923
1035
  }
924
1036
  connectExecution(e, t = {}) {
925
1037
  if (!this.features.trading) throw Error("connectExecution requires features.trading to be enabled");
926
- this.disconnectExecution(), this.executionAdapter = e, this.execTeardown = dt(e, {
1038
+ this.disconnectExecution(), this.executionAdapter = e, this.execTeardown = wt(e, {
927
1039
  onIntent: (e, t) => {
928
1040
  let n = (e) => t(e.payload);
929
1041
  return this.eventBus.on(e, n), () => this.eventBus.off(e, n);
@@ -943,7 +1055,7 @@ var ft = 6, pt = class {
943
1055
  return this.executionAdapter;
944
1056
  }
945
1057
  setBarCountdownVisible(e) {
946
- this.barCountdown.setVisible(e), this.engine.requestRender(r.UI);
1058
+ this.barCountdown.setVisible(e), this.engine.requestRender(r.Hover);
947
1059
  }
948
1060
  setSessionBreaksVisible(e) {
949
1061
  this.sessionBreaks.setVisible(e), this.engine.requestRender(r.Background);
@@ -1005,21 +1117,13 @@ var ft = 6, pt = class {
1005
1117
  this.viewport.scrollToEnd(), this.updateViewportAndRender();
1006
1118
  }
1007
1119
  setVisibleRange(e, t) {
1008
- let n = this.dataManager.getData(), r = 0, i = n.length - 1;
1009
- for (let t = 0; t < n.length; t++) if (n[t].time >= e) {
1010
- r = t;
1011
- break;
1012
- }
1013
- for (let e = n.length - 1; e >= 0; e--) if (n[e].time <= t) {
1014
- i = e;
1015
- break;
1016
- }
1017
- let a = i - r + 1;
1018
- if (a > 0) {
1019
- let e = this.viewport.getState().chartRect.width, t = e / a, n = Math.max(2, t - this.viewport.getState().barSpacing);
1020
- this.viewport.zoom((n - this.viewport.getState().barWidth) / this.viewport.getState().barWidth, e / 2);
1021
- }
1022
- this.updateViewportAndRender();
1120
+ let n = this.dataManager.getData();
1121
+ if (n.length === 0) return;
1122
+ let r = C(Math.min(e, t), n), i = C(Math.max(e, t), n);
1123
+ this.viewport.zoomToBarRange(r, i), this.updateViewportAndRender();
1124
+ }
1125
+ setPanLimits(e) {
1126
+ this.viewport.setPanLimits(e), this.updateViewportAndRender();
1023
1127
  }
1024
1128
  zoomIn() {
1025
1129
  let e = this.viewport.getState().chartRect.width;
@@ -1030,8 +1134,8 @@ var ft = 6, pt = class {
1030
1134
  this.viewport.zoom(-.2, e / 2), this.updateViewportAndRender();
1031
1135
  }
1032
1136
  fitContent() {
1033
- let e = this.dataManager.getData();
1034
- e.length !== 0 && this.setVisibleRange(e[0].time, e[e.length - 1].time);
1137
+ let e = this.dataManager.getLength();
1138
+ e !== 0 && (this.viewport.zoomToBarRange(0, e - 1 + this.viewport.getRightMargin()), this.viewport.scrollToEnd(), this.updateViewportAndRender());
1035
1139
  }
1036
1140
  on(e, t) {
1037
1141
  this.eventBus.on(e, t);
@@ -1061,19 +1165,19 @@ var ft = 6, pt = class {
1061
1165
  }), this.engine.requestRender(r.Background);
1062
1166
  }
1063
1167
  setAutoScale(e) {
1064
- this.options.autoScale = e, this.updateViewportAndRender();
1168
+ this.options.autoScale = e, this.defaultAutoScale = e, this.updateViewportAndRender();
1065
1169
  }
1066
1170
  isAutoScale() {
1067
1171
  return this.options.autoScale !== !1;
1068
1172
  }
1069
1173
  setCrosshairMode(e) {
1070
- this.crosshairHandler.setMode(e), this.engine.requestRender(r.Overlay);
1174
+ this.crosshairHandler.setMode(e), this.engine.requestRender(r.Hover);
1071
1175
  }
1072
1176
  getCrosshairMode() {
1073
1177
  return this.crosshairHandler.getMode();
1074
1178
  }
1075
1179
  setCrosshairPosition(e) {
1076
- e && this.crosshairHandler.onPointerMove(e), this.engine.requestRender(r.Overlay);
1180
+ e && this.crosshairHandler.onPointerMove(e), this.engine.requestRender(r.Hover);
1077
1181
  }
1078
1182
  getData() {
1079
1183
  return this.dataManager.getData();
@@ -1134,7 +1238,7 @@ var ft = 6, pt = class {
1134
1238
  this.periodLevels.setPeriod(e), this.engine.requestRender(r.Main);
1135
1239
  }
1136
1240
  setTimezoneOffset(e) {
1137
- this.timeAxis.setTimezoneOffset(e), this.crosshairHandler.setTimezoneOffset(e), this.engine.requestRender(r.UI), this.engine.requestRender(r.Overlay);
1241
+ this.timeAxis.setTimezoneOffset(e), this.crosshairHandler.setTimezoneOffset(e), this.crosshairTooltip.setTimezoneOffset(e), this.engine.requestRender(r.UI);
1138
1242
  }
1139
1243
  setPivotMarkersVisible(e) {
1140
1244
  this.pivotMarkers.setVisible(e), this.engine.requestRender(r.Overlay);
@@ -1158,31 +1262,31 @@ var ft = 6, pt = class {
1158
1262
  e || this.crosshairTooltip.hide();
1159
1263
  }
1160
1264
  setLegend(e) {
1161
- this.chartLegend.setConfig(e), this.engine.requestRender(r.UI);
1265
+ this.chartLegend.setConfig(e), this.engine.requestRender(r.Hover);
1162
1266
  }
1163
1267
  setSymbolName(e) {
1164
- this.chartLegend.setSymbol(e), this.engine.requestRender(r.UI);
1268
+ this.chartLegend.setSymbol(e), this.engine.requestRender(r.Hover);
1165
1269
  }
1166
1270
  setStatusText(e) {
1167
- this.chartLegend.setStatusText(e), this.engine.requestRender(r.UI);
1271
+ this.chartLegend.setStatusText(e), this.engine.requestRender(r.Hover);
1168
1272
  }
1169
1273
  screenshot(e) {
1170
- this.features.screenshot && S.download(this.container, e, this.themeManager.getTheme().background);
1274
+ this.features.screenshot && x.download(this.container, e, this.themeManager.getTheme().background);
1171
1275
  }
1172
1276
  async copyScreenshot() {
1173
1277
  if (!this.features.screenshot) return !1;
1174
1278
  try {
1175
- let e = await S.toBlob(this.container, this.themeManager.getTheme().background), t = globalThis.ClipboardItem;
1279
+ let e = await x.toBlob(this.container, this.themeManager.getTheme().background), t = globalThis.ClipboardItem;
1176
1280
  return !e || !navigator.clipboard?.write || !t ? !1 : (await navigator.clipboard.write([new t({ "image/png": e })]), !0);
1177
1281
  } catch {
1178
1282
  return !1;
1179
1283
  }
1180
1284
  }
1181
1285
  screenshotDataURL() {
1182
- return this.features.screenshot ? S.toDataURL(this.container, this.themeManager.getTheme().background) : null;
1286
+ return this.features.screenshot ? x.toDataURL(this.container, this.themeManager.getTheme().background) : null;
1183
1287
  }
1184
1288
  async screenshotBlob() {
1185
- return this.features.screenshot ? S.toBlob(this.container, this.themeManager.getTheme().background) : null;
1289
+ return this.features.screenshot ? x.toBlob(this.container, this.themeManager.getTheme().background) : null;
1186
1290
  }
1187
1291
  addAlert(e, t = "crossing", n, r = "price", i) {
1188
1292
  if (!this.features.alerts) return null;
@@ -1246,9 +1350,15 @@ var ft = 6, pt = class {
1246
1350
  replayStart(e) {
1247
1351
  if (!this.features.replay) return;
1248
1352
  let t = this.dataManager.getData();
1249
- this.replayManager.load(t), this.replayManager.on("bar", ({ bar: e, index: n }) => {
1250
- let r = t.slice(0, n + 1);
1251
- this.dataManager.setData(r), this.crosshairHandler.setData(r), this.indicatorEngine.recalculateAll(r), this.updateViewportAndRender();
1353
+ this.replayManager.load(t);
1354
+ let n = -1;
1355
+ this.replayBarUnsub?.(), this.replayBarUnsub = this.replayManager.on("bar", ({ bar: e, index: r }) => {
1356
+ let i = r + 1, a = n > 0 && i > n && this.dataManager.getLength() === n, o = !(a && !this.replaySeeking) || this.autoScrollOnNewBar && this.viewport.isAtEnd();
1357
+ if (a) {
1358
+ for (let e = n; e < i; e++) this.dataManager.appendBar(t[e]);
1359
+ this.indicatorEngine.recalculateFrom(this.dataManager.getData(), n);
1360
+ } else this.dataManager.setData(t.slice(0, i)), this.indicatorEngine.recalculateAll(this.dataManager.getData());
1361
+ n = i, this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.updateViewportAndRender(o);
1252
1362
  }), this.replayManager.play(e);
1253
1363
  }
1254
1364
  replayPause() {
@@ -1261,7 +1371,12 @@ var ft = 6, pt = class {
1261
1371
  this.replayManager.stop();
1262
1372
  }
1263
1373
  replaySeek(e) {
1264
- this.replayManager.seekTo(e);
1374
+ this.replaySeeking = !0;
1375
+ try {
1376
+ this.replayManager.seekTo(e);
1377
+ } finally {
1378
+ this.replaySeeking = !1;
1379
+ }
1265
1380
  }
1266
1381
  setReplaySpeed(e) {
1267
1382
  this.replayManager.setSpeed(e);
@@ -1274,16 +1389,16 @@ var ft = 6, pt = class {
1274
1389
  }
1275
1390
  saveState(e) {
1276
1391
  if (!this.features.saveLoad) return null;
1277
- let t = _.capture({
1392
+ let t = g.capture({
1278
1393
  getDrawings: () => this.getDrawings(),
1279
1394
  getTheme: () => this.getTheme(),
1280
1395
  getAlerts: () => this.getAlerts()
1281
- }, { chartType: this.options.chartType }), n = _.serialize(t);
1282
- return e && _.saveToStorage(e, t), n;
1396
+ }, { chartType: this.options.chartType }), n = g.serialize(t);
1397
+ return e && g.saveToStorage(e, t), n;
1283
1398
  }
1284
1399
  loadState(e) {
1285
1400
  if (!this.features.saveLoad) return;
1286
- let t = _.deserialize(e);
1401
+ let t = g.deserialize(e);
1287
1402
  if (t.chartType && this.setChartType(t.chartType), t.drawings && this.setDrawings(t.drawings), t.theme && this.setTheme(t.theme), t.alerts) {
1288
1403
  this.clearAlerts();
1289
1404
  for (let e of t.alerts) this.addAlert(e.price, e.condition, e.message);
@@ -1291,28 +1406,28 @@ var ft = 6, pt = class {
1291
1406
  }
1292
1407
  loadStateFromStorage(e) {
1293
1408
  if (!this.features.saveLoad) return !1;
1294
- let t = _.loadFromStorage(e);
1295
- return t ? (this.loadState(_.serialize(t)), !0) : !1;
1409
+ let t = g.loadFromStorage(e);
1410
+ return t ? (this.loadState(g.serialize(t)), !0) : !1;
1296
1411
  }
1297
1412
  downloadState(e) {
1298
1413
  if (!this.features.saveLoad) return;
1299
- let t = _.capture({
1414
+ let t = g.capture({
1300
1415
  getDrawings: () => this.getDrawings(),
1301
1416
  getTheme: () => this.getTheme(),
1302
1417
  getAlerts: () => this.getAlerts()
1303
1418
  }, { chartType: this.options.chartType });
1304
- _.downloadFile(t, e);
1419
+ g.downloadFile(t, e);
1305
1420
  }
1306
1421
  async loadStateFromFile() {
1307
1422
  if (!this.features.saveLoad) return;
1308
- let e = await _.loadFromFile();
1309
- this.loadState(_.serialize(e));
1423
+ let e = await g.loadFromFile();
1424
+ this.loadState(g.serialize(e));
1310
1425
  }
1311
1426
  setLocale(e) {
1312
- l(e), this.engine.requestRender();
1427
+ d(e), this.engine.requestRender();
1313
1428
  }
1314
1429
  setNumberLocale(e) {
1315
- this.numberLocale = e, this.priceAxis.setLocale(e), this.crosshairHandler.setLocale(e), this.syncRenderContext(), this.engine.requestRender();
1430
+ this.numberLocale = e, this.priceAxis.setLocale(e), this.crosshairHandler.setLocale(e), this.chartLegend.setLocale(e), this.crosshairTooltip.setLocale(e), this.sessionBreaks.setLocale(e), this.currentPriceLine.setLocale(e), this.updateViewportAndRender();
1316
1431
  }
1317
1432
  getNumberLocale() {
1318
1433
  return this.numberLocale;
@@ -1330,13 +1445,13 @@ var ft = 6, pt = class {
1330
1445
  };
1331
1446
  this.themeManager.setTheme(t);
1332
1447
  }
1333
- e.pricePrecision !== void 0 && (this.tradingManager.setConfig({ pricePrecision: e.pricePrecision }), this.alertManager.setPricePrecision(e.pricePrecision), this.streamManager?.priceLine.setPricePrecision(e.pricePrecision), this.crosshairHandler.setPricePrecision(e.pricePrecision)), this.syncRenderContext(), this.engine.requestRender();
1448
+ e.pricePrecision !== void 0 && (this.tradingManager.setConfig({ pricePrecision: e.pricePrecision }), this.alertManager.setPricePrecision(e.pricePrecision), this.streamManager?.priceLine.setPricePrecision(e.pricePrecision), this.currentPriceLine.setPricePrecision(e.pricePrecision), this.crosshairHandler.setPricePrecision(e.pricePrecision), this.chartLegend.setPricePrecision(e.pricePrecision), this.crosshairTooltip.setPricePrecision(e.pricePrecision)), this.updateViewportAndRender();
1334
1449
  }
1335
1450
  getMarket() {
1336
1451
  return this.marketConfig;
1337
1452
  }
1338
1453
  setPriceLimits(e) {
1339
- this.marketConfig && (s(e, this.marketConfig) && (this.marketConfig.priceLimits = {
1454
+ this.marketConfig && (c(e, this.marketConfig) && (this.marketConfig.priceLimits = {
1340
1455
  ...this.marketConfig.priceLimits,
1341
1456
  referencePrice: e
1342
1457
  }), this.engine.requestRender());
@@ -1345,7 +1460,7 @@ var ft = 6, pt = class {
1345
1460
  return this.features;
1346
1461
  }
1347
1462
  setFeatures(e) {
1348
- Object.assign(this.features, e), e.crosshair === !1 && this.crosshairTooltip.hide(), e.grid !== void 0 && this.engine.requestRender(r.Background), e.volume !== void 0 && (this.volumeRenderer.setVisible(e.volume), this.engine.requestRender(r.Main)), e.drawings === !1 && this.drawingManager.setActiveTool(null), e.trading === !1 && (this.tradingManager.setOrders([]), this.tradingManager.setPositions([])), e.keyboard !== void 0 && this.keyboardHandler?.setEnabled(e.keyboard), this.engine.requestRender();
1463
+ Object.assign(this.features, e), (e.crosshair === !1 || e.crosshairTooltip === !1) && this.crosshairTooltip.hide(), e.grid !== void 0 && this.engine.requestRender(r.Background), e.volume !== void 0 && (this.volumeRenderer.setVisible(e.volume), this.engine.requestRender(r.Main)), e.drawings === !1 && this.drawingManager.setActiveTool(null), e.trading === !1 && (this.tradingManager.setOrders([]), this.tradingManager.setPositions([])), e.keyboard !== void 0 && this.keyboardHandler?.setEnabled(e.keyboard), this.engine.requestRender();
1349
1464
  }
1350
1465
  resize() {
1351
1466
  let e = this.engine.dprManager.readContainerSize();
@@ -1360,42 +1475,63 @@ var ft = 6, pt = class {
1360
1475
  this.countdownInterval && clearInterval(this.countdownInterval), this.disableAutoSave(), this.disconnectStream(), this.disconnectExecution(), this.onWindowKeyDown &&= (window.removeEventListener("keydown", this.onWindowKeyDown), null), this.keyboardHandler = null, this.interactionManager.detach(), this.tradingManager.destroy(), this.animator.dispose(), this.crosshairTooltip.destroy(), this.pinnedTooltip.destroy(), this.replayManager.dispose(), this.undoRedoManager.clear(), this.engine.destroy(), this.eventBus.destroy(), this.container.innerHTML = "";
1361
1476
  }
1362
1477
  createChartRenderer(e) {
1363
- return rt(e, (e) => this.pluginManager.getChartType(e));
1478
+ return lt(e, (e) => this.pluginManager.getChartType(e));
1364
1479
  }
1365
1480
  getDisplayData() {
1366
1481
  if (this.displayDataCache) return this.displayDataCache;
1367
1482
  let e = this.dataManager.getData();
1368
1483
  if (e.length === 0) return e;
1369
- let t = it(this.options.chartType, e, (e) => this.pluginManager.getChartType(e));
1484
+ let t = ut(this.options.chartType, e, (e) => this.pluginManager.getChartType(e));
1370
1485
  return this.displayDataCache = t, t;
1371
1486
  }
1372
1487
  scheduleRender() {
1373
1488
  this.renderScheduled || (this.renderScheduled = !0, requestAnimationFrame(() => {
1374
- this.renderScheduled = !1;
1375
- let e = this.getDisplayData();
1376
- this.viewport.updateData(e, this.options.autoScale !== !1), this.syncRenderContext(), this.engine.requestRender();
1489
+ this.renderScheduled = !1, this.applyDataToViewport(), this.fitPriceAxisWidth() && this.applyDataToViewport(), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
1377
1490
  }));
1378
1491
  }
1379
- updateViewportAndRender(e = !1) {
1380
- this.resolvedLayoutCache = null, this.panelInfoCache = null;
1381
- let t = this.getResolvedLayout();
1382
- this.viewport.setChartRect(t.mainChartRect);
1383
- let n = this.getDisplayData();
1384
- if (this.viewport.updateData(n, this.options.autoScale !== !1), n.length > 0) {
1385
- let e = this.viewport.getState(), t = Math.max(0, Math.min(e.visibleRange.from, n.length - 1));
1386
- this.viewport.setScaleBaseline(n[t]?.close);
1492
+ applyDataToViewport(e = !1) {
1493
+ let t = this.getDisplayData(), n = this.options.autoScale !== !1;
1494
+ this.viewport.updateData(t, n && !e), e && (this.viewport.scrollToEnd(), n && this.viewport.updateData(t, !0));
1495
+ let r = this.viewport.getState();
1496
+ if (t.length > 0) {
1497
+ let e = Math.max(0, Math.min(r.visibleRange.from, t.length - 1));
1498
+ this.viewport.setScaleBaseline(t[e]?.close);
1387
1499
  }
1388
- if (this.options.autoScale !== !1) {
1389
- let e = this.viewport.getState(), t = this.indicatorEngine.getOverlayPriceRange(e.visibleRange.from, Math.min(e.visibleRange.to, n.length - 1));
1390
- if (t) {
1391
- let n = e.priceRange, r = Math.min(n.min, t.min), i = Math.max(n.max, t.max);
1392
- if (r < n.min || i > n.max) {
1393
- let e = i - r || 1;
1394
- this.viewport.setPriceRange(r - e * .02, i + e * .02);
1500
+ if (n) {
1501
+ let e = this.indicatorEngine.getOverlayPriceRange(r.visibleRange.from, Math.min(r.visibleRange.to, t.length - 1));
1502
+ if (e) {
1503
+ let t = r.priceRange, n = Math.min(t.min, e.min), i = Math.max(t.max, e.max);
1504
+ if (n < t.min || i > t.max) {
1505
+ let e = i - n || 1;
1506
+ this.viewport.setPriceRange(n - e * .02, i + e * .02);
1395
1507
  }
1396
1508
  }
1397
1509
  }
1398
- e && this.viewport.scrollToEnd(), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
1510
+ return t;
1511
+ }
1512
+ updateViewportAndRender(e = !1) {
1513
+ this.resolvedLayoutCache = null, this.panelInfoCache = null;
1514
+ let t = this.getResolvedLayout();
1515
+ this.viewport.setChartRect(t.mainChartRect), this.applyDataToViewport(e), this.fitPriceAxisWidth() && this.applyDataToViewport(e), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
1516
+ }
1517
+ fitPriceAxisWidth() {
1518
+ if (!this.features.priceAxis) return !1;
1519
+ let { priceRange: e } = this.viewport.getState(), t = this.themeManager.getTheme(), n = _t({
1520
+ min: e.min,
1521
+ max: e.max,
1522
+ lastPrice: this.currentPriceLine.getPrice(),
1523
+ tagPrecision: this.marketConfig?.pricePrecision ?? null,
1524
+ locale: this.numberLocale,
1525
+ fontFamily: t.font.family,
1526
+ fontSizeSmall: t.font.sizeSmall,
1527
+ measure: (e, t) => this.measureText(e, t)
1528
+ }), r = vt(this.priceAxisWidth, n);
1529
+ return r === this.priceAxisWidth ? !1 : (this.priceAxisWidth = r, this.layoutManager.setPriceAxisWidth(r), this.viewport.setPriceAxisWidth(r), this.resolvedLayoutCache = null, this.panelInfoCache = null, this.viewport.setChartRect(this.getResolvedLayout().mainChartRect), !0);
1530
+ }
1531
+ measureText(e, t) {
1532
+ this.measureCtx === void 0 && (this.measureCtx = typeof document < "u" ? document.createElement("canvas").getContext("2d") : null);
1533
+ let n = this.measureCtx;
1534
+ return n ? (n.font = t, n.measureText(e).width) : e.length * 7;
1399
1535
  }
1400
1536
  emitViewportEvents() {
1401
1537
  let e = this.viewport.getState(), t = Math.max(0, Math.floor(e.visibleRange.from)), n = Math.max(t, Math.ceil(e.visibleRange.to));
@@ -1425,7 +1561,7 @@ var ft = 6, pt = class {
1425
1561
  buildPanelRenderInfos() {
1426
1562
  if (this.panelInfoCache) return this.panelInfoCache;
1427
1563
  let e = this.getResolvedLayout(), t = this.viewport.getState(), { from: n, to: r } = t.visibleRange, i = e.panels.map((e) => {
1428
- let i = at(this.indicatorEngine.getOutput(e.config.id), n, r), a = {
1564
+ let i = dt(this.indicatorEngine.getOutput(e.config.id), n, r), a = {
1429
1565
  x: e.rect.x,
1430
1566
  y: e.rect.y + 20,
1431
1567
  width: e.rect.width,
@@ -1455,7 +1591,7 @@ var ft = 6, pt = class {
1455
1591
  indicatorEngine: this.features.indicators ? this.indicatorEngine : null,
1456
1592
  drawingRenderer: this.features.drawings ? this.drawingRenderer : null,
1457
1593
  tradingRenderer: this.features.trading ? this.tradingRenderer : null,
1458
- currentPriceLine: this.streamManager?.priceLine ?? this.currentPriceLine,
1594
+ currentPriceLine: this.currentPriceLine,
1459
1595
  chartLegend: this.features.legend ? this.chartLegend : null,
1460
1596
  volumeRenderer: this.features.volume ? this.volumeRenderer : null,
1461
1597
  volumeProfile: this.volumeProfile,
@@ -1470,6 +1606,7 @@ var ft = 6, pt = class {
1470
1606
  compareRenderer: this.compareRenderer,
1471
1607
  alertManager: this.features.alerts ? this.alertManager : null,
1472
1608
  measureOverlay: this.measureOverlay,
1609
+ selectionBoxOverlay: this.selectionBoxOverlay,
1473
1610
  signalMarkerManager: this.signalMarkerManager,
1474
1611
  tradeZoneManager: this.tradeZoneManager,
1475
1612
  panels: t,
@@ -1497,7 +1634,7 @@ var ft = 6, pt = class {
1497
1634
  }
1498
1635
  buildPriceLimits() {
1499
1636
  if (!this.marketConfig?.priceLimits?.enabled || !this.marketConfig.priceLimits.referencePrice) return null;
1500
- let e = s(this.marketConfig.priceLimits.referencePrice, this.marketConfig);
1637
+ let e = c(this.marketConfig.priceLimits.referencePrice, this.marketConfig);
1501
1638
  return e ? {
1502
1639
  ...e,
1503
1640
  colors: this.marketConfig.colorScheme ? {
@@ -1520,13 +1657,13 @@ var ft = 6, pt = class {
1520
1657
  ];
1521
1658
  function q(e) {
1522
1659
  let t = e.trim();
1523
- return t ? t[0] === "[" || t[0] === "{" ? mt(t) : ht(t) : {
1660
+ return t ? t[0] === "[" || t[0] === "{" ? Et(t) : Dt(t) : {
1524
1661
  data: [],
1525
1662
  rowCount: 0,
1526
1663
  skipped: 0
1527
1664
  };
1528
1665
  }
1529
- function mt(e) {
1666
+ function Et(e) {
1530
1667
  let t;
1531
1668
  try {
1532
1669
  t = JSON.parse(e);
@@ -1536,19 +1673,19 @@ function mt(e) {
1536
1673
  if (!Array.isArray(t)) throw Error("Expected a JSON array of OHLCV rows");
1537
1674
  let n = [], r = 0;
1538
1675
  for (let e of t) {
1539
- let t = Array.isArray(e) ? yt(e) : vt(e);
1676
+ let t = Array.isArray(e) ? At(e) : Y(e);
1540
1677
  t ? n.push(t) : r++;
1541
1678
  }
1542
- return Z(n, t.length, r);
1679
+ return Q(n, t.length, r);
1543
1680
  }
1544
- function ht(e) {
1681
+ function Dt(e) {
1545
1682
  let t = e.split(/\r?\n/).filter((e) => e.trim().length > 0);
1546
1683
  if (t.length === 0) return {
1547
1684
  data: [],
1548
1685
  rowCount: 0,
1549
1686
  skipped: 0
1550
1687
  };
1551
- let n = gt(t[0]), r = J(t[0], n).map((e) => e.trim().toLowerCase()), i = r.some((e) => isNaN(Number(e)) && e.length > 0), a = i ? _t(r) : {
1688
+ let n = Ot(t[0]), r = J(t[0], n).map((e) => e.trim().toLowerCase()), i = r.some((e) => isNaN(Number(e)) && e.length > 0), a = i ? kt(r) : {
1552
1689
  time: 0,
1553
1690
  open: 1,
1554
1691
  high: 2,
@@ -1559,7 +1696,7 @@ function ht(e) {
1559
1696
  if (a.time < 0 || a.open < 0 || a.high < 0 || a.low < 0 || a.close < 0) throw Error("CSV is missing required column(s): time, open, high, low, close");
1560
1697
  let o = [], s = 0;
1561
1698
  for (let e = +!!i; e < t.length; e++) {
1562
- let r = J(t[e], n), i = X(r[a.time]), c = Y(r[a.open]), l = Y(r[a.high]), u = Y(r[a.low]), d = Y(r[a.close]), f = a.volume >= 0 ? Number(r[a.volume]) : 0;
1699
+ let r = J(t[e], n), i = Z(r[a.time]), c = X(r[a.open]), l = X(r[a.high]), u = X(r[a.low]), d = X(r[a.close]), f = a.volume >= 0 ? Number(r[a.volume]) : 0;
1563
1700
  if (i === null || ![
1564
1701
  c,
1565
1702
  l,
@@ -1578,9 +1715,9 @@ function ht(e) {
1578
1715
  volume: Number.isFinite(f) ? f : 0
1579
1716
  });
1580
1717
  }
1581
- return Z(o, t.length - +!!i, s);
1718
+ return Q(o, t.length - +!!i, s);
1582
1719
  }
1583
- function gt(e) {
1720
+ function Ot(e) {
1584
1721
  let t = {
1585
1722
  ",": 0,
1586
1723
  ";": 0,
@@ -1600,7 +1737,7 @@ function J(e, t) {
1600
1737
  }
1601
1738
  return n.push(r), n;
1602
1739
  }
1603
- function _t(e) {
1740
+ function kt(e) {
1604
1741
  let t = (t) => e.findIndex((e) => t.includes(e));
1605
1742
  return {
1606
1743
  time: t(V),
@@ -1611,14 +1748,14 @@ function _t(e) {
1611
1748
  volume: t(K)
1612
1749
  };
1613
1750
  }
1614
- function vt(e) {
1751
+ function Y(e) {
1615
1752
  let t = (t) => {
1616
1753
  for (let n of t) {
1617
1754
  if (e[n] !== void 0) return e[n];
1618
1755
  let t = n.toUpperCase();
1619
1756
  if (e[t] !== void 0) return e[t];
1620
1757
  }
1621
- }, n = X(String(t(V) ?? "")), r = Number(t(H)), i = Number(t(U)), a = Number(t(W)), o = Number(t(G)), s = Number(t(K) ?? 0);
1758
+ }, n = Z(String(t(V) ?? "")), r = Number(t(H)), i = Number(t(U)), a = Number(t(W)), o = Number(t(G)), s = Number(t(K) ?? 0);
1622
1759
  return n === null || ![
1623
1760
  r,
1624
1761
  i,
@@ -1633,9 +1770,9 @@ function vt(e) {
1633
1770
  volume: Number.isFinite(s) ? s : 0
1634
1771
  };
1635
1772
  }
1636
- function yt(e) {
1773
+ function At(e) {
1637
1774
  if (e.length < 5) return null;
1638
- let t = X(String(e[0])), n = Number(e[1]), r = Number(e[2]), i = Number(e[3]), a = Number(e[4]), o = e.length >= 6 ? Number(e[5]) : 0;
1775
+ let t = Z(String(e[0])), n = Number(e[1]), r = Number(e[2]), i = Number(e[3]), a = Number(e[4]), o = e.length >= 6 ? Number(e[5]) : 0;
1639
1776
  return t === null || ![
1640
1777
  n,
1641
1778
  r,
@@ -1650,10 +1787,10 @@ function yt(e) {
1650
1787
  volume: Number.isFinite(o) ? o : 0
1651
1788
  };
1652
1789
  }
1653
- function Y(e) {
1790
+ function X(e) {
1654
1791
  return e === void 0 || e.trim() === "" ? NaN : Number(e);
1655
1792
  }
1656
- function X(e) {
1793
+ function Z(e) {
1657
1794
  let t = e.trim();
1658
1795
  if (!t) return null;
1659
1796
  let n = Number(t);
@@ -1661,7 +1798,7 @@ function X(e) {
1661
1798
  let r = Date.parse(t);
1662
1799
  return Number.isFinite(r) ? r : null;
1663
1800
  }
1664
- function Z(e, t, n) {
1801
+ function Q(e, t, n) {
1665
1802
  e.sort((e, t) => e.time - t.time);
1666
1803
  let r = [];
1667
1804
  for (let t of e) r.length > 0 && r[r.length - 1].time === t.time ? r[r.length - 1] = t : r.push(t);
@@ -1673,7 +1810,7 @@ function Z(e, t, n) {
1673
1810
  }
1674
1811
  //#endregion
1675
1812
  //#region src/io/DragDropImporter.ts
1676
- var Q = class {
1813
+ var jt = class {
1677
1814
  host;
1678
1815
  overlay = null;
1679
1816
  callbacks;
@@ -1720,12 +1857,12 @@ var Q = class {
1720
1857
  zIndex: "90",
1721
1858
  pointerEvents: "none",
1722
1859
  borderRadius: "10px",
1723
- border: "2px dashed var(--tcw-accent, #4f88ff)",
1860
+ border: "2px dashed var(--tcw-accent, #f2a93b)",
1724
1861
  background: "rgba(79, 136, 255, 0.06)",
1725
1862
  display: "flex",
1726
1863
  alignItems: "center",
1727
1864
  justifyContent: "center",
1728
- color: "var(--tcw-accent, #4f88ff)",
1865
+ color: "var(--tcw-accent, #f2a93b)",
1729
1866
  fontSize: "14px",
1730
1867
  fontWeight: "600",
1731
1868
  letterSpacing: "-0.005em",
@@ -1741,6 +1878,6 @@ function $(e) {
1741
1878
  return e.dataTransfer?.types?.includes("Files") ?? !1;
1742
1879
  }
1743
1880
  //#endregion
1744
- export { ut as a, lt as c, I as d, P as f, z as i, st as l, A as m, q as n, R as o, j as p, pt as r, ct as s, Q as t, F as u };
1881
+ export { Ct as a, St as c, I as d, N as f, z as i, bt as l, k as m, q as n, R as o, A as p, Tt as r, xt as s, jt as t, F as u };
1745
1882
 
1746
- //# sourceMappingURL=DragDropImporter-CLtRQjKD.js.map
1883
+ //# sourceMappingURL=DragDropImporter-cURSpfUb.js.map