@tradecanvas/chart 1.2.0 → 1.4.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 (74) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +858 -824
  3. package/dist/Chart.d.ts +142 -2
  4. package/dist/Chart.d.ts.map +1 -1
  5. package/dist/DragDropImporter-C5kgfbET.cjs +2 -0
  6. package/dist/DragDropImporter-C5kgfbET.cjs.map +1 -0
  7. package/dist/{DragDropImporter-BcTzFeRP.js → DragDropImporter-Dd9Mud5J.js} +423 -159
  8. package/dist/DragDropImporter-Dd9Mud5J.js.map +1 -0
  9. package/dist/PaneManager.d.ts.map +1 -1
  10. package/dist/charts/ChartTypeStrategy.d.ts +6 -0
  11. package/dist/charts/ChartTypeStrategy.d.ts.map +1 -1
  12. package/dist/grid/ChartGrid.d.ts +1 -0
  13. package/dist/grid/ChartGrid.d.ts.map +1 -1
  14. package/dist/index.cjs +1 -1
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.ts +5 -2
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +74 -89
  19. package/dist/index.js.map +1 -1
  20. package/dist/interaction/verticalPanGate.d.ts +22 -0
  21. package/dist/interaction/verticalPanGate.d.ts.map +1 -0
  22. package/dist/widget/ChartWidget.d.ts +71 -7
  23. package/dist/widget/ChartWidget.d.ts.map +1 -1
  24. package/dist/widget/WidgetCommandPalette.d.ts +3 -1
  25. package/dist/widget/WidgetCommandPalette.d.ts.map +1 -1
  26. package/dist/widget/WidgetDrawingSidebar.d.ts +12 -0
  27. package/dist/widget/WidgetDrawingSidebar.d.ts.map +1 -1
  28. package/dist/widget/WidgetGoToDate.d.ts +45 -0
  29. package/dist/widget/WidgetGoToDate.d.ts.map +1 -0
  30. package/dist/widget/WidgetHotkeySheet.d.ts +4 -2
  31. package/dist/widget/WidgetHotkeySheet.d.ts.map +1 -1
  32. package/dist/widget/WidgetIndicatorLegend.d.ts +68 -0
  33. package/dist/widget/WidgetIndicatorLegend.d.ts.map +1 -0
  34. package/dist/widget/WidgetLoadingOverlay.d.ts +3 -1
  35. package/dist/widget/WidgetLoadingOverlay.d.ts.map +1 -1
  36. package/dist/widget/WidgetObjectTree.d.ts +1 -1
  37. package/dist/widget/WidgetReplayBar.d.ts +37 -7
  38. package/dist/widget/WidgetReplayBar.d.ts.map +1 -1
  39. package/dist/widget/WidgetSettings.d.ts +13 -1
  40. package/dist/widget/WidgetSettings.d.ts.map +1 -1
  41. package/dist/widget/WidgetStatusBar.d.ts +16 -1
  42. package/dist/widget/WidgetStatusBar.d.ts.map +1 -1
  43. package/dist/widget/WidgetSymbolSearch.d.ts +3 -1
  44. package/dist/widget/WidgetSymbolSearch.d.ts.map +1 -1
  45. package/dist/widget/WidgetToolbar.d.ts +12 -3
  46. package/dist/widget/WidgetToolbar.d.ts.map +1 -1
  47. package/dist/widget/WidgetTooltip.d.ts +43 -0
  48. package/dist/widget/WidgetTooltip.d.ts.map +1 -0
  49. package/dist/widget/escapeHtml.d.ts +3 -0
  50. package/dist/widget/escapeHtml.d.ts.map +1 -0
  51. package/dist/widget/i18n.d.ts +26 -0
  52. package/dist/widget/i18n.d.ts.map +1 -1
  53. package/dist/widget/iconSet.d.ts +26 -0
  54. package/dist/widget/iconSet.d.ts.map +1 -0
  55. package/dist/widget/icons.d.ts +5 -0
  56. package/dist/widget/icons.d.ts.map +1 -1
  57. package/dist/widget/index.cjs +3035 -2465
  58. package/dist/widget/index.cjs.map +1 -1
  59. package/dist/widget/index.d.ts +3 -0
  60. package/dist/widget/index.d.ts.map +1 -1
  61. package/dist/widget/index.js +1636 -606
  62. package/dist/widget/index.js.map +1 -1
  63. package/dist/widget/legendValues.d.ts +14 -0
  64. package/dist/widget/legendValues.d.ts.map +1 -0
  65. package/dist/widget/types.d.ts +34 -8
  66. package/dist/widget/types.d.ts.map +1 -1
  67. package/dist/widget/widgetConfig.d.ts +1 -5
  68. package/dist/widget/widgetConfig.d.ts.map +1 -1
  69. package/dist/widget/widgetTimeframes.d.ts +20 -0
  70. package/dist/widget/widgetTimeframes.d.ts.map +1 -0
  71. package/package.json +3 -3
  72. package/dist/DragDropImporter-BcTzFeRP.js.map +0 -1
  73. package/dist/DragDropImporter-DZBrretS.cjs +0 -2
  74. package/dist/DragDropImporter-DZBrretS.cjs.map +0 -1
@@ -1,7 +1,7 @@
1
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 y, RenkoRenderer as b, ReplayManager as x, Screenshot as S, SessionBreaks as Ne, SessionShading as Pe, SignalMarkerManager as Fe, StepLineRenderer as Ie, StreamManager as Le, TimeAxis as Re, TradeZoneManager as ze, TradingManager as Be, TradingRenderer as Ve, UndoRedoManager as He, Viewport as Ue, VolumeCandleRenderer as We, VolumeProfileRenderer as Ge, VolumeRenderer as Ke, Watermark as qe, ZoomHandler as Je, findDominantSwing as Ye, registerBuiltInDrawingTools as Xe, registerBuiltInIndicators as C, toHeikinAshi as Ze, toKagi as Qe, toLineBreak as $e, toPointAndFigure as et, toRangeBars as tt, toRenko as nt, xToBarIndex as rt } from "@tradecanvas/core";
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, barTimeStepMs as Ze, findDominantSwing as Qe, rangePresetStart as $e, registerBuiltInDrawingTools as et, registerBuiltInIndicators as S, timestampToBarIndex as C, toHeikinAshi as tt, toKagi as nt, toLineBreak as rt, toPointAndFigure as it, toRangeBars as at, toRenko as ot, xToBarIndex as st } from "@tradecanvas/core";
3
3
  //#region src/charts/ChartTypeStrategy.ts
