@tradecanvas/chart 1.4.0 → 1.10.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 (195) hide show
  1. package/README.md +352 -95
  2. package/dist/Chart.d.ts +621 -23
  3. package/dist/Chart.d.ts.map +1 -1
  4. package/dist/DataManager.d.ts +5 -0
  5. package/dist/DataManager.d.ts.map +1 -1
  6. package/dist/HistoryPager.d.ts +58 -0
  7. package/dist/HistoryPager.d.ts.map +1 -0
  8. package/dist/LayoutSession-BFqQwhvV.cjs +2 -0
  9. package/dist/LayoutSession-BFqQwhvV.cjs.map +1 -0
  10. package/dist/LayoutSession-P9Vb-Jpb.js +3995 -0
  11. package/dist/LayoutSession-P9Vb-Jpb.js.map +1 -0
  12. package/dist/ThemeManager.d.ts +5 -1
  13. package/dist/ThemeManager.d.ts.map +1 -1
  14. package/dist/chartA11y.d.ts +59 -0
  15. package/dist/chartA11y.d.ts.map +1 -0
  16. package/dist/charts/ChartTypeStrategy.d.ts +5 -4
  17. package/dist/charts/ChartTypeStrategy.d.ts.map +1 -1
  18. package/dist/grid/ChartGrid.d.ts +6 -1
  19. package/dist/grid/ChartGrid.d.ts.map +1 -1
  20. package/dist/i18n-CiQ8EDVs.js +1469 -0
  21. package/dist/i18n-CiQ8EDVs.js.map +1 -0
  22. package/dist/i18n-WsLA9SmD.cjs +2 -0
  23. package/dist/i18n-WsLA9SmD.cjs.map +1 -0
  24. package/dist/index.cjs +1 -1
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.ts +24 -5
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +34 -34
  29. package/dist/index.js.map +1 -1
  30. package/dist/indicatorLabel.d.ts +7 -0
  31. package/dist/indicatorLabel.d.ts.map +1 -0
  32. package/dist/layout/LayoutManager.d.ts +50 -0
  33. package/dist/layout/LayoutManager.d.ts.map +1 -1
  34. package/dist/layout/priceAxisWidth.d.ts +2 -0
  35. package/dist/layout/priceAxisWidth.d.ts.map +1 -1
  36. package/dist/regularHours.d.ts +10 -0
  37. package/dist/regularHours.d.ts.map +1 -0
  38. package/dist/state/LayoutSession.d.ts +101 -0
  39. package/dist/state/LayoutSession.d.ts.map +1 -0
  40. package/dist/state/layoutStorage.d.ts +46 -0
  41. package/dist/state/layoutStorage.d.ts.map +1 -0
  42. package/dist/trading/wireExecution.d.ts +7 -3
  43. package/dist/trading/wireExecution.d.ts.map +1 -1
  44. package/dist/widget/ChartWidget.d.ts +219 -10
  45. package/dist/widget/ChartWidget.d.ts.map +1 -1
  46. package/dist/widget/ChartWidgetGrid.d.ts +166 -0
  47. package/dist/widget/ChartWidgetGrid.d.ts.map +1 -0
  48. package/dist/widget/DrawingTemplateStore.d.ts +29 -8
  49. package/dist/widget/DrawingTemplateStore.d.ts.map +1 -1
  50. package/dist/widget/WatchlistStore.d.ts +65 -0
  51. package/dist/widget/WatchlistStore.d.ts.map +1 -0
  52. package/dist/widget/WidgetAccountPanel.d.ts +72 -0
  53. package/dist/widget/WidgetAccountPanel.d.ts.map +1 -0
  54. package/dist/widget/WidgetAlertsPanel.d.ts +50 -3
  55. package/dist/widget/WidgetAlertsPanel.d.ts.map +1 -1
  56. package/dist/widget/WidgetBracketBar.d.ts +3 -1
  57. package/dist/widget/WidgetBracketBar.d.ts.map +1 -1
  58. package/dist/widget/WidgetChartNav.d.ts +36 -0
  59. package/dist/widget/WidgetChartNav.d.ts.map +1 -0
  60. package/dist/widget/WidgetCommandPalette.d.ts +3 -1
  61. package/dist/widget/WidgetCommandPalette.d.ts.map +1 -1
  62. package/dist/widget/WidgetContextMenu.d.ts +40 -0
  63. package/dist/widget/WidgetContextMenu.d.ts.map +1 -0
  64. package/dist/widget/WidgetDataWindow.d.ts +3 -1
  65. package/dist/widget/WidgetDataWindow.d.ts.map +1 -1
  66. package/dist/widget/WidgetDepthLadder.d.ts +3 -1
  67. package/dist/widget/WidgetDepthLadder.d.ts.map +1 -1
  68. package/dist/widget/WidgetDrawingSettings.d.ts +108 -0
  69. package/dist/widget/WidgetDrawingSettings.d.ts.map +1 -0
  70. package/dist/widget/WidgetDrawingSidebar.d.ts +16 -1
  71. package/dist/widget/WidgetDrawingSidebar.d.ts.map +1 -1
  72. package/dist/widget/WidgetDrawingStyle.d.ts +3 -1
  73. package/dist/widget/WidgetDrawingStyle.d.ts.map +1 -1
  74. package/dist/widget/WidgetDropdown.d.ts.map +1 -1
  75. package/dist/widget/WidgetGoToDate.d.ts +5 -4
  76. package/dist/widget/WidgetGoToDate.d.ts.map +1 -1
  77. package/dist/widget/WidgetHistoryPill.d.ts +23 -0
  78. package/dist/widget/WidgetHistoryPill.d.ts.map +1 -0
  79. package/dist/widget/WidgetHotkeySheet.d.ts.map +1 -1
  80. package/dist/widget/WidgetIndicatorLegend.d.ts +31 -1
  81. package/dist/widget/WidgetIndicatorLegend.d.ts.map +1 -1
  82. package/dist/widget/WidgetIndicatorSettings.d.ts +62 -7
  83. package/dist/widget/WidgetIndicatorSettings.d.ts.map +1 -1
  84. package/dist/widget/WidgetIntervalInput.d.ts +34 -0
  85. package/dist/widget/WidgetIntervalInput.d.ts.map +1 -0
  86. package/dist/widget/WidgetLayoutsDialog.d.ts +39 -0
  87. package/dist/widget/WidgetLayoutsDialog.d.ts.map +1 -0
  88. package/dist/widget/WidgetLayoutsUI.d.ts +37 -0
  89. package/dist/widget/WidgetLayoutsUI.d.ts.map +1 -0
  90. package/dist/widget/WidgetNamePrompt.d.ts +31 -0
  91. package/dist/widget/WidgetNamePrompt.d.ts.map +1 -0
  92. package/dist/widget/WidgetObjectTree.d.ts +21 -3
  93. package/dist/widget/WidgetObjectTree.d.ts.map +1 -1
  94. package/dist/widget/WidgetOrderTicket.d.ts +49 -0
  95. package/dist/widget/WidgetOrderTicket.d.ts.map +1 -0
  96. package/dist/widget/WidgetReplayBar.d.ts +15 -0
  97. package/dist/widget/WidgetReplayBar.d.ts.map +1 -1
  98. package/dist/widget/WidgetSettings.d.ts +13 -1
  99. package/dist/widget/WidgetSettings.d.ts.map +1 -1
  100. package/dist/widget/WidgetStatusBar.d.ts +3 -0
  101. package/dist/widget/WidgetStatusBar.d.ts.map +1 -1
  102. package/dist/widget/WidgetStyles.d.ts +3 -1
  103. package/dist/widget/WidgetStyles.d.ts.map +1 -1
  104. package/dist/widget/WidgetSymbolInfo.d.ts +64 -0
  105. package/dist/widget/WidgetSymbolInfo.d.ts.map +1 -0
  106. package/dist/widget/WidgetSymbolSearch.d.ts +26 -5
  107. package/dist/widget/WidgetSymbolSearch.d.ts.map +1 -1
  108. package/dist/widget/WidgetToolbar.d.ts +30 -1
  109. package/dist/widget/WidgetToolbar.d.ts.map +1 -1
  110. package/dist/widget/WidgetWatchlist.d.ts +53 -13
  111. package/dist/widget/WidgetWatchlist.d.ts.map +1 -1
  112. package/dist/widget/chartMenu.d.ts +40 -0
  113. package/dist/widget/chartMenu.d.ts.map +1 -0
  114. package/dist/widget/drawingMenu.d.ts +21 -0
  115. package/dist/widget/drawingMenu.d.ts.map +1 -0
  116. package/dist/widget/focusTrap.d.ts +8 -0
  117. package/dist/widget/focusTrap.d.ts.map +1 -0
  118. package/dist/widget/i18n.d.ts +20 -89
  119. package/dist/widget/i18n.d.ts.map +1 -1
  120. package/dist/widget/iconSet.d.ts.map +1 -1
  121. package/dist/widget/index.cjs +1644 -376
  122. package/dist/widget/index.cjs.map +1 -1
  123. package/dist/widget/index.d.ts +15 -1
  124. package/dist/widget/index.d.ts.map +1 -1
  125. package/dist/widget/index.js +6389 -1228
  126. package/dist/widget/index.js.map +1 -1
  127. package/dist/widget/indicatorTemplates.d.ts +24 -0
  128. package/dist/widget/indicatorTemplates.d.ts.map +1 -0
  129. package/dist/widget/keyTarget.d.ts +11 -0
  130. package/dist/widget/keyTarget.d.ts.map +1 -0
  131. package/dist/widget/legendValues.d.ts +11 -6
  132. package/dist/widget/legendValues.d.ts.map +1 -1
  133. package/dist/widget/locales/ar.d.ts +4 -0
  134. package/dist/widget/locales/ar.d.ts.map +1 -0
  135. package/dist/widget/locales/de.d.ts +4 -0
  136. package/dist/widget/locales/de.d.ts.map +1 -0
  137. package/dist/widget/locales/en.d.ts +722 -0
  138. package/dist/widget/locales/en.d.ts.map +1 -0
  139. package/dist/widget/locales/es.d.ts +4 -0
  140. package/dist/widget/locales/es.d.ts.map +1 -0
  141. package/dist/widget/locales/fr.d.ts +4 -0
  142. package/dist/widget/locales/fr.d.ts.map +1 -0
  143. package/dist/widget/locales/he.d.ts +4 -0
  144. package/dist/widget/locales/he.d.ts.map +1 -0
  145. package/dist/widget/locales/id.d.ts +4 -0
  146. package/dist/widget/locales/id.d.ts.map +1 -0
  147. package/dist/widget/locales/index.cjs +2 -0
  148. package/dist/widget/locales/index.cjs.map +1 -0
  149. package/dist/widget/locales/index.d.ts +33 -0
  150. package/dist/widget/locales/index.d.ts.map +1 -0
  151. package/dist/widget/locales/index.js +10089 -0
  152. package/dist/widget/locales/index.js.map +1 -0
  153. package/dist/widget/locales/ja.d.ts +4 -0
  154. package/dist/widget/locales/ja.d.ts.map +1 -0
  155. package/dist/widget/locales/ko.d.ts +4 -0
  156. package/dist/widget/locales/ko.d.ts.map +1 -0
  157. package/dist/widget/locales/pt.d.ts +4 -0
  158. package/dist/widget/locales/pt.d.ts.map +1 -0
  159. package/dist/widget/locales/ru.d.ts +4 -0
  160. package/dist/widget/locales/ru.d.ts.map +1 -0
  161. package/dist/widget/locales/th.d.ts +4 -0
  162. package/dist/widget/locales/th.d.ts.map +1 -0
  163. package/dist/widget/locales/tr.d.ts +4 -0
  164. package/dist/widget/locales/tr.d.ts.map +1 -0
  165. package/dist/widget/locales/vi.d.ts +4 -0
  166. package/dist/widget/locales/vi.d.ts.map +1 -0
  167. package/dist/widget/locales/zh.d.ts +4 -0
  168. package/dist/widget/locales/zh.d.ts.map +1 -0
  169. package/dist/widget/locales/zhHant.d.ts +4 -0
  170. package/dist/widget/locales/zhHant.d.ts.map +1 -0
  171. package/dist/widget/orderTicket.d.ts +27 -0
  172. package/dist/widget/orderTicket.d.ts.map +1 -0
  173. package/dist/widget/settingsControls.d.ts +24 -0
  174. package/dist/widget/settingsControls.d.ts.map +1 -0
  175. package/dist/widget/types.d.ts +187 -6
  176. package/dist/widget/types.d.ts.map +1 -1
  177. package/dist/widget/widgetConfig.d.ts +4 -0
  178. package/dist/widget/widgetConfig.d.ts.map +1 -1
  179. package/dist/widget/widgetLayout.d.ts +22 -0
  180. package/dist/widget/widgetLayout.d.ts.map +1 -0
  181. package/dist/widget/widgetLocales.d.ts +17 -0
  182. package/dist/widget/widgetLocales.d.ts.map +1 -0
  183. package/dist/widget/widgetTimeframes.d.ts +8 -0
  184. package/dist/widget/widgetTimeframes.d.ts.map +1 -1
  185. package/dist/widget/widgetTimezones.d.ts +32 -0
  186. package/dist/widget/widgetTimezones.d.ts.map +1 -0
  187. package/dist/widget/widgetUI.d.ts +126 -0
  188. package/dist/widget/widgetUI.d.ts.map +1 -0
  189. package/package.json +8 -3
  190. package/dist/DragDropImporter-C5kgfbET.cjs +0 -2
  191. package/dist/DragDropImporter-C5kgfbET.cjs.map +0 -1
  192. package/dist/DragDropImporter-Dd9Mud5J.js +0 -2099
  193. package/dist/DragDropImporter-Dd9Mud5J.js.map +0 -1
  194. package/dist/charts/IndicatorPriceRange.d.ts +0 -20
  195. package/dist/charts/IndicatorPriceRange.d.ts.map +0 -1
