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