4
- function w(e) {
4
+ function ct(e) {
5
5
  switch (e) {
6
6
  case "candlestick":
7
7
  case "heikinAshi":
@@ -12,46 +12,60 @@ function w(e) {
12
12
  case "bar": return new ie();
13
13
  case "hollowCandle": return new ve();
14
14
  case "baseline": return new ae();
15
- case "renko": return new b();
15
+ case "renko": return new y();
16
16
  case "kagi": return new be();
17
17
  case "pointAndFigure": return new je();
18
- case "volumeCandles": return new We();
18
+ case "volumeCandles": return new Ke();
19
19
  case "equivolume": return new me();
20
20
  case "hlcArea": return new _e();
21
- case "stepLine": return new Ie();
21
+ case "stepLine": return new Re();
22
22
  case "lineWithMarkers": return new Ce();
23
23
  default: return new h();
24
24
  }
25
25
  }
26
- function it(e, t) {
26
+ function lt(e, t) {
27
27
  if (t.length === 0) return t;
28
28
  switch (e) {
29
- case "heikinAshi": return Ze(t);
30
- case "renko": return nt(t, {
29
+ case "heikinAshi": return tt(t);
30
+ case "renko": return ot(t, {
31
31
  brickSize: 0,
32
32
  useATR: !0,
33
33
  atrPeriod: 14
34
34
  });
35
- case "lineBreak": return $e(t, 3);
36
- case "kagi": return Qe(t, 4);
37
- case "pointAndFigure": return et(t, T(t) * .01, 3);
38
- case "rangeBars": return tt(t, { rangeSize: T(t) * .005 });
35
+ case "lineBreak": return rt(t, 3);
36
+ case "kagi": return nt(t, 4);
37
+ case "pointAndFigure": return it(t, T(t) * .01, 3);
38
+ case "rangeBars": return at(t, { rangeSize: T(t) * .005 });
39
39
  default: return t;
40
40
  }
41
41
  }
42
+ function w(e) {
43
+ switch (e) {
44
+ case "heikinAshi":
45
+ case "renko":
46
+ case "lineBreak":
47
+ case "kagi":
48
+ case "pointAndFigure":
49
+ case "rangeBars": return !0;
50
+ default: return !1;
51
+ }
52
+ }
53
+ function ut(e) {
54
+ return e !== "heikinAshi" && w(e);
55
+ }
42
56
  function T(e) {
43
57
  let t = 0;
44
58
  for (let n of e) t += n.close;
45
59
  return t / e.length;
46
60
  }
47
- function at(e, t) {
61
+ function dt(e, t) {
48
62
  let n = t?.(e);
49
- return n ? n.createRenderer() : w(e);
63
+ return n ? n.createRenderer() : ct(e);
50
64
  }
51
- function ot(e, t, n) {
65
+ function ft(e, t, n) {
52
66
  if (t.length === 0) return t;
53
67
  let r = n?.(e);
54
- return r?.transform ? r.transform(t) : it(e, t);
68
+ return r?.transform ? r.transform(t) : lt(e, t);
55
69
  }
56
70
  //#endregion
57
71
  //#region src/charts/IndicatorPriceRange.ts
@@ -59,7 +73,7 @@ var E = {
59
73
  min: 0,
60
74
  max: 100
61
75
  }, D = .1;
62
- function st(e, t, n) {
76
+ function pt(e, t, n) {
63
77
  if (!e) return { ...E };
64
78
  let r = Infinity, i = -Infinity;
65
79
  if (e.series) {
@@ -90,7 +104,7 @@ function st(e, t, n) {
90
104
  }
91
105
  //#endregion
92
106
  //#region src/state/AutoSaveScheduler.ts
93
- var ct = class {
107
+ var mt = class {
94
108
  timer = null;
95
109
  delayMs = 0;
96
110
  key = null;
@@ -125,7 +139,7 @@ function O(e) {
125
139
  let { open: t, high: n, low: r, close: i } = e;
126
140
  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));
127
141
  }
128
- function lt(e) {
142
+ function ht(e) {
129
143
  return e.volume !== void 0 && e.high >= e.open && e.high >= e.close && e.low <= e.open && e.low <= e.close;
130
144
  }
131
145
  function k(e) {
@@ -145,7 +159,7 @@ var A = class {
145
159
  let t = [];
146
160
  for (let n = 0; n < e.length; n++) {
147
161
  let r = e[n];
148
- O(r) && t.push(lt(r) ? r : k(r));
162
+ O(r) && t.push(ht(r) ? r : k(r));
149
163
  }
150
164
  this.data = t;
151
165
  }
@@ -313,8 +327,8 @@ var A = class {
313
327
  getMainChartRect() {
314
328
  return this.resolve().mainChartRect;
315
329
  }
316
- }, ut = 14, dt = 14, ft = 22, F = 4;
317
- function pt(e) {
330
+ }, gt = 14, _t = 14, vt = 22, F = 4;
331
+ function yt(e) {
318
332
  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
333
  t,
320
334
  n,
@@ -323,16 +337,30 @@ function pt(e) {
323
337
  for (let e of p) {
324
338
  if (!Number.isFinite(e)) continue;
325
339
  let t = l(e, d, i), n = l(e, f, i);
326
- m = Math.max(m, u(t, `500 ${c}px ${o}`) + ut, u(n, `bold 11px ${o}`) + dt, u(n, `600 ${c}px ${o}`) + ft);
340
+ m = Math.max(m, u(t, `500 ${c}px ${o}`) + gt, u(n, `bold 11px ${o}`) + _t, u(n, `600 ${c}px ${o}`) + vt);
327
341
  }
328
342
  return m <= a ? a : Math.ceil(m / F) * F;
329
343
  }
330
- function mt(e, t) {
344
+ function bt(e, t) {
331
345
  return t > e || t <= e - 12 ? t : e;
332
346
  }
333
- //#endregion
334
- //#region src/plugins/contracts.ts
335
- var ht = 1;
347
+ var xt = class {
348
+ netY = 0;
349
+ travelX = 0;
350
+ engaged = !1;
351
+ reset() {
352
+ this.netY = 0, this.travelX = 0, this.engaged = !1;
353
+ }
354
+ step(e, t, n) {
355
+ if (this.engaged) return !0;
356
+ if (this.netY += t, this.travelX += Math.abs(e), !n) this.engaged = !0;
357
+ else {
358
+ let e = Math.abs(this.netY);
359
+ this.engaged = e > 24 && e >= this.travelX * .5;
360
+ }
361
+ return this.engaged;
362
+ }
363
+ }, St = 1;
336
364
  function I(e, t) {
337
365
  return e.filter((e) => (e.descriptor.layer ?? "overlay") === t);
338
366
  }
@@ -347,16 +375,16 @@ function L(e) {
347
375
  //#endregion
348
376
  //#region src/plugins/registry.ts
349
377
  var R = /* @__PURE__ */ new Map();
350
- function gt(e) {
378
+ function Ct(e) {
351
379
  R.set(L(e), e);
352
380
  }
353
- function _t(e) {
381
+ function wt(e) {
354
382
  return R.delete(e);
355
383
  }
356
384
  function z() {
357
385
  return [...R.values()];
358
386
  }
359
- function vt() {
387
+ function Tt() {
360
388
  R.clear();
361
389
  }
362
390
  //#endregion
@@ -401,7 +429,7 @@ var B = class {
401
429
  positionModify: (e, t) => e.modifyPosition(t),
402
430
  positionClose: (e, t) => e.closePosition(t)
403
431
  };
404
- function yt(e, t) {
432
+ function Et(e, t) {
405
433
  let n = [], r = (e) => t.setOrders(e.data ?? []), i = (e) => t.setPositions(e.data ?? []), a = (e) => t.onError(e.data ?? { message: "Execution error" });
406
434
  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));
407
435
  for (let r of Object.keys(V)) {
@@ -419,8 +447,8 @@ function yt(e, t) {
419
447
  }
420
448
  //#endregion
421
449
  //#region src/Chart.ts
422
- var bt = 6, xt = class {
423
- static version = "1.2.0";
450
+ var Dt = 0xe8d4a51000, Ot = class {
451
+ static version = "1.4.0";
424
452
  engine;
425
453
  viewport;
426
454
  dataManager;
@@ -438,6 +466,7 @@ var bt = 6, xt = class {
438
466
  execTeardown = null;
439
467
  autoScrollOnNewBar = !0;
440
468
  displayDataCache = null;
469
+ indicatorUpdateFrom = null;
441
470
  resolvedLayoutCache = null;
442
471
  panelInfoCache = null;
443
472
  renderScheduled = !1;
@@ -451,6 +480,8 @@ var bt = 6, xt = class {
451
480
  chartLegend;
452
481
  watermark;
453
482
  barCountdown;
483
+ unrestoredIndicators = [];
484
+ displayTzOffset = null;
454
485
  sessionBreaks;
455
486
  sessionShading;
456
487
  compareRenderer;
@@ -465,10 +496,13 @@ var bt = 6, xt = class {
465
496
  signalMarkerManager;
466
497
  tradeZoneManager;
467
498
  measureOverlay;
499
+ selectionBoxOverlay = new Pe();
468
500
  replayManager;
469
501
  replayBarUnsub = null;
502
+ replaySeeking = !1;
503
+ replaySession = null;
470
504
  undoRedoManager;
471
- autoSaveScheduler = new ct((e) => this.saveState(e));
505
+ autoSaveScheduler = new mt((e) => this.saveState(e));
472
506
  animator;
473
507
  crosshairTooltip;
474
508
  pinnedTooltip;
@@ -484,6 +518,8 @@ var bt = 6, xt = class {
484
518
  container;
485
519
  currentPriceLine;
486
520
  numberLocale;
521
+ marketPricePrecision = null;
522
+ paneTitles = !0;
487
523
  defaultAutoScale;
488
524
  keyboardHandler = null;
489
525
  onWindowKeyDown = null;
@@ -497,7 +533,7 @@ var bt = 6, xt = class {
497
533
  drawingMagnet: n.drawingMagnet ?? !0,
498
534
  drawingUndoRedo: n.drawingUndoRedo ?? !0,
499
535
  trading: n.trading ?? !0,
500
- tradingContextMenu: n.tradingContextMenu ?? !0,
536
+ tradingContextMenu: n.tradingContextMenu ?? !1,
501
537
  indicators: n.indicators ?? !0,
502
538
  indicatorIds: n.indicatorIds ?? [],
503
539
  panning: n.panning ?? !0,
@@ -522,36 +558,46 @@ var bt = 6, xt = class {
522
558
  logScale: n.logScale ?? !0,
523
559
  timeframes: n.timeframes ?? [],
524
560
  defaultTimeframeFavorites: n.defaultTimeframeFavorites ?? []
525
- }, 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 v(), this.pluginManager = new B(this.indicatorEngine, { plugins: t.plugins }), this.eventBus = new he(), C(this.indicatorEngine), this.drawingManager = new fe(), Xe(this.drawingManager), this.drawingRenderer = new pe(this.drawingManager), this.drawingManager.setRequestRender(() => {
561
+ }, 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 v(), this.pluginManager = new B(this.indicatorEngine, { plugins: t.plugins }), this.eventBus = new he(), S(this.indicatorEngine), this.drawingManager = new fe(), et(this.drawingManager), this.drawingRenderer = new pe(this.drawingManager), this.drawingManager.setRequestRender(() => {
526
562
  this.syncRenderContext(), this.engine.requestRender(r.Overlay), this.scheduleAutoSave();
527
563
  }), this.drawingManager.setEventCallback((e, t) => {
528
564
  this.eventBus.emit(e, t);
529
- }), this.undoRedoManager = new He(), 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 Be({
565
+ }), this.drawingManager.setToolFilter((e) => this.features.drawings && (this.features.drawingTools.length === 0 || this.features.drawingTools.includes(e))), 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.features.drawingMagnet && this.drawingManager.setMagnetMode("magnet"), this.tradingManager = new He({
530
566
  enabled: this.features.trading,
531
567
  contextMenu: { enabled: this.features.tradingContextMenu }
532
- }), this.tradingRenderer = new Ve(this.tradingManager), this.tradingManager.setContainer(e), this.tradingManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradingManager.setEventCallback((e, t) => {
568
+ }), this.tradingRenderer = new Ue(this.tradingManager), this.tradingManager.setContainer(e), this.tradingManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradingManager.setEventCallback((e, t) => {
533
569
  this.eventBus.emit(e, t);
534
- }), this.engine = new y(e);
570
+ }), this.engine = new Ne(e);
535
571
  let i = this.engine.dprManager.getContainerSize();
536
- if (this.viewport = new Ue(i.width, i.height, t.minBarSpacing ?? 2, t.maxBarSpacing ?? 30, t.rightMargin ?? 5), this.layoutManager.resize(i.width, i.height), this.engine.onContainerResize = (e) => {
572
+ if (this.viewport = new Ge(i.width, i.height, t.minBarSpacing ?? 2, t.maxBarSpacing ?? 30, t.rightMargin ?? 5), this.viewport.setPanLimits({
573
+ freePan: t.freePan ?? !0,
574
+ minVisibleBars: t.panLimits?.minVisibleBars ?? 3
575
+ }), this.layoutManager.resize(i.width, i.height), this.engine.onContainerResize = (e) => {
537
576
  if (e.width <= 0 || e.height <= 0) return;
538
577
  let t = this.viewport.isAtEnd();
539
578
  this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(t);
540
- }, 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 Re(), this.crosshairHandler = new ce(), this.crosshairHandler.setLocale(this.numberLocale), t.crosshair?.mode && this.crosshairHandler.setMode(t.crosshair.mode), this.crosshairHandler.setCallback((e, t) => {
579
+ }, 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) => {
541
580
  if (e !== null && t) {
542
581
  let n = this.dataManager.getData(), r = e < n.length ? n[e] : void 0;
543
- this.chartLegend.setHoverBar(r ?? null), r && this.features.crosshairTooltip && 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", {
582
+ this.chartLegend.setHoverBar(r ?? null);
583
+ let i = this.viewport.getState(), a = t.y >= i.chartRect.y && t.y <= i.chartRect.y + i.chartRect.height;
584
+ r && a && this.features.crosshairTooltip ? this.crosshairTooltip.show(t, r, this.themeManager.getTheme(), this.cachedContainerSize(), {
585
+ prevClose: e > 0 ? n[e - 1]?.close : void 0,
586
+ priceRange: i.priceRange,
587
+ plot: i.chartRect,
588
+ barStepMs: Ze(n)
589
+ }) : this.crosshairTooltip.hide(), this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), r ?? null, e, this.themeManager.getTheme()), this.eventBus.emit("crosshairMove", {
544
590
  point: t,
545
591
  bar: r,
546
592
  barIndex: e
547
593
  });
548
- } else this.crosshairTooltip.hide(), this.chartLegend.setHoverBar(null);
549
- }), this.chartLegend = new oe(), this.chartLegend.setChartType(t.chartType), this.chartLegend.setLocale(this.numberLocale), this.watermark = new qe(), t.watermark && this.watermark.setConfig(t.watermark), this.volumeRenderer = new Ke(), this.volumeProfile = new Ge(), this.marketProfile = new we(), this.depthHeatmap = new de(), this.periodLevels = new Oe(), this.pivotMarkers = new Ae(), this.barCountdown = new re(), this.sessionBreaks = new Ne(), this.sessionBreaks.setLocale(this.numberLocale), this.sessionShading = new Pe(), this.compareRenderer = new se(), t.sessionBreaks ? this.sessionBreaks.setConfig({
594
+ } else this.crosshairTooltip.hide(), this.chartLegend.setHoverBar(null), this.eventBus.emit("crosshairLeave", {});
595
+ }), 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.barCountdown.setVisible(this.features.barCountdown), this.sessionBreaks = new Fe(), this.sessionBreaks.setLocale(this.numberLocale), this.sessionShading = new Ie(), this.compareRenderer = new se(), t.sessionBreaks ? this.sessionBreaks.setConfig({
550
596
  visible: t.sessionBreaks.visible ?? !0,
551
597
  color: t.sessionBreaks.color,
552
598
  lineStyle: t.sessionBreaks.lineStyle,
553
599
  lineWidth: t.sessionBreaks.lineWidth
554
- }) : 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.pinnedTooltip = new ke(), this.pinnedTooltip.create(e), this.keyboardHandler = new xe({
600
+ }) : t.features?.sessionBreaks !== !1 && this.sessionBreaks.setVisible(!0), t.logScale && this.features.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({
555
601
  scrollBars: (e) => {
556
602
  let t = this.viewport.getState().barWidth + this.viewport.getState().barSpacing;
557
603
  this.viewport.scrollBy(e * t), this.updateViewportAndRender();
@@ -571,7 +617,7 @@ var bt = 6, xt = class {
571
617
  if (!this.keyboardHandler) return;
572
618
  let t = document.activeElement;
573
619
  t && t !== this.container && !this.container.contains(t) || t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable) || this.keyboardHandler.handleKey(e) && e.preventDefault();
574
- }, window.addEventListener("keydown", this.onWindowKeyDown), this.currentPriceLine = new ue(), this.currentPriceLine.setLocale(this.numberLocale), this.alertManager = new m(), this.alertManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.alertManager.on("triggered", (e) => {
620
+ }, 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) => {
575
621
  let t = {
576
622
  id: e.id,
577
623
  price: e.price,
@@ -603,7 +649,7 @@ var bt = 6, xt = class {
603
649
  message: e.message,
604
650
  triggered: e.triggered
605
651
  });
606
- }), this.signalMarkerManager = new Fe(), this.signalMarkerManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.signalMarkerManager.setDataGetter(() => this.dataManager.getData()), this.signalMarkerManager.on("added", (e) => {
652
+ }), this.signalMarkerManager = new Le(), this.signalMarkerManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.signalMarkerManager.setDataGetter(() => this.dataManager.getData()), this.signalMarkerManager.on("added", (e) => {
607
653
  this.eventBus.emit("signalMarkerAdd", {
608
654
  id: e.id,
609
655
  source: e.source,
@@ -611,23 +657,21 @@ var bt = 6, xt = class {
611
657
  });
612
658
  }), this.signalMarkerManager.on("removed", (e) => {
613
659
  this.eventBus.emit("signalMarkerRemove", { id: e });
614
- }), this.tradeZoneManager = new ze(), this.tradeZoneManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradeZoneManager.setDataGetter(() => this.dataManager.getData()), this.tradeZoneManager.on("added", (e) => {
660
+ }), this.tradeZoneManager = new Ve(), this.tradeZoneManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradeZoneManager.setDataGetter(() => this.dataManager.getData()), this.tradeZoneManager.on("added", (e) => {
615
661
  this.eventBus.emit("tradeZoneAdd", {
616
662
  id: e.id,
617
663
  direction: e.direction
618
664
  });
619
665
  }), this.tradeZoneManager.on("removed", (e) => {
620
666
  this.eventBus.emit("tradeZoneRemove", { id: e });
621
- }), this.replayManager = new x(), this.measureOverlay = new Te(), this.interactionManager = new ye(e), this.features.panning) {
622
- let e = 0;
667
+ }), this.replayManager = new b(), this.measureOverlay = new Te(), this.interactionManager = new ye(e), this.features.panning) {
668
+ let e = new xt();
623
669
  this.interactionManager.setPanHandler(new Ee((t, n) => {
624
- t && this.viewport.scrollBy(t), n && (e += n, (this.options.autoScale === !1 || Math.abs(e) > bt) && (this.options.autoScale = !1, this.viewport.panPriceRange(n))), this.updateViewportAndRender();
625
- }, () => {
626
- e = 0;
627
- }));
670
+ t && this.viewport.scrollBy(t), e.step(t, n, this.options.autoScale !== !1) && n && (this.options.autoScale = !1, this.viewport.panPriceRange(n)), this.updateViewportAndRender();
671
+ }, () => e.reset()));
628
672
  }
629
673
  if (this.features.zooming) {
630
- this.interactionManager.setZoomHandler(new Je((e, t) => {
674
+ this.interactionManager.setZoomHandler(new Xe((e, t) => {
631
675
  this.viewport.zoom(e, t), this.updateViewportAndRender();
632
676
  }));
633
677
  let e = new ne((e) => {
@@ -662,7 +706,7 @@ var bt = 6, xt = class {
662
706
  x: e.x,
663
707
  y: e.y
664
708
  }), t.length === 0) return;
665
- let n = rt(e.x, this.viewport.getState());
709
+ let n = st(e.x, this.viewport.getState());
666
710
  n < 0 || n >= t.length || this.eventBus.emit("barClick", {
667
711
  bar: t[n],
668
712
  barIndex: n,
@@ -684,34 +728,74 @@ var bt = 6, xt = class {
684
728
  end: () => {
685
729
  this.measureOverlay.end();
686
730
  }
687
- }), this.interactionManager.setOverlayDirtyCallback(() => {
688
- this.engine.requestRender(r.Overlay), this.engine.requestRender(r.UI);
731
+ });
732
+ let o = (e) => {
733
+ let t = this.viewport.getState().chartRect;
734
+ return {
735
+ x: Math.max(t.x, Math.min(t.x + t.width, e.x)),
736
+ y: Math.max(t.y, Math.min(t.y + t.height, e.y))
737
+ };
738
+ };
739
+ this.interactionManager.setBoxSelectHandlers({
740
+ begin: (e) => this.selectionBoxOverlay.begin(o(e)),
741
+ move: (e) => this.selectionBoxOverlay.update(o(e)),
742
+ end: () => {
743
+ let e = this.selectionBoxOverlay.end();
744
+ if (!e || !this.features.drawings) return;
745
+ let t = {
746
+ ...this.viewport.getState(),
747
+ data: this.getDisplayData()
748
+ };
749
+ e.isClick ? this.drawingManager.toggleSelectionAt({
750
+ x: e.x1,
751
+ y: e.y1
752
+ }, t) : this.drawingManager.selectInRect(e, t), this.engine.requestRender(r.Overlay);
753
+ },
754
+ cancel: () => this.selectionBoxOverlay.cancel()
755
+ }), this.interactionManager.setOverlayDirtyCallback((e) => {
756
+ this.engine.requestRender(e ? r.Hover : r.Overlay);
689
757
  }), this.interactionManager.attach(), this.syncRenderContext(), this.engine.start();
690
758
  }
691
759
  setData(e) {
692
- 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 });
760
+ this.endReplaySession(), 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.recalcIndicators(this.dataManager.getData()), e.length > 0 && this.currentPriceLine.setPrice(e[e.length - 1].close), this.updateViewportAndRender(!0), this.eventBus.emit("dataUpdate", { length: e.length });
693
761
  }
694
762
  appendBar(e) {
763
+ if (this.replaySession) {
764
+ this.replaySession.live.appendBar(e);
765
+ return;
766
+ }
695
767
  let t = this.autoScrollOnNewBar && this.viewport.isAtEnd();
696
768
  this.dataManager.appendBar(e);
697
769
  let n = this.dataManager.getData();
698
- this.crosshairHandler.setData(n), this.displayDataCache = null, this.indicatorEngine.recalculateFrom(n, n.length - 2), this.updateViewportAndRender(t);
770
+ this.crosshairHandler.setData(n), this.displayDataCache = null, this.recalcIndicatorsFrom(n, n.length - 2), this.updateViewportAndRender(t);
699
771
  }
700
772
  appendBars(e) {
701
773
  if (e.length === 0) return;
774
+ if (this.replaySession) {
775
+ for (let t of e) this.replaySession.live.appendBar(t);
776
+ return;
777
+ }
702
778
  let t = this.viewport.isAtEnd(), n = this.dataManager.getLength() - 1;
703
779
  for (let t of e) this.dataManager.appendBar(t);
704
- this.displayDataCache = null, this.indicatorEngine.recalculateFrom(this.dataManager.getData(), n), this.crosshairHandler.setData(this.dataManager.getData()), this.updateViewportAndRender(t);
780
+ this.displayDataCache = null, this.recalcIndicatorsFrom(this.dataManager.getData(), n), this.crosshairHandler.setData(this.dataManager.getData()), this.updateViewportAndRender(t);
705
781
  }
706
782
  updateLastBar(e) {
783
+ if (this.replaySession) {
784
+ this.replaySession.live.updateLastBar(e);
785
+ return;
786
+ }
707
787
  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);
708
788
  let t = this.dataManager.getData();
709
- this.indicatorEngine.recalculateFrom(t, t.length - 1), this.scheduleRender();
789
+ this.recalcIndicatorsFrom(t, t.length - 1), this.scheduleRender();
710
790
  }
711
791
  updateLastBarFromTick(e) {
792
+ if (this.replaySession) {
793
+ this.replaySession.live.updateLastBarFromTick(e), Number.isFinite(e.price) && (this.replaySession.price = { price: e.price });
794
+ return;
795
+ }
712
796
  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);
713
797
  let t = this.dataManager.getData();
714
- this.indicatorEngine.recalculateFrom(t, t.length - 1), this.scheduleRender();
798
+ this.recalcIndicatorsFrom(t, t.length - 1), this.scheduleRender();
715
799
  }
716
800
  setChartType(e) {
717
801
  this.options.chartType = e, this.chartRenderer = this.createChartRenderer(e), this.chartLegend.setChartType(e), this.displayDataCache = null, this.updateViewportAndRender(!0);
@@ -722,14 +806,17 @@ var bt = 6, xt = class {
722
806
  return this.indicatorEngine.getAvailableIndicators().find((t) => t.id === e)?.placement === "panel" ? (this.layoutManager.addPanel(r, n), this.updateViewportAndRender()) : this.engine.requestRender(), this.eventBus.emit("indicatorAdd", {
723
807
  instanceId: r,
724
808
  id: e
725
- }), r;
809
+ }), this.scheduleAutoSave(), r;
726
810
  }
727
811
  updateIndicator(e, t) {
728
- this.indicatorEngine.updateIndicator(e, t, this.dataManager.getData()), this.engine.requestRender();
812
+ this.indicatorEngine.updateIndicator(e, t, this.dataManager.getData()), this.announceIndicatorUpdate(0), this.engine.requestRender(), this.scheduleAutoSave();
729
813
  }
730
814
  removeIndicator(e) {
731
815
  let t = this.layoutManager.getPanels().some((t) => t.id === e);
732
- this.indicatorEngine.removeIndicator(e), this.layoutManager.removePanel(e), this.eventBus.emit("indicatorRemove", { instanceId: e }), t ? this.updateViewportAndRender() : this.engine.requestRender();
816
+ this.indicatorEngine.removeIndicator(e), this.layoutManager.removePanel(e), this.eventBus.emit("indicatorRemove", { instanceId: e }), this.scheduleAutoSave(), t ? this.updateViewportAndRender() : this.engine.requestRender();
817
+ }
818
+ getIndicatorStyle(e) {
819
+ return this.indicatorEngine.getIndicatorStyle(e);
733
820
  }
734
821
  getIndicatorOutput(e) {
735
822
  return this.indicatorEngine.getOutput(e);
@@ -742,13 +829,36 @@ var bt = 6, xt = class {
742
829
  }
743
830
  static indicators() {
744
831
  let e = new v();
745
- return C(e), e.getAvailableIndicators();
832
+ return S(e), e.getAvailableIndicators();
746
833
  }
747
834
  setPanelPosition(e, t) {
748
835
  this.layoutManager.setPanelPosition(e, t), this.engine.requestRender();
749
836
  }
750
837
  setPanelSize(e, t) {
751
- this.layoutManager.setPanelSize(e, t), this.updateViewportAndRender();
838
+ this.layoutManager.setPanelSize(e, t), this.updateViewportAndRender(), this.eventBus.emit("paneResize", {
839
+ instanceId: e,
840
+ size: t
841
+ });
842
+ }
843
+ getIndicatorPanes() {
844
+ return this.buildPanelRenderInfos().map((e) => ({
845
+ instanceId: e.instanceId,
846
+ rect: { ...e.rect }
847
+ }));
848
+ }
849
+ setPaneTitlesVisible(e) {
850
+ this.paneTitles = e, this.engine.requestRender();
851
+ }
852
+ getLegendBottom() {
853
+ let e = this.viewport.getState().chartRect.y;
854
+ return this.features.legend ? e + this.chartLegend.getHeight() : e;
855
+ }
856
+ isTimeAligned() {
857
+ return ut(this.options.chartType) ? !1 : this.getDisplayData().length === this.dataManager.getLength();
858
+ }
859
+ formatPrice(e) {
860
+ let { min: t, max: n } = this.viewport.getState().priceRange;
861
+ return l(e, this.marketPricePrecision ?? s(t, n), this.numberLocale);
752
862
  }
753
863
  setDrawingTool(e) {
754
864
  this.features.drawings && (e && this.features.drawingTools.length > 0 && !this.features.drawingTools.includes(e) || this.drawingManager.setActiveTool(e));
@@ -756,6 +866,18 @@ var bt = 6, xt = class {
756
866
  getDrawingTool() {
757
867
  return this.drawingManager.getActiveTool();
758
868
  }
869
+ setStayInDrawingMode(e) {
870
+ this.drawingManager.setStayInDrawingMode(e);
871
+ }
872
+ isStayInDrawingMode() {
873
+ return this.drawingManager.isStayInDrawingMode();
874
+ }
875
+ copyDrawings() {
876
+ return this.drawingManager.copySelection();
877
+ }
878
+ pasteDrawings() {
879
+ return this.features.drawings ? this.drawingManager.paste() : [];
880
+ }
759
881
  setDrawingStyle(e) {
760
882
  this.drawingManager.setStyle(e);
761
883
  }
@@ -781,7 +903,7 @@ var bt = 6, xt = class {
781
903
  }
782
904
  autoFib() {
783
905
  if (!this.features.drawings) return null;
784
- let e = this.getDisplayData(), t = this.viewport.getState(), n = Ye(e, t.visibleRange.from, t.visibleRange.to);
906
+ let e = this.getDisplayData(), t = this.viewport.getState(), n = Qe(e, t.visibleRange.from, t.visibleRange.to);
785
907
  return n ? this.addDrawing({
786
908
  type: "fibRetracement",
787
909
  anchors: [n[0], n[1]]
@@ -812,7 +934,7 @@ var bt = 6, xt = class {
812
934
  return this.undoRedoManager.getState();
813
935
  }
814
936
  setDrawingMagnet(e) {
815
- this.drawingManager.setMagnetMode(e ? "magnet" : "none");
937
+ this.drawingManager.setMagnetMode(e && this.features.drawingMagnet ? "magnet" : "none");
816
938
  }
817
939
  getDrawingMagnet() {
818
940
  return this.drawingManager.getMagnetMode() === "magnet";
@@ -834,6 +956,7 @@ var bt = 6, xt = class {
834
956
  return t ? this.drawingManager.duplicateDrawing(t) : null;
835
957
  }
836
958
  exportVisibleData(e = "csv", t) {
959
+ if (!this.features.dataExport) return;
837
960
  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);
838
961
  if (e === "json") {
839
962
  let e = _.toJSON(o);
@@ -844,6 +967,7 @@ var bt = 6, xt = class {
844
967
  }
845
968
  }
846
969
  exportAllData(e = "csv", t) {
970
+ if (!this.features.dataExport) return;
847
971
  let n = this.dataManager.getData();
848
972
  if (e === "json") {
849
973
  let e = _.toJSON(n);
@@ -876,7 +1000,7 @@ var bt = 6, xt = class {
876
1000
  return this.indicatorEngine.getActiveIndicators();
877
1001
  }
878
1002
  setIndicatorVisible(e, t) {
879
- this.indicatorEngine.setVisible(e, t) !== null && this.updateViewportAndRender();
1003
+ this.indicatorEngine.setVisible(e, t) !== null && (this.updateViewportAndRender(), this.scheduleAutoSave());
880
1004
  }
881
1005
  getIndicatorConfig(e) {
882
1006
  let t = this.indicatorEngine.getIndicatorConfig(e);
@@ -886,7 +1010,7 @@ var bt = 6, xt = class {
886
1010
  } : null;
887
1011
  }
888
1012
  updateIndicatorStyle(e, t) {
889
- this.indicatorEngine.updateIndicatorStyle(e, t), this.engine.requestRender();
1013
+ this.indicatorEngine.updateIndicatorStyle(e, t), this.engine.requestRender(), this.scheduleAutoSave();
890
1014
  }
891
1015
  setOrders(e) {
892
1016
  this.features.trading && this.tradingManager.setOrders(e);
@@ -929,7 +1053,7 @@ var bt = 6, xt = class {
929
1053
  this.features.trading && this.tradingManager.setDepthData(e);
930
1054
  }
931
1055
  setCurrentPrice(e, t) {
932
- this.tradingManager.setCurrentPrice(e), this.currentPriceLine.setPrice(e), this.scheduleRender(), this.features.alerts && (this.alertManager.checkPrice(e), this.feedIndicatorAlerts());
1056
+ this.tradingManager.setCurrentPrice(e), this.replaySession ? this.replaySession.price = { price: e } : (this.currentPriceLine.setPrice(e), this.scheduleRender()), this.features.alerts && (this.alertManager.checkPrice(e), this.feedIndicatorAlerts());
933
1057
  }
934
1058
  feedIndicatorAlerts() {
935
1059
  let e = this.alertManager.getAlerts(), t = this.dataManager.getData();
@@ -948,19 +1072,38 @@ var bt = 6, xt = class {
948
1072
  this.features.trading && this.tradingManager.setConfig(e);
949
1073
  }
950
1074
  async connect(e) {
951
- this.disconnectStream(), this.streamManager = new Le(), this.streamManager.on("snapshot", (e) => {
1075
+ this.replayStop(), this.disconnectStream(), this.streamManager = new ze(), this.streamManager.on("snapshot", (e) => {
1076
+ if (this.replaySession) {
1077
+ this.replaySession.live.setData(e);
1078
+ return;
1079
+ }
952
1080
  this.setData(e);
953
1081
  }), this.streamManager.on("barClose", (e) => {
1082
+ if (this.replaySession) {
1083
+ this.replaySession.live.appendBar(e);
1084
+ return;
1085
+ }
954
1086
  let t = this.autoScrollOnNewBar && this.viewport.isAtEnd();
955
1087
  this.dataManager.appendBar(e);
956
1088
  let n = this.dataManager.getData();
957
- this.crosshairHandler.setData(n), this.displayDataCache = null, this.indicatorEngine.recalculateFrom(n, n.length - 2), this.updateViewportAndRender(t);
1089
+ this.crosshairHandler.setData(n), this.displayDataCache = null, this.recalcIndicatorsFrom(n, n.length - 2), this.updateViewportAndRender(t);
958
1090
  }), this.streamManager.on("barUpdate", (e) => {
1091
+ if (this.replaySession) {
1092
+ this.replaySession.live.updateLastBar(e);
1093
+ return;
1094
+ }
959
1095
  this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close);
960
1096
  let t = this.dataManager.getData();
961
- this.indicatorEngine.recalculateFrom(t, t.length - 1), this.scheduleRender();
1097
+ this.recalcIndicatorsFrom(t, t.length - 1), this.scheduleRender();
962
1098
  }), this.streamManager.on("priceChange", ({ price: e, previousClose: t }) => {
963
- this.tradingManager.setCurrentPrice(e), this.currentPriceLine.setPrice(e, t ?? void 0), this.engine.requestRender(r.Overlay), this.engine.requestRender(r.UI);
1099
+ if (this.tradingManager.setCurrentPrice(e), this.replaySession) {
1100
+ this.replaySession.price = {
1101
+ price: e,
1102
+ previousClose: t ?? void 0
1103
+ };
1104
+ return;
1105
+ }
1106
+ this.currentPriceLine.setPrice(e, t ?? void 0), this.engine.requestRender(r.Overlay);
964
1107
  }), this.streamManager.on("connectionChange", (e) => {
965
1108
  this.eventBus.emit("dataUpdate", { connection: e });
966
1109
  }), this.streamManager.on("error", (e) => {
@@ -970,22 +1113,26 @@ var bt = 6, xt = class {
970
1113
  if (await t.connect(e), this.streamManager !== t) return;
971
1114
  let n = f(e.timeframe);
972
1115
  this.barCountdown.setTimeframeMs(n), this.countdownInterval && clearInterval(this.countdownInterval), this.countdownInterval = setInterval(() => {
973
- this.barCountdown.isVisible() && this.engine.requestRender(r.UI);
1116
+ this.barCountdown.isVisible() && this.engine.requestRender(r.Hover);
974
1117
  }, 1e3);
975
1118
  }
976
1119
  async switchStream(e, t) {
977
1120
  this.streamManager && (this.currentSymbol = e, this.barCountdown.setTimeframeMs(f(t)), await this.streamManager.switchTo(e, t));
978
1121
  }
1122
+ isTimeframeAllowed(e) {
1123
+ let t = this.features.timeframes;
1124
+ return t.length === 0 || t.includes(e);
1125
+ }
979
1126
  async setTimeframe(e) {
980
1127
  if (!this.streamManager) throw Error("No active stream. Call connect() first.");
981
- await this.switchStream(this.currentSymbol, e);
1128
+ this.isTimeframeAllowed(e) && await this.switchStream(this.currentSymbol, e);
982
1129
  }
983
1130
  disconnectStream() {
984
1131
  this.streamManager &&= (this.streamManager.dispose(), null);
985
1132
  }
986
1133
  connectExecution(e, t = {}) {
987
1134
  if (!this.features.trading) throw Error("connectExecution requires features.trading to be enabled");
988
- this.disconnectExecution(), this.executionAdapter = e, this.execTeardown = yt(e, {
1135
+ this.disconnectExecution(), this.executionAdapter = e, this.execTeardown = Et(e, {
989
1136
  onIntent: (e, t) => {
990
1137
  let n = (e) => t(e.payload);
991
1138
  return this.eventBus.on(e, n), () => this.eventBus.off(e, n);
@@ -1005,19 +1152,19 @@ var bt = 6, xt = class {
1005
1152
  return this.executionAdapter;
1006
1153
  }
1007
1154
  setBarCountdownVisible(e) {
1008
- this.barCountdown.setVisible(e), this.engine.requestRender(r.UI);
1155
+ this.barCountdown.setVisible(e && this.features.barCountdown), this.engine.requestRender(r.Hover);
1009
1156
  }
1010
1157
  setSessionBreaksVisible(e) {
1011
1158
  this.sessionBreaks.setVisible(e), this.engine.requestRender(r.Background);
1012
1159
  }
1013
1160
  addCompareSymbol(e, t, n, i) {
1014
- this.compareRenderer.addSymbol({
1161
+ this.features.compareSymbols && (this.compareRenderer.addSymbol({
1015
1162
  id: e,
1016
1163
  label: t,
1017
1164
  data: n,
1018
1165
  color: i,
1019
1166
  visible: !0
1020
- }), this.engine.requestRender(r.Main);
1167
+ }), this.engine.requestRender(r.Main));
1021
1168
  }
1022
1169
  removeCompareSymbol(e) {
1023
1170
  this.compareRenderer.removeSymbol(e), this.engine.requestRender(r.Main);
@@ -1032,13 +1179,19 @@ var bt = 6, xt = class {
1032
1179
  this.compareRenderer.clear(), this.engine.requestRender(r.Main);
1033
1180
  }
1034
1181
  setLogScale(e) {
1035
- this.viewport.setLogScale(e), this.updateViewportAndRender();
1182
+ e && !this.features.logScale || (this.viewport.setLogScale(e), this.updateViewportAndRender());
1036
1183
  }
1037
1184
  isLogScale() {
1038
1185
  return this.viewport.isLogScale();
1039
1186
  }
1187
+ setInvertScale(e) {
1188
+ this.viewport.setInvertScale(e), this.updateViewportAndRender();
1189
+ }
1190
+ isInvertScale() {
1191
+ return this.viewport.isInvertScale();
1192
+ }
1040
1193
  setScaleMode(e) {
1041
- this.viewport.setScaleMode(e), this.updateViewportAndRender();
1194
+ e === "logarithmic" && !this.features.logScale || (this.viewport.setScaleMode(e), this.updateViewportAndRender());
1042
1195
  }
1043
1196
  getScaleMode() {
1044
1197
  return this.viewport.getScaleMode();
@@ -1063,25 +1216,34 @@ var bt = 6, xt = class {
1063
1216
  return;
1064
1217
  }
1065
1218
  }
1219
+ goToTime(e) {
1220
+ let t = this.getDisplayData();
1221
+ if (t.length === 0 || !Number.isFinite(e)) return -1;
1222
+ let n = Math.max(0, Math.min(t.length - 1, Math.floor(C(e, t)))), r = this.viewport.getState(), i = n * (r.barWidth + r.barSpacing) + r.barWidth / 2 - r.chartRect.width / 2;
1223
+ return this.viewport.scrollBy(i - r.offset), this.updateViewportAndRender(), n;
1224
+ }
1225
+ setVisibleRangePreset(e) {
1226
+ let t = this.getDisplayData();
1227
+ if (t.length === 0) return;
1228
+ let n = t.length - 1, r = t[n].time > Dt ? 1 : 1e3, i = $e(e, t[n].time * r, this.displayTzOffset), a = i === null ? null : i / r;
1229
+ if (a === null || a < t[0].time) {
1230
+ this.fitContent();
1231
+ return;
1232
+ }
1233
+ let o = Math.min(n, Math.floor(C(a, t)) + 1);
1234
+ this.viewport.zoomToBarRange(o, n + this.viewport.getRightMargin()), this.viewport.scrollToEnd(), this.updateViewportAndRender();
1235
+ }
1066
1236
  scrollToEnd() {
1067
1237
  this.viewport.scrollToEnd(), this.updateViewportAndRender();
1068
1238
  }
1069
1239
  setVisibleRange(e, t) {
1070
- let n = this.dataManager.getData(), r = 0, i = n.length - 1;
1071
- for (let t = 0; t < n.length; t++) if (n[t].time >= e) {
1072
- r = t;
1073
- break;
1074
- }
1075
- for (let e = n.length - 1; e >= 0; e--) if (n[e].time <= t) {
1076
- i = e;
1077
- break;
1078
- }
1079
- let a = i - r + 1;
1080
- if (a > 0) {
1081
- let e = this.viewport.getState().chartRect.width, t = e / a, n = Math.max(2, t - this.viewport.getState().barSpacing);
1082
- this.viewport.zoom((n - this.viewport.getState().barWidth) / this.viewport.getState().barWidth, e / 2);
1083
- }
1084
- this.updateViewportAndRender();
1240
+ let n = this.dataManager.getData();
1241
+ if (n.length === 0) return;
1242
+ let r = C(Math.min(e, t), n), i = C(Math.max(e, t), n);
1243
+ this.viewport.zoomToBarRange(r, i), this.updateViewportAndRender();
1244
+ }
1245
+ setPanLimits(e) {
1246
+ this.viewport.setPanLimits(e), this.updateViewportAndRender();
1085
1247
  }
1086
1248
  zoomIn() {
1087
1249
  let e = this.viewport.getState().chartRect.width;
@@ -1092,8 +1254,8 @@ var bt = 6, xt = class {
1092
1254
  this.viewport.zoom(-.2, e / 2), this.updateViewportAndRender();
1093
1255
  }
1094
1256
  fitContent() {
1095
- let e = this.dataManager.getData();
1096
- e.length !== 0 && this.setVisibleRange(e[0].time, e[e.length - 1].time);
1257
+ let e = this.dataManager.getLength();
1258
+ e !== 0 && (this.viewport.zoomToBarRange(0, e - 1 + this.viewport.getRightMargin()), this.viewport.scrollToEnd(), this.updateViewportAndRender());
1097
1259
  }
1098
1260
  on(e, t) {
1099
1261
  this.eventBus.on(e, t);
@@ -1129,13 +1291,17 @@ var bt = 6, xt = class {
1129
1291
  return this.options.autoScale !== !1;
1130
1292
  }
1131
1293
  setCrosshairMode(e) {
1132
- this.crosshairHandler.setMode(e), this.engine.requestRender(r.Overlay);
1294
+ this.crosshairHandler.setMode(e), this.engine.requestRender(r.Hover);
1133
1295
  }
1134
1296
  getCrosshairMode() {
1135
1297
  return this.crosshairHandler.getMode();
1136
1298
  }
1137
1299
  setCrosshairPosition(e) {
1138
- e && this.crosshairHandler.onPointerMove(e), this.engine.requestRender(r.Overlay);
1300
+ e ? this.crosshairHandler.onPointerMove(e) : this.crosshairHandler.onPointerLeave(), this.engine.requestRender(r.Hover);
1301
+ }
1302
+ setCrosshairTime(e) {
1303
+ let t = this.getDisplayData(), n = e === null || t.length === 0 ? null : Math.floor(C(e, t));
1304
+ n !== this.crosshairHandler.getSyncedSlot() && (this.crosshairHandler.setSyncedSlot(n), this.engine.requestRender(r.Hover));
1139
1305
  }
1140
1306
  getData() {
1141
1307
  return this.dataManager.getData();
@@ -1196,7 +1362,7 @@ var bt = 6, xt = class {
1196
1362
  this.periodLevels.setPeriod(e), this.engine.requestRender(r.Main);
1197
1363
  }
1198
1364
  setTimezoneOffset(e) {
1199
- this.timeAxis.setTimezoneOffset(e), this.crosshairHandler.setTimezoneOffset(e), this.engine.requestRender(r.UI), this.engine.requestRender(r.Overlay);
1365
+ this.displayTzOffset = e, this.timeAxis.setTimezoneOffset(e), this.crosshairHandler.setTimezoneOffset(e), this.crosshairTooltip.setTimezoneOffset(e), this.engine.requestRender(r.UI);
1200
1366
  }
1201
1367
  setPivotMarkersVisible(e) {
1202
1368
  this.pivotMarkers.setVisible(e), this.engine.requestRender(r.Overlay);
@@ -1220,31 +1386,31 @@ var bt = 6, xt = class {
1220
1386
  e || this.crosshairTooltip.hide();
1221
1387
  }
1222
1388
  setLegend(e) {
1223
- this.chartLegend.setConfig(e), this.engine.requestRender(r.UI);
1389
+ this.chartLegend.setConfig(e), this.engine.requestRender(r.Hover);
1224
1390
  }
1225
1391
  setSymbolName(e) {
1226
- this.chartLegend.setSymbol(e), this.engine.requestRender(r.UI);
1392
+ this.chartLegend.setSymbol(e), this.engine.requestRender(r.Hover);
1227
1393
  }
1228
1394
  setStatusText(e) {
1229
- this.chartLegend.setStatusText(e), this.engine.requestRender(r.UI);
1395
+ this.chartLegend.setStatusText(e), this.engine.requestRender(r.Hover);
1230
1396
  }
1231
1397
  screenshot(e) {
1232
- this.features.screenshot && S.download(this.container, e, this.themeManager.getTheme().background);
1398
+ this.features.screenshot && x.download(this.container, e, this.themeManager.getTheme().background);
1233
1399
  }
1234
1400
  async copyScreenshot() {
1235
1401
  if (!this.features.screenshot) return !1;
1236
1402
  try {
1237
- let e = await S.toBlob(this.container, this.themeManager.getTheme().background), t = globalThis.ClipboardItem;
1403
+ let e = await x.toBlob(this.container, this.themeManager.getTheme().background), t = globalThis.ClipboardItem;
1238
1404
  return !e || !navigator.clipboard?.write || !t ? !1 : (await navigator.clipboard.write([new t({ "image/png": e })]), !0);
1239
1405
  } catch {
1240
1406
  return !1;
1241
1407
  }
1242
1408
  }
1243
1409
  screenshotDataURL() {
1244
- return this.features.screenshot ? S.toDataURL(this.container, this.themeManager.getTheme().background) : null;
1410
+ return this.features.screenshot ? x.toDataURL(this.container, this.themeManager.getTheme().background) : null;
1245
1411
  }
1246
1412
  async screenshotBlob() {
1247
- return this.features.screenshot ? S.toBlob(this.container, this.themeManager.getTheme().background) : null;
1413
+ return this.features.screenshot ? x.toBlob(this.container, this.themeManager.getTheme().background) : null;
1248
1414
  }
1249
1415
  addAlert(e, t = "crossing", n, r = "price", i) {
1250
1416
  if (!this.features.alerts) return null;
@@ -1307,16 +1473,24 @@ var bt = 6, xt = class {
1307
1473
  }
1308
1474
  replayStart(e) {
1309
1475
  if (!this.features.replay) return;
1310
- let t = this.dataManager.getData();
1311
- this.replayManager.load(t);
1476
+ if (!this.replaySession) {
1477
+ if (this.dataManager.getLength() === 0) return;
1478
+ let e = new A();
1479
+ e.setData(this.dataManager.getData()), this.replaySession = {
1480
+ live: e,
1481
+ price: null
1482
+ };
1483
+ }
1484
+ let t = this.replaySession.live.getData().slice();
1485
+ this.options.autoScale = !0, this.replayManager.load(t);
1312
1486
  let n = -1;
1313
1487
  this.replayBarUnsub?.(), this.replayBarUnsub = this.replayManager.on("bar", ({ bar: e, index: r }) => {
1314
- let i = r + 1;
1315
- if (n > 0 && i > n && this.dataManager.getLength() === n) {
1488
+ let i = r + 1, a = n > 0 && i > n && this.dataManager.getLength() === n, o = !(a && !this.replaySeeking) || this.autoScrollOnNewBar && this.viewport.isAtEnd();
1489
+ if (a) {
1316
1490
  for (let e = n; e < i; e++) this.dataManager.appendBar(t[e]);
1317
- this.indicatorEngine.recalculateFrom(this.dataManager.getData(), n);
1318
- } else this.dataManager.setData(t.slice(0, i)), this.indicatorEngine.recalculateAll(this.dataManager.getData());
1319
- n = i, this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.updateViewportAndRender();
1491
+ this.recalcIndicatorsFrom(this.dataManager.getData(), n);
1492
+ } else this.dataManager.setData(t.slice(0, i)), this.recalcIndicators(this.dataManager.getData());
1493
+ n = i, this.currentPriceLine.setPrice(t[r].close, r > 0 ? t[r - 1].close : void 0), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.updateViewportAndRender(o);
1320
1494
  }), this.replayManager.play(e);
1321
1495
  }
1322
1496
  replayPause() {
@@ -1326,10 +1500,31 @@ var bt = 6, xt = class {
1326
1500
  this.replayManager.resume();
1327
1501
  }
1328
1502
  replayStop() {
1329
- this.replayManager.stop();
1503
+ let e = this.replaySession;
1504
+ this.endReplaySession(), e && (this.setData(e.live.getData()), e.price && this.currentPriceLine.setPrice(e.price.price, e.price.previousClose));
1505
+ }
1506
+ isReplayActive() {
1507
+ return this.replaySession !== null;
1508
+ }
1509
+ getPlotRect() {
1510
+ let { x: e, y: t, width: n, height: r } = this.viewport.getState().chartRect;
1511
+ return {
1512
+ x: e,
1513
+ y: t,
1514
+ width: n,
1515
+ height: r
1516
+ };
1517
+ }
1518
+ endReplaySession() {
1519
+ this.replaySession && (this.replaySession = null, this.replayBarUnsub?.(), this.replayBarUnsub = null, this.replayManager.stop());
1330
1520
  }
1331
1521
  replaySeek(e) {
1332
- this.replayManager.seekTo(e);
1522
+ this.replaySeeking = !0;
1523
+ try {
1524
+ this.replayManager.seekTo(e);
1525
+ } finally {
1526
+ this.replaySeeking = !1;
1527
+ }
1333
1528
  }
1334
1529
  setReplaySpeed(e) {
1335
1530
  this.replayManager.setSpeed(e);
@@ -1340,22 +1535,68 @@ var bt = 6, xt = class {
1340
1535
  getReplayProgress() {
1341
1536
  return this.replayManager.getProgress();
1342
1537
  }
1343
- saveState(e) {
1344
- if (!this.features.saveLoad) return null;
1345
- let t = g.capture({
1538
+ captureSnapshot() {
1539
+ let e = this.layoutManager.getPanels();
1540
+ return g.capture({
1346
1541
  getDrawings: () => this.getDrawings(),
1347
1542
  getTheme: () => this.getTheme(),
1348
- getAlerts: () => this.getAlerts()
1349
- }, { chartType: this.options.chartType }), n = g.serialize(t);
1543
+ getAlerts: () => this.getAlerts(),
1544
+ getIndicators: () => [...this.indicatorEngine.getActiveIndicators().map((t) => ({
1545
+ id: t.id,
1546
+ instanceId: t.instanceId,
1547
+ params: t.params,
1548
+ position: e.find((e) => e.id === t.instanceId)?.position,
1549
+ style: this.indicatorEngine.getIndicatorStyle(t.instanceId) ?? void 0,
1550
+ visible: t.visible
1551
+ })), ...this.unrestoredIndicators]
1552
+ }, {
1553
+ chartType: this.options.chartType,
1554
+ symbol: this.currentSymbol || void 0
1555
+ });
1556
+ }
1557
+ saveState(e) {
1558
+ if (!this.features.saveLoad) return null;
1559
+ let t = this.captureSnapshot(), n = g.serialize(t);
1350
1560
  return e && g.saveToStorage(e, t), n;
1351
1561
  }
1352
1562
  loadState(e) {
1353
1563
  if (!this.features.saveLoad) return;
1354
1564
  let t = g.deserialize(e);
1355
- if (t.chartType && this.setChartType(t.chartType), t.drawings && this.setDrawings(t.drawings), t.theme && this.setTheme(t.theme), t.alerts) {
1356
- this.clearAlerts();
1357
- for (let e of t.alerts) this.addAlert(e.price, e.condition, e.message);
1565
+ t.chartType && this.setChartType(t.chartType), t.drawings && this.setDrawings(t.drawings), t.theme && this.setTheme(t.theme);
1566
+ let n = /* @__PURE__ */ new Map();
1567
+ if (t.version >= 2 && this.features.indicators) {
1568
+ this.unrestoredIndicators = [];
1569
+ let e = new Set(this.indicatorEngine.getAvailableIndicators().map((e) => e.id));
1570
+ for (let e of this.indicatorEngine.getActiveIndicators()) this.removeIndicator(e.instanceId);
1571
+ for (let r of t.indicators) {
1572
+ let t = [
1573
+ "top",
1574
+ "bottom",
1575
+ "left",
1576
+ "right"
1577
+ ].find((e) => e === r.position) ?? "bottom", i = null;
1578
+ try {
1579
+ if (!e.has(r.id)) throw Error("no such indicator is registered");
1580
+ i = this.addIndicator(r.id, r.params, t);
1581
+ } catch (e) {
1582
+ console.warn(`Layout indicator "${r.id}" kept but not shown:`, e);
1583
+ }
1584
+ if (!i) {
1585
+ this.unrestoredIndicators.push(r);
1586
+ continue;
1587
+ }
1588
+ n.set(r.instanceId, i), r.style && this.updateIndicatorStyle(i, r.style), r.visible === !1 && this.setIndicatorVisible(i, !1);
1589
+ }
1590
+ }
1591
+ if (t.alerts && this.features.alerts) {
1592
+ this.alertManager.clearAlerts();
1593
+ for (let e of t.alerts) {
1594
+ if (e.triggered && !e.repeating) continue;
1595
+ let t = e.channel.indexOf(":"), r = t > 0 ? n.get(e.channel.slice(0, t)) : void 0, i = r ? r + e.channel.slice(t) : e.channel;
1596
+ this.alertManager.addAlert(e.price, e.condition, e.message, e.repeating, i, e.label);
1597
+ }
1358
1598
  }
1599
+ this.scheduleAutoSave();
1359
1600
  }
1360
1601
  loadStateFromStorage(e) {
1361
1602
  if (!this.features.saveLoad) return !1;
@@ -1363,13 +1604,7 @@ var bt = 6, xt = class {
1363
1604
  return t ? (this.loadState(g.serialize(t)), !0) : !1;
1364
1605
  }
1365
1606
  downloadState(e) {
1366
- if (!this.features.saveLoad) return;
1367
- let t = g.capture({
1368
- getDrawings: () => this.getDrawings(),
1369
- getTheme: () => this.getTheme(),
1370
- getAlerts: () => this.getAlerts()
1371
- }, { chartType: this.options.chartType });
1372
- g.downloadFile(t, e);
1607
+ this.features.saveLoad && g.downloadFile(this.captureSnapshot(), e);
1373
1608
  }
1374
1609
  async loadStateFromFile() {
1375
1610
  if (!this.features.saveLoad) return;
@@ -1380,7 +1615,7 @@ var bt = 6, xt = class {
1380
1615
  d(e), this.engine.requestRender();
1381
1616
  }
1382
1617
  setNumberLocale(e) {
1383
- this.numberLocale = e, this.priceAxis.setLocale(e), this.crosshairHandler.setLocale(e), this.chartLegend.setLocale(e), this.sessionBreaks.setLocale(e), this.currentPriceLine.setLocale(e), this.updateViewportAndRender();
1618
+ 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();
1384
1619
  }
1385
1620
  getNumberLocale() {
1386
1621
  return this.numberLocale;
@@ -1398,7 +1633,7 @@ var bt = 6, xt = class {
1398
1633
  };
1399
1634
  this.themeManager.setTheme(t);
1400
1635
  }
1401
- 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.updateViewportAndRender();
1636
+ e.pricePrecision !== void 0 && (this.marketPricePrecision = e.pricePrecision, 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();
1402
1637
  }
1403
1638
  getMarket() {
1404
1639
  return this.marketConfig;
@@ -1428,15 +1663,31 @@ var bt = 6, xt = class {
1428
1663
  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 = "";
1429
1664
  }
1430
1665
  createChartRenderer(e) {
1431
- return at(e, (e) => this.pluginManager.getChartType(e));
1666
+ return dt(e, (e) => this.pluginManager.getChartType(e));
1432
1667
  }
1433
1668
  getDisplayData() {
1434
1669
  if (this.displayDataCache) return this.displayDataCache;
1435
1670
  let e = this.dataManager.getData();
1436
1671
  if (e.length === 0) return e;
1437
- let t = ot(this.options.chartType, e, (e) => this.pluginManager.getChartType(e));
1672
+ let t = ft(this.options.chartType, e, (e) => this.pluginManager.getChartType(e));
1438
1673
  return this.displayDataCache = t, t;
1439
1674
  }
1675
+ recalcIndicatorsFrom(e, t) {
1676
+ this.indicatorEngine.recalculateFrom(e, t), this.announceIndicatorUpdate(t);
1677
+ }
1678
+ recalcIndicators(e) {
1679
+ this.indicatorEngine.recalculateAll(e), this.announceIndicatorUpdate(0);
1680
+ }
1681
+ announceIndicatorUpdate(e) {
1682
+ if (this.indicatorUpdateFrom !== null) {
1683
+ this.indicatorUpdateFrom = Math.min(this.indicatorUpdateFrom, e);
1684
+ return;
1685
+ }
1686
+ this.indicatorUpdateFrom = e, queueMicrotask(() => {
1687
+ let e = this.indicatorUpdateFrom;
1688
+ this.indicatorUpdateFrom = null, e !== null && this.eventBus.emit("indicatorUpdate", { from: e });
1689
+ });
1690
+ }
1440
1691
  scheduleRender() {
1441
1692
  this.renderScheduled || (this.renderScheduled = !0, requestAnimationFrame(() => {
1442
1693
  this.renderScheduled = !1, this.applyDataToViewport(), this.fitPriceAxisWidth() && this.applyDataToViewport(), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
@@ -1469,7 +1720,7 @@ var bt = 6, xt = class {
1469
1720
  }
1470
1721
  fitPriceAxisWidth() {
1471
1722
  if (!this.features.priceAxis) return !1;
1472
- let { priceRange: e } = this.viewport.getState(), t = this.themeManager.getTheme(), n = pt({
1723
+ let { priceRange: e } = this.viewport.getState(), t = this.themeManager.getTheme(), n = yt({
1473
1724
  min: e.min,
1474
1725
  max: e.max,
1475
1726
  lastPrice: this.currentPriceLine.getPrice(),
@@ -1478,7 +1729,7 @@ var bt = 6, xt = class {
1478
1729
  fontFamily: t.font.family,
1479
1730
  fontSizeSmall: t.font.sizeSmall,
1480
1731
  measure: (e, t) => this.measureText(e, t)
1481
- }), r = mt(this.priceAxisWidth, n);
1732
+ }), r = bt(this.priceAxisWidth, n);
1482
1733
  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);
1483
1734
  }
1484
1735
  measureText(e, t) {
@@ -1505,7 +1756,15 @@ var bt = 6, xt = class {
1505
1756
  })), this.lastEmittedBarWidth !== e.barWidth && (this.lastEmittedBarWidth = e.barWidth, this.eventBus.emit("zoomChange", { barWidth: e.barWidth }));
1506
1757
  }
1507
1758
  getResolvedLayout() {
1508
- return this.resolvedLayoutCache ||= this.layoutManager.resolve(), this.resolvedLayoutCache;
1759
+ return this.resolvedLayoutCache || (this.resolvedLayoutCache = this.layoutManager.resolve(), this.syncCrosshairBounds(this.resolvedLayoutCache)), this.resolvedLayoutCache;
1760
+ }
1761
+ syncCrosshairBounds(e) {
1762
+ let t = e.mainChartRect, n = t.y, r = t.y + t.height;
1763
+ for (let t of e.panels) t.config.position !== "top" && t.config.position !== "bottom" || (n = Math.min(n, t.rect.y), r = Math.max(r, t.rect.y + t.rect.height));
1764
+ this.crosshairHandler.setReportBounds({
1765
+ top: n,
1766
+ bottom: r
1767
+ });
1509
1768
  }
1510
1769
  cachedContainerSize() {
1511
1770
  let e = Date.now();
@@ -1514,7 +1773,7 @@ var bt = 6, xt = class {
1514
1773
  buildPanelRenderInfos() {
1515
1774
  if (this.panelInfoCache) return this.panelInfoCache;
1516
1775
  let e = this.getResolvedLayout(), t = this.viewport.getState(), { from: n, to: r } = t.visibleRange, i = e.panels.map((e) => {
1517
- let i = st(this.indicatorEngine.getOutput(e.config.id), n, r), a = {
1776
+ let i = pt(this.indicatorEngine.getOutput(e.config.id), n, r), a = {
1518
1777
  x: e.rect.x,
1519
1778
  y: e.rect.y + 20,
1520
1779
  width: e.rect.width,
@@ -1526,7 +1785,10 @@ var bt = 6, xt = class {
1526
1785
  viewport: {
1527
1786
  ...t,
1528
1787
  chartRect: a,
1529
- priceRange: i
1788
+ priceRange: i,
1789
+ logScale: !1,
1790
+ scaleMode: "regular",
1791
+ invertScale: !1
1530
1792
  }
1531
1793
  };
1532
1794
  });
@@ -1559,6 +1821,7 @@ var bt = 6, xt = class {
1559
1821
  compareRenderer: this.compareRenderer,
1560
1822
  alertManager: this.features.alerts ? this.alertManager : null,
1561
1823
  measureOverlay: this.measureOverlay,
1824
+ selectionBoxOverlay: this.selectionBoxOverlay,
1562
1825
  signalMarkerManager: this.signalMarkerManager,
1563
1826
  tradeZoneManager: this.tradeZoneManager,
1564
1827
  panels: t,
@@ -1571,6 +1834,7 @@ var bt = 6, xt = class {
1571
1834
  theme: this.themeManager.getTheme(),
1572
1835
  data: i,
1573
1836
  numberLocale: this.numberLocale,
1837
+ paneTitles: this.paneTitles,
1574
1838
  renderOverlayPlugins: (e, t) => this.drawOverlayPlugins(e, t)
1575
1839
  });
1576
1840
  }
@@ -1609,13 +1873,13 @@ var bt = 6, xt = class {
1609
1873
  ];
1610
1874
  function J(e) {
1611
1875
  let t = e.trim();
1612
- return t ? t[0] === "[" || t[0] === "{" ? St(t) : Ct(t) : {
1876
+ return t ? t[0] === "[" || t[0] === "{" ? kt(t) : At(t) : {
1613
1877
  data: [],
1614
1878
  rowCount: 0,
1615
1879
  skipped: 0
1616
1880
  };
1617
1881
  }
1618
- function St(e) {
1882
+ function kt(e) {
1619
1883
  let t;
1620
1884
  try {
1621
1885
  t = JSON.parse(e);
@@ -1625,19 +1889,19 @@ function St(e) {
1625
1889
  if (!Array.isArray(t)) throw Error("Expected a JSON array of OHLCV rows");
1626
1890
  let n = [], r = 0;
1627
1891
  for (let e of t) {
1628
- let t = Array.isArray(e) ? Dt(e) : Et(e);
1892
+ let t = Array.isArray(e) ? Pt(e) : Nt(e);
1629
1893
  t ? n.push(t) : r++;
1630
1894
  }
1631
1895
  return Q(n, t.length, r);
1632
1896
  }
1633
- function Ct(e) {
1897
+ function At(e) {
1634
1898
  let t = e.split(/\r?\n/).filter((e) => e.trim().length > 0);
1635
1899
  if (t.length === 0) return {
1636
1900
  data: [],
1637
1901
  rowCount: 0,
1638
1902
  skipped: 0
1639
1903
  };
1640
- let n = wt(t[0]), r = Y(t[0], n).map((e) => e.trim().toLowerCase()), i = r.some((e) => isNaN(Number(e)) && e.length > 0), a = i ? Tt(r) : {
1904
+ let n = jt(t[0]), r = Y(t[0], n).map((e) => e.trim().toLowerCase()), i = r.some((e) => isNaN(Number(e)) && e.length > 0), a = i ? Mt(r) : {
1641
1905
  time: 0,
1642
1906
  open: 1,
1643
1907
  high: 2,
@@ -1669,7 +1933,7 @@ function Ct(e) {
1669
1933
  }
1670
1934
  return Q(o, t.length - +!!i, s);
1671
1935
  }
1672
- function wt(e) {
1936
+ function jt(e) {
1673
1937
  let t = {
1674
1938
  ",": 0,
1675
1939
  ";": 0,
@@ -1689,7 +1953,7 @@ function Y(e, t) {
1689
1953
  }
1690
1954
  return n.push(r), n;
1691
1955
  }
1692
- function Tt(e) {
1956
+ function Mt(e) {
1693
1957
  let t = (t) => e.findIndex((e) => t.includes(e));
1694
1958
  return {
1695
1959
  time: t(H),
@@ -1700,7 +1964,7 @@ function Tt(e) {
1700
1964
  volume: t(q)
1701
1965
  };
1702
1966
  }
1703
- function Et(e) {
1967
+ function Nt(e) {
1704
1968
  let t = (t) => {
1705
1969
  for (let n of t) {
1706
1970
  if (e[n] !== void 0) return e[n];
@@ -1722,7 +1986,7 @@ function Et(e) {
1722
1986
  volume: Number.isFinite(s) ? s : 0
1723
1987
  };
1724
1988
  }
1725
- function Dt(e) {
1989
+ function Pt(e) {
1726
1990
  if (e.length < 5) return null;
1727
1991
  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;
1728
1992
  return t === null || ![
@@ -1762,7 +2026,7 @@ function Q(e, t, n) {
1762
2026
  }
1763
2027
  //#endregion
1764
2028
  //#region src/io/DragDropImporter.ts
1765
- var Ot = class {
2029
+ var Ft = class {
1766
2030
  host;
1767
2031
  overlay = null;
1768
2032
  callbacks;
@@ -1809,12 +2073,12 @@ var Ot = class {
1809
2073
  zIndex: "90",
1810
2074
  pointerEvents: "none",
1811
2075
  borderRadius: "10px",
1812
- border: "2px dashed var(--tcw-accent, #4f88ff)",
2076
+ border: "2px dashed var(--tcw-accent, #f2a93b)",
1813
2077
  background: "rgba(79, 136, 255, 0.06)",
1814
2078
  display: "flex",
1815
2079
  alignItems: "center",
1816
2080
  justifyContent: "center",
1817
- color: "var(--tcw-accent, #4f88ff)",
2081
+ color: "var(--tcw-accent, #f2a93b)",
1818
2082
  fontSize: "14px",
1819
2083
  fontWeight: "600",
1820
2084
  letterSpacing: "-0.005em",
@@ -1830,6 +2094,6 @@ function $(e) {
1830
2094
  return e.dataTransfer?.types?.includes("Files") ?? !1;
1831
2095
  }
1832
2096
  //#endregion
1833
- export { vt as a, _t as c, L as d, P as f, B as i, ht as l, A as m, J as n, z as o, j as p, xt as r, gt as s, Ot as t, I as u };
2097
+ export { Tt as a, wt as c, L as d, P as f, B as i, St as l, A as m, J as n, z as o, j as p, Ot as r, Ct as s, Ft as t, I as u };
1834
2098
 
1835
- //# sourceMappingURL=DragDropImporter-BcTzFeRP.js.map
2099
+ //# sourceMappingURL=DragDropImporter-Dd9Mud5J.js.map