@@ -0,0 +1,3995 @@
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, fractionTick as u, indicatorSource as d, isValidTimeZone as f, mergeBar as p, normalizeBarTime as m, parseIndicatorSource as h, priceFormatterFor as g, readChartTypeOptions as _, sessionMinute as v, setLocale as ee, stepDecimals as te, tickBarCount as ne, timeframeToMs as y, volumeColor as re, zonedDateFormatter as ie } from "@tradecanvas/commons";
2
+ import { AlertDragHandler as ae, AlertManager as oe, Animator as se, AreaRenderer as ce, AxisDragHandler as le, BarCountdown as ue, BarRenderer as de, BaselineRenderer as fe, CandlestickRenderer as pe, ChartLegend as me, ChartStateManager as b, CompareRenderer as he, CompareSymbolIndicator as ge, CrosshairHandler as _e, CrosshairTooltip as ve, CurrentPriceLine as ye, DEFAULT_SESSION_HOURS as be, DataExporter as x, DepthHeatmapRenderer as xe, DrawingManager as Se, DrawingRenderer as Ce, EquivolumeRenderer as we, EventBus as Te, GridRenderer as Ee, HLCAreaRenderer as De, HiLoRenderer as Oe, HollowCandleRenderer as ke, IndicatorEngine as Ae, InteractionManager as je, KagiRenderer as Me, KeyboardHandler as Ne, LineRenderer as Pe, LineWithMarkersRenderer as Fe, MarketProfileRenderer as Ie, MeasureOverlay as Le, PanHandler as Re, PaneResizeHandler as ze, PeriodLevelsRenderer as Be, PinnedTooltip as Ve, PivotMarkersRenderer as He, PointAndFigureRenderer as Ue, PriceAxis as We, PriceAxisAddButton as Ge, PriceLines as Ke, RenderEngine as qe, RenkoRenderer as Je, ReplayManager as Ye, Screenshot as S, SelectionBoxOverlay as Xe, SessionBreaks as Ze, SessionShading as Qe, SignalMarkerManager as $e, SpreadIndicator as et, StepLineRenderer as tt, StreamManager as nt, SymbolSeriesStore as rt, TimeAxis as it, TradeZoneManager as at, TradingManager as ot, TradingRenderer as st, UndoRedoManager as ct, Viewport as lt, VolumeCandleRenderer as ut, VolumeProfileRenderer as dt, VolumeRenderer as ft, Watermark as pt, ZoomHandler as mt, barTimeStepMs as ht, findDominantSwing as gt, isRegularSession as _t, loadWebGLRenderer as vt, mergeSessionHours as yt, rangePresetStart as bt, readAlertOptions as xt, registerBuiltInDrawingTools as St, registerBuiltInIndicators as C, servesTimeframe as w, sourceParam as T, timestampToBarIndex as E, toHeikinAshi as Ct, toKagi as wt, toLineBreak as Tt, toPointAndFigure as Et, toRangeBars as Dt, toRenko as Ot, withResampling as kt, xToBarIndex as At, xToTime as D, yToPrice as jt } from "@tradecanvas/core";
3
+ //#region src/regularHours.ts
4
+ var Mt = 864e5, Nt = 10;
5
+ function Pt(e, t) {
6
+ let n = e?.timezone;
7
+ if (!n || !f(n) || t.length < 2) return null;
8
+ let r = (e?.sessions ?? []).flatMap((e) => {
9
+ let t = v(e.start), n = v(e.end);
10
+ return t === null || n === null ? [] : [{
11
+ startMinute: t,
12
+ endMinute: n
13
+ }];
14
+ });
15
+ if (r.length === 0) return null;
16
+ let i = Infinity;
17
+ for (let e = Math.max(1, t.length - Nt); e < t.length; e++) {
18
+ let n = m(t[e].time) - m(t[e - 1].time);
19
+ n > 0 && n < i && (i = n);
20
+ }
21
+ if (!(i < Mt)) return null;
22
+ let a = {
23
+ timeZone: n,
24
+ windows: r,
25
+ startMinute: r[0].startMinute,
26
+ endMinute: r[r.length - 1].endMinute
27
+ };
28
+ return (e) => _t(m(e), a);
29
+ }
30
+ //#endregion
31
+ //#region src/chartA11y.ts
32
+ var Ft = {
33
+ role: "chart",
34
+ summary: "{what}. Last price {close}.",
35
+ empty: "Chart, no data.",
36
+ view: "Showing {count} bars, {from} to {to}. High {high}, low {low}.",
37
+ bar: "{time}: open {open}, high {high}, low {low}, close {close}, volume {volume}.",
38
+ keys: "Arrow keys scroll and zoom, Home and End go to the start and the end. Comma and period read the bars one at a time."
39
+ }, O = (e, t) => e.replace(/\{(\w+)\}/g, (e, n) => n in t ? String(t[n]) : e), It = [
40
+ "role",
41
+ "aria-roledescription",
42
+ "aria-label",
43
+ "aria-describedby"
44
+ ], Lt = 400, Rt = 1e3, zt = class {
45
+ live;
46
+ help;
47
+ labels;
48
+ cursor = null;
49
+ viewTimer = null;
50
+ before = /* @__PURE__ */ new Map();
51
+ summaryAt = 0;
52
+ summaryTimer = null;
53
+ onBlur = () => {
54
+ this.cursor = null, this.source.showBar(null);
55
+ };
56
+ constructor(e, t, n = {}) {
57
+ this.container = e, this.source = t, this.labels = {
58
+ ...Ft,
59
+ ...n
60
+ };
61
+ for (let t of It) this.before.set(t, e.getAttribute(t));
62
+ e.setAttribute("role", "application"), this.help = Bt("div", "tc-sr-only"), this.help.id = `tc-chart-keys-${Math.random().toString(36).slice(2, 10)}`, e.setAttribute("aria-describedby", this.help.id), this.live = Bt("div", "tc-sr-only tc-sr-live"), this.live.setAttribute("aria-live", "polite"), this.live.setAttribute("aria-atomic", "true"), e.append(this.help, this.live), e.addEventListener("blur", this.onBlur), this.applyLabels();
63
+ }
64
+ setLabels(e) {
65
+ this.labels = {
66
+ ...Ft,
67
+ ...e
68
+ }, this.applyLabels();
69
+ }
70
+ refresh(e = !1) {
71
+ let t = Rt - (Date.now() - this.summaryAt);
72
+ if (e || t <= 0 || this.container.getAttribute("aria-label") === this.labels.empty) {
73
+ this.summaryTimer && clearTimeout(this.summaryTimer), this.summaryTimer = null, this.summaryAt = Date.now(), this.container.setAttribute("aria-label", this.summary());
74
+ return;
75
+ }
76
+ this.summaryTimer ??= setTimeout(() => {
77
+ this.summaryTimer = null, this.refresh(!0);
78
+ }, t);
79
+ }
80
+ viewMoved() {
81
+ this.cursor = null, this.viewTimer && clearTimeout(this.viewTimer), this.viewTimer = setTimeout(() => {
82
+ this.viewTimer = null, this.say(this.viewText());
83
+ }, Lt);
84
+ }
85
+ readBar(e) {
86
+ let t = this.source.bars();
87
+ if (t.length === 0) {
88
+ this.say(this.labels.empty);
89
+ return;
90
+ }
91
+ let { to: n } = this.source.visibleRange(), r = Math.max(0, Math.min(t.length - 1, Math.floor(n)));
92
+ this.cursor = this.cursor === null ? r : Math.max(0, Math.min(t.length - 1, this.cursor + e));
93
+ let i = t[this.cursor];
94
+ this.source.showBar(i.time);
95
+ let a = this.source.formatPrice;
96
+ this.say(O(this.labels.bar, {
97
+ time: this.source.formatTime(i.time),
98
+ open: a(i.open),
99
+ high: a(i.high),
100
+ low: a(i.low),
101
+ close: a(i.close),
102
+ volume: Vt(i.volume ?? 0)
103
+ }));
104
+ }
105
+ destroy() {
106
+ this.viewTimer && clearTimeout(this.viewTimer), this.summaryTimer && clearTimeout(this.summaryTimer), this.container.removeEventListener("blur", this.onBlur);
107
+ for (let [e, t] of this.before) t === null ? this.container.removeAttribute(e) : this.container.setAttribute(e, t);
108
+ this.help.remove(), this.live.remove();
109
+ }
110
+ applyLabels() {
111
+ this.container.setAttribute("aria-roledescription", this.labels.role), this.help.textContent = this.labels.keys, this.refresh(!0);
112
+ }
113
+ summary() {
114
+ let e = this.source.bars();
115
+ if (e.length === 0) return this.labels.empty;
116
+ let t = this.source.chartType(), n = [
117
+ this.source.symbol(),
118
+ this.labels.typeName ? this.labels.typeName(t) : t,
119
+ this.source.timeframe()
120
+ ].filter(Boolean).join(", ");
121
+ return O(this.labels.summary, {
122
+ what: n,
123
+ close: this.source.formatPrice(e[e.length - 1].close)
124
+ });
125
+ }
126
+ viewText() {
127
+ let e = this.source.bars();
128
+ if (e.length === 0) return this.labels.empty;
129
+ let t = this.source.visibleRange(), n = Math.max(0, Math.min(e.length - 1, Math.ceil(t.from))), r = Math.max(n, Math.min(e.length - 1, Math.floor(t.to))), i = -Infinity, a = Infinity;
130
+ for (let t = n; t <= r; t++) i = Math.max(i, e[t].high), a = Math.min(a, e[t].low);
131
+ return O(this.labels.view, {
132
+ count: r - n + 1,
133
+ from: this.source.formatTime(e[n].time),
134
+ to: this.source.formatTime(e[r].time),
135
+ high: this.source.formatPrice(i),
136
+ low: this.source.formatPrice(a)
137
+ });
138
+ }
139
+ say(e) {
140
+ this.live.textContent = e;
141
+ }
142
+ };
143
+ function Bt(e, t) {
144
+ let n = document.createElement(e);
145
+ return n.className = t, Object.assign(n.style, {
146
+ position: "absolute",
147
+ width: "1px",
148
+ height: "1px",
149
+ margin: "-1px",
150
+ padding: "0",
151
+ overflow: "hidden",
152
+ clip: "rect(0 0 0 0)",
153
+ whiteSpace: "nowrap",
154
+ border: "0"
155
+ }), n;
156
+ }
157
+ function Vt(e) {
158
+ return Number.isInteger(e) ? String(e) : e.toFixed(2);
159
+ }
160
+ //#endregion
161
+ //#region src/indicatorLabel.ts
162
+ function Ht(e, t, n, r) {
163
+ let i = Object.keys(n || t).map((e) => t[e]).filter((e) => typeof e == "number" && Number.isFinite(e)).slice(0, 3).map((e) => String(Number(e.toFixed(4)))), a = typeof t.symbol == "string" && t.symbol ? [t.symbol] : [];
164
+ return [
165
+ e === "spread" && t.mode === "ratio" ? "Ratio" : r ?? e.toUpperCase(),
166
+ ...a,
167
+ ...i
168
+ ].join(" ");
169
+ }
170
+ //#endregion
171
+ //#region src/charts/ChartTypeStrategy.ts
172
+ function Ut(e) {
173
+ switch (e) {
174
+ case "candlestick":
175
+ case "heikinAshi":
176
+ case "lineBreak":
177
+ case "rangeBars": return new pe();
178
+ case "line": return new Pe();
179
+ case "area": return new ce();
180
+ case "bar": return new de();
181
+ case "hollowCandle": return new ke();
182
+ case "baseline": return new fe();
183
+ case "renko": return new Je();
184
+ case "kagi": return new Me();
185
+ case "pointAndFigure": return new Ue();
186
+ case "volumeCandles": return new ut();
187
+ case "equivolume": return new we();
188
+ case "hlcArea": return new De();
189
+ case "stepLine": return new tt();
190
+ case "lineWithMarkers": return new Fe();
191
+ case "hiLo": return new Oe();
192
+ default: return new pe();
193
+ }
194
+ }
195
+ function Wt(e, t, n = {}) {
196
+ if (t.length === 0) return t;
197
+ switch (e) {
198
+ case "heikinAshi": return Ct(t);
199
+ case "renko": {
200
+ let e = n.renko?.boxSize;
201
+ return typeof e == "number" ? Ot(t, { brickSize: e }) : Ot(t, {
202
+ brickSize: 0,
203
+ useATR: !0,
204
+ atrPeriod: n.renko?.atrPeriod ?? 14
205
+ });
206
+ }
207
+ case "lineBreak": return Tt(t, n.lineBreak?.lines ?? 3);
208
+ case "kagi": return wt(t, n.kagi?.reversal ?? 4, n.kagi?.reversalType ?? "percent");
209
+ case "pointAndFigure": {
210
+ let e = n.pointAndFigure?.boxSize;
211
+ return Et(t, typeof e == "number" ? e : qt(t) * .01, n.pointAndFigure?.reversal ?? 3);
212
+ }
213
+ case "rangeBars": {
214
+ let e = n.rangeBars?.range;
215
+ return Dt(t, { rangeSize: typeof e == "number" ? e : qt(t) * .005 });
216
+ }
217
+ default: return t;
218
+ }
219
+ }
220
+ function Gt(e) {
221
+ switch (e) {
222
+ case "heikinAshi":
223
+ case "renko":
224
+ case "lineBreak":
225
+ case "kagi":
226
+ case "pointAndFigure":
227
+ case "rangeBars": return !0;
228
+ default: return !1;
229
+ }
230
+ }
231
+ function Kt(e) {
232
+ return e !== "heikinAshi" && Gt(e);
233
+ }
234
+ function qt(e) {
235
+ let t = 0;
236
+ for (let n of e) t += n.close;
237
+ return t / e.length;
238
+ }
239
+ function Jt(e, t) {
240
+ let n = t?.(e);
241
+ return n ? n.createRenderer() : Ut(e);
242
+ }
243
+ function Yt(e, t, n, r) {
244
+ if (t.length === 0) return t;
245
+ let i = n?.(e);
246
+ return i?.transform ? i.transform(t) : Wt(e, t, r);
247
+ }
248
+ //#endregion
249
+ //#region src/state/AutoSaveScheduler.ts
250
+ var Xt = class {
251
+ timer = null;
252
+ delayMs = 0;
253
+ key = null;
254
+ constructor(e) {
255
+ this.save = e;
256
+ }
257
+ enable(e, t) {
258
+ this.key = e, this.delayMs = t;
259
+ }
260
+ disable() {
261
+ this.key = null, this.delayMs = 0, this.cancel();
262
+ }
263
+ schedule() {
264
+ this.delayMs <= 0 || !this.key || (this.timer && clearTimeout(this.timer), this.timer = setTimeout(() => {
265
+ this.timer = null, this.key && this.save(this.key);
266
+ }, this.delayMs));
267
+ }
268
+ cancel() {
269
+ this.timer &&= (clearTimeout(this.timer), null);
270
+ }
271
+ isEnabled() {
272
+ return this.delayMs > 0 && this.key !== null;
273
+ }
274
+ hasPending() {
275
+ return this.timer !== null;
276
+ }
277
+ };
278
+ //#endregion
279
+ //#region src/DataManager.ts
280
+ function k(e) {
281
+ if (!e || typeof e.time != "number" || !Number.isFinite(e.time)) return !1;
282
+ let { open: t, high: n, low: r, close: i } = e;
283
+ 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));
284
+ }
285
+ function Zt(e) {
286
+ return e.volume !== void 0 && e.high >= e.open && e.high >= e.close && e.low <= e.open && e.low <= e.close;
287
+ }
288
+ function A(e) {
289
+ return {
290
+ ...e,
291
+ high: Math.max(e.open, e.high, e.low, e.close),
292
+ low: Math.min(e.open, e.high, e.low, e.close),
293
+ volume: e.volume === void 0 ? 0 : Math.max(0, e.volume)
294
+ };
295
+ }
296
+ var j = class {
297
+ data = [];
298
+ getData() {
299
+ return this.data;
300
+ }
301
+ setData(e) {
302
+ let t = [];
303
+ for (let n = 0; n < e.length; n++) {
304
+ let r = e[n];
305
+ k(r) && t.push(Zt(r) ? r : A(r));
306
+ }
307
+ this.data = t;
308
+ }
309
+ prependBars(e) {
310
+ let t = this.data.length > 0 ? this.data[0].time : Infinity, n = [];
311
+ for (let r = 0; r < e.length; r++) {
312
+ let i = e[r];
313
+ !k(i) || i.time >= t || n.push(Zt(i) ? i : A(i));
314
+ }
315
+ if (n.length === 0) return 0;
316
+ n.sort((e, t) => e.time - t.time);
317
+ let r = 0;
318
+ for (let e = 0; e < n.length; e++) r > 0 && n[r - 1].time === n[e].time || (n[r++] = n[e]);
319
+ return n.length = r, this.data = n.concat(this.data), r;
320
+ }
321
+ appendBar(e) {
322
+ k(e) && this.data.push(A(e));
323
+ }
324
+ updateLastBar(e) {
325
+ if (!k(e)) return;
326
+ let t = A(e);
327
+ if (this.data.length === 0) {
328
+ this.data.push(t);
329
+ return;
330
+ }
331
+ this.data[this.data.length - 1] = t;
332
+ }
333
+ updateLastBarFromTick(e) {
334
+ 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] = p(this.data[this.data.length - 1], e)));
335
+ }
336
+ getLength() {
337
+ return this.data.length;
338
+ }
339
+ clear() {
340
+ this.data = [];
341
+ }
342
+ }, M = 5e3, Qt = 6e4, $t = 500, en = class {
343
+ loader = null;
344
+ pageSize = 500;
345
+ loading = !1;
346
+ exhausted = !1;
347
+ failures = 0;
348
+ retryAt = 0;
349
+ seq = 0;
350
+ constructor(e) {
351
+ this.host = e;
352
+ }
353
+ setLoader(e, t = 500) {
354
+ this.loader = e, this.pageSize = Math.max(1, Math.floor(t)), this.reset();
355
+ }
356
+ hasLoader() {
357
+ return this.loader !== null;
358
+ }
359
+ reset() {
360
+ this.seq++, this.loading = !1, this.exhausted = !1, this.failures = 0, this.retryAt = 0;
361
+ }
362
+ isLoading() {
363
+ return this.loading;
364
+ }
365
+ hasMore() {
366
+ return !this.exhausted;
367
+ }
368
+ maybeLoad(e, t) {
369
+ e >= t || !this.canLoad() || this.failures >= 5 || this.now() < this.retryAt || this.loadMore();
370
+ }
371
+ async loadMore() {
372
+ let e = this.loader, t = this.host.oldestTime();
373
+ if (!e || !this.canLoad() || t === null) return 0;
374
+ let n = this.seq;
375
+ this.loading = !0, this.emit({
376
+ state: "loading",
377
+ count: 0
378
+ });
379
+ let r;
380
+ try {
381
+ r = await e(t, this.pageSize);
382
+ } catch (e) {
383
+ return n === this.seq ? (this.loading = !1, this.failures++, this.retryAt = this.now() + Math.min(Qt, M * 2 ** (this.failures - 1)), this.emit({
384
+ state: "error",
385
+ count: 0,
386
+ error: e instanceof Error ? e.message : String(e)
387
+ }), 0) : 0;
388
+ }
389
+ if (n !== this.seq) return 0;
390
+ this.loading = !1, this.failures = 0, this.retryAt = 0;
391
+ let i = this.host.prepend(r);
392
+ return i === 0 ? (this.exhausted = !0, this.emit({
393
+ state: "end",
394
+ count: 0
395
+ })) : this.emit({
396
+ state: "loaded",
397
+ count: i
398
+ }), i;
399
+ }
400
+ canLoad() {
401
+ return this.loader !== null && !this.loading && !this.exhausted;
402
+ }
403
+ emit(e) {
404
+ try {
405
+ this.host.emit(e);
406
+ } catch (e) {
407
+ console.error("[TradeCanvas] A historyLoad listener threw:", e);
408
+ }
409
+ }
410
+ now() {
411
+ return this.host.now ? this.host.now() : Date.now();
412
+ }
413
+ }, N = class {
414
+ theme;
415
+ shape = null;
416
+ constructor(t) {
417
+ !t || t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t };
418
+ }
419
+ getTheme() {
420
+ return this.theme;
421
+ }
422
+ setTheme(t) {
423
+ t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t }, this.shape && (this.theme = {
424
+ ...this.theme,
425
+ shape: {
426
+ ...this.theme.shape,
427
+ ...this.shape
428
+ }
429
+ });
430
+ }
431
+ setShape(e) {
432
+ this.shape = e ? { ...e } : null, this.theme = {
433
+ ...this.theme,
434
+ shape: e ? {
435
+ ...this.theme.shape,
436
+ ...e
437
+ } : this.theme.shape
438
+ };
439
+ }
440
+ }, P = 200, F = 80, I = (e) => e.position === "top" || e.position === "bottom", L = class {
441
+ panels = [];
442
+ containerWidth = 0;
443
+ containerHeight = 0;
444
+ priceAxisWidth = a;
445
+ leftAxisWidth = 0;
446
+ maximized = null;
447
+ resize(e, t) {
448
+ this.containerWidth = e, this.containerHeight = t;
449
+ }
450
+ addPanel(e, n = "bottom", r) {
451
+ this.maximized = null;
452
+ let a = n === "left" || n === "right";
453
+ this.panels.push({
454
+ id: e,
455
+ position: n,
456
+ size: r ?? (a ? P : t),
457
+ minSize: a ? F : i,
458
+ content: {
459
+ type: "indicator",
460
+ indicatorInstanceId: e
461
+ }
462
+ });
463
+ }
464
+ renamePanel(e, t) {
465
+ let n = this.panels.find((t) => t.id === e);
466
+ n && (n.id = t, n.content = {
467
+ ...n.content,
468
+ indicatorInstanceId: t
469
+ }, this.maximized === e && (this.maximized = t));
470
+ }
471
+ removePanel(e) {
472
+ this.panels = this.panels.filter((t) => t.id !== e), this.maximized === e && (this.maximized = null);
473
+ }
474
+ setPanelCollapsed(e, t) {
475
+ let n = this.panels.find((t) => t.id === e);
476
+ return !n || !I(n) || this.maximized === null && !!n.collapsed === t ? !1 : (this.maximized = null, n.collapsed = t || void 0, !0);
477
+ }
478
+ isPanelCollapsed(e) {
479
+ return !!this.panels.find((t) => t.id === e)?.collapsed;
480
+ }
481
+ isPanelShownCollapsed(e) {
482
+ let t = this.panels.find((t) => t.id === e);
483
+ return !t || !I(t) ? !1 : this.maximized === null ? !!t.collapsed : this.maximized !== e;
484
+ }
485
+ setPanelScale(e, t) {
486
+ let n = this.panels.find((t) => t.id === e);
487
+ if (!n) return !1;
488
+ let r = !1;
489
+ return t.log !== void 0 && !!n.logScale !== t.log && (n.logScale = t.log || void 0, r = !0), t.invert !== void 0 && !!n.invertScale !== t.invert && (n.invertScale = t.invert || void 0, r = !0), t.percent !== void 0 && !!n.percentScale !== t.percent && (n.percentScale = t.percent || void 0, r = !0), r;
490
+ }
491
+ canMovePanel(e, t) {
492
+ let n = this.panels.find((t) => t.id === e);
493
+ if (!n) return !1;
494
+ let r = this.panels.filter((e) => e.position === n.position);
495
+ return r[r.indexOf(n) + t] !== void 0;
496
+ }
497
+ setMaximizedPanel(e) {
498
+ let t = e === null ? null : this.panels.find((t) => t.id === e);
499
+ return e !== null && (!t || !I(t)) || this.maximized === e ? !1 : (this.maximized = e, t && (t.collapsed = void 0), !0);
500
+ }
501
+ getMaximizedPanel() {
502
+ return this.maximized;
503
+ }
504
+ movePanel(e, t) {
505
+ let n = this.panels.find((t) => t.id === e);
506
+ if (!n) return !1;
507
+ let r = this.panels.filter((e) => e.position === n.position), i = r[r.indexOf(n) + t];
508
+ if (!i) return !1;
509
+ let a = this.panels.indexOf(n), o = this.panels.indexOf(i), s = [...this.panels];
510
+ return s[a] = i, s[o] = n, this.panels = s, !0;
511
+ }
512
+ orderPanels(e) {
513
+ let t = (t) => {
514
+ let n = e.indexOf(t.id);
515
+ return n < 0 ? e.length + this.panels.indexOf(t) : n;
516
+ };
517
+ this.panels = [...this.panels].sort((e, n) => t(e) - t(n));
518
+ }
519
+ shownSize(e, t) {
520
+ return I(e) ? this.maximized ? e.id === this.maximized ? t : 20 : e.collapsed ? 20 : e.size : e.size;
521
+ }
522
+ setPanelPosition(e, n) {
523
+ let r = this.panels.find((t) => t.id === e);
524
+ if (r) {
525
+ let a = r.position === "left" || r.position === "right", o = n === "left" || n === "right";
526
+ r.position = n, a !== o && (r.size = o ? P : t, r.minSize = o ? F : i), o && (r.collapsed = void 0, this.maximized === e && (this.maximized = null));
527
+ }
528
+ }
529
+ setPanelSize(e, t) {
530
+ let n = this.panels.find((t) => t.id === e);
531
+ if (n) {
532
+ let e = I(n) ? this.containerHeight - o - 48 : this.containerWidth / 2, r = e > n.minSize ? Math.min(t, e) : t;
533
+ n.size = Math.max(n.minSize, r), n.collapsed = void 0, this.maximized = null;
534
+ }
535
+ }
536
+ setPriceAxisWidth(e) {
537
+ this.priceAxisWidth = e;
538
+ }
539
+ setLeftAxisWidth(e) {
540
+ this.leftAxisWidth = Math.max(0, e);
541
+ }
542
+ getPanels() {
543
+ return this.panels;
544
+ }
545
+ resolve() {
546
+ 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 = (n.length + r.length - 1) * 20, a = this.maximized ? this.panels.find((e) => e.id === this.maximized) : void 0, s = Math.max(a?.minSize ?? 0, this.containerHeight - o - 48 - i), c = (e) => this.shownSize(e, s), l = e.reduce((e, t) => e + t.size, 0), u = t.reduce((e, t) => e + t.size, 0), d = n.reduce((e, t) => e + c(t), 0), f = r.reduce((e, t) => e + c(t), 0), p = l + this.leftAxisWidth, m = {
547
+ x: p,
548
+ y: d,
549
+ width: Math.max(0, this.containerWidth - p - u - this.priceAxisWidth),
550
+ height: Math.max(0, this.containerHeight - d - f - o)
551
+ }, h = [], g = [], _ = 0;
552
+ for (let t of e) h.push({
553
+ config: t,
554
+ rect: {
555
+ x: _,
556
+ y: 0,
557
+ width: t.size,
558
+ height: this.containerHeight - o
559
+ }
560
+ }), g.push({
561
+ panelId: t.id,
562
+ rect: {
563
+ x: _ + t.size - 2,
564
+ y: 0,
565
+ width: 4,
566
+ height: this.containerHeight
567
+ },
568
+ orientation: "vertical"
569
+ }), _ += t.size;
570
+ let v = 0;
571
+ for (let e of n) {
572
+ let t = c(e);
573
+ h.push({
574
+ config: e,
575
+ rect: {
576
+ x: p,
577
+ y: v,
578
+ width: m.width,
579
+ height: t
580
+ }
581
+ }), g.push({
582
+ panelId: e.id,
583
+ rect: {
584
+ x: p,
585
+ y: v + t - 2,
586
+ width: m.width,
587
+ height: 4
588
+ },
589
+ orientation: "horizontal"
590
+ }), v += t;
591
+ }
592
+ v = m.y + m.height;
593
+ for (let e of r) {
594
+ let t = c(e);
595
+ h.push({
596
+ config: e,
597
+ rect: {
598
+ x: p,
599
+ y: v,
600
+ width: m.width,
601
+ height: t
602
+ }
603
+ }), g.push({
604
+ panelId: e.id,
605
+ rect: {
606
+ x: p,
607
+ y: v - 2,
608
+ width: m.width,
609
+ height: 4
610
+ },
611
+ orientation: "horizontal"
612
+ }), v += t;
613
+ }
614
+ _ = p + m.width + this.priceAxisWidth;
615
+ for (let e of t) h.push({
616
+ config: e,
617
+ rect: {
618
+ x: _,
619
+ y: 0,
620
+ width: e.size,
621
+ height: this.containerHeight - o
622
+ }
623
+ }), g.push({
624
+ panelId: e.id,
625
+ rect: {
626
+ x: _ - 2,
627
+ y: 0,
628
+ width: 4,
629
+ height: this.containerHeight
630
+ },
631
+ orientation: "vertical"
632
+ }), _ += e.size;
633
+ return {
634
+ mainChartRect: m,
635
+ panels: h,
636
+ dividers: g
637
+ };
638
+ }
639
+ getMainChartRect() {
640
+ return this.resolve().mainChartRect;
641
+ }
642
+ }, tn = 14, nn = 14, rn = 22, R = 4;
643
+ function z(e) {
644
+ 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] : [
645
+ t,
646
+ n,
647
+ r
648
+ ], m = a;
649
+ for (let t of p) {
650
+ if (!Number.isFinite(t)) continue;
651
+ let n = e.format ? e.format(t) : l(t, d, i), r = e.format ? n : l(t, f, i);
652
+ m = Math.max(m, u(n, `500 ${c}px ${o}`) + tn, u(r, `bold 11px ${o}`) + nn, u(r, `600 ${c}px ${o}`) + rn);
653
+ }
654
+ return m <= a ? a : Math.ceil(m / R) * R;
655
+ }
656
+ function B(e, t) {
657
+ return t > e || t <= e - 12 ? t : e;
658
+ }
659
+ var an = class {
660
+ netY = 0;
661
+ travelX = 0;
662
+ engaged = !1;
663
+ reset() {
664
+ this.netY = 0, this.travelX = 0, this.engaged = !1;
665
+ }
666
+ step(e, t, n) {
667
+ if (this.engaged) return !0;
668
+ if (this.netY += t, this.travelX += Math.abs(e), !n) this.engaged = !0;
669
+ else {
670
+ let e = Math.abs(this.netY);
671
+ this.engaged = e > 24 && e >= this.travelX * .5;
672
+ }
673
+ return this.engaged;
674
+ }
675
+ }, on = 1;
676
+ function V(e, t) {
677
+ return e.filter((e) => (e.descriptor.layer ?? "overlay") === t);
678
+ }
679
+ function H(e) {
680
+ switch (e.kind) {
681
+ case "indicator": return `indicator:${e.plugin.descriptor.id}`;
682
+ case "drawing": return `drawing:${e.plugin.descriptor.type}`;
683
+ case "chartType": return `chartType:${e.plugin.descriptor.type}`;
684
+ case "overlay": return `overlay:${e.plugin.descriptor.id}`;
685
+ }
686
+ }
687
+ //#endregion
688
+ //#region src/plugins/registry.ts
689
+ var U = /* @__PURE__ */ new Map();
690
+ function sn(e) {
691
+ U.set(H(e), e);
692
+ }
693
+ function cn(e) {
694
+ return U.delete(e);
695
+ }
696
+ function ln() {
697
+ return [...U.values()];
698
+ }
699
+ function un() {
700
+ U.clear();
701
+ }
702
+ //#endregion
703
+ //#region src/plugins/PluginManager.ts
704
+ var dn = class {
705
+ plugins = /* @__PURE__ */ new Map();
706
+ constructor(e, t = {}) {
707
+ if (this.indicatorEngine = e, t.inheritGlobal !== !1) for (let e of ln()) this.add(e);
708
+ for (let e of t.plugins ?? []) this.add(e);
709
+ }
710
+ register(e) {
711
+ this.add(e);
712
+ }
713
+ unregister(e) {
714
+ return this.plugins.delete(e);
715
+ }
716
+ list() {
717
+ return [...this.plugins.values()];
718
+ }
719
+ registerIndicator(e) {
720
+ this.add({
721
+ kind: "indicator",
722
+ plugin: e
723
+ });
724
+ }
725
+ getChartType(e) {
726
+ let t = this.plugins.get(`chartType:${e}`);
727
+ return t?.kind === "chartType" ? t.plugin : void 0;
728
+ }
729
+ getOverlays() {
730
+ let e = [];
731
+ for (let t of this.plugins.values()) t.kind === "overlay" && e.push(t.plugin);
732
+ return e;
733
+ }
734
+ add(e) {
735
+ this.plugins.set(H(e), e), e.kind === "indicator" && this.indicatorEngine.register(e.plugin);
736
+ }
737
+ }, fn = {
738
+ orderPlace: (e, t) => e.placeOrder(t),
739
+ orderModify: (e, t) => e.modifyOrder(t),
740
+ orderCancel: (e, t) => e.cancelOrder(t),
741
+ positionModify: (e, t) => e.modifyPosition(t),
742
+ positionClose: (e, t) => e.closePosition(t),
743
+ positionReverse: (e, t, n) => pn(e, t, n)
744
+ };
745
+ async function pn(e, t, n) {
746
+ let { reversing: r } = n;
747
+ if (!r.has(t.positionId)) {
748
+ r.add(t.positionId);
749
+ try {
750
+ if (e.reversePosition) {
751
+ await e.reversePosition(t);
752
+ return;
753
+ }
754
+ let r = n.positions().find((e) => e.id === t.positionId);
755
+ if (!r) throw Error(`No position ${t.positionId} to reverse`);
756
+ let i = r.quantity - (r.closedQuantity ?? 0);
757
+ if (!(i > 0)) throw Error(`Position ${t.positionId} has nothing open to reverse`);
758
+ await e.closePosition({ positionId: r.id });
759
+ try {
760
+ await e.placeOrder({
761
+ side: r.side === "buy" ? "sell" : "buy",
762
+ type: "market",
763
+ price: r.entryPrice,
764
+ quantity: i
765
+ });
766
+ } catch (e) {
767
+ throw Error(`Position ${t.positionId} was closed, but the order the other way failed`, { cause: e });
768
+ }
769
+ } finally {
770
+ r.delete(t.positionId);
771
+ }
772
+ }
773
+ }
774
+ function mn(e, t) {
775
+ let n = [], r = null, i = {
776
+ positions: () => r ?? t.getPositions?.() ?? [],
777
+ reversing: /* @__PURE__ */ new Set()
778
+ }, a = (e) => t.setOrders(e.data ?? []), o = (e) => {
779
+ r = e.data ?? [], t.setPositions([...r]);
780
+ }, s = (e) => t.onError(e.data ?? { message: "Execution error" }), c = (e) => {
781
+ e.data && t.onFill?.(e.data);
782
+ };
783
+ e.on("orders", a), e.on("positions", o), e.on("error", s), e.on("fill", c), n.push(() => e.off("orders", a), () => e.off("positions", o), () => e.off("error", s), () => e.off("fill", c));
784
+ for (let r of Object.keys(fn)) {
785
+ let a = fn[r], o = t.onIntent(r, (n) => {
786
+ Promise.resolve(a(e, n, i)).catch((e) => t.onError({
787
+ message: `Execution command failed: ${r}`,
788
+ cause: e
789
+ }));
790
+ });
791
+ n.push(o);
792
+ }
793
+ return () => {
794
+ for (let e of n) e();
795
+ };
796
+ }
797
+ //#endregion
798
+ //#region src/Chart.ts
799
+ var hn = {
800
+ min: 0,
801
+ max: 100
802
+ }, gn = 0xe8d4a51000, _n = "exchange";
803
+ function vn(e) {
804
+ if (typeof e == "string" && e !== "exchange" && !f(e)) throw RangeError(`Unknown time zone: ${e}`);
805
+ if (typeof e == "number" && !Number.isFinite(e)) throw RangeError(`Invalid UTC offset: ${e}`);
806
+ }
807
+ var yn = 2, bn = .08, xn = 800, Sn = 20, Cn = 8, wn = class {
808
+ static version = "1.10.0";
809
+ engine;
810
+ viewport;
811
+ dataManager;
812
+ themeManager;
813
+ layoutManager;
814
+ pluginManager;
815
+ indicatorEngine;
816
+ drawingManager;
817
+ drawingRenderer;
818
+ tradingManager;
819
+ tradingRenderer;
820
+ eventBus;
821
+ streamManager = null;
822
+ executionAdapter = null;
823
+ execTeardown = null;
824
+ autoScrollOnNewBar = !0;
825
+ displayDataCache = null;
826
+ indicatorUpdateFrom = null;
827
+ resolvedLayoutCache = null;
828
+ panelInfoCache = null;
829
+ renderScheduled = !1;
830
+ priceAxisWidth = a;
831
+ measureCtx;
832
+ containerSizeCache = null;
833
+ containerSizeCacheTime = 0;
834
+ lastEmittedRange = null;
835
+ lastEmittedPriceRange = null;
836
+ lastEmittedBarWidth = null;
837
+ chartLegend;
838
+ watermark;
839
+ barCountdown;
840
+ unrestoredIndicators = [];
841
+ indicatorHistoryDepth = 0;
842
+ removedDrawingAlerts = /* @__PURE__ */ new Map();
843
+ zoomAreaMode = !1;
844
+ priceAxisAddButton = new Ge();
845
+ displayTz = null;
846
+ timezoneSetting = null;
847
+ symbolInfo = null;
848
+ symbolInfoSeq = 0;
849
+ sessionBreaks;
850
+ sessionShading;
851
+ hostSessionHours = { ...be };
852
+ compareRenderer;
853
+ countdownInterval = null;
854
+ volumeRenderer;
855
+ volumeProfile;
856
+ marketProfile;
857
+ depthHeatmap;
858
+ periodLevels;
859
+ pivotMarkers;
860
+ alertManager;
861
+ signalMarkerManager;
862
+ tradeZoneManager;
863
+ measureOverlay;
864
+ selectionBoxOverlay = new Xe();
865
+ replayManager;
866
+ replayBarUnsub = null;
867
+ replaySeeking = !1;
868
+ replaySession = null;
869
+ replayStepsSeries = null;
870
+ replayCoarse = null;
871
+ undoRedoManager;
872
+ autoSaveScheduler = new Xt((e) => this.saveState(e));
873
+ animator;
874
+ crosshairTooltip;
875
+ pinnedTooltip;
876
+ interactionManager;
877
+ crosshairHandler;
878
+ chartRenderer;
879
+ rendererToken = 0;
880
+ disposed = !1;
881
+ chartTypeOptions = {};
882
+ mainSeriesVisible = !0;
883
+ priceLines = new Ke();
884
+ symbolSeries = new rt();
885
+ extendedHours = !0;
886
+ replayRestarting = !1;
887
+ fullSeries = null;
888
+ requestedSymbols = /* @__PURE__ */ new Set();
889
+ gridRenderer;
890
+ priceAxis;
891
+ leftPriceAxis = new We();
892
+ leftScaleRequested = !1;
893
+ leftAxisWidth = a;
894
+ leftViewport = null;
895
+ timeAxis;
896
+ options;
897
+ features;
898
+ marketConfig = null;
899
+ container;
900
+ currentPriceLine;
901
+ numberLocale;
902
+ marketPricePrecision = null;
903
+ priceFormatter = null;
904
+ priceUnit = null;
905
+ paneTitles = !0;
906
+ defaultAutoScale;
907
+ keyboardHandler = null;
908
+ a11y = null;
909
+ onWindowKeyDown = null;
910
+ currentSymbol = "";
911
+ streamTimeframe = null;
912
+ announcedSymbol = null;
913
+ announcedTimeframe = null;
914
+ streamAdapter = null;
915
+ history;
916
+ historyFromStream = !1;
917
+ hostHistoryLoader = !1;
918
+ snapshotKey = null;
919
+ historyCheckQueued = !1;
920
+ constructor(e, t) {
921
+ t.timeZone != null && vn(t.timeZone), this.container = e, this.options = {
922
+ ...t,
923
+ chartType: t.chartType ?? "candlestick"
924
+ }, this.numberLocale = t.numberLocale ?? "en-US", this.defaultAutoScale = t.autoScale !== !1;
925
+ let n = t.features ?? {};
926
+ this.features = {
927
+ drawings: n.drawings ?? !0,
928
+ drawingTools: n.drawingTools ?? [],
929
+ drawingMagnet: n.drawingMagnet ?? !0,
930
+ drawingUndoRedo: n.drawingUndoRedo ?? !0,
931
+ trading: n.trading ?? !0,
932
+ tradingContextMenu: n.tradingContextMenu ?? !1,
933
+ priceAxisAddButton: n.priceAxisAddButton ?? !1,
934
+ indicators: n.indicators ?? !0,
935
+ indicatorIds: n.indicatorIds ?? [],
936
+ panning: n.panning ?? !0,
937
+ zooming: n.zooming ?? !0,
938
+ crosshair: n.crosshair ?? !0,
939
+ crosshairTooltip: n.crosshairTooltip ?? !0,
940
+ keyboard: n.keyboard ?? !0,
941
+ priceAxis: n.priceAxis ?? !0,
942
+ timeAxis: n.timeAxis ?? !0,
943
+ grid: n.grid ?? t.grid?.visible ?? !0,
944
+ legend: n.legend ?? !0,
945
+ indicatorValueLabels: n.indicatorValueLabels ?? !0,
946
+ volume: n.volume ?? !0,
947
+ watermark: n.watermark ?? !0,
948
+ saveLoad: n.saveLoad ?? !0,
949
+ screenshot: n.screenshot ?? !0,
950
+ alerts: n.alerts ?? !0,
951
+ replay: n.replay ?? !0,
952
+ sessionBreaks: n.sessionBreaks ?? !0,
953
+ barCountdown: n.barCountdown ?? !0,
954
+ compareSymbols: n.compareSymbols ?? !0,
955
+ dataExport: n.dataExport ?? !0,
956
+ logScale: n.logScale ?? !0,
957
+ timeframes: n.timeframes ?? [],
958
+ defaultTimeframeFavorites: n.defaultTimeframeFavorites ?? []
959
+ }, e.style.position = "relative", e.style.overflow = "hidden", e.tabIndex = 0, e.style.outline = "none", e.style.userSelect = "none", e.style.webkitUserSelect = "none", this.dataManager = new j(), this.history = new en({
960
+ oldestTime: () => this.dataManager.getData()[0]?.time ?? null,
961
+ prepend: (e) => this.prependBars(e),
962
+ emit: (e) => this.eventBus.emit("historyLoad", e)
963
+ }), this.themeManager = new N(t.theme), this.layoutManager = new L(), this.indicatorEngine = new Ae(), this.pluginManager = new dn(this.indicatorEngine, { plugins: t.plugins }), this.eventBus = new Te(), C(this.indicatorEngine), this.indicatorEngine.register(new ge(this.symbolSeries)), this.indicatorEngine.register(new et(this.symbolSeries)), this.drawingManager = new Se(), St(this.drawingManager), this.drawingRenderer = new Ce(this.drawingManager), this.drawingManager.setRequestRender(() => {
964
+ this.syncRenderContext(), this.engine.requestRender(r.Overlay), this.scheduleAutoSave();
965
+ }), this.drawingManager.setEventCallback((e, t) => {
966
+ this.followDrawingAlerts(e, t?.id), this.eventBus.emit(e, t), (e === "drawingCreate" || e === "drawingUpdate" || e === "drawingRemove") && this.announceStateChange();
967
+ }), this.drawingManager.setToolFilter((e) => this.features.drawings && (this.features.drawingTools.length === 0 || this.features.drawingTools.includes(e))), this.undoRedoManager = new ct();
968
+ let i = "";
969
+ this.undoRedoManager.setOnChange(() => {
970
+ let { canUndo: e, canRedo: t } = this.undoRedoManager.getState(), n = `${e}|${t}`;
971
+ n !== i && (i = n, this.eventBus.emit("historyChange", {
972
+ canUndo: e,
973
+ canRedo: t
974
+ }));
975
+ }), this.drawingManager.setUndoRedoManager(this.undoRedoManager), this.drawingManager.setSelectionListener((e) => this.eventBus.emit("drawingSelect", {
976
+ ids: e,
977
+ primary: e[0] ?? null
978
+ })), this.drawingManager.setForeignHistory((e, t) => {
979
+ e.type === "custom" ? e.custom?.[t]() : this.applyIndicatorStep(e, t);
980
+ }), 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 ot({
981
+ enabled: this.features.trading,
982
+ contextMenu: { enabled: this.features.tradingContextMenu }
983
+ }), this.tradingRenderer = new st(this.tradingManager), this.tradingManager.setContainer(e), this.tradingManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradingManager.setEventCallback((e, t) => {
984
+ this.eventBus.emit(e, t);
985
+ }), this.engine = new qe(e);
986
+ let a = this.engine.dprManager.getContainerSize();
987
+ if (this.viewport = new lt(a.width, a.height, t.minBarSpacing ?? 2, t.maxBarSpacing ?? 30, t.rightMargin ?? 5), this.viewport.setPanLimits({
988
+ freePan: t.freePan ?? !0,
989
+ minVisibleBars: t.panLimits?.minVisibleBars ?? 3
990
+ }), this.layoutManager.resize(a.width, a.height), this.engine.onContainerResize = (e) => {
991
+ if (e.width <= 0 || e.height <= 0) return;
992
+ let t = this.viewport.isAtEnd();
993
+ this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(t);
994
+ }, this.chartRenderer = this.createChartRenderer(this.options.chartType), this.gridRenderer = new Ee(), t.grid?.visible === !1 && this.gridRenderer.setVisible(!1), this.priceAxis = new We(), this.priceAxis.setLocale(this.numberLocale), this.leftPriceAxis.setLocale(this.numberLocale), this.timeAxis = new it(), this.crosshairHandler = new _e(), this.crosshairHandler.setLocale(this.numberLocale), t.crosshair?.mode && this.crosshairHandler.setMode(t.crosshair.mode), this.crosshairHandler.setCallback((e, t) => {
995
+ if (e !== null && t) {
996
+ let n = this.dataManager.getData(), r = e < n.length ? n[e] : void 0;
997
+ this.chartLegend.setHoverBar(r ?? null);
998
+ let i = this.viewport.getState(), a = t.y >= i.chartRect.y && t.y <= i.chartRect.y + i.chartRect.height;
999
+ r && a && this.features.crosshairTooltip ? this.crosshairTooltip.show(t, r, this.themeManager.getTheme(), this.cachedContainerSize(), {
1000
+ prevClose: e > 0 ? n[e - 1]?.close : void 0,
1001
+ priceRange: i.priceRange,
1002
+ plot: i.chartRect,
1003
+ barStepMs: ht(n)
1004
+ }) : this.crosshairTooltip.hide(), this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), r ?? null, e, this.themeManager.getTheme()), this.eventBus.emit("crosshairMove", {
1005
+ point: t,
1006
+ bar: r,
1007
+ barIndex: e
1008
+ });
1009
+ } else this.crosshairTooltip.hide(), this.chartLegend.setHoverBar(null), this.eventBus.emit("crosshairLeave", {});
1010
+ }), this.chartLegend = new me(), this.chartLegend.setChartType(this.options.chartType), this.chartLegend.setLocale(this.numberLocale), this.watermark = new pt(), t.watermark && this.watermark.setConfig(t.watermark), this.volumeRenderer = new ft(), this.volumeProfile = new dt(), this.marketProfile = new Ie(), this.depthHeatmap = new xe(), this.periodLevels = new Be(), this.pivotMarkers = new He(), this.barCountdown = new ue(), this.barCountdown.setVisible(this.features.barCountdown), this.sessionBreaks = new Ze(), this.sessionBreaks.setLocale(this.numberLocale), this.sessionShading = new Qe(), this.compareRenderer = new he(), t.sessionBreaks ? this.sessionBreaks.setConfig({
1011
+ visible: t.sessionBreaks.visible ?? !0,
1012
+ color: t.sessionBreaks.color,
1013
+ lineStyle: t.sessionBreaks.lineStyle,
1014
+ lineWidth: t.sessionBreaks.lineWidth
1015
+ }) : t.features?.sessionBreaks !== !1 && this.sessionBreaks.setVisible(!0), t.logScale && this.features.logScale && this.viewport.setLogScale(!0), this.animator = new se(), this.crosshairTooltip = new ve(), this.crosshairTooltip.create(e), this.crosshairTooltip.setLocale(this.numberLocale), this.pinnedTooltip = new Ve(), this.pinnedTooltip.create(e), t.priceFormat && this.applyPriceFormat(t.priceFormat), t.chartTypeOptions && (this.chartTypeOptions = _(t.chartTypeOptions)), t.highLowLines && this.priceLines.setHighLow(!0), t.shapes && this.themeManager.setShape(Dn(t.shapes)), this.priceLines.setPriceText((e) => this.formatPrice(e)), t.extendedHours === !1 && (this.extendedHours = !1), t.timeFormatter && this.applyTimeFormatter(t.timeFormatter), this.keyboardHandler = new Ne({
1016
+ scrollBars: (e) => {
1017
+ let t = this.viewport.getState().barWidth + this.viewport.getState().barSpacing;
1018
+ this.viewport.scrollBy(e * t), this.updateViewportAndRender();
1019
+ },
1020
+ zoom: (e) => {
1021
+ let t = this.viewport.getState().chartRect.width;
1022
+ this.viewport.zoom(e, t / 2), this.updateViewportAndRender();
1023
+ },
1024
+ goToStart: () => {
1025
+ this.viewport.scrollBy(-Infinity), this.updateViewportAndRender();
1026
+ },
1027
+ goToEnd: () => {
1028
+ this.viewport.scrollToEnd(), this.updateViewportAndRender();
1029
+ },
1030
+ fitContent: () => this.fitContent()
1031
+ }), this.keyboardHandler.setEnabled(this.features.keyboard), t.a11y !== !1) {
1032
+ this.a11y = new zt(e, {
1033
+ symbol: () => this.currentSymbol || this.symbolInfo?.symbol || "",
1034
+ timeframe: () => this.streamTimeframe ?? "",
1035
+ chartType: () => this.options.chartType ?? "candlestick",
1036
+ bars: () => this.getDisplayData(),
1037
+ visibleRange: () => this.viewport.getState().visibleRange,
1038
+ formatPrice: (e) => this.formatPrice(e),
1039
+ formatTime: (e) => ie(this.numberLocale || "en-US", {
1040
+ dateStyle: "medium",
1041
+ timeStyle: "short"
1042
+ }, this.displayTz)(e > gn ? e : e * 1e3),
1043
+ showBar: (e) => this.setCrosshairTime(e)
1044
+ }, t.a11y?.labels);
1045
+ for (let e of [
1046
+ "dataUpdate",
1047
+ "chartTypeChange",
1048
+ "symbolChange",
1049
+ "timeframeChange"
1050
+ ]) this.eventBus.on(e, () => this.a11y?.refresh(e !== "dataUpdate"));
1051
+ }
1052
+ if (this.onWindowKeyDown = (e) => {
1053
+ if (!this.keyboardHandler) return;
1054
+ let t = document.activeElement;
1055
+ if (!(t && t !== this.container && !this.container.contains(t)) && !(t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable)) && !(t && t !== this.container && t.matches("button, a[href], select, [role=\"button\"], [role=\"menuitem\"]"))) {
1056
+ if (this.a11y && this.features.keyboard && (e.key === "," || e.key === ".") && !e.ctrlKey && !e.metaKey && !e.altKey) {
1057
+ e.preventDefault(), this.a11y.readBar(e.key === "." ? 1 : -1);
1058
+ return;
1059
+ }
1060
+ this.keyboardHandler.handleKey(e) && (e.preventDefault(), this.a11y?.viewMoved());
1061
+ }
1062
+ }, window.addEventListener("keydown", this.onWindowKeyDown), this.currentPriceLine = new ye(), this.currentPriceLine.setLocale(this.numberLocale), this.priceAxis.setReservedPriceProvider(() => this.currentPriceLine.isVisible() ? this.currentPriceLine.getPrice() : null), this.alertManager = new oe(), this.alertManager.setDrawingLevels((e) => this.drawingLevelsNow(e)), this.alertManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.alertManager.on("triggered", (e) => {
1063
+ this.eventBus.emit("alertTriggered", G(e)), this.eventBus.emit("dataUpdate", {
1064
+ alert: "triggered",
1065
+ alertId: e.id,
1066
+ price: e.price,
1067
+ message: e.message
1068
+ });
1069
+ }), this.alertManager.on("added", (e) => {
1070
+ this.eventBus.emit("alertAdd", G(e));
1071
+ }), this.alertManager.on("removed", (e) => {
1072
+ this.eventBus.emit("alertRemove", { id: e });
1073
+ }), this.alertManager.on("expired", (e) => {
1074
+ this.eventBus.emit("alertExpired", G(e));
1075
+ }), this.alertManager.on("updated", (e) => {
1076
+ this.eventBus.emit("alertUpdate", G(e));
1077
+ }), this.signalMarkerManager = new $e(), this.signalMarkerManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.signalMarkerManager.setDataGetter(() => this.dataManager.getData()), this.signalMarkerManager.on("added", (e) => {
1078
+ this.eventBus.emit("signalMarkerAdd", {
1079
+ id: e.id,
1080
+ source: e.source,
1081
+ direction: e.direction
1082
+ });
1083
+ }), this.signalMarkerManager.on("removed", (e) => {
1084
+ this.eventBus.emit("signalMarkerRemove", { id: e });
1085
+ }), this.tradeZoneManager = new at(), this.tradeZoneManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradeZoneManager.setDataGetter(() => this.dataManager.getData()), this.tradeZoneManager.on("added", (e) => {
1086
+ this.eventBus.emit("tradeZoneAdd", {
1087
+ id: e.id,
1088
+ direction: e.direction
1089
+ });
1090
+ }), this.tradeZoneManager.on("removed", (e) => {
1091
+ this.eventBus.emit("tradeZoneRemove", { id: e });
1092
+ }), this.replayManager = new Ye(), this.replayManager.on("stateChange", (e) => {
1093
+ this.replayRestarting || this.eventBus.emit("replayState", { state: e });
1094
+ }), this.measureOverlay = new Le(), this.interactionManager = new je(e), this.features.panning) {
1095
+ let e = new an();
1096
+ this.interactionManager.setPanHandler(new Re((t, n) => {
1097
+ t && this.viewport.scrollBy(t), e.step(t, n, this.options.autoScale !== !1) && n && (this.options.autoScale = !1, this.viewport.panPriceRange(n)), this.updateViewportAndRender();
1098
+ }, () => e.reset()));
1099
+ }
1100
+ if (this.interactionManager.setAxisStrips(() => ({
1101
+ plot: this.viewport.getState().chartRect,
1102
+ timeAxisTop: this.timeAxisTop(),
1103
+ left: {
1104
+ width: this.isLeftPriceScaleShown() ? this.leftAxisWidth : 0,
1105
+ scales: !this.indicatorEngine.hasLeftScaleOverlays()
1106
+ }
1107
+ })), this.features.zooming) {
1108
+ this.interactionManager.setZoomHandler(new mt((e, t) => {
1109
+ this.viewport.zoom(e, t - this.viewport.getState().chartRect.x), this.updateViewportAndRender();
1110
+ }));
1111
+ let e = new le((e) => {
1112
+ this.options.autoScale = !1, this.viewport.scalePriceRange(e), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
1113
+ }, (e) => {
1114
+ let t = this.viewport.getState().chartRect.width;
1115
+ this.viewport.zoom(1 / e - 1, t / 2), this.updateViewportAndRender();
1116
+ });
1117
+ this.interactionManager.setAxisDragHandler(e, () => this.viewport.getState(), (e) => {
1118
+ e === "price" ? (this.options.autoScale = !0, this.updateViewportAndRender()) : this.fitContent();
1119
+ });
1120
+ }
1121
+ if (this.features.crosshair && this.interactionManager.setCrosshairHandler(this.crosshairHandler), this.features.drawings && (this.interactionManager.setDrawingManager(this.drawingManager, () => ({
1122
+ ...this.viewport.getState(),
1123
+ data: this.getDisplayData()
1124
+ })), this.interactionManager.setDrawingDoubleClick((e) => this.eventBus.emit("drawingDoubleClick", { id: e })), this.interactionManager.setDrawingContextMenu((e, t) => {
1125
+ this.drawingManager.select(e) && this.eventBus.emit("drawingContextMenu", {
1126
+ id: e,
1127
+ x: t.x,
1128
+ y: t.y
1129
+ });
1130
+ })), this.interactionManager.setChartContextMenu((e, t) => this.eventBus.hasListeners("chartContextMenu") ? (this.eventBus.emit("chartContextMenu", this.contextAt(e, t)), !0) : !1), this.priceAxisAddButton.setEnabled(this.features.priceAxisAddButton && this.features.crosshair), this.interactionManager.setPriceAxisAddButton(this.priceAxisAddButton, (e) => {
1131
+ let t = jt(e.y, this.viewport.getState());
1132
+ Number.isFinite(t) && this.eventBus.emit("priceAxisAdd", {
1133
+ price: t,
1134
+ x: e.x,
1135
+ y: e.y
1136
+ });
1137
+ }), this.features.trading && this.interactionManager.setTradingManager(this.tradingManager, () => ({
1138
+ ...this.viewport.getState(),
1139
+ data: this.getDisplayData()
1140
+ })), this.features.alerts) {
1141
+ let e = new ae(this.alertManager, () => this.viewport.getState());
1142
+ this.interactionManager.setAlertDragHandler(e);
1143
+ }
1144
+ let o = new ze();
1145
+ o.configure(() => this.getResolvedLayout(), (e, t) => this.setPanelSize(e, t)), this.interactionManager.setPaneResizeHandler(o), this.interactionManager.setAltClickHandler((e) => {
1146
+ let t = this.getDisplayData();
1147
+ if (t.length === 0) return;
1148
+ let n = this.viewport.getState(), i = n.barWidth + n.barSpacing, a = Math.round((n.offset + e.x) / i);
1149
+ a < 0 || a >= t.length || (this.pinnedTooltip.isPinned() && this.pinnedTooltip.getPinnedIndex() === a ? this.pinnedTooltip.unpin() : this.pinnedTooltip.pin(t[a], a, this.themeManager.getTheme()), this.pinnedTooltip.reposition(this.viewport.getState(), this.dataManager.getData()[a] ?? null, a, this.themeManager.getTheme()), this.engine.requestRender(r.Overlay));
1150
+ }), this.interactionManager.setSignalMarkerHitTest((e) => this.eventBus.hasListeners("signalMarkerHover") || this.eventBus.hasListeners("signalMarkerClick") ? this.signalMarkerManager.markerAt(e, this.viewport.getState()) : null, (e, t) => this.eventBus.emit("signalMarkerHover", {
1151
+ marker: e,
1152
+ x: t.x,
1153
+ y: t.y
1154
+ }), () => this.eventBus.hasListeners("signalMarkerClick")), this.interactionManager.setClickHandler((e) => {
1155
+ let t = this.getDisplayData(), n = this.eventBus.hasListeners("signalMarkerClick") ? this.signalMarkerManager.markerAt(e, this.viewport.getState()) : null;
1156
+ if (n) {
1157
+ this.eventBus.emit("signalMarkerClick", {
1158
+ marker: n,
1159
+ x: e.x,
1160
+ y: e.y
1161
+ });
1162
+ return;
1163
+ }
1164
+ if (this.eventBus.emit("click", {
1165
+ x: e.x,
1166
+ y: e.y
1167
+ }), t.length === 0) return;
1168
+ let r = At(e.x, this.viewport.getState());
1169
+ r < 0 || r >= t.length || this.eventBus.emit("barClick", {
1170
+ bar: t[r],
1171
+ barIndex: r,
1172
+ point: e
1173
+ });
1174
+ }), this.interactionManager.setEscapeHandler(() => {
1175
+ if (this.zoomAreaMode) {
1176
+ this.setZoomAreaMode(!1);
1177
+ return;
1178
+ }
1179
+ if (this.features.trading && this.tradingManager.isBracketActive()) {
1180
+ this.tradingManager.cancelBracket(), this.eventBus.emit("dataUpdate", { bracket: "cancelled" });
1181
+ return;
1182
+ }
1183
+ this.pinnedTooltip.isPinned() && (this.pinnedTooltip.unpin(), this.engine.requestRender(r.Overlay));
1184
+ }), this.interactionManager.setConfirmHandler(() => this.features.trading && this.tradingManager.isBracketActive() ? (this.tradingManager.confirmBracket(), !0) : !1), this.interactionManager.setMeasureHandlers({
1185
+ begin: (e) => {
1186
+ this.measureOverlay.begin(e, this.viewport.getState(), this.getDisplayData());
1187
+ },
1188
+ move: (e) => {
1189
+ this.measureOverlay.update(e, this.viewport.getState(), this.getDisplayData());
1190
+ },
1191
+ end: () => {
1192
+ this.measureOverlay.end();
1193
+ }
1194
+ });
1195
+ let s = (e) => {
1196
+ let t = this.viewport.getState().chartRect;
1197
+ return {
1198
+ x: Math.max(t.x, Math.min(t.x + t.width, e.x)),
1199
+ y: Math.max(t.y, Math.min(t.y + t.height, e.y))
1200
+ };
1201
+ };
1202
+ this.interactionManager.setBoxSelectHandlers({
1203
+ begin: (e) => this.selectionBoxOverlay.begin(s(e)),
1204
+ move: (e) => this.selectionBoxOverlay.update(s(e)),
1205
+ end: () => {
1206
+ let e = this.selectionBoxOverlay.end();
1207
+ if (e && this.zoomAreaMode) {
1208
+ if (e.x1 - e.x0 < Cn) return;
1209
+ this.zoomToBox(e), this.setZoomAreaMode(!1);
1210
+ return;
1211
+ }
1212
+ if (!e || !this.features.drawings) return;
1213
+ let t = {
1214
+ ...this.viewport.getState(),
1215
+ data: this.getDisplayData()
1216
+ };
1217
+ e.isClick ? this.drawingManager.toggleSelectionAt({
1218
+ x: e.x1,
1219
+ y: e.y1
1220
+ }, t) : this.drawingManager.selectInRect(e, t), this.engine.requestRender(r.Overlay);
1221
+ },
1222
+ cancel: () => {
1223
+ this.selectionBoxOverlay.cancel(), this.setZoomAreaMode(!1);
1224
+ }
1225
+ }), this.interactionManager.setOverlayDirtyCallback((e) => {
1226
+ this.engine.requestRender(e ? r.Hover : r.Overlay);
1227
+ }), this.interactionManager.attach(), t.timeZone !== void 0 && t.timeZone !== null && this.setTimezone(t.timeZone), t.leftPriceScale && (this.leftScaleRequested = !0), this.syncRenderContext(), this.engine.start(), this.engine.onGpuLost = () => this.eventBus.emit("rendererChange", {
1228
+ renderer: "canvas",
1229
+ reason: "contextLost"
1230
+ }), this.options.renderer && this.options.renderer !== "canvas" && this.setRenderer(this.options.renderer);
1231
+ }
1232
+ setData(e) {
1233
+ this.loadSeries(e, !1);
1234
+ }
1235
+ loadSeries(e, t) {
1236
+ this.snapshotKey = null, this.endReplaySession(), this.history.reset(), this.dataManager.setData(this.regularOnly(e)), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.sessionBreaks.invalidateCache(), this.options.autoScale = this.defaultAutoScale, t || 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 });
1237
+ }
1238
+ prependBars(e) {
1239
+ if (this.replaySession) return 0;
1240
+ let t = null;
1241
+ if (this.fullSeries) {
1242
+ let n = this.fullSeries[0]?.time, r = /* @__PURE__ */ new Set(), i = e.filter((e) => Pn(e) && (n === void 0 || e.time < n) && !r.has(e.time) && r.add(e.time)).sort((e, t) => e.time - t.time);
1243
+ this.fullSeries = [...i, ...this.fullSeries];
1244
+ let a = this.sessionKeep(this.fullSeries);
1245
+ t = i.length, e = a ? i.filter((e) => a(e.time)) : i;
1246
+ }
1247
+ let n = this.getDisplayData(), r = Math.max(0, Math.min(n.length - 1, Math.floor(this.viewport.getState().visibleRange.from))), i = n[r]?.time, a = this.dataManager.prependBars(e);
1248
+ if (a === 0) return t ?? 0;
1249
+ let o = this.dataManager.getData();
1250
+ if (this.crosshairHandler.setData(o), this.displayDataCache = null, this.sessionBreaks.invalidateCache(), this.pinnedTooltip.isPinned() && this.pinnedTooltip.unpin(), this.measureOverlay.end(), this.recalcIndicators(o), i !== void 0) {
1251
+ let e = Math.round(E(i, this.getDisplayData()));
1252
+ this.viewport.prependBars(e - r);
1253
+ }
1254
+ return this.updateViewportAndRender(), t ?? a;
1255
+ }
1256
+ mergeSnapshot(e) {
1257
+ let t = this.fullSeries ?? this.dataManager.getData(), n = e[0]?.time, r = 0;
1258
+ for (; n !== void 0 && r < t.length && t[r].time < n;) r++;
1259
+ if (r === 0 || r === t.length) {
1260
+ this.setData(e);
1261
+ return;
1262
+ }
1263
+ let i = this.viewport.isAtEnd();
1264
+ this.dataManager.setData(this.regularOnly(t.slice(0, r).concat(e)));
1265
+ let a = this.dataManager.getData();
1266
+ this.crosshairHandler.setData(a), this.displayDataCache = null, this.sessionBreaks.invalidateCache(), this.recalcIndicators(a), a.length > 0 && this.currentPriceLine.setPrice(a[a.length - 1].close), this.updateViewportAndRender(i), this.eventBus.emit("dataUpdate", { length: a.length });
1267
+ }
1268
+ setHistoryLoader(e, t) {
1269
+ this.historyFromStream = !1, this.hostHistoryLoader = e !== null, this.history.setLoader(e, t?.pageSize), this.checkHistory();
1270
+ }
1271
+ loadMoreHistory() {
1272
+ return this.replaySession ? Promise.resolve(0) : this.history.loadMore();
1273
+ }
1274
+ hasMoreHistory() {
1275
+ return this.history.hasLoader() && this.history.hasMore();
1276
+ }
1277
+ isLoadingHistory() {
1278
+ return this.history.isLoading();
1279
+ }
1280
+ checkHistory() {
1281
+ this.historyCheckQueued || !this.history.hasLoader() || (this.historyCheckQueued = !0, queueMicrotask(() => {
1282
+ if (this.historyCheckQueued = !1, this.replaySession || !this.history.hasLoader() || Kt(this.options.chartType)) return;
1283
+ let { from: e, to: t } = this.viewport.getState().visibleRange;
1284
+ this.history.maybeLoad(Math.max(0, Math.floor(e)), Math.max(Sn, t - e));
1285
+ }));
1286
+ }
1287
+ useStreamHistory(e, t) {
1288
+ if (this.hostHistoryLoader) return;
1289
+ let n = kt(e), r = n.fetchHistoryBefore, i = this.streamTimeframe;
1290
+ if (!r || i === null || ne(i) !== null) {
1291
+ this.historyFromStream && this.history.setLoader(null), this.historyFromStream = !1;
1292
+ return;
1293
+ }
1294
+ let a = this.currentSymbol;
1295
+ this.history.setLoader((e, t) => r.call(n, a, i, e, t), t), this.historyFromStream = !0, this.checkHistory();
1296
+ }
1297
+ appendBar(e) {
1298
+ if (this.replaySession) {
1299
+ this.replaySession.live.appendBar(e);
1300
+ return;
1301
+ }
1302
+ if (!this.takeBar(e, "append")) return;
1303
+ let t = this.autoScrollOnNewBar && this.viewport.isAtEnd();
1304
+ this.dataManager.appendBar(e);
1305
+ let n = this.dataManager.getData();
1306
+ this.crosshairHandler.setData(n), this.displayDataCache = null, this.recalcIndicatorsFrom(n, n.length - 2), this.updateViewportAndRender(t);
1307
+ }
1308
+ appendBars(e) {
1309
+ if (e.length === 0) return;
1310
+ if (this.replaySession) {
1311
+ for (let t of e) this.replaySession.live.appendBar(t);
1312
+ return;
1313
+ }
1314
+ if (e = e.filter((e) => this.takeBar(e, "append")), e.length === 0) return;
1315
+ let t = this.viewport.isAtEnd(), n = this.dataManager.getLength() - 1;
1316
+ for (let t of e) this.dataManager.appendBar(t);
1317
+ this.displayDataCache = null, this.recalcIndicatorsFrom(this.dataManager.getData(), n), this.crosshairHandler.setData(this.dataManager.getData()), this.updateViewportAndRender(t);
1318
+ }
1319
+ updateLastBar(e) {
1320
+ if (this.replaySession) {
1321
+ this.replaySession.live.updateLastBar(e);
1322
+ return;
1323
+ }
1324
+ if (!this.takeBar(e, "update")) {
1325
+ this.currentPriceLine.setPrice(e.close), this.scheduleRender();
1326
+ return;
1327
+ }
1328
+ 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);
1329
+ let t = this.dataManager.getData();
1330
+ this.recalcIndicatorsFrom(t, t.length - 1), this.scheduleRender();
1331
+ }
1332
+ updateLastBarFromTick(e) {
1333
+ if (this.replaySession) {
1334
+ this.replaySession.live.updateLastBarFromTick(e), Number.isFinite(e.price) && (this.replaySession.price = { price: e.price });
1335
+ return;
1336
+ }
1337
+ let t = this.fullSeries ? this.sessionKeep(this.fullSeries) : null;
1338
+ if (t && !t(e.time)) {
1339
+ this.currentPriceLine.setPrice(e.price), this.scheduleRender();
1340
+ return;
1341
+ }
1342
+ this.dataManager.updateLastBarFromTick(e), this.currentPriceLine.setPrice(e.price);
1343
+ let n = this.fullSeries, r = this.dataManager.getData()[this.dataManager.getLength() - 1];
1344
+ n && r && n.length > 0 && n[n.length - 1].time === r.time && (n[n.length - 1] = r), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null);
1345
+ let i = this.dataManager.getData();
1346
+ this.recalcIndicatorsFrom(i, i.length - 1), this.scheduleRender();
1347
+ }
1348
+ setChartType(e) {
1349
+ let t = this.options.chartType ?? "candlestick";
1350
+ this.options.chartType = e, this.chartRenderer = this.createChartRenderer(e), this.chartLegend.setChartType(e), this.displayDataCache = null, this.updateViewportAndRender(!0), this.markStateChanged(), e !== t && this.eventBus.emit("chartTypeChange", {
1351
+ type: e,
1352
+ previous: t
1353
+ });
1354
+ }
1355
+ setChartTypeOptions(e) {
1356
+ this.chartTypeOptions = {
1357
+ ...this.chartTypeOptions,
1358
+ ..._(e)
1359
+ }, this.displayDataCache = null, this.updateViewportAndRender(!0), this.markStateChanged();
1360
+ }
1361
+ getChartTypeOptions() {
1362
+ return _(this.chartTypeOptions);
1363
+ }
1364
+ setExtendedHours(e) {
1365
+ e !== this.extendedHours && (this.extendedHours = e, this.reapplyExtendedHours(), this.markStateChanged());
1366
+ }
1367
+ isExtendedHoursVisible() {
1368
+ return this.extendedHours;
1369
+ }
1370
+ sessionKeep(e) {
1371
+ return this.extendedHours ? null : Pt(this.symbolInfo, e);
1372
+ }
1373
+ shownBars(e) {
1374
+ let t = this.sessionKeep(e);
1375
+ return t ? e.filter((e) => t(e.time)) : e.slice();
1376
+ }
1377
+ regularOnly(e) {
1378
+ let t = this.sessionKeep(e);
1379
+ return this.fullSeries = t ? e.slice() : null, t ? e.filter((e) => t(e.time)) : e;
1380
+ }
1381
+ placeStreamBar(e) {
1382
+ let t = K(this.dataManager.getData(), e);
1383
+ return t === "stale" ? !1 : (t === "append" ? this.dataManager.appendBar(e) : this.dataManager.updateLastBar(e), !0);
1384
+ }
1385
+ takeBar(e, t) {
1386
+ if (!this.fullSeries && !this.extendedHours && !this.replaySession) {
1387
+ let n = this.dataManager.getData(), r = n.slice(-12), i = t === "append" || r.length === 0 ? [...r, e] : [...r.slice(0, -1), e];
1388
+ if (this.sessionKeep(i)) {
1389
+ this.fullSeries = n.slice();
1390
+ let e = this.sessionKeep(this.fullSeries.length > 1 ? this.fullSeries : i);
1391
+ e && n.some((t) => !e(t.time)) && (this.dataManager.setData(n.filter((t) => e(t.time))), this.displayDataCache = null);
1392
+ }
1393
+ }
1394
+ let n = this.fullSeries;
1395
+ if (!n) return !0;
1396
+ t === "append" || n.length === 0 ? n.push(e) : n[n.length - 1] = e;
1397
+ let r = this.sessionKeep(n);
1398
+ return !r || r(e.time);
1399
+ }
1400
+ reapplyExtendedHours() {
1401
+ if (this.replaySession) return;
1402
+ let e = this.fullSeries ?? this.dataManager.getData().slice();
1403
+ if (!this.fullSeries && !this.sessionKeep(e)) return;
1404
+ this.dataManager.setData(this.regularOnly(e));
1405
+ let t = this.dataManager.getData();
1406
+ this.crosshairHandler.setData(t), this.displayDataCache = null, this.sessionBreaks.invalidateCache(), this.recalcIndicators(t), this.updateViewportAndRender(!0), this.eventBus.emit("dataUpdate", { length: t.length });
1407
+ }
1408
+ quoteLines() {
1409
+ return this.priceLines.setQuoteShown(this.replaySession === null), this.priceLines;
1410
+ }
1411
+ setShapes(e) {
1412
+ let t = Dn(e);
1413
+ t.tagRadius !== void 0 && (this.themeManager.setShape({
1414
+ ...this.themeManager.getTheme().shape,
1415
+ ...t
1416
+ }), this.syncRenderContext(), this.engine.requestRender());
1417
+ }
1418
+ getShapes() {
1419
+ return { ...this.themeManager.getTheme().shape };
1420
+ }
1421
+ setMainSeriesVisible(e) {
1422
+ this.mainSeriesVisible = e, this.syncRenderContext(), this.engine.requestRender();
1423
+ }
1424
+ isMainSeriesVisible() {
1425
+ return this.mainSeriesVisible;
1426
+ }
1427
+ setHighLowLines(e) {
1428
+ this.priceLines.setHighLow(e), this.engine.requestRender();
1429
+ }
1430
+ isHighLowLinesVisible() {
1431
+ return this.priceLines.isHighLowVisible();
1432
+ }
1433
+ setBidAsk(e) {
1434
+ this.priceLines.setBidAsk(e), this.engine.requestRender(r.Overlay);
1435
+ }
1436
+ getBidAsk() {
1437
+ return this.priceLines.getBidAsk();
1438
+ }
1439
+ addIndicator(e, t = {}, n = "bottom", r = {}) {
1440
+ return this.recordIndicators(void 0, () => this.addIndicatorNow(e, t, n, r));
1441
+ }
1442
+ addIndicatorNow(e, t, n, r) {
1443
+ if (!this.features.indicators || this.features.indicatorIds.length > 0 && !this.features.indicatorIds.includes(e)) return null;
1444
+ let i = this.indicatorEngine.getAvailableIndicators().find((t) => t.id === e), a = i ? this.paneFor(i, t, r.pane) : null, o = this.indicatorEngine.addIndicator(e, t, this.dataManager.getData(), {
1445
+ ...a ? { pane: a } : {},
1446
+ ...r.scale === "left" ? { scale: "left" } : {},
1447
+ ...r.instanceId ? { instanceId: r.instanceId } : {}
1448
+ });
1449
+ return i?.placement === "panel" && !a && this.layoutManager.addPanel(o, n), this.updateViewportAndRender(), this.eventBus.emit("indicatorAdd", {
1450
+ instanceId: o,
1451
+ id: e
1452
+ }), this.markStateChanged(), this.requestMissingSymbols(o), o;
1453
+ }
1454
+ setSymbolSeries(e, t) {
1455
+ e = e.trim(), this.symbolSeries.set(e, t), this.requestedSymbols.delete(e);
1456
+ let n = this.dataManager.getData(), r = !1;
1457
+ for (let t of this.indicatorEngine.getActiveIndicators()) !W.has(t.id) || String(t.params.symbol ?? "").trim() !== e.trim() || (this.indicatorEngine.updateIndicator(t.instanceId, {}, n), r = !0);
1458
+ r && (this.announceIndicatorUpdate(0), this.updateViewportAndRender());
1459
+ }
1460
+ forgetUnreadSymbols() {
1461
+ let e = new Set(this.getRequiredSymbols());
1462
+ for (let t of this.requestedSymbols) e.has(t) || this.requestedSymbols.delete(t);
1463
+ }
1464
+ getSymbolSeries(e) {
1465
+ return this.symbolSeries.get(e) ?? null;
1466
+ }
1467
+ getRequiredSymbols() {
1468
+ let e = /* @__PURE__ */ new Set();
1469
+ for (let t of this.indicatorEngine.getActiveIndicators()) {
1470
+ let n = t.params.symbol;
1471
+ W.has(t.id) && typeof n == "string" && n.trim() && e.add(n.trim());
1472
+ }
1473
+ return [...e];
1474
+ }
1475
+ requestMissingSymbols(e) {
1476
+ this.forgetUnreadSymbols();
1477
+ let t = this.indicatorEngine.getIndicatorConfig(e), n = t && W.has(t.id) && typeof t.params.symbol == "string" ? t.params.symbol.trim() : "";
1478
+ !n || this.symbolSeries.has(n) || this.requestedSymbols.has(n) || (this.requestedSymbols.add(n), this.eventBus.emit("symbolSeriesRequest", { symbol: n }));
1479
+ }
1480
+ updateIndicator(e, t) {
1481
+ this.recordIndicators(e, () => this.updateIndicatorNow(e, t));
1482
+ }
1483
+ updateIndicatorNow(e, t) {
1484
+ let n = this.indicatorEngine.getIndicatorDescriptor(e), r = n ? T(n) : null, i = r ? this.indicatorEngine.getIndicatorConfig(e)?.params[r] : void 0;
1485
+ this.indicatorEngine.updateIndicator(e, t, this.dataManager.getData()), this.announceIndicatorUpdate(0), this.markStateChanged(), this.eventBus.emit("indicatorChange", {
1486
+ instanceId: e,
1487
+ change: "params"
1488
+ }), this.requestMissingSymbols(e);
1489
+ let a = this.indicatorEngine.getIndicatorConfig(e);
1490
+ if (n?.placement === "overlay" && a && r && a.params[r] !== i) {
1491
+ let t = h(a.params[r]), n = t ? this.paneHostOf(t.instanceId, e) : h(i) ? null : a.pane ?? null;
1492
+ (n ?? void 0) !== a.pane && (this.indicatorEngine.setPane(e, n), this.eventBus.emit("indicatorChange", {
1493
+ instanceId: e,
1494
+ change: "pane"
1495
+ }));
1496
+ }
1497
+ this.updateViewportAndRender();
1498
+ }
1499
+ paneFor(e, t, n, r) {
1500
+ if (n) return this.paneHostOf(n, r);
1501
+ if (e.placement !== "overlay") return null;
1502
+ let i = T(e), a = i ? h(t[i]) : null;
1503
+ return a ? this.paneHostOf(a.instanceId, r) : null;
1504
+ }
1505
+ paneHostOf(e, t) {
1506
+ if (e === t) return null;
1507
+ if (this.layoutManager.getPanels().some((t) => t.id === e)) return e;
1508
+ let n = this.indicatorEngine.getIndicatorConfig(e)?.pane;
1509
+ return n && n !== t ? n : null;
1510
+ }
1511
+ getIndicatorLevels(e) {
1512
+ return this.indicatorEngine.getLevels(e);
1513
+ }
1514
+ setIndicatorScale(e, t) {
1515
+ return this.recordIndicators(e, () => this.setIndicatorScaleNow(e, t));
1516
+ }
1517
+ setIndicatorScaleNow(e, t) {
1518
+ return this.indicatorEngine.setScale(e, t) ? (this.updateViewportAndRender(), this.markStateChanged(), this.eventBus.emit("indicatorChange", {
1519
+ instanceId: e,
1520
+ change: "scale"
1521
+ }), !0) : !1;
1522
+ }
1523
+ getIndicatorScale(e) {
1524
+ return this.indicatorEngine.getIndicatorConfig(e)?.scale === "left" ? "left" : "right";
1525
+ }
1526
+ setLeftPriceScaleVisible(e) {
1527
+ this.leftScaleRequested = e, this.updateViewportAndRender();
1528
+ }
1529
+ isLeftPriceScaleShown() {
1530
+ return this.features.priceAxis !== !1 && (this.leftScaleRequested || this.indicatorEngine.hasLeftScaleOverlays());
1531
+ }
1532
+ getLeftPriceRange() {
1533
+ return this.leftViewport ? { ...this.leftViewport.priceRange } : null;
1534
+ }
1535
+ computeLeftViewport() {
1536
+ if (!this.isLeftPriceScaleShown()) return null;
1537
+ let e = this.viewport.getState();
1538
+ if (!this.indicatorEngine.hasLeftScaleOverlays()) return e;
1539
+ let t = this.indicatorEngine.getOverlayPriceRange(e.visibleRange.from, e.visibleRange.to, "left");
1540
+ if (!t) return e;
1541
+ let n = t.max - t.min || Math.abs(t.max) || 1;
1542
+ return {
1543
+ ...e,
1544
+ priceRange: {
1545
+ min: t.min - n * bn,
1546
+ max: t.max + n * bn
1547
+ },
1548
+ logScale: !1,
1549
+ scaleMode: "regular",
1550
+ invertScale: !1,
1551
+ formatPrice: void 0,
1552
+ priceUnit: void 0
1553
+ };
1554
+ }
1555
+ setIndicatorLevels(e, t) {
1556
+ this.recordIndicators(e, () => this.setIndicatorLevelsNow(e, t));
1557
+ }
1558
+ setIndicatorLevelsNow(e, t) {
1559
+ this.indicatorEngine.setLevels(e, t) && (this.updateViewportAndRender(), this.markStateChanged(), this.eventBus.emit("indicatorChange", {
1560
+ instanceId: e,
1561
+ change: "levels"
1562
+ }));
1563
+ }
1564
+ removeIndicator(e) {
1565
+ this.recordIndicators(void 0, () => this.removeIndicatorNow(e));
1566
+ }
1567
+ removeIndicatorNow(e) {
1568
+ if (!this.indicatorEngine.getIndicatorConfig(e)) return;
1569
+ let t = [e, ...this.indicatorEngine.getDependents(e)];
1570
+ for (let e of t.reverse()) this.detachIndicator(e);
1571
+ this.markStateChanged(), this.updateViewportAndRender();
1572
+ }
1573
+ detachIndicator(e) {
1574
+ if (!this.indicatorEngine.getIndicatorConfig(e)) return;
1575
+ let t = this.layoutManager.getPanels().find((t) => t.id === e), n = this.indicatorEngine.getPaneMembers(e), r = t ? n.find((e) => this.indicatorEngine.getIndicatorDescriptor(e)?.placement === "panel") ?? null : null;
1576
+ this.indicatorEngine.removeIndicator(e), r ? (this.indicatorEngine.setPane(r, null), this.layoutManager.renamePanel(e, r)) : this.layoutManager.removePanel(e);
1577
+ for (let e of n) e !== r && this.indicatorEngine.setPane(e, r), this.eventBus.emit("indicatorChange", {
1578
+ instanceId: e,
1579
+ change: "pane"
1580
+ });
1581
+ this.eventBus.emit("indicatorRemove", { instanceId: e }), this.forgetUnreadSymbols();
1582
+ }
1583
+ getIndicatorStyle(e) {
1584
+ return this.indicatorEngine.getIndicatorStyle(e);
1585
+ }
1586
+ getIndicatorOutput(e) {
1587
+ return this.indicatorEngine.getOutput(e);
1588
+ }
1589
+ registerIndicator(e) {
1590
+ this.pluginManager.registerIndicator(e);
1591
+ }
1592
+ get plugins() {
1593
+ return this.pluginManager;
1594
+ }
1595
+ static indicators() {
1596
+ let e = new Ae();
1597
+ return C(e), e.getAvailableIndicators();
1598
+ }
1599
+ setPanelPosition(e, t) {
1600
+ this.layoutManager.setPanelPosition(e, t), this.updateViewportAndRender(), this.eventBus.emit("indicatorChange", {
1601
+ instanceId: e,
1602
+ change: "pane"
1603
+ });
1604
+ }
1605
+ setPanelSize(e, t) {
1606
+ this.layoutManager.setPanelSize(e, t), this.updateViewportAndRender(), this.eventBus.emit("paneResize", {
1607
+ instanceId: e,
1608
+ size: t
1609
+ }), this.markStateChanged();
1610
+ }
1611
+ moveIndicatorToPane(e, t) {
1612
+ return this.recordIndicators(e, () => this.moveIndicatorToPaneNow(e, t));
1613
+ }
1614
+ canMoveIndicatorToPane(e, t) {
1615
+ return this.paneMoveHost(e, t) !== void 0;
1616
+ }
1617
+ paneMoveHost(e, t) {
1618
+ let n = this.indicatorEngine.getIndicatorConfig(e), r = this.indicatorEngine.getIndicatorDescriptor(e);
1619
+ if (!n || !r) return;
1620
+ let i = T(r);
1621
+ if (r.placement === "overlay" && i && h(n.params[i])) return;
1622
+ if (t === "price") return r.placement === "overlay" && n.pane ? null : void 0;
1623
+ if (t === "new") {
1624
+ let t = this.layoutManager.getPanels().some((t) => t.id === e);
1625
+ return r.placement === "panel" && !t ? null : void 0;
1626
+ }
1627
+ let a = this.paneHostOf(t, e);
1628
+ return a && a !== n.pane && a !== e ? a : void 0;
1629
+ }
1630
+ moveIndicatorToPaneNow(e, t) {
1631
+ let n = this.paneMoveHost(e, t), r = this.indicatorEngine.getIndicatorConfig(e);
1632
+ if (n === void 0 || !r) return !1;
1633
+ let i = r.pane, a = this.layoutManager.getPanels().some((t) => t.id === e), o = new Set([e]);
1634
+ if (a) {
1635
+ let t = this.indicatorEngine.getPaneMembers(e), r = new Set(this.indicatorEngine.getDependents(e)), i = t.filter((e) => !r.has(e)), a = i.find((e) => this.indicatorEngine.getIndicatorDescriptor(e)?.placement === "panel") ?? null;
1636
+ if (a) {
1637
+ this.indicatorEngine.setPane(a, null), this.layoutManager.renamePanel(e, a);
1638
+ for (let e of i) e !== a && this.indicatorEngine.setPane(e, a);
1639
+ } else {
1640
+ this.layoutManager.removePanel(e);
1641
+ for (let e of i) this.indicatorEngine.setPane(e, null);
1642
+ }
1643
+ for (let i of t) r.has(i) && this.indicatorEngine.setPane(i, n ?? e), o.add(i);
1644
+ }
1645
+ if (this.indicatorEngine.setPane(e, n), t === "new") {
1646
+ this.layoutManager.addPanel(e, "bottom");
1647
+ for (let t of this.indicatorEngine.getDependents(e)) this.indicatorEngine.getIndicatorConfig(t)?.pane === i && (this.indicatorEngine.setPane(t, e), o.add(t));
1648
+ }
1649
+ for (let e of o) this.eventBus.emit("indicatorChange", {
1650
+ instanceId: e,
1651
+ change: "pane"
1652
+ });
1653
+ return this.updateViewportAndRender(), this.markStateChanged(), !0;
1654
+ }
1655
+ setPaneCollapsed(e, t) {
1656
+ let n = this.paneOf(e);
1657
+ return this.recordIndicators(n, () => this.paneChange(n, "collapsed", () => this.layoutManager.setPanelCollapsed(n, t)));
1658
+ }
1659
+ isPaneCollapsed(e) {
1660
+ return this.layoutManager.isPanelShownCollapsed(this.paneOf(e));
1661
+ }
1662
+ setMaximizedPane(e) {
1663
+ let t = e === null ? null : this.paneOf(e), n = t ?? this.layoutManager.getMaximizedPanel() ?? "";
1664
+ return this.recordIndicators(n, () => this.paneChange(n, "maximized", () => this.layoutManager.setMaximizedPanel(t)));
1665
+ }
1666
+ getMaximizedPane() {
1667
+ return this.layoutManager.getMaximizedPanel();
1668
+ }
1669
+ setPaneScale(e, t) {
1670
+ let n = this.paneOf(e);
1671
+ return this.recordIndicators(n, () => this.paneChange(n, "scale", () => this.layoutManager.setPanelScale(n, t)));
1672
+ }
1673
+ getPaneScale(e) {
1674
+ let t = this.layoutManager.getPanels().find((t) => t.id === this.paneOf(e));
1675
+ return {
1676
+ log: !!t?.logScale,
1677
+ invert: !!t?.invertScale,
1678
+ percent: !!t?.percentScale
1679
+ };
1680
+ }
1681
+ paneBaseline(e, t, n) {
1682
+ let r = this.indicatorEngine.getOutput(e)?.series, i = this.indicatorEngine.getIndicatorDescriptor(e);
1683
+ if (!r || !i) return;
1684
+ let a = i.plots?.[0]?.key;
1685
+ for (let e = Math.max(0, t); e <= n && e < r.length; e++) {
1686
+ let t = r[e];
1687
+ if (!t) continue;
1688
+ let n = a === void 0 ? Object.values(t).find((e) => typeof e == "number" && Number.isFinite(e)) : t[a];
1689
+ if (typeof n == "number" && Number.isFinite(n) && n !== 0) return n;
1690
+ }
1691
+ }
1692
+ movePane(e, t) {
1693
+ let n = this.paneOf(e);
1694
+ return this.recordIndicators(n, () => this.paneChange(n, "order", () => this.layoutManager.movePanel(n, t)));
1695
+ }
1696
+ canMovePane(e, t) {
1697
+ return this.layoutManager.canMovePanel(this.paneOf(e), t);
1698
+ }
1699
+ paneOf(e) {
1700
+ return this.indicatorEngine.getIndicatorConfig(e)?.pane ?? e;
1701
+ }
1702
+ paneChange(e, t, n) {
1703
+ return n() ? (this.updateViewportAndRender(), this.eventBus.emit("paneChange", {
1704
+ instanceId: e,
1705
+ change: t
1706
+ }), this.markStateChanged(), !0) : !1;
1707
+ }
1708
+ getIndicatorPanes() {
1709
+ return this.buildPanelRenderInfos().map((e) => ({
1710
+ instanceId: e.instanceId,
1711
+ instanceIds: [e.instanceId, ...e.members ?? []],
1712
+ rect: { ...e.rect }
1713
+ }));
1714
+ }
1715
+ setIndicatorValueLabelsVisible(e) {
1716
+ this.features.indicatorValueLabels = e, this.syncRenderContext(), this.engine.requestRender();
1717
+ }
1718
+ setPaneTitlesVisible(e) {
1719
+ this.paneTitles = e, this.engine.requestRender();
1720
+ }
1721
+ getLegendBottom() {
1722
+ let e = this.viewport.getState().chartRect.y;
1723
+ return this.features.legend ? e + this.chartLegend.getHeight() : e;
1724
+ }
1725
+ isTimeAligned() {
1726
+ return Kt(this.options.chartType) ? !1 : this.getDisplayData().length === this.dataManager.getLength();
1727
+ }
1728
+ roundPrice(e) {
1729
+ if (!Number.isFinite(e)) return e;
1730
+ let t = this.symbolInfo?.minTick ?? this.priceUnit ?? void 0;
1731
+ if (t !== void 0 && t > 0) return Number((Math.round(e / t) * t).toFixed(te(t)));
1732
+ let { min: n, max: r } = this.viewport.getState().priceRange;
1733
+ return Number(e.toFixed(this.marketPricePrecision ?? s(n, r)));
1734
+ }
1735
+ setPriceFormat(e) {
1736
+ this.applyPriceFormat(e), this.updateViewportAndRender();
1737
+ }
1738
+ getPriceFormatter() {
1739
+ return this.priceFormatter;
1740
+ }
1741
+ applyPriceFormat(e) {
1742
+ this.priceFormatter = g(e), this.priceUnit = e && typeof e != "function" ? u(e) : null, this.viewport.setPriceFormat(this.priceFormatter, this.priceUnit), this.crosshairTooltip.setPriceFormatter(this.priceFormatter), this.pinnedTooltip.setPriceFormatter(this.priceFormatter);
1743
+ }
1744
+ setTimeFormatter(e) {
1745
+ this.applyTimeFormatter(e), this.engine.requestRender();
1746
+ }
1747
+ applyTimeFormatter(e) {
1748
+ this.timeAxis.setTimeFormatter(e), this.crosshairHandler.setTimeFormatter(e), this.crosshairTooltip.setTimeFormatter(e);
1749
+ }
1750
+ formatPrice(e) {
1751
+ if (this.priceFormatter) return this.priceFormatter(e);
1752
+ let { min: t, max: n } = this.viewport.getState().priceRange;
1753
+ return l(e, this.marketPricePrecision ?? s(t, n), this.numberLocale);
1754
+ }
1755
+ setDrawingTool(e) {
1756
+ this.features.drawings && (e && this.features.drawingTools.length > 0 && !this.features.drawingTools.includes(e) || (e && this.setZoomAreaMode(!1), this.drawingManager.setActiveTool(e)));
1757
+ }
1758
+ getDrawingTool() {
1759
+ return this.drawingManager.getActiveTool();
1760
+ }
1761
+ setStayInDrawingMode(e) {
1762
+ this.drawingManager.setStayInDrawingMode(e);
1763
+ }
1764
+ isStayInDrawingMode() {
1765
+ return this.drawingManager.isStayInDrawingMode();
1766
+ }
1767
+ copyDrawings() {
1768
+ return this.drawingManager.copySelection();
1769
+ }
1770
+ pasteDrawings() {
1771
+ return this.features.drawings ? this.drawingManager.paste() : [];
1772
+ }
1773
+ setDrawingStyle(e) {
1774
+ this.drawingManager.setStyle(e);
1775
+ }
1776
+ getDrawingStyle() {
1777
+ return this.drawingManager.getActiveStyle();
1778
+ }
1779
+ getSelectedDrawingId() {
1780
+ return this.drawingManager.getSelectedDrawingId();
1781
+ }
1782
+ setSelectedDrawingStyle(e, t) {
1783
+ return this.drawingManager.setSelectedDrawingStyle(e, t);
1784
+ }
1785
+ getDrawings() {
1786
+ return this.drawingManager.getDrawings();
1787
+ }
1788
+ setDrawings(e) {
1789
+ this.drawingManager.setDrawings(e), this.dropOrphanDrawingAlerts(), this.announceStateChange();
1790
+ }
1791
+ addDrawing(e) {
1792
+ if (!this.features.drawings) return null;
1793
+ let t = this.drawingManager.addDrawing(e);
1794
+ return this.markStateChanged(), t;
1795
+ }
1796
+ autoFib() {
1797
+ if (!this.features.drawings) return null;
1798
+ let e = this.getDisplayData(), t = this.viewport.getState(), n = gt(e, t.visibleRange.from, t.visibleRange.to);
1799
+ return n ? this.addDrawing({
1800
+ type: "fibRetracement",
1801
+ anchors: [n[0], n[1]]
1802
+ }) : null;
1803
+ }
1804
+ removeDrawing(e) {
1805
+ this.drawingManager.removeDrawing(e);
1806
+ }
1807
+ removeDrawings(e) {
1808
+ return this.drawingManager.removeDrawings(e);
1809
+ }
1810
+ getDrawingToolDescriptor(e) {
1811
+ let t = this.drawingManager.getDescriptor(e);
1812
+ return t ? structuredClone(t) : null;
1813
+ }
1814
+ getDrawingOptionDefs(e) {
1815
+ return this.drawingManager.getOptionDefs(e);
1816
+ }
1817
+ getDrawingOptions(e) {
1818
+ return this.drawingManager.getDrawingOptions(e);
1819
+ }
1820
+ setDrawingOptions(e, t) {
1821
+ return this.updateDrawing(e, { options: t });
1822
+ }
1823
+ updateDrawing(e, t) {
1824
+ let n = this.drawingManager.updateDrawing(e, t);
1825
+ return n && this.markStateChanged(), n;
1826
+ }
1827
+ beginDrawingEdit(e) {
1828
+ return this.drawingManager.beginEdit(e);
1829
+ }
1830
+ endDrawingEdit(e, t = {}) {
1831
+ this.drawingManager.endEdit(e, t), this.markStateChanged();
1832
+ }
1833
+ setDrawingToolDefaults(e, t) {
1834
+ this.drawingManager.setToolDefaults(e, t);
1835
+ }
1836
+ getDrawingToolDefaults(e) {
1837
+ return this.drawingManager.getToolDefaults(e);
1838
+ }
1839
+ setDrawingVisible(e, t) {
1840
+ this.drawingManager.setDrawingVisible(e, t);
1841
+ }
1842
+ setDrawingLocked(e, t) {
1843
+ this.drawingManager.setDrawingLocked(e, t);
1844
+ }
1845
+ setDrawingsVisible(e, t) {
1846
+ this.drawingManager.setDrawingsVisible(e, t);
1847
+ }
1848
+ setDrawingsLocked(e, t) {
1849
+ this.drawingManager.setDrawingsLocked(e, t);
1850
+ }
1851
+ clearDrawings() {
1852
+ this.drawingManager.clearDrawings(), this.dropOrphanDrawingAlerts();
1853
+ }
1854
+ registerDrawingTool(e) {
1855
+ this.drawingManager.register(e);
1856
+ }
1857
+ undo() {
1858
+ return this.features.drawingUndoRedo ? this.drawingManager.undo() : !1;
1859
+ }
1860
+ redo() {
1861
+ return this.features.drawingUndoRedo ? this.drawingManager.redo() : !1;
1862
+ }
1863
+ selectDrawing(e) {
1864
+ let t = this.drawingManager.select(e);
1865
+ return t && this.engine.requestRender(), t;
1866
+ }
1867
+ getUndoRedoState() {
1868
+ return this.undoRedoManager.getState();
1869
+ }
1870
+ recordUndo(e) {
1871
+ if (!this.features.drawingUndoRedo || typeof e?.undo != "function" || typeof e.redo != "function") return;
1872
+ let t = performance.now(), n = this.undoRedoManager.last();
1873
+ if (e.subject !== void 0 && n?.type === "custom" && n.custom?.subject === e.subject && t - n.custom.at < xn) {
1874
+ this.undoRedoManager.replaceLast({
1875
+ ...n,
1876
+ custom: {
1877
+ undo: n.custom.undo,
1878
+ redo: e.redo,
1879
+ subject: e.subject,
1880
+ at: t
1881
+ }
1882
+ });
1883
+ return;
1884
+ }
1885
+ this.undoRedoManager.push({
1886
+ type: "custom",
1887
+ before: null,
1888
+ after: null,
1889
+ custom: {
1890
+ undo: e.undo,
1891
+ redo: e.redo,
1892
+ subject: e.subject,
1893
+ at: t
1894
+ }
1895
+ });
1896
+ }
1897
+ setDrawingMagnet(e) {
1898
+ this.setDrawingMagnetMode(e ? "weak" : "off");
1899
+ }
1900
+ getDrawingMagnet() {
1901
+ return this.drawingManager.getMagnetMode() !== "none";
1902
+ }
1903
+ setDrawingMagnetMode(e) {
1904
+ let t = this.features.drawingMagnet && e !== "off";
1905
+ this.drawingManager.setMagnetMode(t ? e === "strong" ? "strong" : "magnet" : "none");
1906
+ }
1907
+ getDrawingMagnetMode() {
1908
+ let e = this.drawingManager.getMagnetMode();
1909
+ return e === "none" ? "off" : e === "strong" ? "strong" : "weak";
1910
+ }
1911
+ contextAt(e, t) {
1912
+ let n = {
1913
+ ...this.viewport.getState(),
1914
+ data: this.getDisplayData()
1915
+ }, r = {
1916
+ area: e,
1917
+ x: t.x,
1918
+ y: t.y
1919
+ };
1920
+ if ((e === "plot" || e === "priceAxis") && (r.price = jt(t.y, n)), (e === "plot" || e === "timeAxis") && n.data.length > 0 && (r.time = D(t.x, n)), e === "pane") {
1921
+ let e = this.getIndicatorPanes().find((e) => t.y >= e.rect.y && t.y <= e.rect.y + e.rect.height);
1922
+ e && (r.pane = e.instanceId);
1923
+ }
1924
+ return r;
1925
+ }
1926
+ setPriceAxisAddButton(e) {
1927
+ this.features.priceAxisAddButton = e, this.priceAxisAddButton.setEnabled(e && this.features.crosshair), this.engine.requestRender(r.Overlay);
1928
+ }
1929
+ setEraserMode(e) {
1930
+ e && this.setZoomAreaMode(!1), this.drawingManager.setEraser(e && this.features.drawings);
1931
+ }
1932
+ isEraserMode() {
1933
+ return this.drawingManager.isEraser();
1934
+ }
1935
+ setZoomAreaMode(e) {
1936
+ e !== this.zoomAreaMode && (this.zoomAreaMode = e, e && (this.drawingManager.setEraser(!1), this.drawingManager.setActiveTool(null)), this.interactionManager?.setZoomAreaMode(e), this.eventBus.emit("toolModeChange", { zoomArea: e }));
1937
+ }
1938
+ isZoomAreaMode() {
1939
+ return this.zoomAreaMode;
1940
+ }
1941
+ zoomToBox(e) {
1942
+ let t = {
1943
+ ...this.viewport.getState(),
1944
+ data: this.getDisplayData()
1945
+ };
1946
+ this.setVisibleRange(D(e.x0, t), D(e.x1, t));
1947
+ }
1948
+ lockAllDrawings() {
1949
+ this.drawingManager.lockAllDrawings();
1950
+ }
1951
+ unlockAllDrawings() {
1952
+ this.drawingManager.unlockAllDrawings();
1953
+ }
1954
+ hideAllDrawings() {
1955
+ this.drawingManager.hideAllDrawings();
1956
+ }
1957
+ showAllDrawings() {
1958
+ this.drawingManager.showAllDrawings();
1959
+ }
1960
+ duplicateDrawing(e) {
1961
+ let t = e ?? this.drawingManager.getSelectedDrawingId();
1962
+ return t ? this.drawingManager.duplicateDrawing(t) : null;
1963
+ }
1964
+ exportVisibleData(e = "csv", t, n = {}) {
1965
+ this.features.dataExport && this.download(e, t, {
1966
+ ...n,
1967
+ range: "visible"
1968
+ });
1969
+ }
1970
+ exportAllData(e = "csv", t, n = {}) {
1971
+ this.features.dataExport && this.download(e, t, {
1972
+ ...n,
1973
+ range: "all"
1974
+ });
1975
+ }
1976
+ getExportData(e = {}) {
1977
+ let t = this.dataManager.getData(), n = 0, r = t.length - 1;
1978
+ if (e.range === "visible") {
1979
+ let { visibleRange: e } = this.viewport.getState();
1980
+ n = Math.max(0, e.from), r = Math.min(t.length - 1, e.to);
1981
+ }
1982
+ let i = t.slice(n, r + 1);
1983
+ if (e.indicators === !1) return {
1984
+ bars: i,
1985
+ columns: []
1986
+ };
1987
+ let a = [];
1988
+ for (let e of this.indicatorEngine.getActiveIndicators()) {
1989
+ let t = this.indicatorEngine.getOutput(e.instanceId)?.series;
1990
+ if (!t) continue;
1991
+ let r = Ht(e.id, e.params, e.descriptor.defaultConfig, e.descriptor.shortName), o = e.descriptor.plots ?? Object.keys(t.find((e) => e) ?? {}).map((e) => ({
1992
+ key: e,
1993
+ title: e
1994
+ }));
1995
+ for (let e of o) {
1996
+ let s = o.length > 1 ? ` ${e.title ?? e.key}` : "";
1997
+ a.push({
1998
+ name: `${r}${s}`,
1999
+ values: i.map((r, i) => t[n + i]?.[e.key] ?? null)
2000
+ });
2001
+ }
2002
+ }
2003
+ let o = /* @__PURE__ */ new Map();
2004
+ for (let e of a) {
2005
+ let t = (o.get(e.name) ?? 0) + 1;
2006
+ o.set(e.name, t), t > 1 && (e.name = `${e.name} (${t})`);
2007
+ }
2008
+ return {
2009
+ bars: i,
2010
+ columns: a
2011
+ };
2012
+ }
2013
+ getExportText(e = "csv", t = {}) {
2014
+ let { bars: n, columns: r } = this.getExportData(t);
2015
+ return e === "json" ? x.toJSON(n, r) : x.toCSV(n, r);
2016
+ }
2017
+ download(e, t, n) {
2018
+ let r = this.getExportText(e, n);
2019
+ e === "json" ? x.download(r, t ?? "chart-data.json", "application/json") : x.download(r, t ?? "chart-data.csv", "text/csv");
2020
+ }
2021
+ setAutoSave(e, t = 5e3) {
2022
+ this.autoSaveScheduler.enable(e, t);
2023
+ }
2024
+ disableAutoSave() {
2025
+ this.autoSaveScheduler.disable();
2026
+ }
2027
+ scheduleAutoSave() {
2028
+ this.autoSaveScheduler.schedule();
2029
+ }
2030
+ markStateChanged() {
2031
+ this.scheduleAutoSave(), this.announceStateChange();
2032
+ }
2033
+ announceStateChange() {
2034
+ this.eventBus.hasListeners("stateChange") && this.eventBus.emit("stateChange", {});
2035
+ }
2036
+ getAvailableIndicators() {
2037
+ return this.indicatorEngine.getAvailableIndicators();
2038
+ }
2039
+ getIndicatorInputs(e) {
2040
+ let t = this.indicatorEngine.getAvailableIndicators().find((t) => t.id === e);
2041
+ return t ? {
2042
+ id: t.id,
2043
+ params: t.defaultConfig
2044
+ } : null;
2045
+ }
2046
+ getActiveIndicators() {
2047
+ return this.indicatorEngine.getActiveIndicators();
2048
+ }
2049
+ setIndicatorVisible(e, t) {
2050
+ this.recordIndicators(e, () => this.setIndicatorVisibleNow(e, t));
2051
+ }
2052
+ setIndicatorVisibleNow(e, t) {
2053
+ this.indicatorEngine.setVisible(e, t) !== null && (this.updateViewportAndRender(), this.markStateChanged(), this.eventBus.emit("indicatorChange", {
2054
+ instanceId: e,
2055
+ change: "visible"
2056
+ }));
2057
+ }
2058
+ getIndicatorConfig(e) {
2059
+ let t = this.indicatorEngine.getIndicatorConfig(e);
2060
+ return t ? {
2061
+ id: t.id,
2062
+ params: { ...t.params }
2063
+ } : null;
2064
+ }
2065
+ updateIndicatorStyle(e, t) {
2066
+ this.recordIndicators(e, () => this.updateIndicatorStyleNow(e, t));
2067
+ }
2068
+ updateIndicatorStyleNow(e, t) {
2069
+ this.indicatorEngine.updateIndicatorStyle(e, t), this.engine.requestRender(), this.markStateChanged(), this.eventBus.emit("indicatorChange", {
2070
+ instanceId: e,
2071
+ change: "style"
2072
+ });
2073
+ }
2074
+ setOrders(e) {
2075
+ this.features.trading && (this.tradingManager.setOrders(e), this.eventBus.emit("ordersChange", { orders: e }));
2076
+ }
2077
+ startBracket(e, t) {
2078
+ if (!this.features.trading) return !1;
2079
+ let n = this.dataManager.getData(), r = t ?? (n.length > 0 ? n[n.length - 1].close : null);
2080
+ return r === null ? !1 : (this.tradingManager.startBracket(e, r), !0);
2081
+ }
2082
+ cancelBracket() {
2083
+ this.features.trading && this.tradingManager.cancelBracket();
2084
+ }
2085
+ confirmBracket() {
2086
+ return this.features.trading ? this.tradingManager.confirmBracket() : !1;
2087
+ }
2088
+ isBracketActive() {
2089
+ return this.features.trading && this.tradingManager.isBracketActive();
2090
+ }
2091
+ startOrderDraft(e, t) {
2092
+ if (!this.features.trading) return !1;
2093
+ let n = this.dataManager.getData(), r = t ?? (n.length > 0 ? n[n.length - 1].close : null);
2094
+ return r === null ? !1 : (this.tradingManager.startOrderDraft(e, r), !0);
2095
+ }
2096
+ cancelOrderDraft() {
2097
+ this.features.trading && this.tradingManager.cancelOrderDraft();
2098
+ }
2099
+ confirmOrderDraft() {
2100
+ return this.features.trading ? this.tradingManager.confirmOrderDraft() : !1;
2101
+ }
2102
+ isOrderDraftActive() {
2103
+ return this.features.trading && this.tradingManager.isOrderDraftActive();
2104
+ }
2105
+ placeOrderIntent(e) {
2106
+ this.features.trading && this.eventBus.emit("orderPlace", e);
2107
+ }
2108
+ setPositions(e) {
2109
+ this.features.trading && (this.tradingManager.setPositions(e), this.eventBus.emit("positionsChange", { positions: e }));
2110
+ }
2111
+ getOrders() {
2112
+ return this.tradingManager.getOrders();
2113
+ }
2114
+ getPositions() {
2115
+ return this.tradingManager.getPositions();
2116
+ }
2117
+ getFills() {
2118
+ return this.tradingManager.getFills();
2119
+ }
2120
+ getRealisedPnl() {
2121
+ return this.tradingManager.getRealisedPnl();
2122
+ }
2123
+ addFill(e) {
2124
+ this.features.trading && (this.tradingManager.addFill(e), this.eventBus.emit("executionFill", e));
2125
+ }
2126
+ clearFills() {
2127
+ this.tradingManager.setFills([]);
2128
+ }
2129
+ cancelOrderIntent(e) {
2130
+ this.features.trading && this.eventBus.emit("orderCancel", { orderId: e });
2131
+ }
2132
+ closePositionIntent(e) {
2133
+ this.features.trading && this.eventBus.emit("positionClose", { positionId: e });
2134
+ }
2135
+ reversePositionIntent(e) {
2136
+ this.features.trading && this.eventBus.emit("positionReverse", { positionId: e });
2137
+ }
2138
+ modifyPositionIntent(e) {
2139
+ this.features.trading && this.eventBus.emit("positionModify", e);
2140
+ }
2141
+ setDepthData(e) {
2142
+ this.features.trading && this.tradingManager.setDepthData(e);
2143
+ }
2144
+ setCurrentPrice(e, t) {
2145
+ this.followLivePrice(e), this.replaySession ? this.replaySession.price = { price: e } : (this.currentPriceLine.setPrice(e), this.scheduleRender());
2146
+ }
2147
+ replayTrades() {
2148
+ return this.replaySession !== null && this.executionAdapter?.setMarkPrice !== void 0;
2149
+ }
2150
+ followLivePrice(e) {
2151
+ this.replayTrades() || this.tradingManager.setCurrentPrice(e), this.features.alerts && this.checkAlerts(e);
2152
+ }
2153
+ checkAlerts(e) {
2154
+ let t = this.replaySession ? this.replaySession.live.getData() : this.dataManager.getData();
2155
+ this.alertManager.setBarTime(t.length > 0 ? t[t.length - 1].time : null);
2156
+ let n = new Map([["price", e]]);
2157
+ this.replaySession || this.collectIndicatorValues(n), this.alertManager.checkChannels(n, { together: !0 }), this.alertManager.checkDrawings(e);
2158
+ }
2159
+ collectIndicatorValues(e) {
2160
+ let t = this.dataManager.getData();
2161
+ if (t.length === 0) return;
2162
+ let n = t.length - 1, r = this.alertManager.getAlerts().flatMap((e) => e.target ? [e.channel, e.target] : [e.channel]);
2163
+ for (let t of r) {
2164
+ if (e.has(t)) continue;
2165
+ let r = t.indexOf(":");
2166
+ if (r < 0) continue;
2167
+ let i = this.indicatorEngine.getOutput(t.slice(0, r))?.series?.[n]?.[t.slice(r + 1)];
2168
+ typeof i == "number" && Number.isFinite(i) && e.set(t, i);
2169
+ }
2170
+ }
2171
+ setTradingConfig(e) {
2172
+ this.features.trading && this.tradingManager.setConfig(e);
2173
+ }
2174
+ async connect(e) {
2175
+ if (!w(e.adapter, e.timeframe)) throw RangeError(`${e.adapter.name} cannot serve the ${e.timeframe} timeframe`);
2176
+ this.snapshotKey = null, this.replayStop(), this.disconnectStream(), this.streamManager = new nt(), this.streamManager.on("snapshot", (t) => {
2177
+ let n = `${this.currentSymbol}|${this.streamTimeframe}`;
2178
+ this.replaySession ? this.replaySession.live.setData(t) : n === this.snapshotKey && this.dataManager.getLength() > 0 ? this.mergeSnapshot(t) : this.setData(t), this.snapshotKey = n, this.useStreamHistory(e.adapter, e.historyPageSize);
2179
+ }), this.streamManager.on("barClose", (e) => {
2180
+ if (this.replaySession) {
2181
+ this.replaySession.live.appendBar(e);
2182
+ return;
2183
+ }
2184
+ let t = K(this.fullSeries ?? this.dataManager.getData(), e);
2185
+ if (t === "stale" || !this.takeBar(e, t)) return;
2186
+ let n = this.autoScrollOnNewBar && this.viewport.isAtEnd();
2187
+ if (!this.placeStreamBar(e)) return;
2188
+ let r = this.dataManager.getData();
2189
+ this.crosshairHandler.setData(r), this.displayDataCache = null, this.recalcIndicatorsFrom(r, r.length - 2), this.updateViewportAndRender(n);
2190
+ }), this.streamManager.on("barUpdate", (e) => {
2191
+ if (this.replaySession) {
2192
+ this.replaySession.live.updateLastBar(e);
2193
+ return;
2194
+ }
2195
+ this.currentPriceLine.setPrice(e.close);
2196
+ let t = K(this.fullSeries ?? this.dataManager.getData(), e);
2197
+ if (t === "stale" || !this.takeBar(e, t) || !this.placeStreamBar(e)) {
2198
+ this.scheduleRender();
2199
+ return;
2200
+ }
2201
+ let n = this.dataManager.getData();
2202
+ this.recalcIndicatorsFrom(n, n.length - 1), this.scheduleRender();
2203
+ }), this.setBidAsk(null), this.streamManager.on("quote", (e) => {
2204
+ let t = this.priceLines.getBidAsk();
2205
+ this.setBidAsk({
2206
+ bid: e.bid ?? t?.bid,
2207
+ ask: e.ask ?? t?.ask
2208
+ });
2209
+ }), this.streamManager.on("priceChange", ({ price: e, previousClose: t }) => {
2210
+ if (this.followLivePrice(e), this.replaySession) {
2211
+ this.replaySession.price = {
2212
+ price: e,
2213
+ previousClose: t ?? void 0
2214
+ };
2215
+ return;
2216
+ }
2217
+ this.currentPriceLine.setPrice(e, t ?? void 0), this.engine.requestRender(r.Overlay);
2218
+ }), this.streamManager.on("connectionChange", (e) => {
2219
+ this.eventBus.emit("dataUpdate", { connection: e });
2220
+ }), this.streamManager.on("error", (e) => {
2221
+ this.eventBus.emit("dataUpdate", { error: e.message });
2222
+ }), this.autoScrollOnNewBar = e.autoScroll !== !1, this.setStreamTarget(e.symbol, e.timeframe), this.streamAdapter = e.adapter;
2223
+ let t = this.streamManager;
2224
+ if (this.resolveStreamSymbol(e.adapter, e.symbol), await t.connect(e), this.streamManager !== t) return;
2225
+ let n = y(e.timeframe);
2226
+ this.barCountdown.setTimeframeMs(n), this.countdownInterval && clearInterval(this.countdownInterval), this.countdownInterval = setInterval(() => {
2227
+ this.barCountdown.isVisible() && this.engine.requestRender(r.Hover);
2228
+ }, 1e3);
2229
+ }
2230
+ setStreamTarget(e, t) {
2231
+ let n = this.announcedSymbol, r = this.announcedTimeframe;
2232
+ this.currentSymbol = e, this.streamTimeframe = t, e !== n && (this.announcedSymbol = e, this.eventBus.emit("symbolChange", {
2233
+ symbol: e,
2234
+ previous: n
2235
+ })), t !== r && (this.announcedTimeframe = t, this.eventBus.emit("timeframeChange", {
2236
+ timeframe: t,
2237
+ previous: r
2238
+ }));
2239
+ }
2240
+ async switchStream(e, t) {
2241
+ if (!this.streamManager) return;
2242
+ let n = this.streamAdapter;
2243
+ if (n && !w(n, t)) throw RangeError(`${n.name} cannot serve the ${t} timeframe`);
2244
+ this.setStreamTarget(e, t), this.historyFromStream && this.history.setLoader(null), this.barCountdown.setTimeframeMs(y(t)), n && this.resolveStreamSymbol(n, e), await this.streamManager.switchTo(e, t);
2245
+ }
2246
+ isTimeframeAllowed(e) {
2247
+ let t = this.features.timeframes;
2248
+ return t.length === 0 || t.includes(e);
2249
+ }
2250
+ async setTimeframe(e) {
2251
+ if (!this.streamManager) throw Error("No active stream. Call connect() first.");
2252
+ this.isTimeframeAllowed(e) && await this.switchStream(this.currentSymbol, e);
2253
+ }
2254
+ disconnectStream() {
2255
+ this.symbolInfoSeq++, this.priceLines.setBidAsk(null), this.streamManager &&= (this.streamManager.dispose(), null), this.historyFromStream &&= (this.history.setLoader(null), !1), this.streamAdapter = null;
2256
+ }
2257
+ connectExecution(e, t = {}) {
2258
+ if (!this.features.trading) throw Error("connectExecution requires features.trading to be enabled");
2259
+ this.disconnectExecution(), this.executionAdapter = e, this.execTeardown = mn(e, {
2260
+ onIntent: (e, t) => {
2261
+ let n = (e) => t(e.payload);
2262
+ return this.eventBus.on(e, n), () => this.eventBus.off(e, n);
2263
+ },
2264
+ setOrders: (e) => this.setOrders(e),
2265
+ setPositions: (e) => this.setPositions(e),
2266
+ onError: (e) => this.eventBus.emit("executionError", e),
2267
+ onFill: (e) => {
2268
+ this.tradingManager.addFill(e), this.eventBus.emit("executionFill", e);
2269
+ },
2270
+ getPositions: () => this.tradingManager.getPositions()
2271
+ }), Promise.resolve(e.connect(t)).catch((e) => this.eventBus.emit("executionError", {
2272
+ message: "Execution connect failed",
2273
+ cause: e
2274
+ }));
2275
+ }
2276
+ disconnectExecution() {
2277
+ this.returnMarkToLive(), this.execTeardown &&= (this.execTeardown(), null), this.executionAdapter &&= (this.executionAdapter.disconnect(), null);
2278
+ }
2279
+ getExecutionAdapter() {
2280
+ return this.executionAdapter;
2281
+ }
2282
+ setBarCountdownVisible(e) {
2283
+ this.barCountdown.setVisible(e && this.features.barCountdown), this.engine.requestRender(r.Hover);
2284
+ }
2285
+ setSessionBreaksVisible(e) {
2286
+ this.sessionBreaks.setVisible(e), this.engine.requestRender(r.Background);
2287
+ }
2288
+ addCompareSymbol(e, t, n, r) {
2289
+ this.features.compareSymbols && (this.compareRenderer.addSymbol({
2290
+ id: e,
2291
+ label: t,
2292
+ data: n,
2293
+ color: r,
2294
+ visible: !0
2295
+ }), this.updateViewportAndRender());
2296
+ }
2297
+ removeCompareSymbol(e) {
2298
+ this.compareRenderer.removeSymbol(e), this.updateViewportAndRender();
2299
+ }
2300
+ updateCompareData(e, t) {
2301
+ this.compareRenderer.setSymbolData(e, t), this.updateViewportAndRender();
2302
+ }
2303
+ setCompareMode(e) {
2304
+ this.compareRenderer.setMode(e), this.updateViewportAndRender();
2305
+ }
2306
+ clearCompareSymbols() {
2307
+ this.compareRenderer.clear(), this.updateViewportAndRender();
2308
+ }
2309
+ setLogScale(e) {
2310
+ e && !this.features.logScale || (this.viewport.setLogScale(e), this.updateViewportAndRender());
2311
+ }
2312
+ isLogScale() {
2313
+ return this.viewport.isLogScale();
2314
+ }
2315
+ setInvertScale(e) {
2316
+ this.viewport.setInvertScale(e), this.updateViewportAndRender();
2317
+ }
2318
+ isInvertScale() {
2319
+ return this.viewport.isInvertScale();
2320
+ }
2321
+ setScaleMode(e) {
2322
+ e === "logarithmic" && !this.features.logScale || (this.viewport.setScaleMode(e), this.updateViewportAndRender());
2323
+ }
2324
+ getScaleMode() {
2325
+ return this.viewport.getScaleMode();
2326
+ }
2327
+ setSessionBreaksConfig(e) {
2328
+ this.sessionBreaks.setConfig(e), this.engine.requestRender(r.Background);
2329
+ }
2330
+ getConnectionState() {
2331
+ return this.streamManager?.getConnectionState() ?? "disconnected";
2332
+ }
2333
+ getConnectionInfo() {
2334
+ return this.streamManager?.getConnectionInfo() ?? { state: "disconnected" };
2335
+ }
2336
+ setAutoScroll(e) {
2337
+ this.autoScrollOnNewBar = e;
2338
+ }
2339
+ scrollTo(e) {
2340
+ let t = this.dataManager.getData();
2341
+ for (let n = 0; n < t.length; n++) if (t[n].time >= e) {
2342
+ let e = this.viewport.getState().barWidth + this.viewport.getState().barSpacing;
2343
+ this.viewport.scrollBy(n * e - this.viewport.getState().offset), this.updateViewportAndRender();
2344
+ return;
2345
+ }
2346
+ }
2347
+ goToTime(e) {
2348
+ let t = this.getDisplayData();
2349
+ if (t.length === 0 || !Number.isFinite(e)) return -1;
2350
+ let n = Math.max(0, Math.min(t.length - 1, Math.floor(E(e, t)))), r = this.viewport.getState(), i = n * (r.barWidth + r.barSpacing) + r.barWidth / 2 - r.chartRect.width / 2;
2351
+ return this.viewport.scrollBy(i - r.offset), this.updateViewportAndRender(), n;
2352
+ }
2353
+ setVisibleRangePreset(e) {
2354
+ let t = this.getDisplayData();
2355
+ if (t.length === 0) return;
2356
+ let n = t.length - 1, r = t[n].time > gn ? 1 : 1e3, i = bt(e, t[n].time * r, this.displayTz), a = i === null ? null : i / r;
2357
+ if (a === null || a < t[0].time) {
2358
+ this.fitContent();
2359
+ return;
2360
+ }
2361
+ let o = E(a, t), s = Math.min(n, e === "YTD" ? Math.ceil(o) : Math.floor(o) + 1);
2362
+ this.viewport.zoomToBarRange(s, n + this.viewport.getRightMargin()), this.viewport.scrollToEnd(), this.updateViewportAndRender();
2363
+ }
2364
+ scrollToEnd() {
2365
+ this.viewport.scrollToEnd(), this.updateViewportAndRender();
2366
+ }
2367
+ scrollBars(e) {
2368
+ if (!Number.isFinite(e) || e === 0) return;
2369
+ let { barWidth: t, barSpacing: n } = this.viewport.getState();
2370
+ this.viewport.scrollBy(e * (t + n)), this.updateViewportAndRender();
2371
+ }
2372
+ setVisibleRange(e, t) {
2373
+ let n = this.dataManager.getData();
2374
+ if (n.length === 0) return;
2375
+ let r = E(Math.min(e, t), n), i = E(Math.max(e, t), n);
2376
+ this.viewport.zoomToBarRange(r, i), this.updateViewportAndRender();
2377
+ }
2378
+ setPanLimits(e) {
2379
+ this.viewport.setPanLimits(e), this.updateViewportAndRender();
2380
+ }
2381
+ zoomIn() {
2382
+ let e = this.viewport.getState().chartRect.width;
2383
+ this.viewport.zoom(.2, e / 2), this.updateViewportAndRender();
2384
+ }
2385
+ zoomOut() {
2386
+ let e = this.viewport.getState().chartRect.width;
2387
+ this.viewport.zoom(-.2, e / 2), this.updateViewportAndRender();
2388
+ }
2389
+ fitContent() {
2390
+ let e = this.dataManager.getLength();
2391
+ e !== 0 && (this.viewport.zoomToBarRange(0, e - 1 + this.viewport.getRightMargin()), this.viewport.scrollToEnd(), this.updateViewportAndRender());
2392
+ }
2393
+ on(e, t) {
2394
+ this.eventBus.on(e, t);
2395
+ }
2396
+ off(e, t) {
2397
+ this.eventBus.off(e, t);
2398
+ }
2399
+ enableTauriBridge(e) {
2400
+ this.eventBus.enableTauriBridge({
2401
+ enabled: !0,
2402
+ ...e
2403
+ });
2404
+ }
2405
+ disableTauriBridge() {
2406
+ this.eventBus.disableTauriBridge();
2407
+ }
2408
+ setTheme(e) {
2409
+ this.themeManager.setTheme(e), this.syncRenderContext(), this.container.style.backgroundColor = this.themeManager.getTheme().background, this.engine.requestRender(), this.eventBus.emit("themeChange", { theme: e }), this.markStateChanged();
2410
+ }
2411
+ getTheme() {
2412
+ return this.themeManager.getTheme();
2413
+ }
2414
+ setWatermark(e, t) {
2415
+ this.watermark.setConfig({
2416
+ text: e,
2417
+ ...t
2418
+ }), this.engine.requestRender(r.Background);
2419
+ }
2420
+ setAutoScale(e) {
2421
+ this.options.autoScale = e, this.defaultAutoScale = e, this.updateViewportAndRender();
2422
+ }
2423
+ isAutoScale() {
2424
+ return this.options.autoScale !== !1;
2425
+ }
2426
+ setCrosshairMode(e) {
2427
+ this.crosshairHandler.setMode(e), this.engine.requestRender(r.Hover);
2428
+ }
2429
+ getCrosshairMode() {
2430
+ return this.crosshairHandler.getMode();
2431
+ }
2432
+ setCrosshairPosition(e) {
2433
+ e ? this.crosshairHandler.onPointerMove(e) : this.crosshairHandler.onPointerLeave(), this.engine.requestRender(r.Hover);
2434
+ }
2435
+ setCrosshairTime(e) {
2436
+ let t = this.getDisplayData(), n = e === null || t.length === 0 ? null : Math.floor(E(e, t));
2437
+ n !== this.crosshairHandler.getSyncedSlot() && (this.crosshairHandler.setSyncedSlot(n), this.engine.requestRender(r.Hover));
2438
+ }
2439
+ getData() {
2440
+ return this.dataManager.getData();
2441
+ }
2442
+ setGridVisible(e) {
2443
+ this.gridRenderer.setVisible(e), this.engine.requestRender(r.Background);
2444
+ }
2445
+ isGridVisible() {
2446
+ return this.gridRenderer.isVisible();
2447
+ }
2448
+ setVolumeVisible(e) {
2449
+ this.volumeRenderer.setVisible(e), this.engine.requestRender(r.Main);
2450
+ }
2451
+ setVolumeProfileVisible(e) {
2452
+ this.volumeProfile.setVisible(e), this.engine.requestRender(r.Main);
2453
+ }
2454
+ isVolumeProfileVisible() {
2455
+ return this.volumeProfile.isVisible();
2456
+ }
2457
+ setVolumeProfileConfig(e) {
2458
+ e.buckets !== void 0 && this.volumeProfile.setBuckets(e.buckets), e.widthRatio !== void 0 && this.volumeProfile.setWidthRatio(e.widthRatio), e.opacity !== void 0 && this.volumeProfile.setOpacity(e.opacity), e.highlightPoC !== void 0 && this.volumeProfile.setHighlightPoC(e.highlightPoC), this.engine.requestRender(r.Main);
2459
+ }
2460
+ setMarketProfileVisible(e) {
2461
+ this.marketProfile.setVisible(e), this.engine.requestRender(r.Main);
2462
+ }
2463
+ isMarketProfileVisible() {
2464
+ return this.marketProfile.isVisible();
2465
+ }
2466
+ setMarketProfileConfig(e) {
2467
+ e.buckets !== void 0 && this.marketProfile.setBuckets(e.buckets), e.widthRatio !== void 0 && this.marketProfile.setWidthRatio(e.widthRatio), e.opacity !== void 0 && this.marketProfile.setOpacity(e.opacity), e.valueAreaPct !== void 0 && this.marketProfile.setValueAreaPct(e.valueAreaPct), e.highlightPoC !== void 0 && this.marketProfile.setHighlightPoC(e.highlightPoC), e.showStats !== void 0 && this.marketProfile.setShowStats(e.showStats), e.splitBySession !== void 0 && this.marketProfile.setSplitBySession(e.splitBySession), e.letters !== void 0 && this.marketProfile.setLetters(e.letters), this.engine.requestRender(r.Main);
2468
+ }
2469
+ getMarketProfileStats() {
2470
+ return this.marketProfile.getStats();
2471
+ }
2472
+ setDepthHeatmapVisible(e) {
2473
+ this.depthHeatmap.setVisible(e), this.engine.requestRender(r.Main);
2474
+ }
2475
+ isDepthHeatmapVisible() {
2476
+ return this.depthHeatmap.isVisible();
2477
+ }
2478
+ setDepthHeatmapConfig(e) {
2479
+ e.opacity !== void 0 && this.depthHeatmap.setOpacity(e.opacity), e.capacity !== void 0 && this.depthHeatmap.setCapacity(e.capacity), this.engine.requestRender(r.Main);
2480
+ }
2481
+ pushDepthSnapshot(e) {
2482
+ let t = this.dataManager.getData();
2483
+ t.length !== 0 && (this.depthHeatmap.push(t[t.length - 1].time, e), this.depthHeatmap.isVisible() && this.engine.requestRender(r.Main));
2484
+ }
2485
+ clearDepthHeatmap() {
2486
+ this.depthHeatmap.clear(), this.engine.requestRender(r.Main);
2487
+ }
2488
+ setPeriodLevelsVisible(e) {
2489
+ this.periodLevels.setVisible(e), this.engine.requestRender(r.Main);
2490
+ }
2491
+ isPeriodLevelsVisible() {
2492
+ return this.periodLevels.isVisible();
2493
+ }
2494
+ setPeriodLevelsPeriod(e) {
2495
+ this.periodLevels.setPeriod(e), this.engine.requestRender(r.Main);
2496
+ }
2497
+ setTimezone(e) {
2498
+ vn(e), this.timezoneSetting = e, this.applyTimezone();
2499
+ }
2500
+ getTimezone() {
2501
+ return this.timezoneSetting;
2502
+ }
2503
+ getEffectiveTimezone() {
2504
+ return this.displayTz;
2505
+ }
2506
+ applyTimezone() {
2507
+ let e = this.symbolInfo?.timezone, t = this.timezoneSetting === "exchange" ? e && f(e) ? e : "UTC" : this.timezoneSetting;
2508
+ this.displayTz = t, this.timeAxis.setTimezoneOffset(t), this.crosshairHandler.setTimezoneOffset(t), this.crosshairTooltip.setTimezoneOffset(t), this.pinnedTooltip.setTimezone(t), this.sessionBreaks.setTimezone(t), this.engine.requestRender();
2509
+ }
2510
+ setSymbolInfo(e) {
2511
+ this.symbolInfo = e ? {
2512
+ ...e,
2513
+ sessions: e.sessions?.map((e) => ({ ...e }))
2514
+ } : null, this.marketConfig?.pricePrecision === void 0 && this.applyPricePrecision(this.symbolInfo?.pricePrecision ?? null);
2515
+ let t = (this.symbolInfo?.sessions ?? []).flatMap((e) => {
2516
+ let t = v(e.start), n = v(e.end);
2517
+ return t === null || n === null ? [] : [{
2518
+ startMinute: t,
2519
+ endMinute: n
2520
+ }];
2521
+ }), n = this.symbolInfo?.timezone;
2522
+ this.sessionShading.replaceConfig(t.length > 0 && n && f(n) ? {
2523
+ timeZone: n,
2524
+ windows: t,
2525
+ startMinute: t[0].startMinute,
2526
+ endMinute: t[t.length - 1].endMinute
2527
+ } : this.hostSessionHours), this.timezoneSetting === "exchange" && this.applyTimezone(), this.reapplyExtendedHours(), this.updateViewportAndRender(), this.eventBus.emit("symbolInfoChange", { info: this.symbolInfo });
2528
+ }
2529
+ getSymbolInfo() {
2530
+ return this.symbolInfo;
2531
+ }
2532
+ resolveStreamSymbol(e, t) {
2533
+ let n = e.resolveSymbol?.bind(e);
2534
+ if (!n) return;
2535
+ let r = ++this.symbolInfoSeq;
2536
+ this.symbolInfo && this.symbolInfo.symbol !== t && this.setSymbolInfo(null), Promise.resolve().then(() => n(t)).then((e) => {
2537
+ e && r === this.symbolInfoSeq && this.currentSymbol === t && this.setSymbolInfo(e);
2538
+ }, (e) => {
2539
+ r === this.symbolInfoSeq && console.warn(`No symbol info for "${t}":`, e);
2540
+ });
2541
+ }
2542
+ setTimezoneOffset(e) {
2543
+ this.setTimezone(e);
2544
+ }
2545
+ setPivotMarkersVisible(e) {
2546
+ this.pivotMarkers.setVisible(e), this.engine.requestRender(r.Overlay);
2547
+ }
2548
+ isPivotMarkersVisible() {
2549
+ return this.pivotMarkers.isVisible();
2550
+ }
2551
+ setPivotMarkersConfig(e) {
2552
+ (e.left !== void 0 || e.right !== void 0) && this.pivotMarkers.setStrength(e.left ?? 5, e.right ?? e.left ?? 5), e.showLabels !== void 0 && this.pivotMarkers.setShowLabels(e.showLabels), e.structureLabels !== void 0 && this.pivotMarkers.setStructureLabels(e.structureLabels), this.engine.requestRender(r.Overlay);
2553
+ }
2554
+ setSessionShadingVisible(e) {
2555
+ this.sessionShading.setVisible(e), this.engine.requestRender(r.Background);
2556
+ }
2557
+ isSessionShadingVisible() {
2558
+ return this.sessionShading.isVisible();
2559
+ }
2560
+ setSessionShadingConfig(e) {
2561
+ this.hostSessionHours = yt(this.hostSessionHours, e), this.sessionShading.replaceConfig(this.hostSessionHours), this.engine.requestRender(r.Background);
2562
+ }
2563
+ setTooltipVisible(e) {
2564
+ e || this.crosshairTooltip.hide();
2565
+ }
2566
+ setLegend(e) {
2567
+ this.chartLegend.setConfig(e), this.engine.requestRender(r.Hover);
2568
+ }
2569
+ setSymbolName(e) {
2570
+ this.chartLegend.setSymbol(e), this.engine.requestRender(r.Hover);
2571
+ }
2572
+ setStatusText(e) {
2573
+ this.chartLegend.setStatusText(e), this.engine.requestRender(r.Hover);
2574
+ }
2575
+ async setRenderer(e) {
2576
+ let t = ++this.rendererToken;
2577
+ if (e === "canvas") return this.applyRenderer(null), "canvas";
2578
+ if (this.engine.getGpu()) return "webgl";
2579
+ let n = await vt(e);
2580
+ return t !== this.rendererToken || this.disposed ? (n?.destroy(), this.getRenderer()) : (this.applyRenderer(n, n ? void 0 : "unsupported"), this.getRenderer());
2581
+ }
2582
+ getRenderer() {
2583
+ return this.engine.getGpu() ? "webgl" : "canvas";
2584
+ }
2585
+ applyRenderer(e, t) {
2586
+ let n = this.getRenderer();
2587
+ e ? this.engine.attachGpu(e) : this.engine.detachGpu();
2588
+ let r = this.getRenderer();
2589
+ (r !== n || t) && this.eventBus.emit("rendererChange", t ? {
2590
+ renderer: r,
2591
+ reason: t
2592
+ } : { renderer: r });
2593
+ }
2594
+ freshFrame() {
2595
+ this.engine.getGpu() && this.engine.renderNow();
2596
+ }
2597
+ screenshot(e) {
2598
+ this.features.screenshot && (this.freshFrame(), S.download(this.container, e, this.themeManager.getTheme().background));
2599
+ }
2600
+ async copyScreenshot() {
2601
+ if (!this.features.screenshot) return !1;
2602
+ try {
2603
+ this.freshFrame();
2604
+ let e = await S.toBlob(this.container, this.themeManager.getTheme().background), t = globalThis.ClipboardItem;
2605
+ return !e || !navigator.clipboard?.write || !t ? !1 : (await navigator.clipboard.write([new t({ "image/png": e })]), !0);
2606
+ } catch {
2607
+ return !1;
2608
+ }
2609
+ }
2610
+ screenshotDataURL() {
2611
+ return this.features.screenshot ? (this.freshFrame(), S.toDataURL(this.container, this.themeManager.getTheme().background)) : null;
2612
+ }
2613
+ async screenshotBlob() {
2614
+ return this.features.screenshot ? (this.freshFrame(), S.toBlob(this.container, this.themeManager.getTheme().background)) : null;
2615
+ }
2616
+ addAlert(e, t = "crossing", n, r = "price", i, a = {}) {
2617
+ if (!this.features.alerts) return null;
2618
+ let o = this.alertManager.addAlert(e, t, n, !1, r, i, a);
2619
+ return this.markStateChanged(), o;
2620
+ }
2621
+ removeAlert(e) {
2622
+ this.alertManager.removeAlert(e), this.markStateChanged();
2623
+ }
2624
+ getSelectedDrawingIds() {
2625
+ return this.drawingManager.getSelectedDrawingIds();
2626
+ }
2627
+ moveDrawing(e, t) {
2628
+ let n = this.drawingManager.moveDrawing(e, t);
2629
+ return n && this.markStateChanged(), n;
2630
+ }
2631
+ groupDrawings(e, t) {
2632
+ let n = this.drawingManager.groupDrawings(e, t);
2633
+ return n && this.markStateChanged(), n;
2634
+ }
2635
+ ungroupDrawings(e) {
2636
+ return this.afterDrawingChange(this.drawingManager.ungroup(e));
2637
+ }
2638
+ renameDrawingGroup(e, t) {
2639
+ return this.afterDrawingChange(this.drawingManager.renameGroup(e, t));
2640
+ }
2641
+ setDrawingGroupVisible(e, t) {
2642
+ return this.afterDrawingChange(this.drawingManager.setGroupVisible(e, t));
2643
+ }
2644
+ setDrawingGroupLocked(e, t) {
2645
+ return this.afterDrawingChange(this.drawingManager.setGroupLocked(e, t));
2646
+ }
2647
+ getDrawingGroups() {
2648
+ return this.drawingManager.getGroups();
2649
+ }
2650
+ afterDrawingChange(e) {
2651
+ return e && this.markStateChanged(), e;
2652
+ }
2653
+ canAddDrawingAlert(e) {
2654
+ return this.features.alerts && this.drawingLevelsNow(e) !== null;
2655
+ }
2656
+ drawingLevelsNow(e) {
2657
+ let t = this.replaySession ? this.replaySession.live.getData() : this.getDisplayData();
2658
+ if (t.length === 0) return null;
2659
+ let n = {
2660
+ ...this.viewport.getState(),
2661
+ data: t
2662
+ };
2663
+ return this.drawingManager.priceAt(e, t[t.length - 1].time, n);
2664
+ }
2665
+ followDrawingAlerts(e, t) {
2666
+ if (!(!t || !this.alertManager)) {
2667
+ if (e === "drawingRemove") {
2668
+ let e = this.alertManager.takeDrawingAlerts(t);
2669
+ e.length > 0 && this.removedDrawingAlerts.set(t, e);
2670
+ } else if (e === "drawingCreate") {
2671
+ let e = this.removedDrawingAlerts.get(t);
2672
+ if (!e) return;
2673
+ this.removedDrawingAlerts.delete(t), this.alertManager.restoreAlerts(e);
2674
+ }
2675
+ }
2676
+ }
2677
+ dropOrphanDrawingAlerts() {
2678
+ this.removedDrawingAlerts.clear(), this.alertManager && this.alertManager.pruneDrawingAlerts(new Set(this.drawingManager.getDrawings().map((e) => e.id))) > 0 && this.markStateChanged();
2679
+ }
2680
+ addDrawingAlert(e, t = {}) {
2681
+ if (!this.canAddDrawingAlert(e)) return null;
2682
+ let n = this.alertManager.addDrawingAlert(e, t.condition ?? "crossing", t.message, t.repeating ?? !1, t.label);
2683
+ return this.markStateChanged(), n;
2684
+ }
2685
+ getAlerts() {
2686
+ return this.alertManager.getAlerts();
2687
+ }
2688
+ clearAlerts() {
2689
+ this.alertManager.clearAlerts(), this.markStateChanged();
2690
+ }
2691
+ saveAlerts(e) {
2692
+ this.alertManager.saveToStorage(e);
2693
+ }
2694
+ loadAlerts(e) {
2695
+ this.alertManager.loadFromStorage(e), this.alertManager.pruneDrawingAlerts(new Set(this.drawingManager.getDrawings().map((e) => e.id))), this.engine.requestRender(r.Overlay);
2696
+ }
2697
+ addSignalMarker(e) {
2698
+ return this.signalMarkerManager.addMarker(e);
2699
+ }
2700
+ removeSignalMarker(e) {
2701
+ this.signalMarkerManager.removeMarker(e);
2702
+ }
2703
+ getSignalMarkers() {
2704
+ return this.signalMarkerManager.getMarkers();
2705
+ }
2706
+ setSignalMarkers(e) {
2707
+ this.signalMarkerManager.setMarkers(e);
2708
+ }
2709
+ clearSignalMarkers() {
2710
+ this.signalMarkerManager.clearMarkers();
2711
+ }
2712
+ setSignalMarkerStyle(e) {
2713
+ this.signalMarkerManager.setStyle(e);
2714
+ }
2715
+ addTradeZone(e) {
2716
+ return this.tradeZoneManager.addZone(e);
2717
+ }
2718
+ updateTradeZone(e, t) {
2719
+ this.tradeZoneManager.updateZone(e, t);
2720
+ }
2721
+ removeTradeZone(e) {
2722
+ this.tradeZoneManager.removeZone(e);
2723
+ }
2724
+ getTradeZones() {
2725
+ return this.tradeZoneManager.getZones();
2726
+ }
2727
+ setTradeZones(e) {
2728
+ this.tradeZoneManager.setZones(e);
2729
+ }
2730
+ clearTradeZones() {
2731
+ this.tradeZoneManager.clearZones();
2732
+ }
2733
+ setTradeZoneStyle(e) {
2734
+ this.tradeZoneManager.setStyle(e);
2735
+ }
2736
+ replayStart(e) {
2737
+ if (!this.features.replay) return;
2738
+ if (this.history.reset(), !this.replaySession) {
2739
+ if (this.dataManager.getLength() === 0) return;
2740
+ let e = new j();
2741
+ e.setData(this.fullSeries ?? this.dataManager.getData()), this.replaySession = {
2742
+ live: e,
2743
+ price: null,
2744
+ fedTime: null
2745
+ };
2746
+ }
2747
+ let t = this.shownBars(this.replaySession.live.getData()), { steps: n, ...r } = e ?? {}, i = n ? Nn(n, t) : null;
2748
+ this.replayStepsSeries = i, this.replayCoarse = t, this.options.autoScale = !0, this.replayRestarting = !0;
2749
+ try {
2750
+ this.replayManager.load(i ?? t);
2751
+ } finally {
2752
+ this.replayRestarting = !1;
2753
+ }
2754
+ i && r.startIndex !== void 0 && (r.startIndex = In(i, t, r.startIndex)), this.replayBarUnsub?.();
2755
+ let a = -1, o = -1, s = null, c = i ?? t;
2756
+ this.replayBarUnsub = this.replayManager.on("bar", ({ index: e }) => {
2757
+ let n = e, r = t[e];
2758
+ if (i) {
2759
+ let c = i[e];
2760
+ n = Fn(t, c.time), s = s !== null && o === e - 1 && n === a - 1 && s ? Rn(s, c) : Ln(t[n], i, e), r = s;
2761
+ }
2762
+ o = e;
2763
+ let l = n + 1, u = a > 0 && l >= a && this.dataManager.getLength() === a, d = !(u && !this.replaySeeking) || this.autoScrollOnNewBar && this.viewport.isAtEnd();
2764
+ if (u) {
2765
+ i && l > a && this.dataManager.updateLastBar(t[a - 1]);
2766
+ for (let e = a; e < l - 1; e++) this.dataManager.appendBar(t[e]);
2767
+ l > a ? this.dataManager.appendBar(r) : this.dataManager.updateLastBar(r), this.recalcIndicatorsFrom(this.dataManager.getData(), Math.max(0, a - 1));
2768
+ } else this.dataManager.setData([...t.slice(0, n), r]), this.recalcIndicators(this.dataManager.getData());
2769
+ a = l, this.currentPriceLine.setPrice(r.close, n > 0 ? t[n - 1].close : void 0), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.updateViewportAndRender(d), this.feedReplaySteps(c, e);
2770
+ let f = c[e + 1]?.time ?? c[e].time + (e > 0 ? c[e].time - c[e - 1].time : 0);
2771
+ this.eventBus.emit("replayStep", {
2772
+ barIndex: n,
2773
+ time: t[n].time,
2774
+ until: f
2775
+ });
2776
+ }), this.replayManager.play(r);
2777
+ }
2778
+ replaySeekToTime(e) {
2779
+ if (!this.replaySession || !this.replayCoarse) return;
2780
+ let t = this.replayStepsSeries ?? this.replayCoarse, n = 0, r = t.length - 1;
2781
+ for (; n < r;) {
2782
+ let i = n + r + 1 >> 1;
2783
+ t[i].time < e ? n = i : r = i - 1;
2784
+ }
2785
+ this.replaySeek(n);
2786
+ }
2787
+ feedReplayPrice(e, t) {
2788
+ let n = this.executionAdapter;
2789
+ n?.setMarkPrice && (n.setMarkPrice(e, t), this.tradingManager.setCurrentPrice(e));
2790
+ }
2791
+ returnMarkToLive() {
2792
+ let e = this.replaySession;
2793
+ if (!e || !this.replayTrades()) return;
2794
+ let t = e.live.getData(), n = e.price?.price ?? t[t.length - 1]?.close;
2795
+ n !== void 0 && this.feedReplayPrice(n);
2796
+ }
2797
+ feedReplaySteps(e, t) {
2798
+ let n = this.replaySession, r = this.executionAdapter, i = e[t];
2799
+ if (!n || !r?.setMarkPrice || !i) return;
2800
+ if (n.fedTime === null) {
2801
+ n.fedTime = i.time, this.feedReplayPrice(i.close, i.time);
2802
+ return;
2803
+ }
2804
+ if (i.time <= n.fedTime) return;
2805
+ let a = e.slice(An(e, n.fedTime), t + 1);
2806
+ n.fedTime = i.time;
2807
+ let o = Math.ceil(a.length / kn);
2808
+ for (let e = 0; e < a.length; e += o) for (let [t, n] of jn(a.slice(e, e + o))) r.setMarkPrice(t, n);
2809
+ this.tradingManager.setCurrentPrice(i.close);
2810
+ }
2811
+ getReplayBarIndex() {
2812
+ if (!this.replaySession) return -1;
2813
+ let { current: e } = this.replayManager.getProgress(), t = this.replayStepsSeries;
2814
+ return t && this.replayCoarse ? Fn(this.replayCoarse, t[e]?.time ?? -Infinity) : e;
2815
+ }
2816
+ replaySeekToBar(e) {
2817
+ let t = this.replayStepsSeries;
2818
+ this.replaySeek(t && this.replayCoarse ? In(t, this.replayCoarse, e) : e);
2819
+ }
2820
+ replayPause() {
2821
+ this.replayManager.pause();
2822
+ }
2823
+ replayResume() {
2824
+ this.replayManager.resume();
2825
+ }
2826
+ replayStop() {
2827
+ let e = this.replaySession;
2828
+ this.endReplaySession(), e && (this.loadSeries(e.live.getData(), !0), e.price && this.currentPriceLine.setPrice(e.price.price, e.price.previousClose));
2829
+ }
2830
+ isReplayActive() {
2831
+ return this.replaySession !== null;
2832
+ }
2833
+ getPlotRect() {
2834
+ let { x: e, y: t, width: n, height: r } = this.viewport.getState().chartRect;
2835
+ return {
2836
+ x: e,
2837
+ y: t,
2838
+ width: n,
2839
+ height: r
2840
+ };
2841
+ }
2842
+ endReplaySession() {
2843
+ this.replaySession && (this.returnMarkToLive(), this.replaySession = null, this.replayStepsSeries = null, this.replayCoarse = null, this.replayBarUnsub?.(), this.replayBarUnsub = null, this.replayManager.stop());
2844
+ }
2845
+ replaySeek(e) {
2846
+ this.replaySeeking = !0;
2847
+ try {
2848
+ this.replayManager.seekTo(e);
2849
+ } finally {
2850
+ this.replaySeeking = !1;
2851
+ }
2852
+ }
2853
+ setReplaySpeed(e) {
2854
+ this.replayManager.setSpeed(e);
2855
+ }
2856
+ getReplayState() {
2857
+ return this.replayManager.getState();
2858
+ }
2859
+ getReplayProgress() {
2860
+ return this.replayManager.getProgress();
2861
+ }
2862
+ captureSnapshot() {
2863
+ return b.capture({
2864
+ getDrawings: () => this.getDrawings(),
2865
+ getTheme: () => this.getTheme(),
2866
+ getAlerts: () => this.getAlerts(),
2867
+ getIndicators: () => this.getIndicatorSetup()
2868
+ }, {
2869
+ chartType: this.options.chartType,
2870
+ chartTypeOptions: this.getChartTypeOptions(),
2871
+ symbol: this.currentSymbol || void 0
2872
+ });
2873
+ }
2874
+ restoreIndicators(e, t) {
2875
+ let n = Tn(e), r = /* @__PURE__ */ new Map();
2876
+ this.unrestoredIndicators = [];
2877
+ let i = new Set(this.indicatorEngine.getAvailableIndicators().map((e) => e.id)), a = [], o = /* @__PURE__ */ new Set();
2878
+ if (t) {
2879
+ let e = new Map(n.map((e) => [e.instanceId, e])), t = this.getIndicatorSetup();
2880
+ for (let n of t) {
2881
+ let t = e.get(n.instanceId);
2882
+ t && En(n, t) && o.add(n.instanceId);
2883
+ }
2884
+ for (let e of t) o.has(e.instanceId) || this.removeIndicator(e.instanceId);
2885
+ for (let e of [...o]) this.indicatorEngine.getIndicatorConfig(e) || o.delete(e);
2886
+ } else for (let e of this.indicatorEngine.getActiveIndicators()) this.removeIndicator(e.instanceId);
2887
+ let s = (e) => {
2888
+ let t = { ...e };
2889
+ for (let [e, n] of Object.entries(t)) {
2890
+ let i = h(n), a = i && r.get(i.instanceId);
2891
+ a && (t[e] = d(a, i.key));
2892
+ }
2893
+ return t;
2894
+ };
2895
+ for (let e of n) {
2896
+ let n = null;
2897
+ if (o.has(e.instanceId)) {
2898
+ n = e.instanceId;
2899
+ let t = this.indicatorEngine.getIndicatorConfig(n)?.params ?? {}, r = {};
2900
+ for (let [n, i] of Object.entries(s(e.params))) t[n] !== i && (r[n] = i);
2901
+ Object.keys(r).length > 0 && this.updateIndicator(n, r);
2902
+ } else {
2903
+ let a = [
2904
+ "top",
2905
+ "bottom",
2906
+ "left",
2907
+ "right"
2908
+ ].find((t) => t === e.position) ?? "bottom";
2909
+ try {
2910
+ if (!i.has(e.id)) throw Error("no such indicator is registered");
2911
+ let o = e.pane ? r.get(e.pane) : void 0;
2912
+ n = this.addIndicatorNow(e.id, s(e.params), a, {
2913
+ ...o ? { pane: o } : {},
2914
+ ...e.scale === "left" ? { scale: "left" } : {},
2915
+ ...t ? { instanceId: e.instanceId } : {}
2916
+ });
2917
+ } catch (t) {
2918
+ console.warn(`Layout indicator "${e.id}" kept but not shown:`, t);
2919
+ }
2920
+ }
2921
+ if (!n) {
2922
+ this.unrestoredIndicators.push(e);
2923
+ continue;
2924
+ }
2925
+ r.set(e.instanceId, n), a.push([e, n]), this.restoreLooks(n, e);
2926
+ }
2927
+ return this.restorePanes(a), this.updateViewportAndRender(), r;
2928
+ }
2929
+ restoreLooks(e, t) {
2930
+ let n = this.indicatorEngine.getIndicatorStyle(e);
2931
+ t.style && JSON.stringify({
2932
+ ...n,
2933
+ ...t.style
2934
+ }) !== JSON.stringify(n) && this.updateIndicatorStyle(e, t.style);
2935
+ let r = this.indicatorEngine.getIndicatorConfig(e);
2936
+ (t.visible ?? !0) !== (r?.visible ?? !0) && this.setIndicatorVisible(e, t.visible ?? !0);
2937
+ let i = t.levels ?? null;
2938
+ JSON.stringify(i) !== JSON.stringify(r?.levels ?? null) && this.setIndicatorLevels(e, i);
2939
+ }
2940
+ restorePanes(e) {
2941
+ for (let [t, n] of e) t.paneSize !== void 0 && this.layoutManager.setPanelSize(n, t.paneSize), (t.paneSize !== void 0 || t.paneCollapsed) && this.layoutManager.setPanelCollapsed(n, !!t.paneCollapsed), t.paneSize !== void 0 && this.layoutManager.setPanelScale(n, {
2942
+ log: !!t.paneLog,
2943
+ invert: !!t.paneInvert,
2944
+ percent: !!t.panePercent
2945
+ });
2946
+ let t = e.filter(([e]) => e.paneOrder !== void 0).sort(([e], [t]) => (e.paneOrder ?? 0) - (t.paneOrder ?? 0)).map(([, e]) => e);
2947
+ t.length > 1 && this.layoutManager.orderPanels(t);
2948
+ let n = e.find(([e]) => e.paneMaximized);
2949
+ this.layoutManager.setMaximizedPanel(n ? n[1] : null);
2950
+ }
2951
+ getIndicatorSetup() {
2952
+ let e = this.layoutManager.getPanels(), t = this.layoutManager.getMaximizedPanel();
2953
+ return [...this.indicatorEngine.getActiveIndicators().map((n) => {
2954
+ let r = e.find((e) => e.id === n.instanceId), i = this.indicatorEngine.getIndicatorConfig(n.instanceId);
2955
+ return {
2956
+ id: n.id,
2957
+ instanceId: n.instanceId,
2958
+ params: { ...n.params },
2959
+ position: r?.position,
2960
+ style: this.indicatorEngine.getIndicatorStyle(n.instanceId) ?? void 0,
2961
+ visible: n.visible,
2962
+ levels: i?.levels?.slice(),
2963
+ pane: n.pane,
2964
+ scale: i?.scale,
2965
+ ...r ? {
2966
+ paneSize: r.size,
2967
+ paneOrder: e.indexOf(r),
2968
+ ...r.collapsed ? { paneCollapsed: !0 } : {},
2969
+ ...t === n.instanceId ? { paneMaximized: !0 } : {},
2970
+ ...r.logScale ? { paneLog: !0 } : {},
2971
+ ...r.invertScale ? { paneInvert: !0 } : {},
2972
+ ...r.percentScale ? { panePercent: !0 } : {}
2973
+ } : {}
2974
+ };
2975
+ }), ...this.unrestoredIndicators];
2976
+ }
2977
+ applyIndicatorSetup(e) {
2978
+ this.features.indicators && this.recordIndicators(void 0, () => {
2979
+ let t = new Map(this.indicatorEngine.getActiveIndicators().map((e) => [e.instanceId, e.id])), n = this.withoutIndicatorHistory(() => this.restoreIndicators(e, !1));
2980
+ this.followIndicatorAlerts(t, [...n.values()]), this.markStateChanged();
2981
+ });
2982
+ }
2983
+ followIndicatorAlerts(e, t) {
2984
+ if (!this.features.alerts) return;
2985
+ let n = (n) => {
2986
+ let r = n.indexOf(":");
2987
+ if (r <= 0) return null;
2988
+ let i = n.slice(0, r), a = e.get(i);
2989
+ if (!a || this.indicatorEngine.getIndicatorConfig(i)) return null;
2990
+ let o = t.filter((e) => this.indicatorEngine.getIndicatorConfig(e)?.id === a);
2991
+ return o.length === 1 ? o[0] + n.slice(r) : null;
2992
+ };
2993
+ for (let e of this.alertManager.getAlerts()) {
2994
+ let t = n(e.channel), r = e.target ? n(e.target) : null;
2995
+ if (!t && !r) continue;
2996
+ let { target: i, percent: a, bars: o, onBarClose: s, expiresAt: c } = e;
2997
+ this.alertManager.removeAlert(e.id), this.alertManager.addAlert(e.price, e.condition, e.message, e.repeating, t ?? e.channel, e.label, {
2998
+ ...e.target ? { target: r ?? e.target } : {},
2999
+ ...a === void 0 ? {} : { percent: a },
3000
+ ...o === void 0 ? {} : { bars: o },
3001
+ ...s ? { onBarClose: s } : {},
3002
+ ...c === void 0 ? {} : { expiresAt: c }
3003
+ });
3004
+ }
3005
+ }
3006
+ withoutIndicatorHistory(e) {
3007
+ this.indicatorHistoryDepth++;
3008
+ try {
3009
+ return e();
3010
+ } finally {
3011
+ this.indicatorHistoryDepth--;
3012
+ }
3013
+ }
3014
+ recordIndicators(e, t) {
3015
+ if (this.indicatorHistoryDepth > 0 || !this.features.drawingUndoRedo) return t();
3016
+ let n = this.getIndicatorSetup(), r = this.withoutIndicatorHistory(t), i = this.getIndicatorSetup();
3017
+ if (JSON.stringify(n) === JSON.stringify(i)) return r;
3018
+ let a = performance.now(), o = this.undoRedoManager.last(), s = e !== void 0 && o?.type === "indicators" && o.indicators?.subject === e && a - (o.indicators.at ?? 0) < xn && JSON.stringify(o.indicators.after) === JSON.stringify(n), c = {
3019
+ type: "indicators",
3020
+ before: null,
3021
+ after: null
3022
+ };
3023
+ return s && o?.indicators ? JSON.stringify(o.indicators.before) === JSON.stringify(i) ? this.undoRedoManager.dropLast() : this.undoRedoManager.replaceLast({
3024
+ ...c,
3025
+ indicators: {
3026
+ ...o.indicators,
3027
+ after: i,
3028
+ at: a
3029
+ }
3030
+ }) : this.undoRedoManager.push({
3031
+ ...c,
3032
+ indicators: {
3033
+ before: n,
3034
+ after: i,
3035
+ subject: e,
3036
+ at: a
3037
+ }
3038
+ }), r;
3039
+ }
3040
+ applyIndicatorStep(e, t) {
3041
+ let n = e.indicators;
3042
+ n && (this.withoutIndicatorHistory(() => this.restoreIndicators(t === "undo" ? n.before : n.after, !0)), this.markStateChanged());
3043
+ }
3044
+ saveState(e) {
3045
+ if (!this.features.saveLoad) return null;
3046
+ let t = this.captureSnapshot(), n = b.serialize(t);
3047
+ return e && b.saveToStorage(e, t), n;
3048
+ }
3049
+ loadState(e) {
3050
+ if (!this.features.saveLoad) return;
3051
+ let t = b.deserialize(e);
3052
+ this.chartTypeOptions = t.chartTypeOptions ?? {}, this.displayDataCache = null, t.chartType && this.setChartType(t.chartType), t.drawings && this.setDrawings(t.drawings), t.theme && this.setTheme(t.theme);
3053
+ let n = t.version >= 2 && this.features.indicators ? this.withoutIndicatorHistory(() => this.restoreIndicators(t.indicators, !1)) : /* @__PURE__ */ new Map();
3054
+ if (this.undoRedoManager.clear(), t.alerts && this.features.alerts) {
3055
+ this.alertManager.clearAlerts();
3056
+ for (let e of t.alerts) {
3057
+ if (e.triggered && !e.repeating) continue;
3058
+ let t = (e) => {
3059
+ let t = e.indexOf(":"), r = t > 0 ? n.get(e.slice(0, t)) : void 0;
3060
+ return r ? r + e.slice(t) : e;
3061
+ }, r = t(e.channel), i = {
3062
+ ...xt(e),
3063
+ ...e.target ? { target: t(e.target) } : {}
3064
+ };
3065
+ if (!e.expired) {
3066
+ if (e.drawingId) {
3067
+ this.drawingManager.hasPriceLevels(e.drawingId) && (e.condition === "crossing" || e.condition === "crossingUp" || e.condition === "crossingDown") && this.alertManager.addDrawingAlert(e.drawingId, e.condition, e.message, e.repeating, e.label);
3068
+ continue;
3069
+ }
3070
+ try {
3071
+ this.alertManager.addAlert(e.price, e.condition, e.message, e.repeating, r, e.label, i);
3072
+ } catch (e) {
3073
+ console.warn("Layout alert left out:", e);
3074
+ }
3075
+ }
3076
+ }
3077
+ }
3078
+ this.markStateChanged();
3079
+ }
3080
+ loadStateFromStorage(e) {
3081
+ if (!this.features.saveLoad) return !1;
3082
+ let t = b.loadFromStorage(e);
3083
+ return t ? (this.loadState(b.serialize(t)), !0) : !1;
3084
+ }
3085
+ downloadState(e) {
3086
+ this.features.saveLoad && b.downloadFile(this.captureSnapshot(), e);
3087
+ }
3088
+ async loadStateFromFile() {
3089
+ if (!this.features.saveLoad) return;
3090
+ let e = await b.loadFromFile();
3091
+ this.loadState(b.serialize(e));
3092
+ }
3093
+ setLocale(e) {
3094
+ ee(e), this.engine.requestRender();
3095
+ }
3096
+ setNumberLocale(e) {
3097
+ this.numberLocale = e, this.priceAxis.setLocale(e), this.leftPriceAxis.setLocale(e), this.crosshairHandler.setLocale(e), this.chartLegend.setLocale(e), this.crosshairTooltip.setLocale(e), this.sessionBreaks.setLocale(e), this.currentPriceLine.setLocale(e), this.updateViewportAndRender();
3098
+ }
3099
+ getNumberLocale() {
3100
+ return this.numberLocale;
3101
+ }
3102
+ setMarket(e) {
3103
+ if (this.marketConfig = e, e.colorScheme) {
3104
+ let t = {
3105
+ ...this.themeManager.getTheme(),
3106
+ candleUp: e.colorScheme.up,
3107
+ candleDown: e.colorScheme.down,
3108
+ candleUpWick: e.colorScheme.up,
3109
+ candleDownWick: e.colorScheme.down,
3110
+ volumeUp: re(e.colorScheme.up),
3111
+ volumeDown: re(e.colorScheme.down)
3112
+ };
3113
+ this.themeManager.setTheme(t);
3114
+ }
3115
+ e.pricePrecision !== void 0 && this.applyPricePrecision(e.pricePrecision), this.updateViewportAndRender();
3116
+ }
3117
+ applyPricePrecision(e) {
3118
+ this.marketPricePrecision = e, this.tradingManager.setConfig({ pricePrecision: e ?? void 0 }), this.alertManager.setPricePrecision(e ?? yn), this.streamManager?.priceLine.setPricePrecision(e), this.currentPriceLine.setPricePrecision(e), this.crosshairHandler.setPricePrecision(e), this.chartLegend.setPricePrecision(e), this.crosshairTooltip.setPricePrecision(e);
3119
+ }
3120
+ getMarket() {
3121
+ return this.marketConfig;
3122
+ }
3123
+ setPriceLimits(e) {
3124
+ this.marketConfig && (c(e, this.marketConfig) && (this.marketConfig.priceLimits = {
3125
+ ...this.marketConfig.priceLimits,
3126
+ referencePrice: e
3127
+ }), this.engine.requestRender());
3128
+ }
3129
+ getFeatures() {
3130
+ return this.features;
3131
+ }
3132
+ setFeatures(e) {
3133
+ 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();
3134
+ }
3135
+ resize() {
3136
+ let e = this.engine.dprManager.readContainerSize();
3137
+ if (e.width <= 0 || e.height <= 0) return;
3138
+ this.containerSizeCache = e, this.containerSizeCacheTime = Date.now();
3139
+ let t = this.engine.dprManager.getDpr();
3140
+ this.engine.layerManager.resize(e, t);
3141
+ let n = this.viewport.isAtEnd();
3142
+ this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(n), this.eventBus.emit("resize", e);
3143
+ }
3144
+ destroy() {
3145
+ this.disposed = !0, this.countdownInterval && clearInterval(this.countdownInterval), this.history.setLoader(null), this.disableAutoSave(), this.disconnectStream(), this.disconnectExecution(), this.onWindowKeyDown &&= (window.removeEventListener("keydown", this.onWindowKeyDown), null), this.keyboardHandler = null, this.a11y?.destroy(), this.a11y = null, this.interactionManager.detach(), this.tradingManager.destroy(), this.animator.dispose(), this.crosshairTooltip.destroy(), this.pinnedTooltip.destroy(), this.replayRestarting = !0, this.replayManager.dispose(), this.alertManager.dispose(), this.undoRedoManager.clear(), this.engine.destroy(), this.eventBus.destroy(), this.container.innerHTML = "";
3146
+ }
3147
+ createChartRenderer(e) {
3148
+ let t = Jt(e, (e) => this.pluginManager.getChartType(e));
3149
+ return t instanceof Oe && t.setPriceText((e) => this.formatPrice(e)), t;
3150
+ }
3151
+ getDisplayData() {
3152
+ if (this.displayDataCache) return this.displayDataCache;
3153
+ let e = this.dataManager.getData();
3154
+ if (e.length === 0) return e;
3155
+ let t = Yt(this.options.chartType, e, (e) => this.pluginManager.getChartType(e), this.chartTypeOptions);
3156
+ return this.displayDataCache = t, t;
3157
+ }
3158
+ recalcIndicatorsFrom(e, t) {
3159
+ this.indicatorEngine.recalculateFrom(e, t), this.announceIndicatorUpdate(t);
3160
+ }
3161
+ recalcIndicators(e) {
3162
+ this.indicatorEngine.recalculateAll(e), this.announceIndicatorUpdate(0);
3163
+ }
3164
+ announceIndicatorUpdate(e) {
3165
+ if (this.indicatorUpdateFrom !== null) {
3166
+ this.indicatorUpdateFrom = Math.min(this.indicatorUpdateFrom, e);
3167
+ return;
3168
+ }
3169
+ this.indicatorUpdateFrom = e, queueMicrotask(() => {
3170
+ let e = this.indicatorUpdateFrom;
3171
+ this.indicatorUpdateFrom = null, e !== null && this.eventBus.emit("indicatorUpdate", { from: e });
3172
+ });
3173
+ }
3174
+ scheduleRender() {
3175
+ this.renderScheduled || (this.renderScheduled = !0, requestAnimationFrame(() => {
3176
+ this.renderScheduled = !1, this.panelInfoCache = null, this.fitDataAndAxes(), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
3177
+ }));
3178
+ }
3179
+ applyDataToViewport(e = !1) {
3180
+ let t = this.getDisplayData(), n = this.options.autoScale !== !1;
3181
+ this.viewport.updateData(t, n && !e), e && (this.viewport.scrollToEnd(), n && this.viewport.updateData(t, !0));
3182
+ let r = this.viewport.getState();
3183
+ if (t.length > 0) {
3184
+ let e = Math.max(0, Math.min(r.visibleRange.from, t.length - 1));
3185
+ this.viewport.setScaleBaseline(t[e]?.close);
3186
+ }
3187
+ if (n) {
3188
+ let e = On(this.indicatorEngine.getOverlayPriceRange(r.visibleRange.from, Math.min(r.visibleRange.to, t.length - 1)), this.features.compareSymbols ? this.compareRenderer.getPriceRange(t, r) : null);
3189
+ if (e) {
3190
+ let t = r.priceRange, n = Math.min(t.min, e.min), i = Math.max(t.max, e.max);
3191
+ if (n < t.min || i > t.max) {
3192
+ let e = i - n || 1;
3193
+ this.viewport.setPriceRange(n - e * .02, i + e * .02);
3194
+ }
3195
+ }
3196
+ }
3197
+ return t;
3198
+ }
3199
+ updateViewportAndRender(e = !1) {
3200
+ this.resolvedLayoutCache = null, this.panelInfoCache = null, this.layoutManager.setLeftAxisWidth(this.isLeftPriceScaleShown() ? this.leftAxisWidth : 0);
3201
+ let t = this.getResolvedLayout();
3202
+ this.viewport.setChartRect(t.mainChartRect), this.fitDataAndAxes(e), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
3203
+ }
3204
+ fitDataAndAxes(e = !1) {
3205
+ this.applyDataToViewport(e);
3206
+ let t = this.fitPriceAxisWidth();
3207
+ this.leftViewport = this.computeLeftViewport(), (this.fitLeftAxisWidth() || t) && this.applyDataToViewport(e);
3208
+ }
3209
+ fitLeftAxisWidth() {
3210
+ let e = this.leftViewport;
3211
+ if (!e) return !1;
3212
+ let t = this.themeManager.getTheme(), n = z({
3213
+ min: e.priceRange.min,
3214
+ max: e.priceRange.max,
3215
+ lastPrice: null,
3216
+ tagPrecision: null,
3217
+ locale: this.numberLocale,
3218
+ fontFamily: t.font.family,
3219
+ fontSizeSmall: t.font.sizeSmall,
3220
+ measure: (e, t) => this.measureText(e, t)
3221
+ }), r = B(this.leftAxisWidth, n);
3222
+ return r === this.leftAxisWidth ? !1 : (this.leftAxisWidth = r, this.layoutManager.setLeftAxisWidth(r), this.resolvedLayoutCache = null, this.panelInfoCache = null, this.viewport.setChartRect(this.getResolvedLayout().mainChartRect), !0);
3223
+ }
3224
+ fitPriceAxisWidth() {
3225
+ if (!this.features.priceAxis) return !1;
3226
+ let { priceRange: e } = this.viewport.getState(), t = this.themeManager.getTheme(), n = z({
3227
+ min: e.min,
3228
+ max: e.max,
3229
+ lastPrice: this.currentPriceLine.getPrice(),
3230
+ tagPrecision: this.marketPricePrecision,
3231
+ locale: this.numberLocale,
3232
+ format: this.priceFormatter,
3233
+ fontFamily: t.font.family,
3234
+ fontSizeSmall: t.font.sizeSmall,
3235
+ measure: (e, t) => this.measureText(e, t)
3236
+ }), r = B(this.priceAxisWidth, n);
3237
+ 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);
3238
+ }
3239
+ measureText(e, t) {
3240
+ this.measureCtx === void 0 && (this.measureCtx = typeof document < "u" ? document.createElement("canvas").getContext("2d") : null);
3241
+ let n = this.measureCtx;
3242
+ return n ? (n.font = t, n.measureText(e).width) : e.length * 7;
3243
+ }
3244
+ emitViewportEvents() {
3245
+ let e = this.viewport.getState(), t = Math.max(0, Math.floor(e.visibleRange.from)), n = Math.max(t, Math.ceil(e.visibleRange.to));
3246
+ (!this.lastEmittedRange || this.lastEmittedRange.from !== t || this.lastEmittedRange.to !== n) && (this.lastEmittedRange = {
3247
+ from: t,
3248
+ to: n
3249
+ }, this.eventBus.emit("visibleRangeChange", {
3250
+ from: t,
3251
+ to: n
3252
+ }));
3253
+ let { min: r, max: i } = e.priceRange;
3254
+ (!this.lastEmittedPriceRange || this.lastEmittedPriceRange.min !== r || this.lastEmittedPriceRange.max !== i) && (this.lastEmittedPriceRange = {
3255
+ min: r,
3256
+ max: i
3257
+ }, this.eventBus.emit("priceRangeChange", {
3258
+ min: r,
3259
+ max: i
3260
+ })), this.lastEmittedBarWidth !== e.barWidth && (this.lastEmittedBarWidth = e.barWidth, this.eventBus.emit("zoomChange", { barWidth: e.barWidth })), this.checkHistory();
3261
+ }
3262
+ getResolvedLayout() {
3263
+ return this.resolvedLayoutCache || (this.resolvedLayoutCache = this.layoutManager.resolve(), this.syncCrosshairBounds(this.resolvedLayoutCache)), this.resolvedLayoutCache;
3264
+ }
3265
+ syncCrosshairBounds(e) {
3266
+ let t = e.mainChartRect, n = t.y, r = t.y + t.height;
3267
+ 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));
3268
+ this.crosshairHandler.setReportBounds({
3269
+ top: n,
3270
+ bottom: r
3271
+ });
3272
+ }
3273
+ cachedContainerSize() {
3274
+ let e = Date.now();
3275
+ return (!this.containerSizeCache || e - this.containerSizeCacheTime > 500) && (this.containerSizeCache = this.engine.dprManager.getContainerSize(), this.containerSizeCacheTime = e), this.containerSizeCache;
3276
+ }
3277
+ buildPanelRenderInfos() {
3278
+ if (this.panelInfoCache) return this.panelInfoCache;
3279
+ let e = this.getResolvedLayout(), t = this.viewport.getState(), { from: n, to: r } = t.visibleRange, i = e.panels.map((e) => {
3280
+ let i = e.config.logScale ? this.indicatorEngine.getPaneValueRange(e.config.id, n, r, !0) : null, a = i ?? this.indicatorEngine.getPaneValueRange(e.config.id, n, r) ?? { ...hn }, o = {
3281
+ x: e.rect.x,
3282
+ y: e.rect.y + 20,
3283
+ width: e.rect.width,
3284
+ height: Math.max(0, e.rect.height - 20)
3285
+ };
3286
+ return {
3287
+ instanceId: e.config.id,
3288
+ members: this.indicatorEngine.getPaneMembers(e.config.id),
3289
+ rect: e.rect,
3290
+ viewport: {
3291
+ ...t,
3292
+ chartRect: o,
3293
+ priceRange: a,
3294
+ logScale: i !== null,
3295
+ scaleMode: e.config.percentScale ? "percentage" : "regular",
3296
+ scaleBaseline: e.config.percentScale ? this.paneBaseline(e.config.id, n, r) : void 0,
3297
+ formatPrice: void 0,
3298
+ priceUnit: void 0,
3299
+ invertScale: !!e.config.invertScale
3300
+ }
3301
+ };
3302
+ });
3303
+ return this.panelInfoCache = i, i;
3304
+ }
3305
+ timeAxisTop() {
3306
+ let e = this.getResolvedLayout(), t = e.panels.filter((e) => e.config.position === "bottom").reduce((e, t) => e + t.rect.height, 0);
3307
+ return e.mainChartRect.y + e.mainChartRect.height + t;
3308
+ }
3309
+ syncRenderContext() {
3310
+ this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), null, null, this.themeManager.getTheme());
3311
+ let e = this.features.indicators ? this.buildPanelRenderInfos() : [], t = this.timeAxisTop(), n = this.getDisplayData();
3312
+ this.leftViewport = this.computeLeftViewport(), this.engine.setRenderContext({
3313
+ leftViewport: this.leftViewport,
3314
+ leftPriceAxis: this.leftPriceAxis,
3315
+ leftAxisWidth: this.leftAxisWidth,
3316
+ chartRenderer: this.mainSeriesVisible ? this.chartRenderer : null,
3317
+ priceLines: this.quoteLines(),
3318
+ gridRenderer: this.features.grid ? this.gridRenderer : null,
3319
+ priceAxis: this.features.priceAxis ? this.priceAxis : null,
3320
+ timeAxis: this.features.timeAxis ? this.timeAxis : null,
3321
+ crosshairHandler: this.features.crosshair ? this.crosshairHandler : null,
3322
+ indicatorEngine: this.features.indicators ? this.indicatorEngine : null,
3323
+ drawingRenderer: this.features.drawings ? this.drawingRenderer : null,
3324
+ tradingRenderer: this.features.trading ? this.tradingRenderer : null,
3325
+ currentPriceLine: this.currentPriceLine,
3326
+ chartLegend: this.features.legend ? this.chartLegend : null,
3327
+ volumeRenderer: this.features.volume ? this.volumeRenderer : null,
3328
+ volumeProfile: this.volumeProfile,
3329
+ marketProfile: this.marketProfile,
3330
+ depthHeatmap: this.depthHeatmap,
3331
+ periodLevels: this.periodLevels,
3332
+ pivotMarkers: this.pivotMarkers,
3333
+ watermark: this.features.watermark ? this.watermark : null,
3334
+ barCountdown: this.barCountdown,
3335
+ sessionBreaks: this.sessionBreaks,
3336
+ sessionShading: this.sessionShading,
3337
+ compareRenderer: this.compareRenderer,
3338
+ alertManager: this.features.alerts ? this.alertManager : null,
3339
+ measureOverlay: this.measureOverlay,
3340
+ selectionBoxOverlay: this.selectionBoxOverlay,
3341
+ priceAxisAddButton: this.priceAxisAddButton,
3342
+ signalMarkerManager: this.signalMarkerManager,
3343
+ tradeZoneManager: this.tradeZoneManager,
3344
+ panels: e,
3345
+ priceLimits: this.buildPriceLimits(),
3346
+ timeAxisY: t,
3347
+ viewport: {
3348
+ ...this.viewport.getState(),
3349
+ data: n
3350
+ },
3351
+ theme: this.themeManager.getTheme(),
3352
+ data: n,
3353
+ numberLocale: this.numberLocale,
3354
+ paneTitles: this.paneTitles,
3355
+ indicatorValueLabels: this.features.indicatorValueLabels,
3356
+ formatPrice: (e) => this.formatPrice(e),
3357
+ renderOverlayPlugins: (e, t) => this.drawOverlayPlugins(e, t)
3358
+ });
3359
+ }
3360
+ drawOverlayPlugins(e, t) {
3361
+ let n = V(this.pluginManager.getOverlays(), t);
3362
+ if (n.length === 0) return;
3363
+ let r = {
3364
+ viewport: this.viewport.getState(),
3365
+ data: this.getDisplayData(),
3366
+ theme: this.themeManager.getTheme()
3367
+ };
3368
+ for (let t of n) t.render(e, r);
3369
+ }
3370
+ buildPriceLimits() {
3371
+ if (!this.marketConfig?.priceLimits?.enabled || !this.marketConfig.priceLimits.referencePrice) return null;
3372
+ let e = c(this.marketConfig.priceLimits.referencePrice, this.marketConfig);
3373
+ return e ? {
3374
+ ...e,
3375
+ colors: this.marketConfig.colorScheme ? {
3376
+ ceiling: this.marketConfig.colorScheme.ceiling,
3377
+ floor: this.marketConfig.colorScheme.floor,
3378
+ reference: this.marketConfig.colorScheme.reference
3379
+ } : void 0
3380
+ } : null;
3381
+ }
3382
+ };
3383
+ function Tn(e) {
3384
+ let t = new Map(e.map((e) => [e.instanceId, e])), n = [], r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = (e) => {
3385
+ if (r.has(e.instanceId) || i.has(e.instanceId)) return;
3386
+ i.add(e.instanceId);
3387
+ let o = [e.pane, ...Object.values(e.params).map((e) => h(e)?.instanceId)];
3388
+ for (let e of o) {
3389
+ let n = e ? t.get(e) : void 0;
3390
+ n && a(n);
3391
+ }
3392
+ i.delete(e.instanceId), r.add(e.instanceId), n.push(e);
3393
+ };
3394
+ for (let t of e) a(t);
3395
+ return n;
3396
+ }
3397
+ function En(e, t) {
3398
+ return e.id === t.id && (e.pane ?? null) === (t.pane ?? null) && (e.scale ?? null) === (t.scale ?? null) && e.position === void 0 == (t.position === void 0);
3399
+ }
3400
+ function Dn(e) {
3401
+ let t = e.tagRadius;
3402
+ return typeof t == "number" && Number.isFinite(t) && t >= 0 ? { tagRadius: Math.min(t, 999) } : {};
3403
+ }
3404
+ var W = new Set(["compareSymbol", "spread"]);
3405
+ function On(e, t) {
3406
+ return e ? t ? {
3407
+ min: Math.min(e.min, t.min),
3408
+ max: Math.max(e.max, t.max)
3409
+ } : e : t;
3410
+ }
3411
+ function G(e) {
3412
+ return {
3413
+ id: e.id,
3414
+ price: e.price,
3415
+ condition: e.condition,
3416
+ message: e.message,
3417
+ triggered: e.triggered,
3418
+ channel: e.channel,
3419
+ label: e.label,
3420
+ target: e.target,
3421
+ drawingId: e.drawingId,
3422
+ percent: e.percent,
3423
+ bars: e.bars
3424
+ };
3425
+ }
3426
+ var kn = 500;
3427
+ function An(e, t) {
3428
+ let n = 0, r = e.length;
3429
+ for (; n < r;) {
3430
+ let i = n + r >> 1;
3431
+ e[i].time <= t ? n = i + 1 : r = i;
3432
+ }
3433
+ return n;
3434
+ }
3435
+ function jn(e) {
3436
+ let t = 0, n = 0;
3437
+ for (let r = 1; r < e.length; r++) e[r].low < e[t].low && (t = r), e[r].high > e[n].high && (n = r);
3438
+ let r = [e[t].low, e[t].time], i = [e[n].high, e[n].time], a = t === n ? e[t].close >= e[t].open : t < n, o = e[e.length - 1];
3439
+ return [...a ? [r, i] : [i, r], [o.close, o.time]];
3440
+ }
3441
+ function Mn(e) {
3442
+ let t = 0;
3443
+ for (let n = Math.max(1, e.length - 10); n < e.length; n++) t = Math.max(t, e[n].time - e[n - 1].time);
3444
+ return t > 0 ? t : Infinity;
3445
+ }
3446
+ function Nn(e, t) {
3447
+ if (t.length === 0) return null;
3448
+ let n = t[t.length - 1].time + Mn(t), r = e.filter((e) => Pn(e) && e.time >= t[0].time && e.time < n).sort((e, t) => e.time - t.time), i = [];
3449
+ for (let e of r) (i.length === 0 || i[i.length - 1].time !== e.time) && i.push(e);
3450
+ if (i.length === 0) return null;
3451
+ let a = t.findIndex((e) => e.time >= i[0].time);
3452
+ if (a < 0) return null;
3453
+ let o = t.slice(0, a), s = i.filter((e) => e.time >= t[a].time);
3454
+ return [...o, ...s];
3455
+ }
3456
+ function Pn(e) {
3457
+ return [
3458
+ e.time,
3459
+ e.open,
3460
+ e.high,
3461
+ e.low,
3462
+ e.close
3463
+ ].every(Number.isFinite);
3464
+ }
3465
+ function Fn(e, t) {
3466
+ let n = 0, r = e.length - 1;
3467
+ for (; n < r;) {
3468
+ let i = n + r + 1 >> 1;
3469
+ e[i].time <= t ? n = i : r = i - 1;
3470
+ }
3471
+ return n;
3472
+ }
3473
+ function In(e, t, n) {
3474
+ let r = Math.max(0, Math.min(Math.floor(Number.isFinite(n) ? n : 0), t.length - 1)), i = r + 1 < t.length ? t[r + 1].time : Infinity, a = -1;
3475
+ for (let t = 0; t < e.length && e[t].time < i; t++) a = t;
3476
+ return Math.max(0, a);
3477
+ }
3478
+ function Ln(e, t, n) {
3479
+ let r = n;
3480
+ for (; r > 0 && t[r - 1].time >= e.time;) r--;
3481
+ let i = {
3482
+ ...t[r],
3483
+ time: e.time
3484
+ };
3485
+ for (let e = r + 1; e <= n; e++) i = Rn(i, t[e]);
3486
+ return i;
3487
+ }
3488
+ function Rn(e, t) {
3489
+ return {
3490
+ time: e.time,
3491
+ open: e.open,
3492
+ high: Math.max(e.high, t.high),
3493
+ low: Math.min(e.low, t.low),
3494
+ close: t.close,
3495
+ volume: (e.volume ?? 0) + (t.volume ?? 0)
3496
+ };
3497
+ }
3498
+ function K(e, t) {
3499
+ let n = e[e.length - 1];
3500
+ if (!n) return "append";
3501
+ let r = m(t.time), i = m(n.time);
3502
+ return r > i ? "append" : r === i ? "update" : "stale";
3503
+ }
3504
+ //#endregion
3505
+ //#region src/io/parseOHLCV.ts
3506
+ var zn = [
3507
+ "time",
3508
+ "timestamp",
3509
+ "date",
3510
+ "datetime",
3511
+ "t"
3512
+ ], Bn = ["open", "o"], Vn = ["high", "h"], Hn = ["low", "l"], Un = ["close", "c"], Wn = [
3513
+ "volume",
3514
+ "vol",
3515
+ "v"
3516
+ ];
3517
+ function Gn(e) {
3518
+ let t = e.trim();
3519
+ return t ? t[0] === "[" || t[0] === "{" ? Kn(t) : qn(t) : {
3520
+ data: [],
3521
+ rowCount: 0,
3522
+ skipped: 0
3523
+ };
3524
+ }
3525
+ function Kn(e) {
3526
+ let t;
3527
+ try {
3528
+ t = JSON.parse(e);
3529
+ } catch (e) {
3530
+ throw Error(`Invalid JSON: ${e.message}`);
3531
+ }
3532
+ if (!Array.isArray(t)) throw Error("Expected a JSON array of OHLCV rows");
3533
+ let n = [], r = 0;
3534
+ for (let e of t) {
3535
+ let t = Array.isArray(e) ? Qn(e) : Zn(e);
3536
+ t ? n.push(t) : r++;
3537
+ }
3538
+ return Y(n, t.length, r);
3539
+ }
3540
+ function qn(e) {
3541
+ let t = e.split(/\r?\n/).filter((e) => e.trim().length > 0);
3542
+ if (t.length === 0) return {
3543
+ data: [],
3544
+ rowCount: 0,
3545
+ skipped: 0
3546
+ };
3547
+ let n = Jn(t[0]), r = Yn(t[0], n).map((e) => e.trim().toLowerCase()), i = r.some((e) => isNaN(Number(e)) && e.length > 0), a = i ? Xn(r) : {
3548
+ time: 0,
3549
+ open: 1,
3550
+ high: 2,
3551
+ low: 3,
3552
+ close: 4,
3553
+ volume: 5
3554
+ };
3555
+ 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");
3556
+ let o = [], s = 0;
3557
+ for (let e = +!!i; e < t.length; e++) {
3558
+ let r = Yn(t[e], n), i = J(r[a.time]), c = q(r[a.open]), l = q(r[a.high]), u = q(r[a.low]), d = q(r[a.close]), f = a.volume >= 0 ? Number(r[a.volume]) : 0;
3559
+ if (i === null || ![
3560
+ c,
3561
+ l,
3562
+ u,
3563
+ d
3564
+ ].every(Number.isFinite)) {
3565
+ s++;
3566
+ continue;
3567
+ }
3568
+ o.push({
3569
+ time: i,
3570
+ open: c,
3571
+ high: l,
3572
+ low: u,
3573
+ close: d,
3574
+ volume: Number.isFinite(f) ? f : 0
3575
+ });
3576
+ }
3577
+ return Y(o, t.length - +!!i, s);
3578
+ }
3579
+ function Jn(e) {
3580
+ let t = {
3581
+ ",": 0,
3582
+ ";": 0,
3583
+ " ": 0,
3584
+ "|": 0
3585
+ };
3586
+ for (let n of e) n in t && t[n]++;
3587
+ let n = ",", r = 0;
3588
+ for (let [e, i] of Object.entries(t)) i > r && (n = e, r = i);
3589
+ return n;
3590
+ }
3591
+ function Yn(e, t) {
3592
+ let n = [], r = "", i = !1;
3593
+ for (let a = 0; a < e.length; a++) {
3594
+ let o = e[a];
3595
+ o === "\"" ? i && e[a + 1] === "\"" ? (r += "\"", a++) : i = !i : o === t && !i ? (n.push(r), r = "") : r += o;
3596
+ }
3597
+ return n.push(r), n;
3598
+ }
3599
+ function Xn(e) {
3600
+ let t = (t) => e.findIndex((e) => t.includes(e));
3601
+ return {
3602
+ time: t(zn),
3603
+ open: t(Bn),
3604
+ high: t(Vn),
3605
+ low: t(Hn),
3606
+ close: t(Un),
3607
+ volume: t(Wn)
3608
+ };
3609
+ }
3610
+ function Zn(e) {
3611
+ let t = (t) => {
3612
+ for (let n of t) {
3613
+ if (e[n] !== void 0) return e[n];
3614
+ let t = n.toUpperCase();
3615
+ if (e[t] !== void 0) return e[t];
3616
+ }
3617
+ }, n = J(String(t(zn) ?? "")), r = Number(t(Bn)), i = Number(t(Vn)), a = Number(t(Hn)), o = Number(t(Un)), s = Number(t(Wn) ?? 0);
3618
+ return n === null || ![
3619
+ r,
3620
+ i,
3621
+ a,
3622
+ o
3623
+ ].every(Number.isFinite) ? null : {
3624
+ time: n,
3625
+ open: r,
3626
+ high: i,
3627
+ low: a,
3628
+ close: o,
3629
+ volume: Number.isFinite(s) ? s : 0
3630
+ };
3631
+ }
3632
+ function Qn(e) {
3633
+ if (e.length < 5) return null;
3634
+ let t = J(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;
3635
+ return t === null || ![
3636
+ n,
3637
+ r,
3638
+ i,
3639
+ a
3640
+ ].every(Number.isFinite) ? null : {
3641
+ time: t,
3642
+ open: n,
3643
+ high: r,
3644
+ low: i,
3645
+ close: a,
3646
+ volume: Number.isFinite(o) ? o : 0
3647
+ };
3648
+ }
3649
+ function q(e) {
3650
+ return e === void 0 || e.trim() === "" ? NaN : Number(e);
3651
+ }
3652
+ function J(e) {
3653
+ let t = e.trim();
3654
+ if (!t) return null;
3655
+ let n = Number(t);
3656
+ if (Number.isFinite(n) && n > 0) return n < 0xe8d4a51000 ? n * 1e3 : n;
3657
+ let r = Date.parse(t);
3658
+ return Number.isFinite(r) ? r : null;
3659
+ }
3660
+ function Y(e, t, n) {
3661
+ e.sort((e, t) => e.time - t.time);
3662
+ let r = [];
3663
+ for (let t of e) r.length > 0 && r[r.length - 1].time === t.time ? r[r.length - 1] = t : r.push(t);
3664
+ return {
3665
+ data: r,
3666
+ rowCount: t,
3667
+ skipped: n
3668
+ };
3669
+ }
3670
+ //#endregion
3671
+ //#region src/io/DragDropImporter.ts
3672
+ var $n = class {
3673
+ host;
3674
+ overlay = null;
3675
+ callbacks;
3676
+ bound;
3677
+ depth = 0;
3678
+ constructor(e, t) {
3679
+ this.host = e, this.callbacks = t, this.bound = {
3680
+ dragenter: (e) => this.onDragEnter(e),
3681
+ dragover: (e) => this.onDragOver(e),
3682
+ dragleave: (e) => this.onDragLeave(e),
3683
+ drop: (e) => this.onDrop(e)
3684
+ };
3685
+ }
3686
+ attach() {
3687
+ this.host.addEventListener("dragenter", this.bound.dragenter), this.host.addEventListener("dragover", this.bound.dragover), this.host.addEventListener("dragleave", this.bound.dragleave), this.host.addEventListener("drop", this.bound.drop);
3688
+ }
3689
+ detach() {
3690
+ this.host.removeEventListener("dragenter", this.bound.dragenter), this.host.removeEventListener("dragover", this.bound.dragover), this.host.removeEventListener("dragleave", this.bound.dragleave), this.host.removeEventListener("drop", this.bound.drop), this.hideOverlay();
3691
+ }
3692
+ onDragEnter(e) {
3693
+ X(e) && (e.preventDefault(), this.depth++, this.showOverlay());
3694
+ }
3695
+ onDragOver(e) {
3696
+ X(e) && (e.preventDefault(), e.dataTransfer && (e.dataTransfer.dropEffect = "copy"));
3697
+ }
3698
+ onDragLeave(e) {
3699
+ X(e) && (this.depth = Math.max(0, this.depth - 1), this.depth === 0 && this.hideOverlay());
3700
+ }
3701
+ async onDrop(e) {
3702
+ e.preventDefault(), this.depth = 0, this.hideOverlay();
3703
+ let t = e.dataTransfer?.files?.[0];
3704
+ if (t) try {
3705
+ let e = Gn(await t.text());
3706
+ if (e.data.length === 0) throw Error(`No valid OHLCV rows found in "${t.name}"`);
3707
+ this.callbacks.onData(e.data, e, t);
3708
+ } catch (e) {
3709
+ this.callbacks.onError?.(e, t);
3710
+ }
3711
+ }
3712
+ showOverlay() {
3713
+ this.overlay || (this.overlay = document.createElement("div"), Object.assign(this.overlay.style, {
3714
+ position: "absolute",
3715
+ inset: "8px",
3716
+ zIndex: "90",
3717
+ pointerEvents: "none",
3718
+ borderRadius: "10px",
3719
+ border: "2px dashed var(--tcw-accent, #f2a93b)",
3720
+ background: "rgba(79, 136, 255, 0.06)",
3721
+ display: "flex",
3722
+ alignItems: "center",
3723
+ justifyContent: "center",
3724
+ color: "var(--tcw-accent, #f2a93b)",
3725
+ fontSize: "14px",
3726
+ fontWeight: "600",
3727
+ letterSpacing: "-0.005em",
3728
+ fontFamily: "inherit",
3729
+ backdropFilter: "blur(2px)"
3730
+ }), this.overlay.textContent = "Drop CSV or JSON to load chart data", getComputedStyle(this.host).position === "static" && (this.host.style.position = "relative"), this.host.appendChild(this.overlay));
3731
+ }
3732
+ hideOverlay() {
3733
+ this.overlay?.remove(), this.overlay = null;
3734
+ }
3735
+ };
3736
+ function X(e) {
3737
+ return e.dataTransfer?.types?.includes("Files") ?? !1;
3738
+ }
3739
+ //#endregion
3740
+ //#region src/state/layoutStorage.ts
3741
+ function Z(e) {
3742
+ let t = {
3743
+ id: e.id,
3744
+ name: e.name,
3745
+ updatedAt: e.updatedAt
3746
+ };
3747
+ return e.symbol !== void 0 && (t.symbol = e.symbol), e.timeframe !== void 0 && (t.timeframe = e.timeframe), e.kind !== void 0 && (t.kind = e.kind), t;
3748
+ }
3749
+ var er = (e, t) => t.updatedAt - e.updatedAt;
3750
+ function Q(e) {
3751
+ if (typeof e != "object" || !e) return null;
3752
+ let t = e;
3753
+ return typeof t.id != "string" || !t.id || typeof t.name != "string" || typeof t.updatedAt != "number" || !Number.isFinite(t.updatedAt) ? null : Z({
3754
+ id: t.id,
3755
+ name: t.name,
3756
+ updatedAt: t.updatedAt,
3757
+ symbol: typeof t.symbol == "string" ? t.symbol : void 0,
3758
+ timeframe: typeof t.timeframe == "string" ? t.timeframe : void 0,
3759
+ kind: typeof t.kind == "string" ? t.kind : void 0
3760
+ });
3761
+ }
3762
+ function tr(e) {
3763
+ let t = Q(e), n = t ? e.content : void 0;
3764
+ return t && typeof n == "string" ? {
3765
+ ...t,
3766
+ content: n
3767
+ } : null;
3768
+ }
3769
+ function nr(e = []) {
3770
+ let t = new Map(e.map((e) => [e.id, { ...e }]));
3771
+ return {
3772
+ list: () => [...t.values()].map(Z).sort(er),
3773
+ load: (e) => {
3774
+ let n = t.get(e);
3775
+ return n ? { ...n } : null;
3776
+ },
3777
+ save: (e) => {
3778
+ t.set(e.id, { ...e });
3779
+ },
3780
+ remove: (e) => {
3781
+ t.delete(e);
3782
+ }
3783
+ };
3784
+ }
3785
+ function rr(e = "tcw:layouts:") {
3786
+ let t = `${e}index`, n = (t) => `${e}item:${t}`, r = () => {
3787
+ let e;
3788
+ try {
3789
+ e = JSON.parse(localStorage.getItem(t) ?? "[]");
3790
+ } catch {
3791
+ return [];
3792
+ }
3793
+ return Array.isArray(e) ? e.map(Q).filter((e) => e !== null) : [];
3794
+ }, i = (e) => localStorage.setItem(t, JSON.stringify(e));
3795
+ return {
3796
+ list: () => r().sort(er),
3797
+ load: (e) => {
3798
+ let t = r().find((t) => t.id === e), i = t ? localStorage.getItem(n(e)) : null;
3799
+ return t && i !== null ? {
3800
+ ...t,
3801
+ content: i
3802
+ } : null;
3803
+ },
3804
+ save: (e) => {
3805
+ localStorage.setItem(n(e.id), e.content), i([...r().filter((t) => t.id !== e.id), Z(e)]);
3806
+ },
3807
+ remove: (e) => {
3808
+ i(r().filter((t) => t.id !== e)), localStorage.removeItem(n(e));
3809
+ }
3810
+ };
3811
+ }
3812
+ //#endregion
3813
+ //#region src/state/LayoutSession.ts
3814
+ var ir = 80;
3815
+ function $(e) {
3816
+ return e.replace(/\s+/g, " ").trim().slice(0, 80).trim() || null;
3817
+ }
3818
+ function ar() {
3819
+ return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
3820
+ }
3821
+ function or(e) {
3822
+ let { id: t, name: n, symbol: r, timeframe: i, updatedAt: a, kind: o } = e;
3823
+ return {
3824
+ id: t,
3825
+ name: n,
3826
+ ...r === void 0 ? {} : { symbol: r },
3827
+ ...i === void 0 ? {} : { timeframe: i },
3828
+ updatedAt: a,
3829
+ ...o === void 0 ? {} : { kind: o }
3830
+ };
3831
+ }
3832
+ var sr = class {
3833
+ currentLayout = null;
3834
+ savedContent = null;
3835
+ dirty = !1;
3836
+ autoSave;
3837
+ debounceMs;
3838
+ kind;
3839
+ timer = null;
3840
+ applying = 0;
3841
+ busy = 0;
3842
+ changedWhileBusy = !1;
3843
+ tail = Promise.resolve();
3844
+ destroyed = !1;
3845
+ now;
3846
+ newId;
3847
+ constructor(e, t, n = {}) {
3848
+ this.storage = e, this.host = t, this.options = n, this.autoSave = n.autoSave ?? !0, this.debounceMs = n.debounceMs ?? 1500, this.kind = n.kind ?? "chart", this.now = n.now ?? Date.now, this.newId = n.newId ?? ar;
3849
+ }
3850
+ current() {
3851
+ return this.currentLayout;
3852
+ }
3853
+ isDirty() {
3854
+ return this.dirty;
3855
+ }
3856
+ isAutoSave() {
3857
+ return this.autoSave;
3858
+ }
3859
+ setAutoSave(e) {
3860
+ this.autoSave !== e && (this.autoSave = e, this.notify(), e && this.dirty && this.changed());
3861
+ }
3862
+ async list() {
3863
+ let e = await this.storage.list();
3864
+ return Array.isArray(e) ? e.map(Q).filter((e) => e !== null && (e.kind ?? "chart") === this.kind).sort((e, t) => t.updatedAt - e.updatedAt) : [];
3865
+ }
3866
+ save() {
3867
+ return this.queue(() => {
3868
+ let e = this.currentLayout;
3869
+ return e ? this.write(e.id, e.name) : null;
3870
+ });
3871
+ }
3872
+ saveAs(e) {
3873
+ let t = $(e);
3874
+ return t ? this.queue(() => this.write(this.newId(), t)) : Promise.reject(/* @__PURE__ */ Error("A layout needs a name"));
3875
+ }
3876
+ open(e) {
3877
+ return this.queue(async () => {
3878
+ let t = tr(await this.storage.load(e));
3879
+ if (!t || t.id !== e || (t.kind ?? "chart") !== this.kind || this.destroyed) return !1;
3880
+ this.cancelTimer(), this.applying++;
3881
+ try {
3882
+ await this.host.apply(t);
3883
+ } catch (e) {
3884
+ throw this.forget(), e;
3885
+ } finally {
3886
+ this.applying--;
3887
+ }
3888
+ return this.cancelTimer(), this.currentLayout = or(t), this.savedContent = this.host.capture().content, this.dirty = !1, this.notify(), !0;
3889
+ });
3890
+ }
3891
+ rename(e, t) {
3892
+ let n = $(t);
3893
+ return n ? this.queue(async () => {
3894
+ let t = tr(await this.storage.load(e));
3895
+ !t || t.id !== e || (await this.storage.save({
3896
+ ...t,
3897
+ name: n
3898
+ }), this.currentLayout?.id === e && (this.currentLayout = {
3899
+ ...this.currentLayout,
3900
+ name: n
3901
+ }), this.notify());
3902
+ }) : Promise.reject(/* @__PURE__ */ Error("A layout needs a name"));
3903
+ }
3904
+ remove(e) {
3905
+ return this.queue(async () => {
3906
+ await this.storage.remove(e), this.currentLayout?.id === e && this.forget();
3907
+ });
3908
+ }
3909
+ changed() {
3910
+ if (!(this.destroyed || this.applying > 0)) {
3911
+ if (!this.currentLayout) {
3912
+ this.busy > 0 && (this.changedWhileBusy = !0);
3913
+ return;
3914
+ }
3915
+ this.cancelTimer(), this.timer = setTimeout(() => {
3916
+ this.timer = null, this.queue(() => this.settle());
3917
+ }, this.debounceMs);
3918
+ }
3919
+ }
3920
+ destroy() {
3921
+ if (this.destroyed) return;
3922
+ let e = this.timer !== null;
3923
+ this.cancelTimer();
3924
+ let t = this.currentLayout;
3925
+ if (e && t && this.autoSave) {
3926
+ let e = null;
3927
+ try {
3928
+ e = this.host.capture();
3929
+ } catch (e) {
3930
+ this.options.onError?.(e);
3931
+ }
3932
+ if (e && e.content !== this.savedContent) {
3933
+ let n = e;
3934
+ this.queue(() => this.write(t.id, t.name, n)).catch((e) => this.options.onError?.(e));
3935
+ }
3936
+ }
3937
+ this.destroyed = !0;
3938
+ }
3939
+ async settle() {
3940
+ let e = this.currentLayout;
3941
+ if (this.destroyed || !e) return;
3942
+ let t;
3943
+ try {
3944
+ t = this.host.capture();
3945
+ } catch (e) {
3946
+ this.options.onError?.(e);
3947
+ return;
3948
+ }
3949
+ let n = t.content !== this.savedContent;
3950
+ if (n && this.autoSave) {
3951
+ try {
3952
+ await this.write(e.id, e.name, t);
3953
+ } catch (e) {
3954
+ this.dirty = !0, this.notify(), this.options.onError?.(e);
3955
+ }
3956
+ return;
3957
+ }
3958
+ n !== this.dirty && (this.dirty = n, this.notify());
3959
+ }
3960
+ async write(e, t, n = this.host.capture()) {
3961
+ this.cancelTimer();
3962
+ let r = {
3963
+ id: e,
3964
+ name: t,
3965
+ ...n.symbol === void 0 ? {} : { symbol: n.symbol },
3966
+ ...n.timeframe === void 0 ? {} : { timeframe: n.timeframe },
3967
+ updatedAt: this.now(),
3968
+ kind: this.kind,
3969
+ content: n.content
3970
+ };
3971
+ await this.storage.save(r);
3972
+ let i = or(r);
3973
+ return this.currentLayout = i, this.savedContent = n.content, this.dirty = !1, this.notify(), i;
3974
+ }
3975
+ forget() {
3976
+ this.cancelTimer(), this.currentLayout = null, this.savedContent = null, this.dirty = !1, this.notify();
3977
+ }
3978
+ queue(e) {
3979
+ this.busy++;
3980
+ let t = this.tail.then(e).finally(() => {
3981
+ this.busy--, this.busy === 0 && this.changedWhileBusy && (this.changedWhileBusy = !1, this.changed());
3982
+ });
3983
+ return this.tail = t.catch(() => void 0), t;
3984
+ }
3985
+ cancelTimer() {
3986
+ this.timer &&= (clearTimeout(this.timer), null);
3987
+ }
3988
+ notify() {
3989
+ this.destroyed || this.options.onChange?.();
3990
+ }
3991
+ };
3992
+ //#endregion
3993
+ export { Ht as C, j as S, H as _, nr as a, $t as b, wn as c, un as d, ln as f, V as g, on as h, rr as i, _n as l, cn as m, ir as n, $n as o, sn as p, $ as r, Gn as s, sr as t, dn as u, L as v, M as x, N as y };
3994
+
3995
+ //# sourceMappingURL=LayoutSession-P9Vb-Jpb.js.map