@tradecanvas/chart 1.3.0 → 1.7.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 (205) hide show
  1. package/README.md +131 -49
  2. package/dist/Chart.d.ts +724 -18
  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-CTZB90NX.cjs +2 -0
  9. package/dist/LayoutSession-CTZB90NX.cjs.map +1 -0
  10. package/dist/LayoutSession-CWn3sdbs.js +3967 -0
  11. package/dist/LayoutSession-CWn3sdbs.js.map +1 -0
  12. package/dist/PaneManager.d.ts.map +1 -1
  13. package/dist/ThemeManager.d.ts +5 -1
  14. package/dist/ThemeManager.d.ts.map +1 -1
  15. package/dist/chartA11y.d.ts +59 -0
  16. package/dist/chartA11y.d.ts.map +1 -0
  17. package/dist/charts/ChartTypeStrategy.d.ts +11 -4
  18. package/dist/charts/ChartTypeStrategy.d.ts.map +1 -1
  19. package/dist/grid/ChartGrid.d.ts +7 -1
  20. package/dist/grid/ChartGrid.d.ts.map +1 -1
  21. package/dist/i18n-CiQ8EDVs.js +1469 -0
  22. package/dist/i18n-CiQ8EDVs.js.map +1 -0
  23. package/dist/i18n-WsLA9SmD.cjs +2 -0
  24. package/dist/i18n-WsLA9SmD.cjs.map +1 -0
  25. package/dist/index.cjs +1 -1
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.ts +24 -3
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +74 -89
  30. package/dist/index.js.map +1 -1
  31. package/dist/indicatorLabel.d.ts +7 -0
  32. package/dist/indicatorLabel.d.ts.map +1 -0
  33. package/dist/layout/LayoutManager.d.ts +50 -0
  34. package/dist/layout/LayoutManager.d.ts.map +1 -1
  35. package/dist/layout/priceAxisWidth.d.ts +2 -0
  36. package/dist/layout/priceAxisWidth.d.ts.map +1 -1
  37. package/dist/regularHours.d.ts +10 -0
  38. package/dist/regularHours.d.ts.map +1 -0
  39. package/dist/state/LayoutSession.d.ts +101 -0
  40. package/dist/state/LayoutSession.d.ts.map +1 -0
  41. package/dist/state/layoutStorage.d.ts +46 -0
  42. package/dist/state/layoutStorage.d.ts.map +1 -0
  43. package/dist/trading/wireExecution.d.ts +7 -3
  44. package/dist/trading/wireExecution.d.ts.map +1 -1
  45. package/dist/widget/ChartWidget.d.ts +283 -10
  46. package/dist/widget/ChartWidget.d.ts.map +1 -1
  47. package/dist/widget/ChartWidgetGrid.d.ts +166 -0
  48. package/dist/widget/ChartWidgetGrid.d.ts.map +1 -0
  49. package/dist/widget/DrawingTemplateStore.d.ts +29 -8
  50. package/dist/widget/DrawingTemplateStore.d.ts.map +1 -1
  51. package/dist/widget/WatchlistStore.d.ts +65 -0
  52. package/dist/widget/WatchlistStore.d.ts.map +1 -0
  53. package/dist/widget/WidgetAccountPanel.d.ts +72 -0
  54. package/dist/widget/WidgetAccountPanel.d.ts.map +1 -0
  55. package/dist/widget/WidgetAlertsPanel.d.ts +50 -3
  56. package/dist/widget/WidgetAlertsPanel.d.ts.map +1 -1
  57. package/dist/widget/WidgetBracketBar.d.ts +3 -1
  58. package/dist/widget/WidgetBracketBar.d.ts.map +1 -1
  59. package/dist/widget/WidgetChartNav.d.ts +36 -0
  60. package/dist/widget/WidgetChartNav.d.ts.map +1 -0
  61. package/dist/widget/WidgetCommandPalette.d.ts +5 -1
  62. package/dist/widget/WidgetCommandPalette.d.ts.map +1 -1
  63. package/dist/widget/WidgetContextMenu.d.ts +40 -0
  64. package/dist/widget/WidgetContextMenu.d.ts.map +1 -0
  65. package/dist/widget/WidgetDataWindow.d.ts +3 -1
  66. package/dist/widget/WidgetDataWindow.d.ts.map +1 -1
  67. package/dist/widget/WidgetDepthLadder.d.ts +3 -1
  68. package/dist/widget/WidgetDepthLadder.d.ts.map +1 -1
  69. package/dist/widget/WidgetDrawingSettings.d.ts +108 -0
  70. package/dist/widget/WidgetDrawingSettings.d.ts.map +1 -0
  71. package/dist/widget/WidgetDrawingSidebar.d.ts +26 -1
  72. package/dist/widget/WidgetDrawingSidebar.d.ts.map +1 -1
  73. package/dist/widget/WidgetDrawingStyle.d.ts +3 -1
  74. package/dist/widget/WidgetDrawingStyle.d.ts.map +1 -1
  75. package/dist/widget/WidgetDropdown.d.ts.map +1 -1
  76. package/dist/widget/WidgetGoToDate.d.ts +46 -0
  77. package/dist/widget/WidgetGoToDate.d.ts.map +1 -0
  78. package/dist/widget/WidgetHistoryPill.d.ts +23 -0
  79. package/dist/widget/WidgetHistoryPill.d.ts.map +1 -0
  80. package/dist/widget/WidgetHotkeySheet.d.ts +3 -1
  81. package/dist/widget/WidgetHotkeySheet.d.ts.map +1 -1
  82. package/dist/widget/WidgetIndicatorLegend.d.ts +98 -0
  83. package/dist/widget/WidgetIndicatorLegend.d.ts.map +1 -0
  84. package/dist/widget/WidgetIndicatorSettings.d.ts +62 -7
  85. package/dist/widget/WidgetIndicatorSettings.d.ts.map +1 -1
  86. package/dist/widget/WidgetIntervalInput.d.ts +34 -0
  87. package/dist/widget/WidgetIntervalInput.d.ts.map +1 -0
  88. package/dist/widget/WidgetLayoutsDialog.d.ts +39 -0
  89. package/dist/widget/WidgetLayoutsDialog.d.ts.map +1 -0
  90. package/dist/widget/WidgetLayoutsUI.d.ts +37 -0
  91. package/dist/widget/WidgetLayoutsUI.d.ts.map +1 -0
  92. package/dist/widget/WidgetLoadingOverlay.d.ts.map +1 -1
  93. package/dist/widget/WidgetNamePrompt.d.ts +31 -0
  94. package/dist/widget/WidgetNamePrompt.d.ts.map +1 -0
  95. package/dist/widget/WidgetObjectTree.d.ts +21 -3
  96. package/dist/widget/WidgetObjectTree.d.ts.map +1 -1
  97. package/dist/widget/WidgetOrderTicket.d.ts +49 -0
  98. package/dist/widget/WidgetOrderTicket.d.ts.map +1 -0
  99. package/dist/widget/WidgetReplayBar.d.ts +52 -7
  100. package/dist/widget/WidgetReplayBar.d.ts.map +1 -1
  101. package/dist/widget/WidgetSettings.d.ts +26 -2
  102. package/dist/widget/WidgetSettings.d.ts.map +1 -1
  103. package/dist/widget/WidgetStatusBar.d.ts +19 -1
  104. package/dist/widget/WidgetStatusBar.d.ts.map +1 -1
  105. package/dist/widget/WidgetStyles.d.ts +3 -1
  106. package/dist/widget/WidgetStyles.d.ts.map +1 -1
  107. package/dist/widget/WidgetSymbolInfo.d.ts +64 -0
  108. package/dist/widget/WidgetSymbolInfo.d.ts.map +1 -0
  109. package/dist/widget/WidgetSymbolSearch.d.ts +28 -5
  110. package/dist/widget/WidgetSymbolSearch.d.ts.map +1 -1
  111. package/dist/widget/WidgetToolbar.d.ts +42 -4
  112. package/dist/widget/WidgetToolbar.d.ts.map +1 -1
  113. package/dist/widget/WidgetTooltip.d.ts +43 -0
  114. package/dist/widget/WidgetTooltip.d.ts.map +1 -0
  115. package/dist/widget/WidgetWatchlist.d.ts +53 -13
  116. package/dist/widget/WidgetWatchlist.d.ts.map +1 -1
  117. package/dist/widget/chartMenu.d.ts +40 -0
  118. package/dist/widget/chartMenu.d.ts.map +1 -0
  119. package/dist/widget/drawingMenu.d.ts +21 -0
  120. package/dist/widget/drawingMenu.d.ts.map +1 -0
  121. package/dist/widget/escapeHtml.d.ts +3 -0
  122. package/dist/widget/escapeHtml.d.ts.map +1 -0
  123. package/dist/widget/focusTrap.d.ts +8 -0
  124. package/dist/widget/focusTrap.d.ts.map +1 -0
  125. package/dist/widget/i18n.d.ts +20 -63
  126. package/dist/widget/i18n.d.ts.map +1 -1
  127. package/dist/widget/iconSet.d.ts +26 -0
  128. package/dist/widget/iconSet.d.ts.map +1 -0
  129. package/dist/widget/icons.d.ts +5 -0
  130. package/dist/widget/icons.d.ts.map +1 -1
  131. package/dist/widget/index.cjs +2145 -405
  132. package/dist/widget/index.cjs.map +1 -1
  133. package/dist/widget/index.d.ts +18 -1
  134. package/dist/widget/index.d.ts.map +1 -1
  135. package/dist/widget/index.js +7376 -1274
  136. package/dist/widget/index.js.map +1 -1
  137. package/dist/widget/indicatorTemplates.d.ts +24 -0
  138. package/dist/widget/indicatorTemplates.d.ts.map +1 -0
  139. package/dist/widget/keyTarget.d.ts +11 -0
  140. package/dist/widget/keyTarget.d.ts.map +1 -0
  141. package/dist/widget/legendValues.d.ts +19 -0
  142. package/dist/widget/legendValues.d.ts.map +1 -0
  143. package/dist/widget/locales/ar.d.ts +4 -0
  144. package/dist/widget/locales/ar.d.ts.map +1 -0
  145. package/dist/widget/locales/de.d.ts +4 -0
  146. package/dist/widget/locales/de.d.ts.map +1 -0
  147. package/dist/widget/locales/en.d.ts +722 -0
  148. package/dist/widget/locales/en.d.ts.map +1 -0
  149. package/dist/widget/locales/es.d.ts +4 -0
  150. package/dist/widget/locales/es.d.ts.map +1 -0
  151. package/dist/widget/locales/fr.d.ts +4 -0
  152. package/dist/widget/locales/fr.d.ts.map +1 -0
  153. package/dist/widget/locales/he.d.ts +4 -0
  154. package/dist/widget/locales/he.d.ts.map +1 -0
  155. package/dist/widget/locales/id.d.ts +4 -0
  156. package/dist/widget/locales/id.d.ts.map +1 -0
  157. package/dist/widget/locales/index.cjs +2 -0
  158. package/dist/widget/locales/index.cjs.map +1 -0
  159. package/dist/widget/locales/index.d.ts +33 -0
  160. package/dist/widget/locales/index.d.ts.map +1 -0
  161. package/dist/widget/locales/index.js +10089 -0
  162. package/dist/widget/locales/index.js.map +1 -0
  163. package/dist/widget/locales/ja.d.ts +4 -0
  164. package/dist/widget/locales/ja.d.ts.map +1 -0
  165. package/dist/widget/locales/ko.d.ts +4 -0
  166. package/dist/widget/locales/ko.d.ts.map +1 -0
  167. package/dist/widget/locales/pt.d.ts +4 -0
  168. package/dist/widget/locales/pt.d.ts.map +1 -0
  169. package/dist/widget/locales/ru.d.ts +4 -0
  170. package/dist/widget/locales/ru.d.ts.map +1 -0
  171. package/dist/widget/locales/th.d.ts +4 -0
  172. package/dist/widget/locales/th.d.ts.map +1 -0
  173. package/dist/widget/locales/tr.d.ts +4 -0
  174. package/dist/widget/locales/tr.d.ts.map +1 -0
  175. package/dist/widget/locales/vi.d.ts +4 -0
  176. package/dist/widget/locales/vi.d.ts.map +1 -0
  177. package/dist/widget/locales/zh.d.ts +4 -0
  178. package/dist/widget/locales/zh.d.ts.map +1 -0
  179. package/dist/widget/locales/zhHant.d.ts +4 -0
  180. package/dist/widget/locales/zhHant.d.ts.map +1 -0
  181. package/dist/widget/orderTicket.d.ts +27 -0
  182. package/dist/widget/orderTicket.d.ts.map +1 -0
  183. package/dist/widget/settingsControls.d.ts +24 -0
  184. package/dist/widget/settingsControls.d.ts.map +1 -0
  185. package/dist/widget/types.d.ts +215 -13
  186. package/dist/widget/types.d.ts.map +1 -1
  187. package/dist/widget/widgetConfig.d.ts +1 -5
  188. package/dist/widget/widgetConfig.d.ts.map +1 -1
  189. package/dist/widget/widgetLayout.d.ts +22 -0
  190. package/dist/widget/widgetLayout.d.ts.map +1 -0
  191. package/dist/widget/widgetLocales.d.ts +17 -0
  192. package/dist/widget/widgetLocales.d.ts.map +1 -0
  193. package/dist/widget/widgetTimeframes.d.ts +28 -0
  194. package/dist/widget/widgetTimeframes.d.ts.map +1 -0
  195. package/dist/widget/widgetTimezones.d.ts +32 -0
  196. package/dist/widget/widgetTimezones.d.ts.map +1 -0
  197. package/dist/widget/widgetUI.d.ts +126 -0
  198. package/dist/widget/widgetUI.d.ts.map +1 -0
  199. package/package.json +8 -3
  200. package/dist/DragDropImporter-BazeSQPD.cjs +0 -2
  201. package/dist/DragDropImporter-BazeSQPD.cjs.map +0 -1
  202. package/dist/DragDropImporter-cURSpfUb.js +0 -1883
  203. package/dist/DragDropImporter-cURSpfUb.js.map +0 -1
  204. package/dist/charts/IndicatorPriceRange.d.ts +0 -20
  205. package/dist/charts/IndicatorPriceRange.d.ts.map +0 -1
@@ -1,1883 +0,0 @@
1
- import { DARK_THEME as e, DEFAULT_PANEL_HEIGHT as t, LIGHT_THEME as n, LayerType as r, MIN_PANEL_HEIGHT as i, PRICE_AXIS_WIDTH as a, TIME_AXIS_HEIGHT as o, autoPricePrecision as s, computePriceLimits as c, formatPrice as l, mergeBar as u, setLocale as d, timeframeToMs as f } from "@tradecanvas/commons";
2
- import { AlertDragHandler as p, AlertManager as m, Animator as ee, AreaRenderer as te, AxisDragHandler as ne, BarCountdown as re, BarRenderer as ie, BaselineRenderer as ae, CandlestickRenderer as h, ChartLegend as oe, ChartStateManager as g, CompareRenderer as se, CrosshairHandler as ce, CrosshairTooltip as le, CurrentPriceLine as ue, DataExporter as _, DepthHeatmapRenderer as de, DrawingManager as fe, DrawingRenderer as pe, EquivolumeRenderer as me, EventBus as he, GridRenderer as ge, HLCAreaRenderer as _e, HollowCandleRenderer as ve, IndicatorEngine as v, InteractionManager as ye, KagiRenderer as be, KeyboardHandler as xe, LineRenderer as Se, LineWithMarkersRenderer as Ce, MarketProfileRenderer as we, MeasureOverlay as Te, PanHandler as Ee, PaneResizeHandler as De, PeriodLevelsRenderer as Oe, PinnedTooltip as ke, PivotMarkersRenderer as Ae, PointAndFigureRenderer as je, PriceAxis as Me, RenderEngine as Ne, RenkoRenderer as y, ReplayManager as b, Screenshot as x, SelectionBoxOverlay as Pe, SessionBreaks as Fe, SessionShading as Ie, SignalMarkerManager as Le, StepLineRenderer as Re, StreamManager as ze, TimeAxis as Be, TradeZoneManager as Ve, TradingManager as He, TradingRenderer as Ue, UndoRedoManager as We, Viewport as Ge, VolumeCandleRenderer as Ke, VolumeProfileRenderer as qe, VolumeRenderer as Je, Watermark as Ye, ZoomHandler as Xe, barTimeStep as Ze, findDominantSwing as Qe, registerBuiltInDrawingTools as $e, registerBuiltInIndicators as S, timestampToBarIndex as C, toHeikinAshi as et, toKagi as tt, toLineBreak as nt, toPointAndFigure as rt, toRangeBars as it, toRenko as at, xToBarIndex as ot } from "@tradecanvas/core";
3
- //#region src/charts/ChartTypeStrategy.ts
4
- function st(e) {
5
- switch (e) {
6
- case "candlestick":
7
- case "heikinAshi":
8
- case "lineBreak":
9
- case "rangeBars": return new h();
10
- case "line": return new Se();
11
- case "area": return new te();
12
- case "bar": return new ie();
13
- case "hollowCandle": return new ve();
14
- case "baseline": return new ae();
15
- case "renko": return new y();
16
- case "kagi": return new be();
17
- case "pointAndFigure": return new je();
18
- case "volumeCandles": return new Ke();
19
- case "equivolume": return new me();
20
- case "hlcArea": return new _e();
21
- case "stepLine": return new Re();
22
- case "lineWithMarkers": return new Ce();
23
- default: return new h();
24
- }
25
- }
26
- function ct(e, t) {
27
- if (t.length === 0) return t;
28
- switch (e) {
29
- case "heikinAshi": return et(t);
30
- case "renko": return at(t, {
31
- brickSize: 0,
32
- useATR: !0,
33
- atrPeriod: 14
34
- });
35
- case "lineBreak": return nt(t, 3);
36
- case "kagi": return tt(t, 4);
37
- case "pointAndFigure": return rt(t, w(t) * .01, 3);
38
- case "rangeBars": return it(t, { rangeSize: w(t) * .005 });
39
- default: return t;
40
- }
41
- }
42
- function w(e) {
43
- let t = 0;
44
- for (let n of e) t += n.close;
45
- return t / e.length;
46
- }
47
- function lt(e, t) {
48
- let n = t?.(e);
49
- return n ? n.createRenderer() : st(e);
50
- }
51
- function ut(e, t, n) {
52
- if (t.length === 0) return t;
53
- let r = n?.(e);
54
- return r?.transform ? r.transform(t) : ct(e, t);
55
- }
56
- //#endregion
57
- //#region src/charts/IndicatorPriceRange.ts
58
- var T = {
59
- min: 0,
60
- max: 100
61
- }, E = .1;
62
- function dt(e, t, n) {
63
- if (!e) return { ...T };
64
- let r = Infinity, i = -Infinity;
65
- if (e.series) {
66
- let a = Math.min(n, e.series.length - 1);
67
- for (let n = Math.max(0, t); n <= a; n++) {
68
- let t = e.series[n];
69
- if (t) for (let e in t) {
70
- let n = t[e];
71
- n !== void 0 && Number.isFinite(n) && (n < r && (r = n), n > i && (i = n));
72
- }
73
- }
74
- } else {
75
- let a = 0;
76
- for (let [, o] of e.values) {
77
- if (a >= t && a <= n) for (let e in o) {
78
- let t = o[e];
79
- t !== void 0 && Number.isFinite(t) && (t < r && (r = t), t > i && (i = t));
80
- }
81
- a++;
82
- }
83
- }
84
- if (r === Infinity) return { ...T };
85
- let a = i - r || 1;
86
- return {
87
- min: r - a * E,
88
- max: i + a * E
89
- };
90
- }
91
- //#endregion
92
- //#region src/state/AutoSaveScheduler.ts
93
- var ft = class {
94
- timer = null;
95
- delayMs = 0;
96
- key = null;
97
- constructor(e) {
98
- this.save = e;
99
- }
100
- enable(e, t) {
101
- this.key = e, this.delayMs = t;
102
- }
103
- disable() {
104
- this.key = null, this.delayMs = 0, this.cancel();
105
- }
106
- schedule() {
107
- this.delayMs <= 0 || !this.key || (this.timer && clearTimeout(this.timer), this.timer = setTimeout(() => {
108
- this.timer = null, this.key && this.save(this.key);
109
- }, this.delayMs));
110
- }
111
- cancel() {
112
- this.timer &&= (clearTimeout(this.timer), null);
113
- }
114
- isEnabled() {
115
- return this.delayMs > 0 && this.key !== null;
116
- }
117
- hasPending() {
118
- return this.timer !== null;
119
- }
120
- };
121
- //#endregion
122
- //#region src/DataManager.ts
123
- function D(e) {
124
- if (!e || typeof e.time != "number") return !1;
125
- let { open: t, high: n, low: r, close: i } = e;
126
- return !(!isFinite(t) || !isFinite(n) || !isFinite(r) || !isFinite(i) || t < 0 || n < 0 || r < 0 || i < 0 || n < r || e.volume !== void 0 && (!isFinite(e.volume) || e.volume < 0));
127
- }
128
- function pt(e) {
129
- return e.volume !== void 0 && e.high >= e.open && e.high >= e.close && e.low <= e.open && e.low <= e.close;
130
- }
131
- function O(e) {
132
- return {
133
- ...e,
134
- high: Math.max(e.open, e.high, e.low, e.close),
135
- low: Math.min(e.open, e.high, e.low, e.close),
136
- volume: e.volume === void 0 ? 0 : Math.max(0, e.volume)
137
- };
138
- }
139
- var k = class {
140
- data = [];
141
- getData() {
142
- return this.data;
143
- }
144
- setData(e) {
145
- let t = [];
146
- for (let n = 0; n < e.length; n++) {
147
- let r = e[n];
148
- D(r) && t.push(pt(r) ? r : O(r));
149
- }
150
- this.data = t;
151
- }
152
- appendBar(e) {
153
- D(e) && this.data.push(O(e));
154
- }
155
- updateLastBar(e) {
156
- if (!D(e)) return;
157
- let t = O(e);
158
- if (this.data.length === 0) {
159
- this.data.push(t);
160
- return;
161
- }
162
- this.data[this.data.length - 1] = t;
163
- }
164
- updateLastBarFromTick(e) {
165
- this.data.length !== 0 && (!isFinite(e.price) || e.price < 0 || e.volume !== void 0 && (!isFinite(e.volume) || e.volume < 0) || (this.data[this.data.length - 1] = u(this.data[this.data.length - 1], e)));
166
- }
167
- getLength() {
168
- return this.data.length;
169
- }
170
- clear() {
171
- this.data = [];
172
- }
173
- }, A = class {
174
- theme;
175
- constructor(t) {
176
- !t || t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t };
177
- }
178
- getTheme() {
179
- return this.theme;
180
- }
181
- setTheme(t) {
182
- t === "dark" ? this.theme = { ...e } : t === "light" ? this.theme = { ...n } : this.theme = { ...t };
183
- }
184
- }, j = 200, M = 80, N = class {
185
- panels = [];
186
- containerWidth = 0;
187
- containerHeight = 0;
188
- priceAxisWidth = a;
189
- resize(e, t) {
190
- this.containerWidth = e, this.containerHeight = t;
191
- }
192
- addPanel(e, n = "bottom", r) {
193
- let a = n === "left" || n === "right";
194
- this.panels.push({
195
- id: e,
196
- position: n,
197
- size: r ?? (a ? j : t),
198
- minSize: a ? M : i,
199
- content: {
200
- type: "indicator",
201
- indicatorInstanceId: e
202
- }
203
- });
204
- }
205
- removePanel(e) {
206
- this.panels = this.panels.filter((t) => t.id !== e);
207
- }
208
- setPanelPosition(e, n) {
209
- let r = this.panels.find((t) => t.id === e);
210
- if (r) {
211
- let e = r.position === "left" || r.position === "right", a = n === "left" || n === "right";
212
- r.position = n, e !== a && (r.size = a ? j : t, r.minSize = a ? M : i);
213
- }
214
- }
215
- setPanelSize(e, t) {
216
- let n = this.panels.find((t) => t.id === e);
217
- n && (n.size = Math.max(n.minSize, t));
218
- }
219
- setPriceAxisWidth(e) {
220
- this.priceAxisWidth = e;
221
- }
222
- getPanels() {
223
- return this.panels;
224
- }
225
- resolve() {
226
- let e = this.panels.filter((e) => e.position === "left"), t = this.panels.filter((e) => e.position === "right"), n = this.panels.filter((e) => e.position === "top"), r = this.panels.filter((e) => e.position === "bottom"), i = e.reduce((e, t) => e + t.size, 0), a = t.reduce((e, t) => e + t.size, 0), s = n.reduce((e, t) => e + t.size, 0), c = r.reduce((e, t) => e + t.size, 0), l = {
227
- x: i,
228
- y: s,
229
- width: Math.max(0, this.containerWidth - i - a - this.priceAxisWidth),
230
- height: Math.max(0, this.containerHeight - s - c - o)
231
- }, u = [], d = [], f = 0;
232
- for (let t of e) u.push({
233
- config: t,
234
- rect: {
235
- x: f,
236
- y: 0,
237
- width: t.size,
238
- height: this.containerHeight - o
239
- }
240
- }), d.push({
241
- panelId: t.id,
242
- rect: {
243
- x: f + t.size - 2,
244
- y: 0,
245
- width: 4,
246
- height: this.containerHeight
247
- },
248
- orientation: "vertical"
249
- }), f += t.size;
250
- let p = 0;
251
- for (let e of n) u.push({
252
- config: e,
253
- rect: {
254
- x: i,
255
- y: p,
256
- width: l.width,
257
- height: e.size
258
- }
259
- }), d.push({
260
- panelId: e.id,
261
- rect: {
262
- x: i,
263
- y: p + e.size - 2,
264
- width: l.width,
265
- height: 4
266
- },
267
- orientation: "horizontal"
268
- }), p += e.size;
269
- p = l.y + l.height;
270
- for (let e of r) u.push({
271
- config: e,
272
- rect: {
273
- x: i,
274
- y: p,
275
- width: l.width,
276
- height: e.size
277
- }
278
- }), d.push({
279
- panelId: e.id,
280
- rect: {
281
- x: i,
282
- y: p - 2,
283
- width: l.width,
284
- height: 4
285
- },
286
- orientation: "horizontal"
287
- }), p += e.size;
288
- f = i + l.width + this.priceAxisWidth;
289
- for (let e of t) u.push({
290
- config: e,
291
- rect: {
292
- x: f,
293
- y: 0,
294
- width: e.size,
295
- height: this.containerHeight - o
296
- }
297
- }), d.push({
298
- panelId: e.id,
299
- rect: {
300
- x: f - 2,
301
- y: 0,
302
- width: 4,
303
- height: this.containerHeight
304
- },
305
- orientation: "vertical"
306
- }), f += e.size;
307
- return {
308
- mainChartRect: l,
309
- panels: u,
310
- dividers: d
311
- };
312
- }
313
- getMainChartRect() {
314
- return this.resolve().mainChartRect;
315
- }
316
- }, mt = 14, ht = 14, gt = 22, P = 4;
317
- function _t(e) {
318
- let { min: t, max: n, lastPrice: r, locale: i, fontFamily: o, fontSizeSmall: c, measure: u } = e, d = s(t, n), f = e.tagPrecision ?? d, p = r === null ? [t, n] : [
319
- t,
320
- n,
321
- r
322
- ], m = a;
323
- for (let e of p) {
324
- if (!Number.isFinite(e)) continue;
325
- let t = l(e, d, i), n = l(e, f, i);
326
- m = Math.max(m, u(t, `500 ${c}px ${o}`) + mt, u(n, `bold 11px ${o}`) + ht, u(n, `600 ${c}px ${o}`) + gt);
327
- }
328
- return m <= a ? a : Math.ceil(m / P) * P;
329
- }
330
- function vt(e, t) {
331
- return t > e || t <= e - 12 ? t : e;
332
- }
333
- var yt = class {
334
- netY = 0;
335
- travelX = 0;
336
- engaged = !1;
337
- reset() {
338
- this.netY = 0, this.travelX = 0, this.engaged = !1;
339
- }
340
- step(e, t, n) {
341
- if (this.engaged) return !0;
342
- if (this.netY += t, this.travelX += Math.abs(e), !n) this.engaged = !0;
343
- else {
344
- let e = Math.abs(this.netY);
345
- this.engaged = e > 24 && e >= this.travelX * .5;
346
- }
347
- return this.engaged;
348
- }
349
- }, bt = 1;
350
- function F(e, t) {
351
- return e.filter((e) => (e.descriptor.layer ?? "overlay") === t);
352
- }
353
- function I(e) {
354
- switch (e.kind) {
355
- case "indicator": return `indicator:${e.plugin.descriptor.id}`;
356
- case "drawing": return `drawing:${e.plugin.descriptor.type}`;
357
- case "chartType": return `chartType:${e.plugin.descriptor.type}`;
358
- case "overlay": return `overlay:${e.plugin.descriptor.id}`;
359
- }
360
- }
361
- //#endregion
362
- //#region src/plugins/registry.ts
363
- var L = /* @__PURE__ */ new Map();
364
- function xt(e) {
365
- L.set(I(e), e);
366
- }
367
- function St(e) {
368
- return L.delete(e);
369
- }
370
- function R() {
371
- return [...L.values()];
372
- }
373
- function Ct() {
374
- L.clear();
375
- }
376
- //#endregion
377
- //#region src/plugins/PluginManager.ts
378
- var z = class {
379
- plugins = /* @__PURE__ */ new Map();
380
- constructor(e, t = {}) {
381
- if (this.indicatorEngine = e, t.inheritGlobal !== !1) for (let e of R()) this.add(e);
382
- for (let e of t.plugins ?? []) this.add(e);
383
- }
384
- register(e) {
385
- this.add(e);
386
- }
387
- unregister(e) {
388
- return this.plugins.delete(e);
389
- }
390
- list() {
391
- return [...this.plugins.values()];
392
- }
393
- registerIndicator(e) {
394
- this.add({
395
- kind: "indicator",
396
- plugin: e
397
- });
398
- }
399
- getChartType(e) {
400
- let t = this.plugins.get(`chartType:${e}`);
401
- return t?.kind === "chartType" ? t.plugin : void 0;
402
- }
403
- getOverlays() {
404
- let e = [];
405
- for (let t of this.plugins.values()) t.kind === "overlay" && e.push(t.plugin);
406
- return e;
407
- }
408
- add(e) {
409
- this.plugins.set(I(e), e), e.kind === "indicator" && this.indicatorEngine.register(e.plugin);
410
- }
411
- }, B = {
412
- orderPlace: (e, t) => e.placeOrder(t),
413
- orderModify: (e, t) => e.modifyOrder(t),
414
- orderCancel: (e, t) => e.cancelOrder(t),
415
- positionModify: (e, t) => e.modifyPosition(t),
416
- positionClose: (e, t) => e.closePosition(t)
417
- };
418
- function wt(e, t) {
419
- let n = [], r = (e) => t.setOrders(e.data ?? []), i = (e) => t.setPositions(e.data ?? []), a = (e) => t.onError(e.data ?? { message: "Execution error" });
420
- e.on("orders", r), e.on("positions", i), e.on("error", a), n.push(() => e.off("orders", r), () => e.off("positions", i), () => e.off("error", a));
421
- for (let r of Object.keys(B)) {
422
- let i = B[r], a = t.onIntent(r, (n) => {
423
- Promise.resolve(i(e, n)).catch((e) => t.onError({
424
- message: `Execution command failed: ${r}`,
425
- cause: e
426
- }));
427
- });
428
- n.push(a);
429
- }
430
- return () => {
431
- for (let e of n) e();
432
- };
433
- }
434
- //#endregion
435
- //#region src/Chart.ts
436
- var Tt = class {
437
- static version = "1.3.0";
438
- engine;
439
- viewport;
440
- dataManager;
441
- themeManager;
442
- layoutManager;
443
- pluginManager;
444
- indicatorEngine;
445
- drawingManager;
446
- drawingRenderer;
447
- tradingManager;
448
- tradingRenderer;
449
- eventBus;
450
- streamManager = null;
451
- executionAdapter = null;
452
- execTeardown = null;
453
- autoScrollOnNewBar = !0;
454
- displayDataCache = null;
455
- resolvedLayoutCache = null;
456
- panelInfoCache = null;
457
- renderScheduled = !1;
458
- priceAxisWidth = a;
459
- measureCtx;
460
- containerSizeCache = null;
461
- containerSizeCacheTime = 0;
462
- lastEmittedRange = null;
463
- lastEmittedPriceRange = null;
464
- lastEmittedBarWidth = null;
465
- chartLegend;
466
- watermark;
467
- barCountdown;
468
- sessionBreaks;
469
- sessionShading;
470
- compareRenderer;
471
- countdownInterval = null;
472
- volumeRenderer;
473
- volumeProfile;
474
- marketProfile;
475
- depthHeatmap;
476
- periodLevels;
477
- pivotMarkers;
478
- alertManager;
479
- signalMarkerManager;
480
- tradeZoneManager;
481
- measureOverlay;
482
- selectionBoxOverlay = new Pe();
483
- replayManager;
484
- replayBarUnsub = null;
485
- replaySeeking = !1;
486
- undoRedoManager;
487
- autoSaveScheduler = new ft((e) => this.saveState(e));
488
- animator;
489
- crosshairTooltip;
490
- pinnedTooltip;
491
- interactionManager;
492
- crosshairHandler;
493
- chartRenderer;
494
- gridRenderer;
495
- priceAxis;
496
- timeAxis;
497
- options;
498
- features;
499
- marketConfig = null;
500
- container;
501
- currentPriceLine;
502
- numberLocale;
503
- defaultAutoScale;
504
- keyboardHandler = null;
505
- onWindowKeyDown = null;
506
- currentSymbol = "";
507
- constructor(e, t) {
508
- this.container = e, this.options = t, this.numberLocale = t.numberLocale ?? "en-US", this.defaultAutoScale = t.autoScale !== !1;
509
- let n = t.features ?? {};
510
- this.features = {
511
- drawings: n.drawings ?? !0,
512
- drawingTools: n.drawingTools ?? [],
513
- drawingMagnet: n.drawingMagnet ?? !0,
514
- drawingUndoRedo: n.drawingUndoRedo ?? !0,
515
- trading: n.trading ?? !0,
516
- tradingContextMenu: n.tradingContextMenu ?? !1,
517
- indicators: n.indicators ?? !0,
518
- indicatorIds: n.indicatorIds ?? [],
519
- panning: n.panning ?? !0,
520
- zooming: n.zooming ?? !0,
521
- crosshair: n.crosshair ?? !0,
522
- crosshairTooltip: n.crosshairTooltip ?? !0,
523
- keyboard: n.keyboard ?? !0,
524
- priceAxis: n.priceAxis ?? !0,
525
- timeAxis: n.timeAxis ?? !0,
526
- grid: n.grid ?? t.grid?.visible ?? !0,
527
- legend: n.legend ?? !0,
528
- volume: n.volume ?? !0,
529
- watermark: n.watermark ?? !0,
530
- saveLoad: n.saveLoad ?? !0,
531
- screenshot: n.screenshot ?? !0,
532
- alerts: n.alerts ?? !0,
533
- replay: n.replay ?? !0,
534
- sessionBreaks: n.sessionBreaks ?? !0,
535
- barCountdown: n.barCountdown ?? !0,
536
- compareSymbols: n.compareSymbols ?? !0,
537
- dataExport: n.dataExport ?? !0,
538
- logScale: n.logScale ?? !0,
539
- timeframes: n.timeframes ?? [],
540
- defaultTimeframeFavorites: n.defaultTimeframeFavorites ?? []
541
- }, e.style.position = "relative", e.style.overflow = "hidden", e.tabIndex = 0, e.style.outline = "none", this.dataManager = new k(), this.themeManager = new A(t.theme), this.layoutManager = new N(), this.indicatorEngine = new v(), this.pluginManager = new z(this.indicatorEngine, { plugins: t.plugins }), this.eventBus = new he(), S(this.indicatorEngine), this.drawingManager = new fe(), $e(this.drawingManager), this.drawingRenderer = new pe(this.drawingManager), this.drawingManager.setRequestRender(() => {
542
- this.syncRenderContext(), this.engine.requestRender(r.Overlay), this.scheduleAutoSave();
543
- }), this.drawingManager.setEventCallback((e, t) => {
544
- this.eventBus.emit(e, t);
545
- }), this.undoRedoManager = new We(), this.drawingManager.setUndoRedoManager(this.undoRedoManager), this.drawingManager.setDataGetter(() => this.dataManager.getData()), this.drawingManager.setDisplayDataGetter(() => this.getDisplayData()), t.crosshair?.mode === "magnet" && this.drawingManager.setMagnetMode("magnet"), this.tradingManager = new He({
546
- enabled: this.features.trading,
547
- contextMenu: { enabled: this.features.tradingContextMenu }
548
- }), this.tradingRenderer = new Ue(this.tradingManager), this.tradingManager.setContainer(e), this.tradingManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradingManager.setEventCallback((e, t) => {
549
- this.eventBus.emit(e, t);
550
- }), this.engine = new Ne(e);
551
- let i = this.engine.dprManager.getContainerSize();
552
- if (this.viewport = new Ge(i.width, i.height, t.minBarSpacing ?? 2, t.maxBarSpacing ?? 30, t.rightMargin ?? 5), this.viewport.setPanLimits({
553
- freePan: t.freePan ?? !0,
554
- minVisibleBars: t.panLimits?.minVisibleBars ?? 3
555
- }), this.layoutManager.resize(i.width, i.height), this.engine.onContainerResize = (e) => {
556
- if (e.width <= 0 || e.height <= 0) return;
557
- let t = this.viewport.isAtEnd();
558
- this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(t);
559
- }, this.chartRenderer = this.createChartRenderer(t.chartType), this.gridRenderer = new ge(), t.grid?.visible === !1 && this.gridRenderer.setVisible(!1), this.priceAxis = new Me(), this.priceAxis.setLocale(this.numberLocale), this.timeAxis = new Be(), this.crosshairHandler = new ce(), this.crosshairHandler.setLocale(this.numberLocale), t.crosshair?.mode && this.crosshairHandler.setMode(t.crosshair.mode), this.crosshairHandler.setCallback((e, t) => {
560
- if (e !== null && t) {
561
- let n = this.dataManager.getData(), r = e < n.length ? n[e] : void 0;
562
- if (this.chartLegend.setHoverBar(r ?? null), r && this.features.crosshairTooltip) {
563
- let i = this.viewport.getState();
564
- this.crosshairTooltip.show(t, r, this.themeManager.getTheme(), this.cachedContainerSize(), {
565
- prevClose: e > 0 ? n[e - 1]?.close : void 0,
566
- priceRange: i.priceRange,
567
- plot: i.chartRect,
568
- barStepMs: Ze(n)
569
- });
570
- }
571
- this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), r ?? null, e, this.themeManager.getTheme()), this.eventBus.emit("crosshairMove", {
572
- point: t,
573
- bar: r,
574
- barIndex: e
575
- });
576
- } else this.crosshairTooltip.hide(), this.chartLegend.setHoverBar(null);
577
- }), this.chartLegend = new oe(), this.chartLegend.setChartType(t.chartType), this.chartLegend.setLocale(this.numberLocale), this.watermark = new Ye(), t.watermark && this.watermark.setConfig(t.watermark), this.volumeRenderer = new Je(), this.volumeProfile = new qe(), this.marketProfile = new we(), this.depthHeatmap = new de(), this.periodLevels = new Oe(), this.pivotMarkers = new Ae(), this.barCountdown = new re(), this.sessionBreaks = new Fe(), this.sessionBreaks.setLocale(this.numberLocale), this.sessionShading = new Ie(), this.compareRenderer = new se(), t.sessionBreaks ? this.sessionBreaks.setConfig({
578
- visible: t.sessionBreaks.visible ?? !0,
579
- color: t.sessionBreaks.color,
580
- lineStyle: t.sessionBreaks.lineStyle,
581
- lineWidth: t.sessionBreaks.lineWidth
582
- }) : t.features?.sessionBreaks !== !1 && this.sessionBreaks.setVisible(!0), t.logScale && this.viewport.setLogScale(!0), this.animator = new ee(), this.crosshairTooltip = new le(), this.crosshairTooltip.create(e), this.crosshairTooltip.setLocale(this.numberLocale), this.pinnedTooltip = new ke(), this.pinnedTooltip.create(e), this.keyboardHandler = new xe({
583
- scrollBars: (e) => {
584
- let t = this.viewport.getState().barWidth + this.viewport.getState().barSpacing;
585
- this.viewport.scrollBy(e * t), this.updateViewportAndRender();
586
- },
587
- zoom: (e) => {
588
- let t = this.viewport.getState().chartRect.width;
589
- this.viewport.zoom(e, t / 2), this.updateViewportAndRender();
590
- },
591
- goToStart: () => {
592
- this.viewport.scrollBy(-Infinity), this.updateViewportAndRender();
593
- },
594
- goToEnd: () => {
595
- this.viewport.scrollToEnd(), this.updateViewportAndRender();
596
- },
597
- fitContent: () => this.fitContent()
598
- }), this.keyboardHandler.setEnabled(this.features.keyboard), this.onWindowKeyDown = (e) => {
599
- if (!this.keyboardHandler) return;
600
- let t = document.activeElement;
601
- t && t !== this.container && !this.container.contains(t) || t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable) || this.keyboardHandler.handleKey(e) && e.preventDefault();
602
- }, window.addEventListener("keydown", this.onWindowKeyDown), this.currentPriceLine = new ue(), this.currentPriceLine.setLocale(this.numberLocale), this.priceAxis.setReservedPriceProvider(() => this.currentPriceLine.isVisible() ? this.currentPriceLine.getPrice() : null), this.alertManager = new m(), this.alertManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.alertManager.on("triggered", (e) => {
603
- let t = {
604
- id: e.id,
605
- price: e.price,
606
- condition: e.condition,
607
- message: e.message,
608
- triggered: e.triggered
609
- };
610
- this.eventBus.emit("alertTriggered", t), this.eventBus.emit("dataUpdate", {
611
- alert: "triggered",
612
- alertId: e.id,
613
- price: e.price,
614
- message: e.message
615
- });
616
- }), this.alertManager.on("added", (e) => {
617
- this.eventBus.emit("alertAdd", {
618
- id: e.id,
619
- price: e.price,
620
- condition: e.condition,
621
- message: e.message,
622
- triggered: e.triggered
623
- });
624
- }), this.alertManager.on("removed", (e) => {
625
- this.eventBus.emit("alertRemove", { id: e });
626
- }), this.alertManager.on("updated", (e) => {
627
- this.eventBus.emit("alertUpdate", {
628
- id: e.id,
629
- price: e.price,
630
- condition: e.condition,
631
- message: e.message,
632
- triggered: e.triggered
633
- });
634
- }), this.signalMarkerManager = new Le(), this.signalMarkerManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.signalMarkerManager.setDataGetter(() => this.dataManager.getData()), this.signalMarkerManager.on("added", (e) => {
635
- this.eventBus.emit("signalMarkerAdd", {
636
- id: e.id,
637
- source: e.source,
638
- direction: e.direction
639
- });
640
- }), this.signalMarkerManager.on("removed", (e) => {
641
- this.eventBus.emit("signalMarkerRemove", { id: e });
642
- }), this.tradeZoneManager = new Ve(), this.tradeZoneManager.setRequestRender(() => this.engine.requestRender(r.Overlay)), this.tradeZoneManager.setDataGetter(() => this.dataManager.getData()), this.tradeZoneManager.on("added", (e) => {
643
- this.eventBus.emit("tradeZoneAdd", {
644
- id: e.id,
645
- direction: e.direction
646
- });
647
- }), this.tradeZoneManager.on("removed", (e) => {
648
- this.eventBus.emit("tradeZoneRemove", { id: e });
649
- }), this.replayManager = new b(), this.measureOverlay = new Te(), this.interactionManager = new ye(e), this.features.panning) {
650
- let e = new yt();
651
- this.interactionManager.setPanHandler(new Ee((t, n) => {
652
- t && this.viewport.scrollBy(t), e.step(t, n, this.options.autoScale !== !1) && n && (this.options.autoScale = !1, this.viewport.panPriceRange(n)), this.updateViewportAndRender();
653
- }, () => e.reset()));
654
- }
655
- if (this.features.zooming) {
656
- this.interactionManager.setZoomHandler(new Xe((e, t) => {
657
- this.viewport.zoom(e, t), this.updateViewportAndRender();
658
- }));
659
- let e = new ne((e) => {
660
- this.options.autoScale = !1, this.viewport.scalePriceRange(e), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
661
- }, (e) => {
662
- let t = this.viewport.getState().chartRect.width;
663
- this.viewport.zoom(1 / e - 1, t / 2), this.updateViewportAndRender();
664
- });
665
- this.interactionManager.setAxisDragHandler(e, () => this.viewport.getState(), (e) => {
666
- e === "price" ? (this.options.autoScale = !0, this.updateViewportAndRender()) : this.fitContent();
667
- });
668
- }
669
- if (this.features.crosshair && this.interactionManager.setCrosshairHandler(this.crosshairHandler), this.features.drawings && this.interactionManager.setDrawingManager(this.drawingManager, () => ({
670
- ...this.viewport.getState(),
671
- data: this.getDisplayData()
672
- })), this.features.trading && this.interactionManager.setTradingManager(this.tradingManager, () => ({
673
- ...this.viewport.getState(),
674
- data: this.getDisplayData()
675
- })), this.features.alerts) {
676
- let e = new p(this.alertManager, () => this.viewport.getState());
677
- this.interactionManager.setAlertDragHandler(e);
678
- }
679
- let a = new De();
680
- a.configure(() => this.getResolvedLayout(), (e, t) => this.setPanelSize(e, t)), this.interactionManager.setPaneResizeHandler(a), this.interactionManager.setAltClickHandler((e) => {
681
- let t = this.getDisplayData();
682
- if (t.length === 0) return;
683
- let n = this.viewport.getState(), i = n.barWidth + n.barSpacing, a = Math.round((n.offset + e.x) / i);
684
- 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));
685
- }), this.interactionManager.setClickHandler((e) => {
686
- let t = this.getDisplayData();
687
- if (this.eventBus.emit("click", {
688
- x: e.x,
689
- y: e.y
690
- }), t.length === 0) return;
691
- let n = ot(e.x, this.viewport.getState());
692
- n < 0 || n >= t.length || this.eventBus.emit("barClick", {
693
- bar: t[n],
694
- barIndex: n,
695
- point: e
696
- });
697
- }), this.interactionManager.setEscapeHandler(() => {
698
- if (this.features.trading && this.tradingManager.isBracketActive()) {
699
- this.tradingManager.cancelBracket(), this.eventBus.emit("dataUpdate", { bracket: "cancelled" });
700
- return;
701
- }
702
- this.pinnedTooltip.isPinned() && (this.pinnedTooltip.unpin(), this.engine.requestRender(r.Overlay));
703
- }), this.interactionManager.setConfirmHandler(() => this.features.trading && this.tradingManager.isBracketActive() ? (this.tradingManager.confirmBracket(), !0) : !1), this.interactionManager.setMeasureHandlers({
704
- begin: (e) => {
705
- this.measureOverlay.begin(e, this.viewport.getState(), this.getDisplayData());
706
- },
707
- move: (e) => {
708
- this.measureOverlay.update(e, this.viewport.getState(), this.getDisplayData());
709
- },
710
- end: () => {
711
- this.measureOverlay.end();
712
- }
713
- });
714
- let o = (e) => {
715
- let t = this.viewport.getState().chartRect;
716
- return {
717
- x: Math.max(t.x, Math.min(t.x + t.width, e.x)),
718
- y: Math.max(t.y, Math.min(t.y + t.height, e.y))
719
- };
720
- };
721
- this.interactionManager.setBoxSelectHandlers({
722
- begin: (e) => this.selectionBoxOverlay.begin(o(e)),
723
- move: (e) => this.selectionBoxOverlay.update(o(e)),
724
- end: () => {
725
- let e = this.selectionBoxOverlay.end();
726
- if (!e || !this.features.drawings) return;
727
- let t = {
728
- ...this.viewport.getState(),
729
- data: this.getDisplayData()
730
- };
731
- e.isClick ? this.drawingManager.toggleSelectionAt({
732
- x: e.x1,
733
- y: e.y1
734
- }, t) : this.drawingManager.selectInRect(e, t), this.engine.requestRender(r.Overlay);
735
- },
736
- cancel: () => this.selectionBoxOverlay.cancel()
737
- }), this.interactionManager.setOverlayDirtyCallback((e) => {
738
- this.engine.requestRender(e ? r.Hover : r.Overlay);
739
- }), this.interactionManager.attach(), this.syncRenderContext(), this.engine.start();
740
- }
741
- setData(e) {
742
- this.dataManager.setData(e), this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.sessionBreaks.invalidateCache(), this.options.autoScale = this.defaultAutoScale, this.alertManager.clearLastValues(), this.indicatorEngine.recalculateAll(this.dataManager.getData()), e.length > 0 && this.currentPriceLine.setPrice(e[e.length - 1].close), this.updateViewportAndRender(!0), this.eventBus.emit("dataUpdate", { length: e.length });
743
- }
744
- appendBar(e) {
745
- let t = this.autoScrollOnNewBar && this.viewport.isAtEnd();
746
- this.dataManager.appendBar(e);
747
- let n = this.dataManager.getData();
748
- this.crosshairHandler.setData(n), this.displayDataCache = null, this.indicatorEngine.recalculateFrom(n, n.length - 2), this.updateViewportAndRender(t);
749
- }
750
- appendBars(e) {
751
- if (e.length === 0) return;
752
- let t = this.viewport.isAtEnd(), n = this.dataManager.getLength() - 1;
753
- for (let t of e) this.dataManager.appendBar(t);
754
- this.displayDataCache = null, this.indicatorEngine.recalculateFrom(this.dataManager.getData(), n), this.crosshairHandler.setData(this.dataManager.getData()), this.updateViewportAndRender(t);
755
- }
756
- updateLastBar(e) {
757
- this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null);
758
- let t = this.dataManager.getData();
759
- this.indicatorEngine.recalculateFrom(t, t.length - 1), this.scheduleRender();
760
- }
761
- updateLastBarFromTick(e) {
762
- this.dataManager.updateLastBarFromTick(e), this.currentPriceLine.setPrice(e.price), this.options.chartType !== "candlestick" && this.options.chartType !== "line" && this.options.chartType !== "area" && this.options.chartType !== "bar" && this.options.chartType !== "hollowCandle" && (this.displayDataCache = null);
763
- let t = this.dataManager.getData();
764
- this.indicatorEngine.recalculateFrom(t, t.length - 1), this.scheduleRender();
765
- }
766
- setChartType(e) {
767
- this.options.chartType = e, this.chartRenderer = this.createChartRenderer(e), this.chartLegend.setChartType(e), this.displayDataCache = null, this.updateViewportAndRender(!0);
768
- }
769
- addIndicator(e, t = {}, n = "bottom") {
770
- if (!this.features.indicators || this.features.indicatorIds.length > 0 && !this.features.indicatorIds.includes(e)) return null;
771
- let r = this.indicatorEngine.addIndicator(e, t, this.dataManager.getData());
772
- return this.indicatorEngine.getAvailableIndicators().find((t) => t.id === e)?.placement === "panel" ? (this.layoutManager.addPanel(r, n), this.updateViewportAndRender()) : this.engine.requestRender(), this.eventBus.emit("indicatorAdd", {
773
- instanceId: r,
774
- id: e
775
- }), r;
776
- }
777
- updateIndicator(e, t) {
778
- this.indicatorEngine.updateIndicator(e, t, this.dataManager.getData()), this.engine.requestRender();
779
- }
780
- removeIndicator(e) {
781
- let t = this.layoutManager.getPanels().some((t) => t.id === e);
782
- this.indicatorEngine.removeIndicator(e), this.layoutManager.removePanel(e), this.eventBus.emit("indicatorRemove", { instanceId: e }), t ? this.updateViewportAndRender() : this.engine.requestRender();
783
- }
784
- getIndicatorOutput(e) {
785
- return this.indicatorEngine.getOutput(e);
786
- }
787
- registerIndicator(e) {
788
- this.pluginManager.registerIndicator(e);
789
- }
790
- get plugins() {
791
- return this.pluginManager;
792
- }
793
- static indicators() {
794
- let e = new v();
795
- return S(e), e.getAvailableIndicators();
796
- }
797
- setPanelPosition(e, t) {
798
- this.layoutManager.setPanelPosition(e, t), this.engine.requestRender();
799
- }
800
- setPanelSize(e, t) {
801
- this.layoutManager.setPanelSize(e, t), this.updateViewportAndRender();
802
- }
803
- setDrawingTool(e) {
804
- this.features.drawings && (e && this.features.drawingTools.length > 0 && !this.features.drawingTools.includes(e) || this.drawingManager.setActiveTool(e));
805
- }
806
- getDrawingTool() {
807
- return this.drawingManager.getActiveTool();
808
- }
809
- setDrawingStyle(e) {
810
- this.drawingManager.setStyle(e);
811
- }
812
- getDrawingStyle() {
813
- return this.drawingManager.getActiveStyle();
814
- }
815
- getSelectedDrawingId() {
816
- return this.drawingManager.getSelectedDrawingId();
817
- }
818
- setSelectedDrawingStyle(e, t) {
819
- return this.drawingManager.setSelectedDrawingStyle(e, t);
820
- }
821
- getDrawings() {
822
- return this.drawingManager.getDrawings();
823
- }
824
- setDrawings(e) {
825
- this.drawingManager.setDrawings(e);
826
- }
827
- addDrawing(e) {
828
- if (!this.features.drawings) return null;
829
- let t = this.drawingManager.addDrawing(e);
830
- return this.scheduleAutoSave(), t;
831
- }
832
- autoFib() {
833
- if (!this.features.drawings) return null;
834
- let e = this.getDisplayData(), t = this.viewport.getState(), n = Qe(e, t.visibleRange.from, t.visibleRange.to);
835
- return n ? this.addDrawing({
836
- type: "fibRetracement",
837
- anchors: [n[0], n[1]]
838
- }) : null;
839
- }
840
- removeDrawing(e) {
841
- this.drawingManager.removeDrawing(e);
842
- }
843
- setDrawingVisible(e, t) {
844
- this.drawingManager.setDrawingVisible(e, t);
845
- }
846
- setDrawingLocked(e, t) {
847
- this.drawingManager.setDrawingLocked(e, t);
848
- }
849
- clearDrawings() {
850
- this.drawingManager.clearDrawings();
851
- }
852
- registerDrawingTool(e) {
853
- this.drawingManager.register(e);
854
- }
855
- undo() {
856
- return this.features.drawingUndoRedo ? this.drawingManager.undo() : !1;
857
- }
858
- redo() {
859
- return this.features.drawingUndoRedo ? this.drawingManager.redo() : !1;
860
- }
861
- getUndoRedoState() {
862
- return this.undoRedoManager.getState();
863
- }
864
- setDrawingMagnet(e) {
865
- this.drawingManager.setMagnetMode(e ? "magnet" : "none");
866
- }
867
- getDrawingMagnet() {
868
- return this.drawingManager.getMagnetMode() === "magnet";
869
- }
870
- lockAllDrawings() {
871
- this.drawingManager.lockAllDrawings();
872
- }
873
- unlockAllDrawings() {
874
- this.drawingManager.unlockAllDrawings();
875
- }
876
- hideAllDrawings() {
877
- this.drawingManager.hideAllDrawings();
878
- }
879
- showAllDrawings() {
880
- this.drawingManager.showAllDrawings();
881
- }
882
- duplicateDrawing(e) {
883
- let t = e ?? this.drawingManager.getSelectedDrawingId();
884
- return t ? this.drawingManager.duplicateDrawing(t) : null;
885
- }
886
- exportVisibleData(e = "csv", t) {
887
- let n = this.viewport.getState(), r = this.dataManager.getData(), i = Math.max(0, n.visibleRange.from), a = Math.min(r.length - 1, n.visibleRange.to), o = r.slice(i, a + 1);
888
- if (e === "json") {
889
- let e = _.toJSON(o);
890
- _.download(e, t ?? "chart-data.json", "application/json");
891
- } else {
892
- let e = _.toCSV(o);
893
- _.download(e, t ?? "chart-data.csv", "text/csv");
894
- }
895
- }
896
- exportAllData(e = "csv", t) {
897
- let n = this.dataManager.getData();
898
- if (e === "json") {
899
- let e = _.toJSON(n);
900
- _.download(e, t ?? "chart-data.json", "application/json");
901
- } else {
902
- let e = _.toCSV(n);
903
- _.download(e, t ?? "chart-data.csv", "text/csv");
904
- }
905
- }
906
- setAutoSave(e, t = 5e3) {
907
- this.autoSaveScheduler.enable(e, t);
908
- }
909
- disableAutoSave() {
910
- this.autoSaveScheduler.disable();
911
- }
912
- scheduleAutoSave() {
913
- this.autoSaveScheduler.schedule();
914
- }
915
- getAvailableIndicators() {
916
- return this.indicatorEngine.getAvailableIndicators();
917
- }
918
- getIndicatorInputs(e) {
919
- let t = this.indicatorEngine.getAvailableIndicators().find((t) => t.id === e);
920
- return t ? {
921
- id: t.id,
922
- params: t.defaultConfig
923
- } : null;
924
- }
925
- getActiveIndicators() {
926
- return this.indicatorEngine.getActiveIndicators();
927
- }
928
- setIndicatorVisible(e, t) {
929
- this.indicatorEngine.setVisible(e, t) !== null && this.updateViewportAndRender();
930
- }
931
- getIndicatorConfig(e) {
932
- let t = this.indicatorEngine.getIndicatorConfig(e);
933
- return t ? {
934
- id: t.id,
935
- params: { ...t.params }
936
- } : null;
937
- }
938
- updateIndicatorStyle(e, t) {
939
- this.indicatorEngine.updateIndicatorStyle(e, t), this.engine.requestRender();
940
- }
941
- setOrders(e) {
942
- this.features.trading && this.tradingManager.setOrders(e);
943
- }
944
- startBracket(e, t) {
945
- if (!this.features.trading) return !1;
946
- let n = this.dataManager.getData(), r = t ?? (n.length > 0 ? n[n.length - 1].close : null);
947
- return r === null ? !1 : (this.tradingManager.startBracket(e, r), !0);
948
- }
949
- cancelBracket() {
950
- this.features.trading && this.tradingManager.cancelBracket();
951
- }
952
- confirmBracket() {
953
- return this.features.trading ? this.tradingManager.confirmBracket() : !1;
954
- }
955
- isBracketActive() {
956
- return this.features.trading && this.tradingManager.isBracketActive();
957
- }
958
- startOrderDraft(e, t) {
959
- if (!this.features.trading) return !1;
960
- let n = this.dataManager.getData(), r = t ?? (n.length > 0 ? n[n.length - 1].close : null);
961
- return r === null ? !1 : (this.tradingManager.startOrderDraft(e, r), !0);
962
- }
963
- cancelOrderDraft() {
964
- this.features.trading && this.tradingManager.cancelOrderDraft();
965
- }
966
- confirmOrderDraft() {
967
- return this.features.trading ? this.tradingManager.confirmOrderDraft() : !1;
968
- }
969
- isOrderDraftActive() {
970
- return this.features.trading && this.tradingManager.isOrderDraftActive();
971
- }
972
- placeOrderIntent(e) {
973
- this.features.trading && this.eventBus.emit("orderPlace", e);
974
- }
975
- setPositions(e) {
976
- this.features.trading && this.tradingManager.setPositions(e);
977
- }
978
- setDepthData(e) {
979
- this.features.trading && this.tradingManager.setDepthData(e);
980
- }
981
- setCurrentPrice(e, t) {
982
- this.tradingManager.setCurrentPrice(e), this.currentPriceLine.setPrice(e), this.scheduleRender(), this.features.alerts && (this.alertManager.checkPrice(e), this.feedIndicatorAlerts());
983
- }
984
- feedIndicatorAlerts() {
985
- let e = this.alertManager.getAlerts(), t = this.dataManager.getData();
986
- if (t.length === 0) return;
987
- let n = t.length - 1, r = /* @__PURE__ */ new Set();
988
- for (let t of e) {
989
- if (t.channel === "price" || r.has(t.channel)) continue;
990
- r.add(t.channel);
991
- let e = t.channel.indexOf(":");
992
- if (e < 0) continue;
993
- let i = t.channel.slice(0, e), a = t.channel.slice(e + 1), o = this.indicatorEngine.getOutput(i)?.series?.[n]?.[a];
994
- typeof o == "number" && Number.isFinite(o) && this.alertManager.checkChannel(t.channel, o);
995
- }
996
- }
997
- setTradingConfig(e) {
998
- this.features.trading && this.tradingManager.setConfig(e);
999
- }
1000
- async connect(e) {
1001
- this.disconnectStream(), this.streamManager = new ze(), this.streamManager.on("snapshot", (e) => {
1002
- this.setData(e);
1003
- }), this.streamManager.on("barClose", (e) => {
1004
- let t = this.autoScrollOnNewBar && this.viewport.isAtEnd();
1005
- this.dataManager.appendBar(e);
1006
- let n = this.dataManager.getData();
1007
- this.crosshairHandler.setData(n), this.displayDataCache = null, this.indicatorEngine.recalculateFrom(n, n.length - 2), this.updateViewportAndRender(t);
1008
- }), this.streamManager.on("barUpdate", (e) => {
1009
- this.dataManager.updateLastBar(e), this.currentPriceLine.setPrice(e.close);
1010
- let t = this.dataManager.getData();
1011
- this.indicatorEngine.recalculateFrom(t, t.length - 1), this.scheduleRender();
1012
- }), this.streamManager.on("priceChange", ({ price: e, previousClose: t }) => {
1013
- this.tradingManager.setCurrentPrice(e), this.currentPriceLine.setPrice(e, t ?? void 0), this.engine.requestRender(r.Overlay);
1014
- }), this.streamManager.on("connectionChange", (e) => {
1015
- this.eventBus.emit("dataUpdate", { connection: e });
1016
- }), this.streamManager.on("error", (e) => {
1017
- this.eventBus.emit("dataUpdate", { error: e.message });
1018
- }), this.autoScrollOnNewBar = e.autoScroll !== !1, this.currentSymbol = e.symbol;
1019
- let t = this.streamManager;
1020
- if (await t.connect(e), this.streamManager !== t) return;
1021
- let n = f(e.timeframe);
1022
- this.barCountdown.setTimeframeMs(n), this.countdownInterval && clearInterval(this.countdownInterval), this.countdownInterval = setInterval(() => {
1023
- this.barCountdown.isVisible() && this.engine.requestRender(r.Hover);
1024
- }, 1e3);
1025
- }
1026
- async switchStream(e, t) {
1027
- this.streamManager && (this.currentSymbol = e, this.barCountdown.setTimeframeMs(f(t)), await this.streamManager.switchTo(e, t));
1028
- }
1029
- async setTimeframe(e) {
1030
- if (!this.streamManager) throw Error("No active stream. Call connect() first.");
1031
- await this.switchStream(this.currentSymbol, e);
1032
- }
1033
- disconnectStream() {
1034
- this.streamManager &&= (this.streamManager.dispose(), null);
1035
- }
1036
- connectExecution(e, t = {}) {
1037
- if (!this.features.trading) throw Error("connectExecution requires features.trading to be enabled");
1038
- this.disconnectExecution(), this.executionAdapter = e, this.execTeardown = wt(e, {
1039
- onIntent: (e, t) => {
1040
- let n = (e) => t(e.payload);
1041
- return this.eventBus.on(e, n), () => this.eventBus.off(e, n);
1042
- },
1043
- setOrders: (e) => this.setOrders(e),
1044
- setPositions: (e) => this.setPositions(e),
1045
- onError: (e) => this.eventBus.emit("executionError", e)
1046
- }), Promise.resolve(e.connect(t)).catch((e) => this.eventBus.emit("executionError", {
1047
- message: "Execution connect failed",
1048
- cause: e
1049
- }));
1050
- }
1051
- disconnectExecution() {
1052
- this.execTeardown &&= (this.execTeardown(), null), this.executionAdapter &&= (this.executionAdapter.disconnect(), null);
1053
- }
1054
- getExecutionAdapter() {
1055
- return this.executionAdapter;
1056
- }
1057
- setBarCountdownVisible(e) {
1058
- this.barCountdown.setVisible(e), this.engine.requestRender(r.Hover);
1059
- }
1060
- setSessionBreaksVisible(e) {
1061
- this.sessionBreaks.setVisible(e), this.engine.requestRender(r.Background);
1062
- }
1063
- addCompareSymbol(e, t, n, i) {
1064
- this.compareRenderer.addSymbol({
1065
- id: e,
1066
- label: t,
1067
- data: n,
1068
- color: i,
1069
- visible: !0
1070
- }), this.engine.requestRender(r.Main);
1071
- }
1072
- removeCompareSymbol(e) {
1073
- this.compareRenderer.removeSymbol(e), this.engine.requestRender(r.Main);
1074
- }
1075
- updateCompareData(e, t) {
1076
- this.compareRenderer.setSymbolData(e, t), this.engine.requestRender(r.Main);
1077
- }
1078
- setCompareMode(e) {
1079
- this.compareRenderer.setMode(e), this.engine.requestRender(r.Main);
1080
- }
1081
- clearCompareSymbols() {
1082
- this.compareRenderer.clear(), this.engine.requestRender(r.Main);
1083
- }
1084
- setLogScale(e) {
1085
- this.viewport.setLogScale(e), this.updateViewportAndRender();
1086
- }
1087
- isLogScale() {
1088
- return this.viewport.isLogScale();
1089
- }
1090
- setScaleMode(e) {
1091
- this.viewport.setScaleMode(e), this.updateViewportAndRender();
1092
- }
1093
- getScaleMode() {
1094
- return this.viewport.getScaleMode();
1095
- }
1096
- setSessionBreaksConfig(e) {
1097
- this.sessionBreaks.setConfig(e), this.engine.requestRender(r.Background);
1098
- }
1099
- getConnectionState() {
1100
- return this.streamManager?.getConnectionState() ?? "disconnected";
1101
- }
1102
- getConnectionInfo() {
1103
- return this.streamManager?.getConnectionInfo() ?? { state: "disconnected" };
1104
- }
1105
- setAutoScroll(e) {
1106
- this.autoScrollOnNewBar = e;
1107
- }
1108
- scrollTo(e) {
1109
- let t = this.dataManager.getData();
1110
- for (let n = 0; n < t.length; n++) if (t[n].time >= e) {
1111
- let e = this.viewport.getState().barWidth + this.viewport.getState().barSpacing;
1112
- this.viewport.scrollBy(n * e - this.viewport.getState().offset), this.updateViewportAndRender();
1113
- return;
1114
- }
1115
- }
1116
- scrollToEnd() {
1117
- this.viewport.scrollToEnd(), this.updateViewportAndRender();
1118
- }
1119
- setVisibleRange(e, t) {
1120
- let n = this.dataManager.getData();
1121
- if (n.length === 0) return;
1122
- let r = C(Math.min(e, t), n), i = C(Math.max(e, t), n);
1123
- this.viewport.zoomToBarRange(r, i), this.updateViewportAndRender();
1124
- }
1125
- setPanLimits(e) {
1126
- this.viewport.setPanLimits(e), this.updateViewportAndRender();
1127
- }
1128
- zoomIn() {
1129
- let e = this.viewport.getState().chartRect.width;
1130
- this.viewport.zoom(.2, e / 2), this.updateViewportAndRender();
1131
- }
1132
- zoomOut() {
1133
- let e = this.viewport.getState().chartRect.width;
1134
- this.viewport.zoom(-.2, e / 2), this.updateViewportAndRender();
1135
- }
1136
- fitContent() {
1137
- let e = this.dataManager.getLength();
1138
- e !== 0 && (this.viewport.zoomToBarRange(0, e - 1 + this.viewport.getRightMargin()), this.viewport.scrollToEnd(), this.updateViewportAndRender());
1139
- }
1140
- on(e, t) {
1141
- this.eventBus.on(e, t);
1142
- }
1143
- off(e, t) {
1144
- this.eventBus.off(e, t);
1145
- }
1146
- enableTauriBridge(e) {
1147
- this.eventBus.enableTauriBridge({
1148
- enabled: !0,
1149
- ...e
1150
- });
1151
- }
1152
- disableTauriBridge() {
1153
- this.eventBus.disableTauriBridge();
1154
- }
1155
- setTheme(e) {
1156
- this.themeManager.setTheme(e), this.syncRenderContext(), this.container.style.backgroundColor = this.themeManager.getTheme().background, this.engine.requestRender(), this.eventBus.emit("themeChange", { theme: e });
1157
- }
1158
- getTheme() {
1159
- return this.themeManager.getTheme();
1160
- }
1161
- setWatermark(e, t) {
1162
- this.watermark.setConfig({
1163
- text: e,
1164
- ...t
1165
- }), this.engine.requestRender(r.Background);
1166
- }
1167
- setAutoScale(e) {
1168
- this.options.autoScale = e, this.defaultAutoScale = e, this.updateViewportAndRender();
1169
- }
1170
- isAutoScale() {
1171
- return this.options.autoScale !== !1;
1172
- }
1173
- setCrosshairMode(e) {
1174
- this.crosshairHandler.setMode(e), this.engine.requestRender(r.Hover);
1175
- }
1176
- getCrosshairMode() {
1177
- return this.crosshairHandler.getMode();
1178
- }
1179
- setCrosshairPosition(e) {
1180
- e && this.crosshairHandler.onPointerMove(e), this.engine.requestRender(r.Hover);
1181
- }
1182
- getData() {
1183
- return this.dataManager.getData();
1184
- }
1185
- setGridVisible(e) {
1186
- this.gridRenderer.setVisible(e), this.engine.requestRender(r.Background);
1187
- }
1188
- isGridVisible() {
1189
- return this.gridRenderer.isVisible();
1190
- }
1191
- setVolumeVisible(e) {
1192
- this.volumeRenderer.setVisible(e), this.engine.requestRender(r.Main);
1193
- }
1194
- setVolumeProfileVisible(e) {
1195
- this.volumeProfile.setVisible(e), this.engine.requestRender(r.Main);
1196
- }
1197
- isVolumeProfileVisible() {
1198
- return this.volumeProfile.isVisible();
1199
- }
1200
- setVolumeProfileConfig(e) {
1201
- 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);
1202
- }
1203
- setMarketProfileVisible(e) {
1204
- this.marketProfile.setVisible(e), this.engine.requestRender(r.Main);
1205
- }
1206
- isMarketProfileVisible() {
1207
- return this.marketProfile.isVisible();
1208
- }
1209
- setMarketProfileConfig(e) {
1210
- 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);
1211
- }
1212
- getMarketProfileStats() {
1213
- return this.marketProfile.getStats();
1214
- }
1215
- setDepthHeatmapVisible(e) {
1216
- this.depthHeatmap.setVisible(e), this.engine.requestRender(r.Main);
1217
- }
1218
- isDepthHeatmapVisible() {
1219
- return this.depthHeatmap.isVisible();
1220
- }
1221
- setDepthHeatmapConfig(e) {
1222
- e.opacity !== void 0 && this.depthHeatmap.setOpacity(e.opacity), e.capacity !== void 0 && this.depthHeatmap.setCapacity(e.capacity), this.engine.requestRender(r.Main);
1223
- }
1224
- pushDepthSnapshot(e) {
1225
- let t = this.dataManager.getData();
1226
- t.length !== 0 && (this.depthHeatmap.push(t[t.length - 1].time, e), this.depthHeatmap.isVisible() && this.engine.requestRender(r.Main));
1227
- }
1228
- clearDepthHeatmap() {
1229
- this.depthHeatmap.clear(), this.engine.requestRender(r.Main);
1230
- }
1231
- setPeriodLevelsVisible(e) {
1232
- this.periodLevels.setVisible(e), this.engine.requestRender(r.Main);
1233
- }
1234
- isPeriodLevelsVisible() {
1235
- return this.periodLevels.isVisible();
1236
- }
1237
- setPeriodLevelsPeriod(e) {
1238
- this.periodLevels.setPeriod(e), this.engine.requestRender(r.Main);
1239
- }
1240
- setTimezoneOffset(e) {
1241
- this.timeAxis.setTimezoneOffset(e), this.crosshairHandler.setTimezoneOffset(e), this.crosshairTooltip.setTimezoneOffset(e), this.engine.requestRender(r.UI);
1242
- }
1243
- setPivotMarkersVisible(e) {
1244
- this.pivotMarkers.setVisible(e), this.engine.requestRender(r.Overlay);
1245
- }
1246
- isPivotMarkersVisible() {
1247
- return this.pivotMarkers.isVisible();
1248
- }
1249
- setPivotMarkersConfig(e) {
1250
- (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);
1251
- }
1252
- setSessionShadingVisible(e) {
1253
- this.sessionShading.setVisible(e), this.engine.requestRender(r.Background);
1254
- }
1255
- isSessionShadingVisible() {
1256
- return this.sessionShading.isVisible();
1257
- }
1258
- setSessionShadingConfig(e) {
1259
- this.sessionShading.setConfig(e), this.engine.requestRender(r.Background);
1260
- }
1261
- setTooltipVisible(e) {
1262
- e || this.crosshairTooltip.hide();
1263
- }
1264
- setLegend(e) {
1265
- this.chartLegend.setConfig(e), this.engine.requestRender(r.Hover);
1266
- }
1267
- setSymbolName(e) {
1268
- this.chartLegend.setSymbol(e), this.engine.requestRender(r.Hover);
1269
- }
1270
- setStatusText(e) {
1271
- this.chartLegend.setStatusText(e), this.engine.requestRender(r.Hover);
1272
- }
1273
- screenshot(e) {
1274
- this.features.screenshot && x.download(this.container, e, this.themeManager.getTheme().background);
1275
- }
1276
- async copyScreenshot() {
1277
- if (!this.features.screenshot) return !1;
1278
- try {
1279
- let e = await x.toBlob(this.container, this.themeManager.getTheme().background), t = globalThis.ClipboardItem;
1280
- return !e || !navigator.clipboard?.write || !t ? !1 : (await navigator.clipboard.write([new t({ "image/png": e })]), !0);
1281
- } catch {
1282
- return !1;
1283
- }
1284
- }
1285
- screenshotDataURL() {
1286
- return this.features.screenshot ? x.toDataURL(this.container, this.themeManager.getTheme().background) : null;
1287
- }
1288
- async screenshotBlob() {
1289
- return this.features.screenshot ? x.toBlob(this.container, this.themeManager.getTheme().background) : null;
1290
- }
1291
- addAlert(e, t = "crossing", n, r = "price", i) {
1292
- if (!this.features.alerts) return null;
1293
- let a = this.alertManager.addAlert(e, t, n, !1, r, i);
1294
- return this.scheduleAutoSave(), a;
1295
- }
1296
- removeAlert(e) {
1297
- this.alertManager.removeAlert(e), this.scheduleAutoSave();
1298
- }
1299
- getAlerts() {
1300
- return this.alertManager.getAlerts();
1301
- }
1302
- clearAlerts() {
1303
- this.alertManager.clearAlerts(), this.scheduleAutoSave();
1304
- }
1305
- saveAlerts(e) {
1306
- this.alertManager.saveToStorage(e);
1307
- }
1308
- loadAlerts(e) {
1309
- this.alertManager.loadFromStorage(e), this.engine.requestRender(r.Overlay);
1310
- }
1311
- addSignalMarker(e) {
1312
- return this.signalMarkerManager.addMarker(e);
1313
- }
1314
- removeSignalMarker(e) {
1315
- this.signalMarkerManager.removeMarker(e);
1316
- }
1317
- getSignalMarkers() {
1318
- return this.signalMarkerManager.getMarkers();
1319
- }
1320
- setSignalMarkers(e) {
1321
- this.signalMarkerManager.setMarkers(e);
1322
- }
1323
- clearSignalMarkers() {
1324
- this.signalMarkerManager.clearMarkers();
1325
- }
1326
- setSignalMarkerStyle(e) {
1327
- this.signalMarkerManager.setStyle(e);
1328
- }
1329
- addTradeZone(e) {
1330
- return this.tradeZoneManager.addZone(e);
1331
- }
1332
- updateTradeZone(e, t) {
1333
- this.tradeZoneManager.updateZone(e, t);
1334
- }
1335
- removeTradeZone(e) {
1336
- this.tradeZoneManager.removeZone(e);
1337
- }
1338
- getTradeZones() {
1339
- return this.tradeZoneManager.getZones();
1340
- }
1341
- setTradeZones(e) {
1342
- this.tradeZoneManager.setZones(e);
1343
- }
1344
- clearTradeZones() {
1345
- this.tradeZoneManager.clearZones();
1346
- }
1347
- setTradeZoneStyle(e) {
1348
- this.tradeZoneManager.setStyle(e);
1349
- }
1350
- replayStart(e) {
1351
- if (!this.features.replay) return;
1352
- let t = this.dataManager.getData();
1353
- this.replayManager.load(t);
1354
- let n = -1;
1355
- this.replayBarUnsub?.(), this.replayBarUnsub = this.replayManager.on("bar", ({ bar: e, index: r }) => {
1356
- let i = r + 1, a = n > 0 && i > n && this.dataManager.getLength() === n, o = !(a && !this.replaySeeking) || this.autoScrollOnNewBar && this.viewport.isAtEnd();
1357
- if (a) {
1358
- for (let e = n; e < i; e++) this.dataManager.appendBar(t[e]);
1359
- this.indicatorEngine.recalculateFrom(this.dataManager.getData(), n);
1360
- } else this.dataManager.setData(t.slice(0, i)), this.indicatorEngine.recalculateAll(this.dataManager.getData());
1361
- n = i, this.crosshairHandler.setData(this.dataManager.getData()), this.displayDataCache = null, this.updateViewportAndRender(o);
1362
- }), this.replayManager.play(e);
1363
- }
1364
- replayPause() {
1365
- this.replayManager.pause();
1366
- }
1367
- replayResume() {
1368
- this.replayManager.resume();
1369
- }
1370
- replayStop() {
1371
- this.replayManager.stop();
1372
- }
1373
- replaySeek(e) {
1374
- this.replaySeeking = !0;
1375
- try {
1376
- this.replayManager.seekTo(e);
1377
- } finally {
1378
- this.replaySeeking = !1;
1379
- }
1380
- }
1381
- setReplaySpeed(e) {
1382
- this.replayManager.setSpeed(e);
1383
- }
1384
- getReplayState() {
1385
- return this.replayManager.getState();
1386
- }
1387
- getReplayProgress() {
1388
- return this.replayManager.getProgress();
1389
- }
1390
- saveState(e) {
1391
- if (!this.features.saveLoad) return null;
1392
- let t = g.capture({
1393
- getDrawings: () => this.getDrawings(),
1394
- getTheme: () => this.getTheme(),
1395
- getAlerts: () => this.getAlerts()
1396
- }, { chartType: this.options.chartType }), n = g.serialize(t);
1397
- return e && g.saveToStorage(e, t), n;
1398
- }
1399
- loadState(e) {
1400
- if (!this.features.saveLoad) return;
1401
- let t = g.deserialize(e);
1402
- if (t.chartType && this.setChartType(t.chartType), t.drawings && this.setDrawings(t.drawings), t.theme && this.setTheme(t.theme), t.alerts) {
1403
- this.clearAlerts();
1404
- for (let e of t.alerts) this.addAlert(e.price, e.condition, e.message);
1405
- }
1406
- }
1407
- loadStateFromStorage(e) {
1408
- if (!this.features.saveLoad) return !1;
1409
- let t = g.loadFromStorage(e);
1410
- return t ? (this.loadState(g.serialize(t)), !0) : !1;
1411
- }
1412
- downloadState(e) {
1413
- if (!this.features.saveLoad) return;
1414
- let t = g.capture({
1415
- getDrawings: () => this.getDrawings(),
1416
- getTheme: () => this.getTheme(),
1417
- getAlerts: () => this.getAlerts()
1418
- }, { chartType: this.options.chartType });
1419
- g.downloadFile(t, e);
1420
- }
1421
- async loadStateFromFile() {
1422
- if (!this.features.saveLoad) return;
1423
- let e = await g.loadFromFile();
1424
- this.loadState(g.serialize(e));
1425
- }
1426
- setLocale(e) {
1427
- d(e), this.engine.requestRender();
1428
- }
1429
- setNumberLocale(e) {
1430
- this.numberLocale = e, this.priceAxis.setLocale(e), this.crosshairHandler.setLocale(e), this.chartLegend.setLocale(e), this.crosshairTooltip.setLocale(e), this.sessionBreaks.setLocale(e), this.currentPriceLine.setLocale(e), this.updateViewportAndRender();
1431
- }
1432
- getNumberLocale() {
1433
- return this.numberLocale;
1434
- }
1435
- setMarket(e) {
1436
- if (this.marketConfig = e, e.colorScheme) {
1437
- let t = {
1438
- ...this.themeManager.getTheme(),
1439
- candleUp: e.colorScheme.up,
1440
- candleDown: e.colorScheme.down,
1441
- candleUpWick: e.colorScheme.up,
1442
- candleDownWick: e.colorScheme.down,
1443
- volumeUp: e.colorScheme.up.replace(")", ", 0.3)").replace("rgb(", "rgba(") || `${e.colorScheme.up}4D`,
1444
- volumeDown: e.colorScheme.down.replace(")", ", 0.3)").replace("rgb(", "rgba(") || `${e.colorScheme.down}4D`
1445
- };
1446
- this.themeManager.setTheme(t);
1447
- }
1448
- e.pricePrecision !== void 0 && (this.tradingManager.setConfig({ pricePrecision: e.pricePrecision }), this.alertManager.setPricePrecision(e.pricePrecision), this.streamManager?.priceLine.setPricePrecision(e.pricePrecision), this.currentPriceLine.setPricePrecision(e.pricePrecision), this.crosshairHandler.setPricePrecision(e.pricePrecision), this.chartLegend.setPricePrecision(e.pricePrecision), this.crosshairTooltip.setPricePrecision(e.pricePrecision)), this.updateViewportAndRender();
1449
- }
1450
- getMarket() {
1451
- return this.marketConfig;
1452
- }
1453
- setPriceLimits(e) {
1454
- this.marketConfig && (c(e, this.marketConfig) && (this.marketConfig.priceLimits = {
1455
- ...this.marketConfig.priceLimits,
1456
- referencePrice: e
1457
- }), this.engine.requestRender());
1458
- }
1459
- getFeatures() {
1460
- return this.features;
1461
- }
1462
- setFeatures(e) {
1463
- Object.assign(this.features, e), (e.crosshair === !1 || e.crosshairTooltip === !1) && this.crosshairTooltip.hide(), e.grid !== void 0 && this.engine.requestRender(r.Background), e.volume !== void 0 && (this.volumeRenderer.setVisible(e.volume), this.engine.requestRender(r.Main)), e.drawings === !1 && this.drawingManager.setActiveTool(null), e.trading === !1 && (this.tradingManager.setOrders([]), this.tradingManager.setPositions([])), e.keyboard !== void 0 && this.keyboardHandler?.setEnabled(e.keyboard), this.engine.requestRender();
1464
- }
1465
- resize() {
1466
- let e = this.engine.dprManager.readContainerSize();
1467
- if (e.width <= 0 || e.height <= 0) return;
1468
- this.containerSizeCache = e, this.containerSizeCacheTime = Date.now();
1469
- let t = this.engine.dprManager.getDpr();
1470
- this.engine.layerManager.resize(e, t);
1471
- let n = this.viewport.isAtEnd();
1472
- this.viewport.resize(e.width, e.height), this.layoutManager.resize(e.width, e.height), this.updateViewportAndRender(n), this.eventBus.emit("resize", e);
1473
- }
1474
- destroy() {
1475
- this.countdownInterval && clearInterval(this.countdownInterval), this.disableAutoSave(), this.disconnectStream(), this.disconnectExecution(), this.onWindowKeyDown &&= (window.removeEventListener("keydown", this.onWindowKeyDown), null), this.keyboardHandler = null, this.interactionManager.detach(), this.tradingManager.destroy(), this.animator.dispose(), this.crosshairTooltip.destroy(), this.pinnedTooltip.destroy(), this.replayManager.dispose(), this.undoRedoManager.clear(), this.engine.destroy(), this.eventBus.destroy(), this.container.innerHTML = "";
1476
- }
1477
- createChartRenderer(e) {
1478
- return lt(e, (e) => this.pluginManager.getChartType(e));
1479
- }
1480
- getDisplayData() {
1481
- if (this.displayDataCache) return this.displayDataCache;
1482
- let e = this.dataManager.getData();
1483
- if (e.length === 0) return e;
1484
- let t = ut(this.options.chartType, e, (e) => this.pluginManager.getChartType(e));
1485
- return this.displayDataCache = t, t;
1486
- }
1487
- scheduleRender() {
1488
- this.renderScheduled || (this.renderScheduled = !0, requestAnimationFrame(() => {
1489
- this.renderScheduled = !1, this.applyDataToViewport(), this.fitPriceAxisWidth() && this.applyDataToViewport(), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
1490
- }));
1491
- }
1492
- applyDataToViewport(e = !1) {
1493
- let t = this.getDisplayData(), n = this.options.autoScale !== !1;
1494
- this.viewport.updateData(t, n && !e), e && (this.viewport.scrollToEnd(), n && this.viewport.updateData(t, !0));
1495
- let r = this.viewport.getState();
1496
- if (t.length > 0) {
1497
- let e = Math.max(0, Math.min(r.visibleRange.from, t.length - 1));
1498
- this.viewport.setScaleBaseline(t[e]?.close);
1499
- }
1500
- if (n) {
1501
- let e = this.indicatorEngine.getOverlayPriceRange(r.visibleRange.from, Math.min(r.visibleRange.to, t.length - 1));
1502
- if (e) {
1503
- let t = r.priceRange, n = Math.min(t.min, e.min), i = Math.max(t.max, e.max);
1504
- if (n < t.min || i > t.max) {
1505
- let e = i - n || 1;
1506
- this.viewport.setPriceRange(n - e * .02, i + e * .02);
1507
- }
1508
- }
1509
- }
1510
- return t;
1511
- }
1512
- updateViewportAndRender(e = !1) {
1513
- this.resolvedLayoutCache = null, this.panelInfoCache = null;
1514
- let t = this.getResolvedLayout();
1515
- this.viewport.setChartRect(t.mainChartRect), this.applyDataToViewport(e), this.fitPriceAxisWidth() && this.applyDataToViewport(e), this.syncRenderContext(), this.engine.requestRender(), this.emitViewportEvents();
1516
- }
1517
- fitPriceAxisWidth() {
1518
- if (!this.features.priceAxis) return !1;
1519
- let { priceRange: e } = this.viewport.getState(), t = this.themeManager.getTheme(), n = _t({
1520
- min: e.min,
1521
- max: e.max,
1522
- lastPrice: this.currentPriceLine.getPrice(),
1523
- tagPrecision: this.marketConfig?.pricePrecision ?? null,
1524
- locale: this.numberLocale,
1525
- fontFamily: t.font.family,
1526
- fontSizeSmall: t.font.sizeSmall,
1527
- measure: (e, t) => this.measureText(e, t)
1528
- }), r = vt(this.priceAxisWidth, n);
1529
- return r === this.priceAxisWidth ? !1 : (this.priceAxisWidth = r, this.layoutManager.setPriceAxisWidth(r), this.viewport.setPriceAxisWidth(r), this.resolvedLayoutCache = null, this.panelInfoCache = null, this.viewport.setChartRect(this.getResolvedLayout().mainChartRect), !0);
1530
- }
1531
- measureText(e, t) {
1532
- this.measureCtx === void 0 && (this.measureCtx = typeof document < "u" ? document.createElement("canvas").getContext("2d") : null);
1533
- let n = this.measureCtx;
1534
- return n ? (n.font = t, n.measureText(e).width) : e.length * 7;
1535
- }
1536
- emitViewportEvents() {
1537
- let e = this.viewport.getState(), t = Math.max(0, Math.floor(e.visibleRange.from)), n = Math.max(t, Math.ceil(e.visibleRange.to));
1538
- (!this.lastEmittedRange || this.lastEmittedRange.from !== t || this.lastEmittedRange.to !== n) && (this.lastEmittedRange = {
1539
- from: t,
1540
- to: n
1541
- }, this.eventBus.emit("visibleRangeChange", {
1542
- from: t,
1543
- to: n
1544
- }));
1545
- let { min: r, max: i } = e.priceRange;
1546
- (!this.lastEmittedPriceRange || this.lastEmittedPriceRange.min !== r || this.lastEmittedPriceRange.max !== i) && (this.lastEmittedPriceRange = {
1547
- min: r,
1548
- max: i
1549
- }, this.eventBus.emit("priceRangeChange", {
1550
- min: r,
1551
- max: i
1552
- })), this.lastEmittedBarWidth !== e.barWidth && (this.lastEmittedBarWidth = e.barWidth, this.eventBus.emit("zoomChange", { barWidth: e.barWidth }));
1553
- }
1554
- getResolvedLayout() {
1555
- return this.resolvedLayoutCache ||= this.layoutManager.resolve(), this.resolvedLayoutCache;
1556
- }
1557
- cachedContainerSize() {
1558
- let e = Date.now();
1559
- return (!this.containerSizeCache || e - this.containerSizeCacheTime > 500) && (this.containerSizeCache = this.engine.dprManager.getContainerSize(), this.containerSizeCacheTime = e), this.containerSizeCache;
1560
- }
1561
- buildPanelRenderInfos() {
1562
- if (this.panelInfoCache) return this.panelInfoCache;
1563
- let e = this.getResolvedLayout(), t = this.viewport.getState(), { from: n, to: r } = t.visibleRange, i = e.panels.map((e) => {
1564
- let i = dt(this.indicatorEngine.getOutput(e.config.id), n, r), a = {
1565
- x: e.rect.x,
1566
- y: e.rect.y + 20,
1567
- width: e.rect.width,
1568
- height: Math.max(0, e.rect.height - 20)
1569
- };
1570
- return {
1571
- instanceId: e.config.id,
1572
- rect: e.rect,
1573
- viewport: {
1574
- ...t,
1575
- chartRect: a,
1576
- priceRange: i
1577
- }
1578
- };
1579
- });
1580
- return this.panelInfoCache = i, i;
1581
- }
1582
- syncRenderContext() {
1583
- this.pinnedTooltip.isPinned() && this.pinnedTooltip.reposition(this.viewport.getState(), null, null, this.themeManager.getTheme());
1584
- let e = this.getResolvedLayout(), t = this.features.indicators ? this.buildPanelRenderInfos() : [], n = e.panels.filter((e) => e.config.position === "bottom").reduce((e, t) => e + t.rect.height, 0), r = e.mainChartRect.y + e.mainChartRect.height + n, i = this.getDisplayData();
1585
- this.engine.setRenderContext({
1586
- chartRenderer: this.chartRenderer,
1587
- gridRenderer: this.features.grid ? this.gridRenderer : null,
1588
- priceAxis: this.features.priceAxis ? this.priceAxis : null,
1589
- timeAxis: this.features.timeAxis ? this.timeAxis : null,
1590
- crosshairHandler: this.features.crosshair ? this.crosshairHandler : null,
1591
- indicatorEngine: this.features.indicators ? this.indicatorEngine : null,
1592
- drawingRenderer: this.features.drawings ? this.drawingRenderer : null,
1593
- tradingRenderer: this.features.trading ? this.tradingRenderer : null,
1594
- currentPriceLine: this.currentPriceLine,
1595
- chartLegend: this.features.legend ? this.chartLegend : null,
1596
- volumeRenderer: this.features.volume ? this.volumeRenderer : null,
1597
- volumeProfile: this.volumeProfile,
1598
- marketProfile: this.marketProfile,
1599
- depthHeatmap: this.depthHeatmap,
1600
- periodLevels: this.periodLevels,
1601
- pivotMarkers: this.pivotMarkers,
1602
- watermark: this.features.watermark ? this.watermark : null,
1603
- barCountdown: this.barCountdown,
1604
- sessionBreaks: this.sessionBreaks,
1605
- sessionShading: this.sessionShading,
1606
- compareRenderer: this.compareRenderer,
1607
- alertManager: this.features.alerts ? this.alertManager : null,
1608
- measureOverlay: this.measureOverlay,
1609
- selectionBoxOverlay: this.selectionBoxOverlay,
1610
- signalMarkerManager: this.signalMarkerManager,
1611
- tradeZoneManager: this.tradeZoneManager,
1612
- panels: t,
1613
- priceLimits: this.buildPriceLimits(),
1614
- timeAxisY: r,
1615
- viewport: {
1616
- ...this.viewport.getState(),
1617
- data: i
1618
- },
1619
- theme: this.themeManager.getTheme(),
1620
- data: i,
1621
- numberLocale: this.numberLocale,
1622
- renderOverlayPlugins: (e, t) => this.drawOverlayPlugins(e, t)
1623
- });
1624
- }
1625
- drawOverlayPlugins(e, t) {
1626
- let n = F(this.pluginManager.getOverlays(), t);
1627
- if (n.length === 0) return;
1628
- let r = {
1629
- viewport: this.viewport.getState(),
1630
- data: this.getDisplayData(),
1631
- theme: this.themeManager.getTheme()
1632
- };
1633
- for (let t of n) t.render(e, r);
1634
- }
1635
- buildPriceLimits() {
1636
- if (!this.marketConfig?.priceLimits?.enabled || !this.marketConfig.priceLimits.referencePrice) return null;
1637
- let e = c(this.marketConfig.priceLimits.referencePrice, this.marketConfig);
1638
- return e ? {
1639
- ...e,
1640
- colors: this.marketConfig.colorScheme ? {
1641
- ceiling: this.marketConfig.colorScheme.ceiling,
1642
- floor: this.marketConfig.colorScheme.floor,
1643
- reference: this.marketConfig.colorScheme.reference
1644
- } : void 0
1645
- } : null;
1646
- }
1647
- }, V = [
1648
- "time",
1649
- "timestamp",
1650
- "date",
1651
- "datetime",
1652
- "t"
1653
- ], H = ["open", "o"], U = ["high", "h"], W = ["low", "l"], G = ["close", "c"], K = [
1654
- "volume",
1655
- "vol",
1656
- "v"
1657
- ];
1658
- function q(e) {
1659
- let t = e.trim();
1660
- return t ? t[0] === "[" || t[0] === "{" ? Et(t) : Dt(t) : {
1661
- data: [],
1662
- rowCount: 0,
1663
- skipped: 0
1664
- };
1665
- }
1666
- function Et(e) {
1667
- let t;
1668
- try {
1669
- t = JSON.parse(e);
1670
- } catch (e) {
1671
- throw Error(`Invalid JSON: ${e.message}`);
1672
- }
1673
- if (!Array.isArray(t)) throw Error("Expected a JSON array of OHLCV rows");
1674
- let n = [], r = 0;
1675
- for (let e of t) {
1676
- let t = Array.isArray(e) ? At(e) : Y(e);
1677
- t ? n.push(t) : r++;
1678
- }
1679
- return Q(n, t.length, r);
1680
- }
1681
- function Dt(e) {
1682
- let t = e.split(/\r?\n/).filter((e) => e.trim().length > 0);
1683
- if (t.length === 0) return {
1684
- data: [],
1685
- rowCount: 0,
1686
- skipped: 0
1687
- };
1688
- let n = Ot(t[0]), r = J(t[0], n).map((e) => e.trim().toLowerCase()), i = r.some((e) => isNaN(Number(e)) && e.length > 0), a = i ? kt(r) : {
1689
- time: 0,
1690
- open: 1,
1691
- high: 2,
1692
- low: 3,
1693
- close: 4,
1694
- volume: 5
1695
- };
1696
- if (a.time < 0 || a.open < 0 || a.high < 0 || a.low < 0 || a.close < 0) throw Error("CSV is missing required column(s): time, open, high, low, close");
1697
- let o = [], s = 0;
1698
- for (let e = +!!i; e < t.length; e++) {
1699
- let r = J(t[e], n), i = Z(r[a.time]), c = X(r[a.open]), l = X(r[a.high]), u = X(r[a.low]), d = X(r[a.close]), f = a.volume >= 0 ? Number(r[a.volume]) : 0;
1700
- if (i === null || ![
1701
- c,
1702
- l,
1703
- u,
1704
- d
1705
- ].every(Number.isFinite)) {
1706
- s++;
1707
- continue;
1708
- }
1709
- o.push({
1710
- time: i,
1711
- open: c,
1712
- high: l,
1713
- low: u,
1714
- close: d,
1715
- volume: Number.isFinite(f) ? f : 0
1716
- });
1717
- }
1718
- return Q(o, t.length - +!!i, s);
1719
- }
1720
- function Ot(e) {
1721
- let t = {
1722
- ",": 0,
1723
- ";": 0,
1724
- " ": 0,
1725
- "|": 0
1726
- };
1727
- for (let n of e) n in t && t[n]++;
1728
- let n = ",", r = 0;
1729
- for (let [e, i] of Object.entries(t)) i > r && (n = e, r = i);
1730
- return n;
1731
- }
1732
- function J(e, t) {
1733
- let n = [], r = "", i = !1;
1734
- for (let a = 0; a < e.length; a++) {
1735
- let o = e[a];
1736
- o === "\"" ? i && e[a + 1] === "\"" ? (r += "\"", a++) : i = !i : o === t && !i ? (n.push(r), r = "") : r += o;
1737
- }
1738
- return n.push(r), n;
1739
- }
1740
- function kt(e) {
1741
- let t = (t) => e.findIndex((e) => t.includes(e));
1742
- return {
1743
- time: t(V),
1744
- open: t(H),
1745
- high: t(U),
1746
- low: t(W),
1747
- close: t(G),
1748
- volume: t(K)
1749
- };
1750
- }
1751
- function Y(e) {
1752
- let t = (t) => {
1753
- for (let n of t) {
1754
- if (e[n] !== void 0) return e[n];
1755
- let t = n.toUpperCase();
1756
- if (e[t] !== void 0) return e[t];
1757
- }
1758
- }, n = Z(String(t(V) ?? "")), r = Number(t(H)), i = Number(t(U)), a = Number(t(W)), o = Number(t(G)), s = Number(t(K) ?? 0);
1759
- return n === null || ![
1760
- r,
1761
- i,
1762
- a,
1763
- o
1764
- ].every(Number.isFinite) ? null : {
1765
- time: n,
1766
- open: r,
1767
- high: i,
1768
- low: a,
1769
- close: o,
1770
- volume: Number.isFinite(s) ? s : 0
1771
- };
1772
- }
1773
- function At(e) {
1774
- if (e.length < 5) return null;
1775
- let t = Z(String(e[0])), n = Number(e[1]), r = Number(e[2]), i = Number(e[3]), a = Number(e[4]), o = e.length >= 6 ? Number(e[5]) : 0;
1776
- return t === null || ![
1777
- n,
1778
- r,
1779
- i,
1780
- a
1781
- ].every(Number.isFinite) ? null : {
1782
- time: t,
1783
- open: n,
1784
- high: r,
1785
- low: i,
1786
- close: a,
1787
- volume: Number.isFinite(o) ? o : 0
1788
- };
1789
- }
1790
- function X(e) {
1791
- return e === void 0 || e.trim() === "" ? NaN : Number(e);
1792
- }
1793
- function Z(e) {
1794
- let t = e.trim();
1795
- if (!t) return null;
1796
- let n = Number(t);
1797
- if (Number.isFinite(n) && n > 0) return n < 0xe8d4a51000 ? n * 1e3 : n;
1798
- let r = Date.parse(t);
1799
- return Number.isFinite(r) ? r : null;
1800
- }
1801
- function Q(e, t, n) {
1802
- e.sort((e, t) => e.time - t.time);
1803
- let r = [];
1804
- for (let t of e) r.length > 0 && r[r.length - 1].time === t.time ? r[r.length - 1] = t : r.push(t);
1805
- return {
1806
- data: r,
1807
- rowCount: t,
1808
- skipped: n
1809
- };
1810
- }
1811
- //#endregion
1812
- //#region src/io/DragDropImporter.ts
1813
- var jt = class {
1814
- host;
1815
- overlay = null;
1816
- callbacks;
1817
- bound;
1818
- depth = 0;
1819
- constructor(e, t) {
1820
- this.host = e, this.callbacks = t, this.bound = {
1821
- dragenter: (e) => this.onDragEnter(e),
1822
- dragover: (e) => this.onDragOver(e),
1823
- dragleave: (e) => this.onDragLeave(e),
1824
- drop: (e) => this.onDrop(e)
1825
- };
1826
- }
1827
- attach() {
1828
- 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);
1829
- }
1830
- detach() {
1831
- 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();
1832
- }
1833
- onDragEnter(e) {
1834
- $(e) && (e.preventDefault(), this.depth++, this.showOverlay());
1835
- }
1836
- onDragOver(e) {
1837
- $(e) && (e.preventDefault(), e.dataTransfer && (e.dataTransfer.dropEffect = "copy"));
1838
- }
1839
- onDragLeave(e) {
1840
- $(e) && (this.depth = Math.max(0, this.depth - 1), this.depth === 0 && this.hideOverlay());
1841
- }
1842
- async onDrop(e) {
1843
- e.preventDefault(), this.depth = 0, this.hideOverlay();
1844
- let t = e.dataTransfer?.files?.[0];
1845
- if (t) try {
1846
- let e = q(await t.text());
1847
- if (e.data.length === 0) throw Error(`No valid OHLCV rows found in "${t.name}"`);
1848
- this.callbacks.onData(e.data, e, t);
1849
- } catch (e) {
1850
- this.callbacks.onError?.(e, t);
1851
- }
1852
- }
1853
- showOverlay() {
1854
- this.overlay || (this.overlay = document.createElement("div"), Object.assign(this.overlay.style, {
1855
- position: "absolute",
1856
- inset: "8px",
1857
- zIndex: "90",
1858
- pointerEvents: "none",
1859
- borderRadius: "10px",
1860
- border: "2px dashed var(--tcw-accent, #f2a93b)",
1861
- background: "rgba(79, 136, 255, 0.06)",
1862
- display: "flex",
1863
- alignItems: "center",
1864
- justifyContent: "center",
1865
- color: "var(--tcw-accent, #f2a93b)",
1866
- fontSize: "14px",
1867
- fontWeight: "600",
1868
- letterSpacing: "-0.005em",
1869
- fontFamily: "inherit",
1870
- backdropFilter: "blur(2px)"
1871
- }), 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));
1872
- }
1873
- hideOverlay() {
1874
- this.overlay?.remove(), this.overlay = null;
1875
- }
1876
- };
1877
- function $(e) {
1878
- return e.dataTransfer?.types?.includes("Files") ?? !1;
1879
- }
1880
- //#endregion
1881
- export { Ct as a, St as c, I as d, N as f, z as i, bt as l, k as m, q as n, R as o, A as p, Tt as r, xt as s, jt as t, F as u };
1882
-
1883
- //# sourceMappingURL=DragDropImporter-cURSpfUb.js.map