@tradecanvas/chart 0.1.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.
- package/dist/Chart.d.ts +238 -0
- package/dist/Chart.d.ts.map +1 -0
- package/dist/DataManager.d.ts +16 -0
- package/dist/DataManager.d.ts.map +1 -0
- package/dist/PaneManager.d.ts +19 -0
- package/dist/PaneManager.d.ts.map +1 -0
- package/dist/ThemeManager.d.ts +8 -0
- package/dist/ThemeManager.d.ts.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +966 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/LayoutManager.d.ts +15 -0
- package/dist/layout/LayoutManager.d.ts.map +1 -0
- package/dist/plugins/PluginManager.d.ts +8 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -0
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/package.json +39 -0
package/dist/Chart.d.ts
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { ChartOptions, ChartType, OHLCBar, DataSeries, Theme, ThemeName, ChartEventType, ChartEvent, TauriBridgeOptions, IndicatorPlugin, IndicatorDescriptor, IndicatorOutput, DrawingToolType, DrawingState, DrawingStyle, DrawingPlugin, PanelPosition, TradingOrder, TradingPosition, DepthData, TradingConfig, MarketConfig, Locale, StreamConfig, ConnectionState, ConnectionInfo, TimeFrame, FeaturesConfig } from '@tradecanvas/commons';
|
|
2
|
+
export declare class Chart {
|
|
3
|
+
static version: string;
|
|
4
|
+
private engine;
|
|
5
|
+
private viewport;
|
|
6
|
+
private dataManager;
|
|
7
|
+
private themeManager;
|
|
8
|
+
private layoutManager;
|
|
9
|
+
private pluginManager;
|
|
10
|
+
private indicatorEngine;
|
|
11
|
+
private drawingManager;
|
|
12
|
+
private drawingRenderer;
|
|
13
|
+
private tradingManager;
|
|
14
|
+
private tradingRenderer;
|
|
15
|
+
private eventBus;
|
|
16
|
+
private streamManager;
|
|
17
|
+
private autoScrollOnNewBar;
|
|
18
|
+
private displayDataCache;
|
|
19
|
+
private resolvedLayoutCache;
|
|
20
|
+
private panelInfoCache;
|
|
21
|
+
private renderScheduled;
|
|
22
|
+
private containerSizeCache;
|
|
23
|
+
private containerSizeCacheTime;
|
|
24
|
+
private chartLegend;
|
|
25
|
+
private watermark;
|
|
26
|
+
private barCountdown;
|
|
27
|
+
private sessionBreaks;
|
|
28
|
+
private compareRenderer;
|
|
29
|
+
private countdownInterval;
|
|
30
|
+
private volumeRenderer;
|
|
31
|
+
private alertManager;
|
|
32
|
+
private replayManager;
|
|
33
|
+
private undoRedoManager;
|
|
34
|
+
private autoSaveTimer;
|
|
35
|
+
private autoSaveDelay;
|
|
36
|
+
private autoSaveKey;
|
|
37
|
+
private animator;
|
|
38
|
+
private crosshairTooltip;
|
|
39
|
+
private interactionManager;
|
|
40
|
+
private crosshairHandler;
|
|
41
|
+
private chartRenderer;
|
|
42
|
+
private gridRenderer;
|
|
43
|
+
private priceAxis;
|
|
44
|
+
private timeAxis;
|
|
45
|
+
private options;
|
|
46
|
+
private features;
|
|
47
|
+
private marketConfig;
|
|
48
|
+
private container;
|
|
49
|
+
private currentPriceLine;
|
|
50
|
+
constructor(container: HTMLElement, options: ChartOptions);
|
|
51
|
+
setData(data: DataSeries): void;
|
|
52
|
+
appendBar(bar: OHLCBar): void;
|
|
53
|
+
updateLastBar(bar: OHLCBar): void;
|
|
54
|
+
/** Merge a price tick into the current last bar (convenience for live feeds) */
|
|
55
|
+
updateLastBarFromTick(tick: {
|
|
56
|
+
price: number;
|
|
57
|
+
volume?: number;
|
|
58
|
+
time: number;
|
|
59
|
+
}): void;
|
|
60
|
+
setChartType(type: ChartType): void;
|
|
61
|
+
addIndicator(id: string, params?: Record<string, number | string | boolean>, position?: PanelPosition): string | null;
|
|
62
|
+
updateIndicator(instanceId: string, params: Record<string, number | string | boolean>): void;
|
|
63
|
+
removeIndicator(instanceId: string): void;
|
|
64
|
+
getIndicatorOutput(instanceId: string): IndicatorOutput | null;
|
|
65
|
+
registerIndicator(plugin: IndicatorPlugin): void;
|
|
66
|
+
static indicators(): IndicatorDescriptor[];
|
|
67
|
+
setPanelPosition(instanceId: string, position: PanelPosition): void;
|
|
68
|
+
setPanelSize(instanceId: string, size: number): void;
|
|
69
|
+
setDrawingTool(type: DrawingToolType | null): void;
|
|
70
|
+
getDrawingTool(): DrawingToolType | null;
|
|
71
|
+
setDrawingStyle(style: Partial<DrawingStyle>): void;
|
|
72
|
+
getDrawings(): DrawingState[];
|
|
73
|
+
setDrawings(drawings: DrawingState[]): void;
|
|
74
|
+
removeDrawing(id: string): void;
|
|
75
|
+
clearDrawings(): void;
|
|
76
|
+
registerDrawingTool(plugin: DrawingPlugin): void;
|
|
77
|
+
undo(): boolean;
|
|
78
|
+
redo(): boolean;
|
|
79
|
+
getUndoRedoState(): {
|
|
80
|
+
canUndo: boolean;
|
|
81
|
+
canRedo: boolean;
|
|
82
|
+
};
|
|
83
|
+
setDrawingMagnet(enabled: boolean): void;
|
|
84
|
+
getDrawingMagnet(): boolean;
|
|
85
|
+
lockAllDrawings(): void;
|
|
86
|
+
unlockAllDrawings(): void;
|
|
87
|
+
hideAllDrawings(): void;
|
|
88
|
+
showAllDrawings(): void;
|
|
89
|
+
duplicateDrawing(id?: string): string | null;
|
|
90
|
+
exportVisibleData(format?: 'csv' | 'json', filename?: string): void;
|
|
91
|
+
exportAllData(format?: 'csv' | 'json', filename?: string): void;
|
|
92
|
+
setAutoSave(key: string, delayMs?: number): void;
|
|
93
|
+
disableAutoSave(): void;
|
|
94
|
+
private scheduleAutoSave;
|
|
95
|
+
getAvailableIndicators(): IndicatorDescriptor[];
|
|
96
|
+
getIndicatorInputs(id: string): {
|
|
97
|
+
id: string;
|
|
98
|
+
params: Record<string, unknown>;
|
|
99
|
+
} | null;
|
|
100
|
+
/** Get all active indicator instances with their current params */
|
|
101
|
+
getActiveIndicators(): {
|
|
102
|
+
instanceId: string;
|
|
103
|
+
id: string;
|
|
104
|
+
params: Record<string, unknown>;
|
|
105
|
+
descriptor: IndicatorDescriptor;
|
|
106
|
+
}[];
|
|
107
|
+
/** Get current config for a specific indicator instance */
|
|
108
|
+
getIndicatorConfig(instanceId: string): {
|
|
109
|
+
id: string;
|
|
110
|
+
params: Record<string, unknown>;
|
|
111
|
+
} | null;
|
|
112
|
+
/** Update indicator colors/line widths at runtime */
|
|
113
|
+
updateIndicatorStyle(instanceId: string, style: {
|
|
114
|
+
colors?: string[];
|
|
115
|
+
lineWidths?: number[];
|
|
116
|
+
opacity?: number;
|
|
117
|
+
}): void;
|
|
118
|
+
setOrders(orders: TradingOrder[]): void;
|
|
119
|
+
setPositions(positions: TradingPosition[]): void;
|
|
120
|
+
setDepthData(depth: DepthData | null): void;
|
|
121
|
+
setCurrentPrice(price: number): void;
|
|
122
|
+
setTradingConfig(config: Partial<TradingConfig>): void;
|
|
123
|
+
/**
|
|
124
|
+
* Connect to a real-time data source.
|
|
125
|
+
* Loads history, starts streaming, manages reconnection automatically.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* import { BinanceAdapter } from '@tradecanvas/core';
|
|
129
|
+
* chart.connect({
|
|
130
|
+
* adapter: new BinanceAdapter(),
|
|
131
|
+
* symbol: 'BTCUSDT',
|
|
132
|
+
* timeframe: '1m',
|
|
133
|
+
* });
|
|
134
|
+
*/
|
|
135
|
+
connect(config: StreamConfig): Promise<void>;
|
|
136
|
+
/**
|
|
137
|
+
* Switch symbol or timeframe on an active stream without full reconnect.
|
|
138
|
+
*/
|
|
139
|
+
switchStream(symbol: string, timeframe: TimeFrame): Promise<void>;
|
|
140
|
+
/**
|
|
141
|
+
* Disconnect the real-time stream.
|
|
142
|
+
*/
|
|
143
|
+
disconnectStream(): void;
|
|
144
|
+
setBarCountdownVisible(visible: boolean): void;
|
|
145
|
+
setSessionBreaksVisible(visible: boolean): void;
|
|
146
|
+
addCompareSymbol(id: string, label: string, data: DataSeries, color: string): void;
|
|
147
|
+
removeCompareSymbol(id: string): void;
|
|
148
|
+
updateCompareData(id: string, data: DataSeries): void;
|
|
149
|
+
setCompareMode(mode: 'percent' | 'absolute'): void;
|
|
150
|
+
clearCompareSymbols(): void;
|
|
151
|
+
setLogScale(enabled: boolean): void;
|
|
152
|
+
isLogScale(): boolean;
|
|
153
|
+
setSessionBreaksConfig(config: {
|
|
154
|
+
color?: string;
|
|
155
|
+
lineStyle?: 'solid' | 'dashed' | 'dotted';
|
|
156
|
+
lineWidth?: number;
|
|
157
|
+
}): void;
|
|
158
|
+
getConnectionState(): ConnectionState;
|
|
159
|
+
getConnectionInfo(): ConnectionInfo;
|
|
160
|
+
setAutoScroll(enabled: boolean): void;
|
|
161
|
+
scrollTo(timestamp: number): void;
|
|
162
|
+
scrollToEnd(): void;
|
|
163
|
+
setVisibleRange(fromTimestamp: number, toTimestamp: number): void;
|
|
164
|
+
zoomIn(): void;
|
|
165
|
+
zoomOut(): void;
|
|
166
|
+
fitContent(): void;
|
|
167
|
+
on(type: ChartEventType, handler: (event: ChartEvent) => void): void;
|
|
168
|
+
off(type: ChartEventType, handler: (event: ChartEvent) => void): void;
|
|
169
|
+
enableTauriBridge(options?: Partial<TauriBridgeOptions>): void;
|
|
170
|
+
disableTauriBridge(): void;
|
|
171
|
+
setTheme(themeOrName: ThemeName | Theme): void;
|
|
172
|
+
getTheme(): Theme;
|
|
173
|
+
setWatermark(text: string, opts?: {
|
|
174
|
+
color?: string;
|
|
175
|
+
fontSize?: number;
|
|
176
|
+
}): void;
|
|
177
|
+
setAutoScale(enabled: boolean): void;
|
|
178
|
+
isAutoScale(): boolean;
|
|
179
|
+
setCrosshairMode(mode: 'normal' | 'magnet' | 'hidden'): void;
|
|
180
|
+
getCrosshairMode(): string;
|
|
181
|
+
setGridVisible(visible: boolean): void;
|
|
182
|
+
isGridVisible(): boolean;
|
|
183
|
+
setVolumeVisible(visible: boolean): void;
|
|
184
|
+
setTooltipVisible(visible: boolean): void;
|
|
185
|
+
setLegend(config: Partial<import('@tradecanvas/core').LegendConfig>): void;
|
|
186
|
+
setSymbolName(symbol: string): void;
|
|
187
|
+
screenshot(filename?: string): void;
|
|
188
|
+
screenshotDataURL(): string | null;
|
|
189
|
+
screenshotBlob(): Promise<Blob | null>;
|
|
190
|
+
addAlert(price: number, condition?: import('@tradecanvas/core').AlertCondition, message?: string): string | null;
|
|
191
|
+
removeAlert(id: string): void;
|
|
192
|
+
getAlerts(): import('@tradecanvas/core').PriceAlert[];
|
|
193
|
+
clearAlerts(): void;
|
|
194
|
+
saveAlerts(key: string): void;
|
|
195
|
+
loadAlerts(key: string): void;
|
|
196
|
+
replay(config?: Partial<import('@tradecanvas/core').ReplayConfig>): void;
|
|
197
|
+
replayPause(): void;
|
|
198
|
+
replayResume(): void;
|
|
199
|
+
replayStop(): void;
|
|
200
|
+
replaySeek(index: number): void;
|
|
201
|
+
setReplaySpeed(speed: number): void;
|
|
202
|
+
getReplayState(): 'playing' | 'paused' | 'stopped';
|
|
203
|
+
getReplayProgress(): {
|
|
204
|
+
current: number;
|
|
205
|
+
total: number;
|
|
206
|
+
percent: number;
|
|
207
|
+
};
|
|
208
|
+
saveState(key?: string): string | null;
|
|
209
|
+
loadState(json: string): void;
|
|
210
|
+
loadStateFromStorage(key: string): boolean;
|
|
211
|
+
downloadState(filename?: string): void;
|
|
212
|
+
loadStateFromFile(): Promise<void>;
|
|
213
|
+
setLocale(locale: Locale): void;
|
|
214
|
+
setMarket(config: MarketConfig): void;
|
|
215
|
+
getMarket(): MarketConfig | null;
|
|
216
|
+
setPriceLimits(referencePrice: number): void;
|
|
217
|
+
/** Get the resolved feature configuration */
|
|
218
|
+
getFeatures(): Readonly<Required<FeaturesConfig>>;
|
|
219
|
+
/** Update feature flags at runtime. Only provided keys are changed. */
|
|
220
|
+
setFeatures(patch: Partial<FeaturesConfig>): void;
|
|
221
|
+
resize(): void;
|
|
222
|
+
destroy(): void;
|
|
223
|
+
private createChartRenderer;
|
|
224
|
+
/** Cached display data. Invalidated when raw data or chart type changes. */
|
|
225
|
+
private getDisplayData;
|
|
226
|
+
/** Lightweight render for streaming updates. No layout resolve, no indicator recalc. */
|
|
227
|
+
private scheduleRender;
|
|
228
|
+
/** Full update: resolve layout, update viewport, sync context, request render. */
|
|
229
|
+
private updateViewportAndRender;
|
|
230
|
+
private getResolvedLayout;
|
|
231
|
+
/** Cache container size for 500ms to avoid layout thrashing on rapid calls */
|
|
232
|
+
private cachedContainerSize;
|
|
233
|
+
private buildPanelRenderInfos;
|
|
234
|
+
private syncRenderContext;
|
|
235
|
+
private timeframeToMs;
|
|
236
|
+
private buildPriceLimits;
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=Chart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Chart.d.ts","sourceRoot":"","sources":["../src/Chart.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { OHLCBar, DataSeries } from '@tradecanvas/commons';
|
|
2
|
+
export declare class DataManager {
|
|
3
|
+
private data;
|
|
4
|
+
getData(): DataSeries;
|
|
5
|
+
setData(data: DataSeries): void;
|
|
6
|
+
appendBar(bar: OHLCBar): void;
|
|
7
|
+
updateLastBar(bar: OHLCBar): void;
|
|
8
|
+
updateLastBarFromTick(tick: {
|
|
9
|
+
price: number;
|
|
10
|
+
volume?: number;
|
|
11
|
+
time: number;
|
|
12
|
+
}): void;
|
|
13
|
+
getLength(): number;
|
|
14
|
+
clear(): void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=DataManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataManager.d.ts","sourceRoot":"","sources":["../src/DataManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AA4BhE,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAAkB;IAE9B,OAAO,IAAI,UAAU;IAIrB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAO/B,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAK7B,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAUjC,qBAAqB,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAOnF,SAAS,IAAI,MAAM;IAInB,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ViewportState, Rect } from '@tradecanvas/commons';
|
|
2
|
+
export interface PaneInfo {
|
|
3
|
+
instanceId: string;
|
|
4
|
+
height: number;
|
|
5
|
+
rect: Rect;
|
|
6
|
+
}
|
|
7
|
+
export declare class PaneManager {
|
|
8
|
+
private panels;
|
|
9
|
+
private containerWidth;
|
|
10
|
+
private containerHeight;
|
|
11
|
+
resize(width: number, height: number): void;
|
|
12
|
+
addPanel(instanceId: string, height?: number): void;
|
|
13
|
+
removePanel(instanceId: string): void;
|
|
14
|
+
getPanels(): PaneInfo[];
|
|
15
|
+
getMainChartRect(): Rect;
|
|
16
|
+
createPanelViewport(panel: PaneInfo, mainViewport: ViewportState): ViewportState;
|
|
17
|
+
private recalcLayout;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=PaneManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PaneManager.d.ts","sourceRoot":"","sources":["../src/PaneManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAGhE,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,eAAe,CAAK;IAE5B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAM3C,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,SAAuB,GAAG,IAAI;IAKjE,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAKrC,SAAS,IAAI,QAAQ,EAAE;IAIvB,gBAAgB,IAAI,IAAI;IAUxB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,GAAG,aAAa;IAQhF,OAAO,CAAC,YAAY;CAarB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Theme, ThemeName } from '@tradecanvas/commons';
|
|
2
|
+
export declare class ThemeManager {
|
|
3
|
+
private theme;
|
|
4
|
+
constructor(themeOrName?: ThemeName | Theme);
|
|
5
|
+
getTheme(): Theme;
|
|
6
|
+
setTheme(themeOrName: ThemeName | Theme): void;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=ThemeManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThemeManager.d.ts","sourceRoot":"","sources":["../src/ThemeManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAG7D,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAQ;gBAET,WAAW,CAAC,EAAE,SAAS,GAAG,KAAK;IAU3C,QAAQ,IAAI,KAAK;IAIjB,QAAQ,CAAC,WAAW,EAAE,SAAS,GAAG,KAAK,GAAG,IAAI;CAS/C"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@tradecanvas/commons`),t=require(`@tradecanvas/core`);function n(e){if(!e||typeof e.time!=`number`)return!1;let{open:t,high:n,low:r,close:i}=e;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))}function r(e){return{...e,high:Math.max(e.open,e.high,e.low,e.close),low:Math.min(e.open,e.high,e.low,e.close),volume:e.volume===void 0?0:Math.max(0,e.volume)}}var i=class{data=[];getData(){return this.data}setData(e){this.data=e.filter(n).map(r)}appendBar(e){n(e)&&this.data.push(r(e))}updateLastBar(e){if(!n(e))return;let t=r(e);if(this.data.length===0){this.data.push(t);return}this.data[this.data.length-1]=t}updateLastBarFromTick(t){this.data.length!==0&&(!isFinite(t.price)||t.price<0||t.volume!==void 0&&(!isFinite(t.volume)||t.volume<0)||(this.data[this.data.length-1]=(0,e.mergeBar)(this.data[this.data.length-1],t)))}getLength(){return this.data.length}clear(){this.data=[]}},a=class{theme;constructor(t){!t||t===`dark`?this.theme={...e.DARK_THEME}:t===`light`?this.theme={...e.LIGHT_THEME}:this.theme={...t}}getTheme(){return this.theme}setTheme(t){t===`dark`?this.theme={...e.DARK_THEME}:t===`light`?this.theme={...e.LIGHT_THEME}:this.theme={...t}}},o=200,s=80,c=class{panels=[];containerWidth=0;containerHeight=0;resize(e,t){this.containerWidth=e,this.containerHeight=t}addPanel(t,n=`bottom`,r){let i=n===`left`||n===`right`;this.panels.push({id:t,position:n,size:r??(i?o:e.DEFAULT_PANEL_HEIGHT),minSize:i?s:e.MIN_PANEL_HEIGHT,content:{type:`indicator`,indicatorInstanceId:t}})}removePanel(e){this.panels=this.panels.filter(t=>t.id!==e)}setPanelPosition(t,n){let r=this.panels.find(e=>e.id===t);if(r){let t=r.position===`left`||r.position===`right`,i=n===`left`||n===`right`;r.position=n,t!==i&&(r.size=i?o:e.DEFAULT_PANEL_HEIGHT,r.minSize=i?s:e.MIN_PANEL_HEIGHT)}}setPanelSize(e,t){let n=this.panels.find(t=>t.id===e);n&&(n.size=Math.max(n.minSize,t))}getPanels(){return this.panels}resolve(){let t=this.panels.filter(e=>e.position===`left`),n=this.panels.filter(e=>e.position===`right`),r=this.panels.filter(e=>e.position===`top`),i=this.panels.filter(e=>e.position===`bottom`),a=t.reduce((e,t)=>e+t.size,0),o=n.reduce((e,t)=>e+t.size,0),s=r.reduce((e,t)=>e+t.size,0),c=i.reduce((e,t)=>e+t.size,0),l={x:a,y:s,width:Math.max(0,this.containerWidth-a-o-e.PRICE_AXIS_WIDTH),height:Math.max(0,this.containerHeight-s-c-e.TIME_AXIS_HEIGHT)},u=[],d=[],f=0;for(let n of t)u.push({config:n,rect:{x:f,y:0,width:n.size,height:this.containerHeight-e.TIME_AXIS_HEIGHT}}),d.push({panelId:n.id,rect:{x:f+n.size-2,y:0,width:4,height:this.containerHeight},orientation:`vertical`}),f+=n.size;let p=0;for(let e of r)u.push({config:e,rect:{x:a,y:p,width:l.width,height:e.size}}),d.push({panelId:e.id,rect:{x:a,y:p+e.size-2,width:l.width,height:4},orientation:`horizontal`}),p+=e.size;p=l.y+l.height;for(let e of i)u.push({config:e,rect:{x:a,y:p,width:l.width,height:e.size}}),d.push({panelId:e.id,rect:{x:a,y:p-2,width:l.width,height:4},orientation:`horizontal`}),p+=e.size;f=a+l.width+e.PRICE_AXIS_WIDTH;for(let t of n)u.push({config:t,rect:{x:f,y:0,width:t.size,height:this.containerHeight-e.TIME_AXIS_HEIGHT}}),d.push({panelId:t.id,rect:{x:f-2,y:0,width:4,height:this.containerHeight},orientation:`vertical`}),f+=t.size;return{mainChartRect:l,panels:u,dividers:d}}getMainChartRect(){return this.resolve().mainChartRect}},l=class{constructor(e){this.indicatorEngine=e}registerIndicator(e){this.indicatorEngine.register(e)}},u=class{static version=`0.3.0`;engine;viewport;dataManager;themeManager;layoutManager;pluginManager;indicatorEngine;drawingManager;drawingRenderer;tradingManager;tradingRenderer;eventBus;streamManager=null;autoScrollOnNewBar=!0;displayDataCache=null;resolvedLayoutCache=null;panelInfoCache=null;renderScheduled=!1;containerSizeCache=null;containerSizeCacheTime=0;chartLegend;watermark;barCountdown;sessionBreaks;compareRenderer;countdownInterval=null;volumeRenderer;alertManager;replayManager;undoRedoManager;autoSaveTimer=null;autoSaveDelay=0;autoSaveKey=null;animator;crosshairTooltip;interactionManager;crosshairHandler;chartRenderer;gridRenderer;priceAxis;timeAxis;options;features;marketConfig=null;container;currentPriceLine;constructor(n,r){this.container=n,this.options=r;let o=r.features??{};this.features={drawings:o.drawings??!0,drawingTools:o.drawingTools??[],drawingMagnet:o.drawingMagnet??!0,drawingUndoRedo:o.drawingUndoRedo??!0,trading:o.trading??!0,tradingContextMenu:o.tradingContextMenu??!0,indicators:o.indicators??!0,indicatorIds:o.indicatorIds??[],panning:o.panning??!0,zooming:o.zooming??!0,crosshair:o.crosshair??!0,keyboard:o.keyboard??!0,priceAxis:o.priceAxis??!0,timeAxis:o.timeAxis??!0,grid:o.grid??r.grid?.visible??!0,legend:o.legend??!0,volume:o.volume??!0,watermark:o.watermark??!0,saveLoad:o.saveLoad??!0,screenshot:o.screenshot??!0,alerts:o.alerts??!0,replay:o.replay??!0,sessionBreaks:o.sessionBreaks??!0,barCountdown:o.barCountdown??!0,compareSymbols:o.compareSymbols??!0,dataExport:o.dataExport??!0,logScale:o.logScale??!0,timeframes:o.timeframes??[],defaultTimeframeFavorites:o.defaultTimeframeFavorites??[]},n.style.position=`relative`,n.style.overflow=`hidden`,n.tabIndex=0,n.style.outline=`none`,this.dataManager=new i,this.themeManager=new a(r.theme),this.layoutManager=new c,this.indicatorEngine=new t.IndicatorEngine,this.pluginManager=new l(this.indicatorEngine),this.eventBus=new t.EventBus,(0,t.registerBuiltInIndicators)(this.indicatorEngine),this.drawingManager=new t.DrawingManager,(0,t.registerBuiltInDrawingTools)(this.drawingManager),this.drawingRenderer=new t.DrawingRenderer(this.drawingManager),this.drawingManager.setRequestRender(()=>{this.syncRenderContext(),this.engine.requestRender(e.LayerType.Overlay),this.scheduleAutoSave()}),this.drawingManager.setEventCallback((e,t)=>{this.eventBus.emit(e,t)}),this.undoRedoManager=new t.UndoRedoManager,this.drawingManager.setUndoRedoManager(this.undoRedoManager),this.drawingManager.setDataGetter(()=>this.dataManager.getData()),this.drawingManager.setDisplayDataGetter(()=>this.getDisplayData()),r.crosshair?.mode===`magnet`&&this.drawingManager.setMagnetMode(`magnet`),this.tradingManager=new t.TradingManager,this.tradingRenderer=new t.TradingRenderer(this.tradingManager),this.tradingManager.setContainer(n),this.tradingManager.setRequestRender(()=>this.engine.requestRender(e.LayerType.Overlay)),this.tradingManager.setEventCallback((e,t)=>{this.eventBus.emit(e,t)}),this.engine=new t.RenderEngine(n);let s=this.engine.dprManager.getContainerSize();this.viewport=new t.Viewport(s.width,s.height,r.minBarSpacing??2,r.maxBarSpacing??30,r.rightMargin??5),this.layoutManager.resize(s.width,s.height),this.engine.onContainerResize=e=>{if(e.width<=0||e.height<=0)return;let t=this.viewport.isAtEnd();this.viewport.resize(e.width,e.height),this.layoutManager.resize(e.width,e.height),this.updateViewportAndRender(t)},this.chartRenderer=this.createChartRenderer(r.chartType),this.gridRenderer=new t.GridRenderer,r.grid?.visible===!1&&this.gridRenderer.setVisible(!1),this.priceAxis=new t.PriceAxis,this.timeAxis=new t.TimeAxis,this.crosshairHandler=new t.CrosshairHandler,r.crosshair?.mode&&this.crosshairHandler.setMode(r.crosshair.mode),this.crosshairHandler.setCallback((e,t)=>{if(e!==null&&t){let n=this.dataManager.getData(),r=e<n.length?n[e]:void 0;this.chartLegend.setHoverBar(r??null),r&&this.crosshairTooltip.show(t,r,this.themeManager.getTheme(),this.cachedContainerSize()),this.eventBus.emit(`crosshairMove`,{point:t,bar:r,barIndex:e})}else this.crosshairTooltip.hide(),this.chartLegend.setHoverBar(null)}),this.chartLegend=new t.ChartLegend,this.chartLegend.setChartType(r.chartType),this.watermark=new t.Watermark,r.watermark&&this.watermark.setConfig(r.watermark),this.volumeRenderer=new t.VolumeRenderer,this.barCountdown=new t.BarCountdown,this.sessionBreaks=new t.SessionBreaks,this.compareRenderer=new t.CompareRenderer,r.sessionBreaks?this.sessionBreaks.setConfig({visible:r.sessionBreaks.visible??!0,color:r.sessionBreaks.color,lineStyle:r.sessionBreaks.lineStyle,lineWidth:r.sessionBreaks.lineWidth}):r.features?.sessionBreaks!==!1&&this.sessionBreaks.setVisible(!0),r.logScale&&this.viewport.setLogScale(!0),this.animator=new t.Animator,this.crosshairTooltip=new t.CrosshairTooltip,this.crosshairTooltip.create(n),new t.KeyboardHandler({scrollBars:e=>{let t=this.viewport.getState().barWidth+this.viewport.getState().barSpacing;this.viewport.scrollBy(e*t),this.updateViewportAndRender()},zoom:e=>{let t=this.viewport.getState().chartRect.width;this.viewport.zoom(e,t/2),this.updateViewportAndRender()},goToStart:()=>{this.viewport.scrollBy(-1/0),this.updateViewportAndRender()},goToEnd:()=>{this.viewport.scrollToEnd(),this.updateViewportAndRender()},fitContent:()=>this.fitContent()}),this.currentPriceLine=new t.CurrentPriceLine,this.alertManager=new t.AlertManager,this.alertManager.setRequestRender(()=>this.engine.requestRender(e.LayerType.Overlay)),this.alertManager.on(`triggered`,e=>{this.eventBus.emit(`dataUpdate`,{alert:`triggered`,alertId:e.id,price:e.price,message:e.message})}),this.replayManager=new t.ReplayManager,this.interactionManager=new t.InteractionManager(n),this.features.panning&&this.interactionManager.setPanHandler(new t.PanHandler(e=>{this.viewport.scrollBy(e),this.updateViewportAndRender()})),this.features.zooming&&this.interactionManager.setZoomHandler(new t.ZoomHandler((e,t)=>{this.viewport.zoom(e,t),this.updateViewportAndRender()})),this.features.crosshair&&this.interactionManager.setCrosshairHandler(this.crosshairHandler),this.features.drawings&&this.interactionManager.setDrawingManager(this.drawingManager,()=>this.viewport.getState()),this.features.trading&&this.interactionManager.setTradingManager(this.tradingManager,()=>this.viewport.getState()),this.interactionManager.setOverlayDirtyCallback(()=>{this.engine.requestRender(e.LayerType.Overlay),this.layoutManager.getPanels().length>0&&this.engine.requestRender(e.LayerType.UI)}),this.interactionManager.attach(),this.syncRenderContext(),this.engine.start()}setData(e){this.dataManager.setData(e),this.crosshairHandler.setData(this.dataManager.getData()),this.displayDataCache=null,this.sessionBreaks.invalidateCache(),this.indicatorEngine.recalculateAll(this.dataManager.getData()),e.length>0&&this.currentPriceLine.setPrice(e[e.length-1].close),this.updateViewportAndRender(!0),this.eventBus.emit(`dataUpdate`,{length:e.length})}appendBar(e){this.dataManager.appendBar(e),this.crosshairHandler.setData(this.dataManager.getData()),this.displayDataCache=null,this.autoScrollOnNewBar&&this.viewport.scrollToEnd(),this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.updateViewportAndRender()}updateLastBar(e){this.dataManager.updateLastBar(e),this.currentPriceLine.setPrice(e.close),this.options.chartType!==`candlestick`&&this.options.chartType!==`line`&&this.options.chartType!==`area`&&this.options.chartType!==`bar`&&this.options.chartType!==`hollowCandle`&&(this.displayDataCache=null),this.scheduleRender()}updateLastBarFromTick(e){this.dataManager.updateLastBarFromTick(e),this.currentPriceLine.setPrice(e.price),this.options.chartType!==`candlestick`&&this.options.chartType!==`line`&&this.options.chartType!==`area`&&this.options.chartType!==`bar`&&this.options.chartType!==`hollowCandle`&&(this.displayDataCache=null),this.scheduleRender()}setChartType(e){this.options.chartType=e,this.chartRenderer=this.createChartRenderer(e),this.chartLegend.setChartType(e),this.displayDataCache=null,this.updateViewportAndRender(!0)}addIndicator(e,t={},n=`bottom`){if(!this.features.indicators||this.features.indicatorIds.length>0&&!this.features.indicatorIds.includes(e))return null;let r=this.indicatorEngine.addIndicator(e,t,this.dataManager.getData());return this.indicatorEngine.getAvailableIndicators().find(t=>t.id===e)?.placement===`panel`&&this.layoutManager.addPanel(r,n),this.eventBus.emit(`indicatorAdd`,{instanceId:r,id:e}),this.engine.requestRender(),r}updateIndicator(e,t){this.indicatorEngine.updateIndicator(e,t,this.dataManager.getData()),this.engine.requestRender()}removeIndicator(e){this.indicatorEngine.removeIndicator(e),this.layoutManager.removePanel(e),this.eventBus.emit(`indicatorRemove`,{instanceId:e}),this.engine.requestRender()}getIndicatorOutput(e){return this.indicatorEngine.getOutput(e)}registerIndicator(e){this.pluginManager.registerIndicator(e)}static indicators(){let e=new t.IndicatorEngine;return(0,t.registerBuiltInIndicators)(e),e.getAvailableIndicators()}setPanelPosition(e,t){this.layoutManager.setPanelPosition(e,t),this.engine.requestRender()}setPanelSize(e,t){this.layoutManager.setPanelSize(e,t),this.engine.requestRender()}setDrawingTool(e){this.features.drawings&&(e&&this.features.drawingTools.length>0&&!this.features.drawingTools.includes(e)||this.drawingManager.setActiveTool(e))}getDrawingTool(){return this.drawingManager.getActiveTool()}setDrawingStyle(e){this.drawingManager.setStyle(e)}getDrawings(){return this.drawingManager.getDrawings()}setDrawings(e){this.drawingManager.setDrawings(e)}removeDrawing(e){this.drawingManager.removeDrawing(e)}clearDrawings(){this.drawingManager.clearDrawings()}registerDrawingTool(e){this.drawingManager.register(e)}undo(){return this.features.drawingUndoRedo?this.drawingManager.undo():!1}redo(){return this.features.drawingUndoRedo?this.drawingManager.redo():!1}getUndoRedoState(){return this.undoRedoManager.getState()}setDrawingMagnet(e){this.drawingManager.setMagnetMode(e?`magnet`:`none`)}getDrawingMagnet(){return this.drawingManager.getMagnetMode()===`magnet`}lockAllDrawings(){this.drawingManager.lockAllDrawings()}unlockAllDrawings(){this.drawingManager.unlockAllDrawings()}hideAllDrawings(){this.drawingManager.hideAllDrawings()}showAllDrawings(){this.drawingManager.showAllDrawings()}duplicateDrawing(e){let t=e??this.drawingManager.getSelectedDrawingId();return t?this.drawingManager.duplicateDrawing(t):null}exportVisibleData(e=`csv`,n){let r=this.viewport.getState(),i=this.dataManager.getData(),a=Math.max(0,r.visibleRange.from),o=Math.min(i.length-1,r.visibleRange.to),s=i.slice(a,o+1);if(e===`json`){let e=t.DataExporter.toJSON(s);t.DataExporter.download(e,n??`chart-data.json`,`application/json`)}else{let e=t.DataExporter.toCSV(s);t.DataExporter.download(e,n??`chart-data.csv`,`text/csv`)}}exportAllData(e=`csv`,n){let r=this.dataManager.getData();if(e===`json`){let e=t.DataExporter.toJSON(r);t.DataExporter.download(e,n??`chart-data.json`,`application/json`)}else{let e=t.DataExporter.toCSV(r);t.DataExporter.download(e,n??`chart-data.csv`,`text/csv`)}}setAutoSave(e,t=5e3){this.autoSaveKey=e,this.autoSaveDelay=t}disableAutoSave(){this.autoSaveDelay=0,this.autoSaveKey=null,this.autoSaveTimer&&=(clearTimeout(this.autoSaveTimer),null)}scheduleAutoSave(){this.autoSaveDelay<=0||!this.autoSaveKey||(this.autoSaveTimer&&clearTimeout(this.autoSaveTimer),this.autoSaveTimer=setTimeout(()=>{this.autoSaveTimer=null,this.autoSaveKey&&this.saveState(this.autoSaveKey)},this.autoSaveDelay))}getAvailableIndicators(){return this.indicatorEngine.getAvailableIndicators()}getIndicatorInputs(e){let t=this.indicatorEngine.getAvailableIndicators().find(t=>t.id===e);return t?{id:t.id,params:t.defaultConfig}:null}getActiveIndicators(){return this.indicatorEngine.getActiveIndicators()}getIndicatorConfig(e){let t=this.indicatorEngine.getIndicatorConfig(e);return t?{id:t.id,params:{...t.params}}:null}updateIndicatorStyle(e,t){this.indicatorEngine.updateIndicatorStyle(e,t),this.engine.requestRender()}setOrders(e){this.features.trading&&this.tradingManager.setOrders(e)}setPositions(e){this.features.trading&&this.tradingManager.setPositions(e)}setDepthData(e){this.features.trading&&this.tradingManager.setDepthData(e)}setCurrentPrice(e){this.tradingManager.setCurrentPrice(e),this.currentPriceLine.setPrice(e),this.scheduleRender(),this.features.alerts&&this.alertManager.checkPrice(e)}setTradingConfig(e){this.features.trading&&this.tradingManager.setConfig(e)}async connect(n){this.disconnectStream(),this.streamManager=new t.StreamManager,this.streamManager.on(`snapshot`,e=>{this.setData(e)}),this.streamManager.on(`barClose`,e=>{this.dataManager.appendBar(e),this.crosshairHandler.setData(this.dataManager.getData()),this.autoScrollOnNewBar&&this.viewport.scrollToEnd(),this.indicatorEngine.recalculateAll(this.dataManager.getData()),this.updateViewportAndRender()}),this.streamManager.on(`barUpdate`,e=>{this.dataManager.updateLastBar(e),this.currentPriceLine.setPrice(e.close),this.scheduleRender()}),this.streamManager.on(`priceChange`,({price:t})=>{this.tradingManager.setCurrentPrice(t),this.currentPriceLine.setPrice(t),this.engine.requestRender(e.LayerType.Overlay),this.engine.requestRender(e.LayerType.UI)}),this.streamManager.on(`connectionChange`,e=>{this.eventBus.emit(`dataUpdate`,{connection:e})}),this.streamManager.on(`error`,e=>{this.eventBus.emit(`dataUpdate`,{error:e.message})}),this.autoScrollOnNewBar=n.autoScroll!==!1,await this.streamManager.connect(n);let r=this.timeframeToMs(n.timeframe);this.barCountdown.setTimeframeMs(r),this.countdownInterval&&clearInterval(this.countdownInterval),this.countdownInterval=setInterval(()=>{this.barCountdown.isVisible()&&this.engine.requestRender(e.LayerType.UI)},1e3)}async switchStream(e,t){this.streamManager&&await this.streamManager.switchTo(e,t)}disconnectStream(){this.streamManager&&=(this.streamManager.dispose(),null)}setBarCountdownVisible(t){this.barCountdown.setVisible(t),this.engine.requestRender(e.LayerType.UI)}setSessionBreaksVisible(t){this.sessionBreaks.setVisible(t),this.engine.requestRender(e.LayerType.Background)}addCompareSymbol(t,n,r,i){this.compareRenderer.addSymbol({id:t,label:n,data:r,color:i,visible:!0}),this.engine.requestRender(e.LayerType.Main)}removeCompareSymbol(t){this.compareRenderer.removeSymbol(t),this.engine.requestRender(e.LayerType.Main)}updateCompareData(t,n){this.compareRenderer.setSymbolData(t,n),this.engine.requestRender(e.LayerType.Main)}setCompareMode(t){this.compareRenderer.setMode(t),this.engine.requestRender(e.LayerType.Main)}clearCompareSymbols(){this.compareRenderer.clear(),this.engine.requestRender(e.LayerType.Main)}setLogScale(e){this.viewport.setLogScale(e),this.updateViewportAndRender()}isLogScale(){return this.viewport.isLogScale()}setSessionBreaksConfig(t){this.sessionBreaks.setConfig(t),this.engine.requestRender(e.LayerType.Background)}getConnectionState(){return this.streamManager?.getConnectionState()??`disconnected`}getConnectionInfo(){return this.streamManager?.getConnectionInfo()??{state:`disconnected`}}setAutoScroll(e){this.autoScrollOnNewBar=e}scrollTo(e){let t=this.dataManager.getData();for(let n=0;n<t.length;n++)if(t[n].time>=e){let e=this.viewport.getState().barWidth+this.viewport.getState().barSpacing;this.viewport.scrollBy(n*e-this.viewport.getState().offset),this.updateViewportAndRender();return}}scrollToEnd(){this.viewport.scrollToEnd(),this.updateViewportAndRender()}setVisibleRange(e,t){let n=this.dataManager.getData(),r=0,i=n.length-1;for(let t=0;t<n.length;t++)if(n[t].time>=e){r=t;break}for(let e=n.length-1;e>=0;e--)if(n[e].time<=t){i=e;break}let a=i-r+1;if(a>0){let e=this.viewport.getState().chartRect.width,t=e/a,n=Math.max(2,t-this.viewport.getState().barSpacing);this.viewport.zoom((n-this.viewport.getState().barWidth)/this.viewport.getState().barWidth,e/2)}this.updateViewportAndRender()}zoomIn(){let e=this.viewport.getState().chartRect.width;this.viewport.zoom(.2,e/2),this.updateViewportAndRender()}zoomOut(){let e=this.viewport.getState().chartRect.width;this.viewport.zoom(-.2,e/2),this.updateViewportAndRender()}fitContent(){let e=this.dataManager.getData();e.length!==0&&this.setVisibleRange(e[0].time,e[e.length-1].time)}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}enableTauriBridge(e){this.eventBus.enableTauriBridge({enabled:!0,...e})}disableTauriBridge(){this.eventBus.disableTauriBridge()}setTheme(e){this.themeManager.setTheme(e),this.syncRenderContext(),this.container.style.backgroundColor=this.themeManager.getTheme().background,this.engine.requestRender(),this.eventBus.emit(`themeChange`,{theme:e})}getTheme(){return this.themeManager.getTheme()}setWatermark(t,n){this.watermark.setConfig({text:t,...n}),this.engine.requestRender(e.LayerType.Background)}setAutoScale(e){this.options.autoScale=e,this.updateViewportAndRender()}isAutoScale(){return this.options.autoScale!==!1}setCrosshairMode(t){this.crosshairHandler.setMode(t),this.engine.requestRender(e.LayerType.Overlay)}getCrosshairMode(){return this.crosshairHandler.getMode()}setGridVisible(t){this.gridRenderer.setVisible(t),this.engine.requestRender(e.LayerType.Background)}isGridVisible(){return this.gridRenderer.isVisible()}setVolumeVisible(t){this.volumeRenderer.setVisible(t),this.engine.requestRender(e.LayerType.Main)}setTooltipVisible(e){e||this.crosshairTooltip.hide()}setLegend(t){this.chartLegend.setConfig(t),this.engine.requestRender(e.LayerType.UI)}setSymbolName(t){this.chartLegend.setSymbol(t),this.engine.requestRender(e.LayerType.UI)}screenshot(e){this.features.screenshot&&t.Screenshot.download(this.container,e,this.themeManager.getTheme().background)}screenshotDataURL(){return this.features.screenshot?t.Screenshot.toDataURL(this.container,this.themeManager.getTheme().background):null}async screenshotBlob(){return this.features.screenshot?t.Screenshot.toBlob(this.container,this.themeManager.getTheme().background):null}addAlert(e,t=`crossing`,n){if(!this.features.alerts)return null;let r=this.alertManager.addAlert(e,t,n);return this.scheduleAutoSave(),r}removeAlert(e){this.alertManager.removeAlert(e),this.scheduleAutoSave()}getAlerts(){return this.alertManager.getAlerts()}clearAlerts(){this.alertManager.clearAlerts(),this.scheduleAutoSave()}saveAlerts(e){this.alertManager.saveToStorage(e)}loadAlerts(t){this.alertManager.loadFromStorage(t),this.engine.requestRender(e.LayerType.Overlay)}replay(e){if(!this.features.replay)return;let t=this.dataManager.getData();this.replayManager.load(t),this.replayManager.on(`bar`,({bar:e,index:n})=>{let r=t.slice(0,n+1);this.dataManager.setData(r),this.crosshairHandler.setData(r),this.indicatorEngine.recalculateAll(r),this.updateViewportAndRender()}),this.replayManager.play(e)}replayPause(){this.replayManager.pause()}replayResume(){this.replayManager.resume()}replayStop(){this.replayManager.stop()}replaySeek(e){this.replayManager.seekTo(e)}setReplaySpeed(e){this.replayManager.setSpeed(e)}getReplayState(){return this.replayManager.getState()}getReplayProgress(){return this.replayManager.getProgress()}saveState(e){if(!this.features.saveLoad)return null;let n=t.ChartStateManager.capture({getDrawings:()=>this.getDrawings(),getTheme:()=>this.getTheme(),getAlerts:()=>this.getAlerts()},{chartType:this.options.chartType}),r=t.ChartStateManager.serialize(n);return e&&t.ChartStateManager.saveToStorage(e,n),r}loadState(e){if(!this.features.saveLoad)return;let n=t.ChartStateManager.deserialize(e);if(n.chartType&&this.setChartType(n.chartType),n.drawings&&this.setDrawings(n.drawings),n.theme&&this.setTheme(n.theme),n.alerts){this.clearAlerts();for(let e of n.alerts)this.addAlert(e.price,e.condition,e.message)}}loadStateFromStorage(e){if(!this.features.saveLoad)return!1;let n=t.ChartStateManager.loadFromStorage(e);return n?(this.loadState(t.ChartStateManager.serialize(n)),!0):!1}downloadState(e){if(!this.features.saveLoad)return;let n=t.ChartStateManager.capture({getDrawings:()=>this.getDrawings(),getTheme:()=>this.getTheme(),getAlerts:()=>this.getAlerts()},{chartType:this.options.chartType});t.ChartStateManager.downloadFile(n,e)}async loadStateFromFile(){if(!this.features.saveLoad)return;let e=await t.ChartStateManager.loadFromFile();this.loadState(t.ChartStateManager.serialize(e))}setLocale(t){(0,e.setLocale)(t),this.engine.requestRender()}setMarket(e){if(this.marketConfig=e,e.colorScheme){let t={...this.themeManager.getTheme(),candleUp:e.colorScheme.up,candleDown:e.colorScheme.down,candleUpWick:e.colorScheme.up,candleDownWick:e.colorScheme.down,volumeUp:e.colorScheme.up.replace(`)`,`, 0.3)`).replace(`rgb(`,`rgba(`)||`${e.colorScheme.up}4D`,volumeDown:e.colorScheme.down.replace(`)`,`, 0.3)`).replace(`rgb(`,`rgba(`)||`${e.colorScheme.down}4D`};this.themeManager.setTheme(t)}e.pricePrecision!==void 0&&(this.tradingManager.setConfig({pricePrecision:e.pricePrecision}),this.alertManager.setPricePrecision(e.pricePrecision),this.streamManager?.priceLine.setPricePrecision(e.pricePrecision),this.crosshairHandler.setPricePrecision(e.pricePrecision)),this.syncRenderContext(),this.engine.requestRender()}getMarket(){return this.marketConfig}setPriceLimits(t){this.marketConfig&&((0,e.computePriceLimits)(t,this.marketConfig)&&(this.marketConfig.priceLimits={...this.marketConfig.priceLimits,referencePrice:t}),this.engine.requestRender())}getFeatures(){return this.features}setFeatures(t){Object.assign(this.features,t),t.crosshair===!1&&this.crosshairTooltip.hide(),t.grid!==void 0&&this.engine.requestRender(e.LayerType.Background),t.volume!==void 0&&(this.volumeRenderer.setVisible(t.volume),this.engine.requestRender(e.LayerType.Main)),t.drawings===!1&&this.drawingManager.setActiveTool(null),t.trading===!1&&(this.tradingManager.setOrders([]),this.tradingManager.setPositions([])),this.engine.requestRender()}resize(){let e=this.engine.dprManager.readContainerSize();if(e.width<=0||e.height<=0)return;this.containerSizeCache=e,this.containerSizeCacheTime=Date.now();let t=this.engine.dprManager.getDpr();this.engine.layerManager.resize(e,t);let n=this.viewport.isAtEnd();this.viewport.resize(e.width,e.height),this.layoutManager.resize(e.width,e.height),this.updateViewportAndRender(n),this.eventBus.emit(`resize`,e)}destroy(){this.countdownInterval&&clearInterval(this.countdownInterval),this.disableAutoSave(),this.disconnectStream(),this.interactionManager.detach(),this.tradingManager.destroy(),this.animator.dispose(),this.crosshairTooltip.destroy(),this.replayManager.dispose(),this.undoRedoManager.clear(),this.engine.destroy(),this.eventBus.destroy(),this.container.innerHTML=``}createChartRenderer(e){switch(e){case`candlestick`:return new t.CandlestickRenderer;case`heikinAshi`:return new t.CandlestickRenderer;case`line`:return new t.LineRenderer;case`area`:return new t.AreaRenderer;case`bar`:return new t.BarRenderer;case`hollowCandle`:return new t.HollowCandleRenderer;case`baseline`:return new t.BaselineRenderer;case`renko`:return new t.RenkoRenderer;case`lineBreak`:return new t.CandlestickRenderer;case`kagi`:return new t.KagiRenderer;case`pointAndFigure`:return new t.PointAndFigureRenderer;default:return new t.CandlestickRenderer}}getDisplayData(){if(this.displayDataCache)return this.displayDataCache;let e=this.dataManager.getData();if(e.length===0)return e;let n;switch(this.options.chartType){case`heikinAshi`:n=(0,t.toHeikinAshi)(e);break;case`renko`:n=(0,t.toRenko)(e,{brickSize:0,useATR:!0,atrPeriod:14});break;case`lineBreak`:n=(0,t.toLineBreak)(e,3);break;case`kagi`:n=(0,t.toKagi)(e,4);break;case`pointAndFigure`:n=(0,t.toPointAndFigure)(e,e.reduce((e,t)=>e+t.close,0)/e.length*.01,3);break;default:n=e}return this.displayDataCache=n,n}scheduleRender(){this.renderScheduled||(this.renderScheduled=!0,requestAnimationFrame(()=>{this.renderScheduled=!1;let e=this.getDisplayData();this.viewport.updateData(e,this.options.autoScale!==!1),this.syncRenderContext(),this.engine.requestRender()}))}updateViewportAndRender(e=!1){this.resolvedLayoutCache=null,this.panelInfoCache=null;let t=this.getResolvedLayout();this.viewport.setChartRect(t.mainChartRect);let n=this.getDisplayData();this.viewport.updateData(n,this.options.autoScale!==!1),e&&this.viewport.scrollToEnd(),this.syncRenderContext(),this.engine.requestRender()}getResolvedLayout(){return this.resolvedLayoutCache||=this.layoutManager.resolve(),this.resolvedLayoutCache}cachedContainerSize(){let e=Date.now();return(!this.containerSizeCache||e-this.containerSizeCacheTime>500)&&(this.containerSizeCache=this.engine.dprManager.getContainerSize(),this.containerSizeCacheTime=e),this.containerSizeCache}buildPanelRenderInfos(){if(this.panelInfoCache)return this.panelInfoCache;let e=this.getResolvedLayout(),t=this.viewport.getState(),n=e.panels.map(e=>{let n=this.indicatorEngine.getOutput(e.config.id),r=0,i=100;if(n){let e=1/0,a=-1/0,{from:o,to:s}=t.visibleRange,c=0;for(let[,t]of n.values){if(c>=o&&c<=s)for(let n in t){let r=t[n];r!==void 0&&(r<e&&(e=r),r>a&&(a=r))}c++}if(e!==1/0){let t=a-e||1;r=e-t*.1,i=a+t*.1}}let a={x:e.rect.x,y:e.rect.y+20,width:e.rect.width,height:Math.max(0,e.rect.height-20)};return{instanceId:e.config.id,rect:e.rect,viewport:{...t,chartRect:a,priceRange:{min:r,max:i}}}});return this.panelInfoCache=n,n}syncRenderContext(){let e=this.getResolvedLayout(),t=this.features.indicators?this.buildPanelRenderInfos():[],n=e.panels.filter(e=>e.config.position===`bottom`).reduce((e,t)=>e+t.rect.height,0),r=e.mainChartRect.y+e.mainChartRect.height+n;this.engine.setRenderContext({chartRenderer:this.chartRenderer,gridRenderer:this.features.grid?this.gridRenderer:null,priceAxis:this.features.priceAxis?this.priceAxis:null,timeAxis:this.features.timeAxis?this.timeAxis:null,crosshairHandler:this.features.crosshair?this.crosshairHandler:null,indicatorEngine:this.features.indicators?this.indicatorEngine:null,drawingRenderer:this.features.drawings?this.drawingRenderer:null,tradingRenderer:this.features.trading?this.tradingRenderer:null,currentPriceLine:this.streamManager?.priceLine??this.currentPriceLine,chartLegend:this.features.legend?this.chartLegend:null,volumeRenderer:this.features.volume?this.volumeRenderer:null,watermark:this.features.watermark?this.watermark:null,barCountdown:this.barCountdown,sessionBreaks:this.sessionBreaks,compareRenderer:this.compareRenderer,panels:t,priceLimits:this.buildPriceLimits(),timeAxisY:r,viewport:this.viewport.getState(),theme:this.themeManager.getTheme(),data:this.getDisplayData()})}timeframeToMs(e){let t=e.match(/^(\d+)([smhdwMy])$/);if(!t)return 0;let n=parseInt(t[1],10);switch(t[2]){case`s`:return n*1e3;case`m`:return n*6e4;case`h`:return n*36e5;case`d`:return n*864e5;case`w`:return n*6048e5;case`M`:return n*2592e6;default:return 0}}buildPriceLimits(){if(!this.marketConfig?.priceLimits?.enabled||!this.marketConfig.priceLimits.referencePrice)return null;let t=(0,e.computePriceLimits)(this.marketConfig.priceLimits.referencePrice,this.marketConfig);return t?{...t,colors:this.marketConfig.colorScheme?{ceiling:this.marketConfig.colorScheme.ceiling,floor:this.marketConfig.colorScheme.floor,reference:this.marketConfig.colorScheme.reference}:void 0}:null}};Object.defineProperty(exports,`AlertManager`,{enumerable:!0,get:function(){return t.AlertManager}}),Object.defineProperty(exports,`Animator`,{enumerable:!0,get:function(){return t.Animator}}),Object.defineProperty(exports,`BarCountdown`,{enumerable:!0,get:function(){return t.BarCountdown}}),Object.defineProperty(exports,`BinanceAdapter`,{enumerable:!0,get:function(){return t.BinanceAdapter}}),exports.Chart=u,Object.defineProperty(exports,`ChartLegend`,{enumerable:!0,get:function(){return t.ChartLegend}}),Object.defineProperty(exports,`ChartStateManager`,{enumerable:!0,get:function(){return t.ChartStateManager}}),Object.defineProperty(exports,`CompareRenderer`,{enumerable:!0,get:function(){return t.CompareRenderer}}),Object.defineProperty(exports,`CrosshairTooltip`,{enumerable:!0,get:function(){return t.CrosshairTooltip}}),Object.defineProperty(exports,`CurrentPriceLine`,{enumerable:!0,get:function(){return t.CurrentPriceLine}}),Object.defineProperty(exports,`DARK_THEME`,{enumerable:!0,get:function(){return e.DARK_THEME}}),Object.defineProperty(exports,`DEFAULT_DRAWING_STYLE`,{enumerable:!0,get:function(){return e.DEFAULT_DRAWING_STYLE}}),Object.defineProperty(exports,`DEFAULT_LEGEND_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_LEGEND_CONFIG}}),Object.defineProperty(exports,`DEFAULT_RECONNECT`,{enumerable:!0,get:function(){return e.DEFAULT_RECONNECT}}),Object.defineProperty(exports,`DEFAULT_STREAM_CONFIG`,{enumerable:!0,get:function(){return e.DEFAULT_STREAM_CONFIG}}),Object.defineProperty(exports,`DEFAULT_TIMEFRAME_FAVORITES`,{enumerable:!0,get:function(){return e.DEFAULT_TIMEFRAME_FAVORITES}}),Object.defineProperty(exports,`DEFAULT_TRADING_CONFIG`,{enumerable:!0,get:function(){return e.DEFAULT_TRADING_CONFIG}}),Object.defineProperty(exports,`DataExporter`,{enumerable:!0,get:function(){return t.DataExporter}}),exports.DataManager=i,Object.defineProperty(exports,`DrawingBase`,{enumerable:!0,get:function(){return t.DrawingBase}}),Object.defineProperty(exports,`Easing`,{enumerable:!0,get:function(){return t.Easing}}),Object.defineProperty(exports,`IndicatorBase`,{enumerable:!0,get:function(){return t.IndicatorBase}}),Object.defineProperty(exports,`KeyboardHandler`,{enumerable:!0,get:function(){return t.KeyboardHandler}}),Object.defineProperty(exports,`LIGHT_THEME`,{enumerable:!0,get:function(){return e.LIGHT_THEME}}),exports.LayoutManager=c,Object.defineProperty(exports,`MARKET_CRYPTO`,{enumerable:!0,get:function(){return e.MARKET_CRYPTO}}),Object.defineProperty(exports,`MARKET_HNX`,{enumerable:!0,get:function(){return e.MARKET_HNX}}),Object.defineProperty(exports,`MARKET_HOSE`,{enumerable:!0,get:function(){return e.MARKET_HOSE}}),Object.defineProperty(exports,`MARKET_NYSE`,{enumerable:!0,get:function(){return e.MARKET_NYSE}}),Object.defineProperty(exports,`MARKET_UPCOM`,{enumerable:!0,get:function(){return e.MARKET_UPCOM}}),Object.defineProperty(exports,`MockAdapter`,{enumerable:!0,get:function(){return t.MockAdapter}}),exports.PluginManager=l,Object.defineProperty(exports,`ReplayManager`,{enumerable:!0,get:function(){return t.ReplayManager}}),Object.defineProperty(exports,`Screenshot`,{enumerable:!0,get:function(){return t.Screenshot}}),Object.defineProperty(exports,`SessionBreaks`,{enumerable:!0,get:function(){return t.SessionBreaks}}),Object.defineProperty(exports,`StreamManager`,{enumerable:!0,get:function(){return t.StreamManager}}),Object.defineProperty(exports,`TIMEFRAMES_CRYPTO`,{enumerable:!0,get:function(){return e.TIMEFRAMES_CRYPTO}}),Object.defineProperty(exports,`TIMEFRAMES_FOREX`,{enumerable:!0,get:function(){return e.TIMEFRAMES_FOREX}}),Object.defineProperty(exports,`TIMEFRAMES_STOCK`,{enumerable:!0,get:function(){return e.TIMEFRAMES_STOCK}}),exports.ThemeManager=a,Object.defineProperty(exports,`TickAggregator`,{enumerable:!0,get:function(){return t.TickAggregator}}),Object.defineProperty(exports,`UndoRedoManager`,{enumerable:!0,get:function(){return t.UndoRedoManager}}),Object.defineProperty(exports,`VN_COLORS`,{enumerable:!0,get:function(){return e.VN_COLORS}}),Object.defineProperty(exports,`VolumeRenderer`,{enumerable:!0,get:function(){return t.VolumeRenderer}}),Object.defineProperty(exports,`Watermark`,{enumerable:!0,get:function(){return t.Watermark}}),Object.defineProperty(exports,`computePriceLimits`,{enumerable:!0,get:function(){return e.computePriceLimits}}),Object.defineProperty(exports,`createVNTheme`,{enumerable:!0,get:function(){return e.createVNTheme}}),Object.defineProperty(exports,`formatNumber`,{enumerable:!0,get:function(){return e.formatNumber}}),Object.defineProperty(exports,`formatVND`,{enumerable:!0,get:function(){return e.formatVND}}),Object.defineProperty(exports,`formatVolumeLoc`,{enumerable:!0,get:function(){return e.formatVolumeLoc}}),Object.defineProperty(exports,`getCurrentSession`,{enumerable:!0,get:function(){return e.getCurrentSession}}),Object.defineProperty(exports,`getLocale`,{enumerable:!0,get:function(){return e.getLocale}}),Object.defineProperty(exports,`registerLocale`,{enumerable:!0,get:function(){return e.registerLocale}}),Object.defineProperty(exports,`setLocale`,{enumerable:!0,get:function(){return e.setLocale}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return e.t}}),Object.defineProperty(exports,`toHeikinAshi`,{enumerable:!0,get:function(){return t.toHeikinAshi}}),Object.defineProperty(exports,`toKagi`,{enumerable:!0,get:function(){return t.toKagi}}),Object.defineProperty(exports,`toLineBreak`,{enumerable:!0,get:function(){return t.toLineBreak}}),Object.defineProperty(exports,`toPointAndFigure`,{enumerable:!0,get:function(){return t.toPointAndFigure}}),Object.defineProperty(exports,`toRenko`,{enumerable:!0,get:function(){return t.toRenko}});
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../src/DataManager.ts","../src/ThemeManager.ts","../src/layout/LayoutManager.ts","../src/plugins/PluginManager.ts","../src/Chart.ts"],"sourcesContent":["import type { OHLCBar, DataSeries } from '@tradecanvas/commons';\nimport { mergeBar } from '@tradecanvas/commons';\n\n/** Validate a single OHLC bar. Returns true if bar is usable. */\nfunction isValidBar(bar: OHLCBar): boolean {\n if (!bar || typeof bar.time !== 'number') return false;\n const { open, high, low, close } = bar;\n // Reject NaN / Infinity\n if (!isFinite(open) || !isFinite(high) || !isFinite(low) || !isFinite(close)) return false;\n // Reject negative prices\n if (open < 0 || high < 0 || low < 0 || close < 0) return false;\n // High must be >= low\n if (high < low) return false;\n // Volume (optional) must be non-negative if present\n if (bar.volume !== undefined && (!isFinite(bar.volume) || bar.volume < 0)) return false;\n return true;\n}\n\n/** Sanitize a bar: clamp high/low to envelope OHLC values. */\nfunction sanitizeBar(bar: OHLCBar): OHLCBar {\n return {\n ...bar,\n high: Math.max(bar.open, bar.high, bar.low, bar.close),\n low: Math.min(bar.open, bar.high, bar.low, bar.close),\n volume: bar.volume !== undefined ? Math.max(0, bar.volume) : 0,\n };\n}\n\nexport class DataManager {\n private data: DataSeries = [];\n\n getData(): DataSeries {\n return this.data;\n }\n\n setData(data: DataSeries): void {\n // Filter out completely invalid bars, sanitize the rest\n this.data = data\n .filter(isValidBar)\n .map(sanitizeBar);\n }\n\n appendBar(bar: OHLCBar): void {\n if (!isValidBar(bar)) return;\n this.data.push(sanitizeBar(bar));\n }\n\n updateLastBar(bar: OHLCBar): void {\n if (!isValidBar(bar)) return;\n const sanitized = sanitizeBar(bar);\n if (this.data.length === 0) {\n this.data.push(sanitized);\n return;\n }\n this.data[this.data.length - 1] = sanitized;\n }\n\n updateLastBarFromTick(tick: { price: number; volume?: number; time: number }): void {\n if (this.data.length === 0) return;\n if (!isFinite(tick.price) || tick.price < 0) return;\n if (tick.volume !== undefined && (!isFinite(tick.volume) || tick.volume < 0)) return;\n this.data[this.data.length - 1] = mergeBar(this.data[this.data.length - 1], tick);\n }\n\n getLength(): number {\n return this.data.length;\n }\n\n clear(): void {\n this.data = [];\n }\n}\n","import type { Theme, ThemeName } from '@tradecanvas/commons';\nimport { DARK_THEME, LIGHT_THEME } from '@tradecanvas/commons';\n\nexport class ThemeManager {\n private theme: Theme;\n\n constructor(themeOrName?: ThemeName | Theme) {\n if (!themeOrName || themeOrName === 'dark') {\n this.theme = { ...DARK_THEME };\n } else if (themeOrName === 'light') {\n this.theme = { ...LIGHT_THEME };\n } else {\n this.theme = { ...themeOrName };\n }\n }\n\n getTheme(): Theme {\n return this.theme;\n }\n\n setTheme(themeOrName: ThemeName | Theme): void {\n if (themeOrName === 'dark') {\n this.theme = { ...DARK_THEME };\n } else if (themeOrName === 'light') {\n this.theme = { ...LIGHT_THEME };\n } else {\n this.theme = { ...themeOrName };\n }\n }\n}\n","import type { PanelPosition, PanelConfig, ResolvedLayout, ResolvedPanel, DividerRect, Rect } from '@tradecanvas/commons';\nimport { DEFAULT_PANEL_HEIGHT, MIN_PANEL_HEIGHT, PRICE_AXIS_WIDTH, TIME_AXIS_HEIGHT } from '@tradecanvas/commons';\n\nconst DEFAULT_PANEL_WIDTH = 200;\nconst MIN_PANEL_WIDTH = 80;\n\nexport class LayoutManager {\n private panels: PanelConfig[] = [];\n private containerWidth = 0;\n private containerHeight = 0;\n\n resize(width: number, height: number): void {\n this.containerWidth = width;\n this.containerHeight = height;\n }\n\n addPanel(instanceId: string, position: PanelPosition = 'bottom', size?: number): void {\n const isVertical = position === 'left' || position === 'right';\n this.panels.push({\n id: instanceId,\n position,\n size: size ?? (isVertical ? DEFAULT_PANEL_WIDTH : DEFAULT_PANEL_HEIGHT),\n minSize: isVertical ? MIN_PANEL_WIDTH : MIN_PANEL_HEIGHT,\n content: { type: 'indicator', indicatorInstanceId: instanceId },\n });\n }\n\n removePanel(instanceId: string): void {\n this.panels = this.panels.filter((p) => p.id !== instanceId);\n }\n\n setPanelPosition(instanceId: string, position: PanelPosition): void {\n const panel = this.panels.find((p) => p.id === instanceId);\n if (panel) {\n const wasVertical = panel.position === 'left' || panel.position === 'right';\n const isVertical = position === 'left' || position === 'right';\n panel.position = position;\n if (wasVertical !== isVertical) {\n panel.size = isVertical ? DEFAULT_PANEL_WIDTH : DEFAULT_PANEL_HEIGHT;\n panel.minSize = isVertical ? MIN_PANEL_WIDTH : MIN_PANEL_HEIGHT;\n }\n }\n }\n\n setPanelSize(instanceId: string, size: number): void {\n const panel = this.panels.find((p) => p.id === instanceId);\n if (panel) {\n panel.size = Math.max(panel.minSize, size);\n }\n }\n\n getPanels(): PanelConfig[] {\n return this.panels;\n }\n\n resolve(): ResolvedLayout {\n const leftPanels = this.panels.filter((p) => p.position === 'left');\n const rightPanels = this.panels.filter((p) => p.position === 'right');\n const topPanels = this.panels.filter((p) => p.position === 'top');\n const bottomPanels = this.panels.filter((p) => p.position === 'bottom');\n\n const leftWidth = leftPanels.reduce((s, p) => s + p.size, 0);\n const rightWidth = rightPanels.reduce((s, p) => s + p.size, 0);\n const topHeight = topPanels.reduce((s, p) => s + p.size, 0);\n const bottomHeight = bottomPanels.reduce((s, p) => s + p.size, 0);\n\n const mainChartRect: Rect = {\n x: leftWidth,\n y: topHeight,\n width: Math.max(0, this.containerWidth - leftWidth - rightWidth - PRICE_AXIS_WIDTH),\n height: Math.max(0, this.containerHeight - topHeight - bottomHeight - TIME_AXIS_HEIGHT),\n };\n\n const resolvedPanels: ResolvedPanel[] = [];\n const dividers: DividerRect[] = [];\n\n // Left panels (stacked vertically)\n let x = 0;\n for (const panel of leftPanels) {\n resolvedPanels.push({\n config: panel,\n rect: { x, y: 0, width: panel.size, height: this.containerHeight - TIME_AXIS_HEIGHT },\n });\n dividers.push({\n panelId: panel.id,\n rect: { x: x + panel.size - 2, y: 0, width: 4, height: this.containerHeight },\n orientation: 'vertical',\n });\n x += panel.size;\n }\n\n // Top panels (stacked horizontally, full width minus left/right)\n let y = 0;\n for (const panel of topPanels) {\n resolvedPanels.push({\n config: panel,\n rect: { x: leftWidth, y, width: mainChartRect.width, height: panel.size },\n });\n dividers.push({\n panelId: panel.id,\n rect: { x: leftWidth, y: y + panel.size - 2, width: mainChartRect.width, height: 4 },\n orientation: 'horizontal',\n });\n y += panel.size;\n }\n\n // Bottom panels\n y = mainChartRect.y + mainChartRect.height;\n for (const panel of bottomPanels) {\n resolvedPanels.push({\n config: panel,\n rect: { x: leftWidth, y, width: mainChartRect.width, height: panel.size },\n });\n dividers.push({\n panelId: panel.id,\n rect: { x: leftWidth, y: y - 2, width: mainChartRect.width, height: 4 },\n orientation: 'horizontal',\n });\n y += panel.size;\n }\n\n // Right panels\n x = leftWidth + mainChartRect.width + PRICE_AXIS_WIDTH;\n for (const panel of rightPanels) {\n resolvedPanels.push({\n config: panel,\n rect: { x, y: 0, width: panel.size, height: this.containerHeight - TIME_AXIS_HEIGHT },\n });\n dividers.push({\n panelId: panel.id,\n rect: { x: x - 2, y: 0, width: 4, height: this.containerHeight },\n orientation: 'vertical',\n });\n x += panel.size;\n }\n\n return { mainChartRect, panels: resolvedPanels, dividers };\n }\n\n getMainChartRect(): Rect {\n return this.resolve().mainChartRect;\n }\n}\n","import type { IndicatorPlugin } from '@tradecanvas/commons';\nimport type { IndicatorEngine } from '@tradecanvas/core';\n\nexport class PluginManager {\n constructor(private indicatorEngine: IndicatorEngine) {}\n\n registerIndicator(plugin: IndicatorPlugin): void {\n this.indicatorEngine.register(plugin);\n }\n}\n","import type {\n ChartOptions,\n ChartType,\n OHLCBar,\n DataSeries,\n Theme,\n ThemeName,\n ChartEventType,\n ChartEvent,\n TauriBridgeOptions,\n IndicatorPlugin,\n IndicatorDescriptor,\n IndicatorOutput,\n DrawingToolType,\n DrawingState,\n DrawingStyle,\n DrawingPlugin,\n PanelPosition,\n TradingOrder,\n TradingPosition,\n DepthData,\n TradingConfig,\n MarketConfig,\n Locale,\n StreamConfig,\n ConnectionState,\n ConnectionInfo,\n TimeFrame,\n FeaturesConfig,\n} from '@tradecanvas/commons';\nimport { LayerType, setLocale as setGlobalLocale, computePriceLimits } from '@tradecanvas/commons';\nimport {\n RenderEngine,\n Viewport,\n CandlestickRenderer,\n LineRenderer,\n AreaRenderer,\n BarRenderer,\n GridRenderer,\n PriceAxis,\n TimeAxis,\n InteractionManager,\n PanHandler,\n ZoomHandler,\n CrosshairHandler,\n IndicatorEngine,\n registerBuiltInIndicators,\n EventBus,\n DrawingManager,\n DrawingRenderer,\n registerBuiltInDrawingTools,\n TradingManager,\n TradingRenderer,\n StreamManager,\n ChartLegend,\n Screenshot,\n Watermark,\n BarCountdown,\n VolumeRenderer,\n AlertManager,\n ReplayManager,\n ChartStateManager,\n UndoRedoManager,\n Animator,\n KeyboardHandler,\n CrosshairTooltip,\n HollowCandleRenderer,\n BaselineRenderer,\n RenkoRenderer,\n KagiRenderer,\n PointAndFigureRenderer,\n toHeikinAshi,\n toRenko,\n toLineBreak,\n toKagi,\n toPointAndFigure,\n DataExporter,\n SessionBreaks,\n CompareRenderer,\n CurrentPriceLine,\n} from '@tradecanvas/core';\nimport type { ChartRendererInterface } from '@tradecanvas/core';\nimport { DataManager } from './DataManager.js';\nimport { ThemeManager } from './ThemeManager.js';\nimport { LayoutManager } from './layout/LayoutManager.js';\nimport { PluginManager } from './plugins/PluginManager.js';\n\nexport class Chart {\n static version = '0.3.0';\n\n private engine: RenderEngine;\n private viewport: Viewport;\n private dataManager: DataManager;\n private themeManager: ThemeManager;\n private layoutManager: LayoutManager;\n private pluginManager: PluginManager;\n private indicatorEngine: IndicatorEngine;\n private drawingManager: DrawingManager;\n private drawingRenderer: DrawingRenderer;\n private tradingManager: TradingManager;\n private tradingRenderer: TradingRenderer;\n private eventBus: EventBus;\n private streamManager: StreamManager | null = null;\n private autoScrollOnNewBar = true;\n private displayDataCache: DataSeries | null = null;\n private resolvedLayoutCache: import('@tradecanvas/commons').ResolvedLayout | null = null;\n private panelInfoCache: import('@tradecanvas/core').PanelRenderInfo[] | null = null;\n private renderScheduled = false;\n private containerSizeCache: { width: number; height: number } | null = null;\n private containerSizeCacheTime = 0;\n private chartLegend: ChartLegend;\n private watermark: Watermark;\n private barCountdown: BarCountdown;\n private sessionBreaks: SessionBreaks;\n private compareRenderer: CompareRenderer;\n private countdownInterval: ReturnType<typeof setInterval> | null = null;\n private volumeRenderer: VolumeRenderer;\n private alertManager: AlertManager;\n private replayManager: ReplayManager;\n private undoRedoManager: UndoRedoManager;\n private autoSaveTimer: ReturnType<typeof setTimeout> | null = null;\n private autoSaveDelay = 0; // 0 = disabled\n private autoSaveKey: string | null = null;\n private animator: Animator;\n private crosshairTooltip: CrosshairTooltip;\n private interactionManager: InteractionManager;\n private crosshairHandler: CrosshairHandler;\n private chartRenderer: ChartRendererInterface;\n private gridRenderer: GridRenderer;\n private priceAxis: PriceAxis;\n private timeAxis: TimeAxis;\n private options: ChartOptions;\n private features: Required<FeaturesConfig>;\n private marketConfig: MarketConfig | null = null;\n private container: HTMLElement;\n private currentPriceLine: import('@tradecanvas/core').CurrentPriceLine;\n\n constructor(container: HTMLElement, options: ChartOptions) {\n this.container = container;\n this.options = options;\n\n // Resolve feature flags (all default to true)\n const f = options.features ?? {};\n this.features = {\n drawings: f.drawings ?? true,\n drawingTools: f.drawingTools ?? [],\n drawingMagnet: f.drawingMagnet ?? true,\n drawingUndoRedo: f.drawingUndoRedo ?? true,\n trading: f.trading ?? true,\n tradingContextMenu: f.tradingContextMenu ?? true,\n indicators: f.indicators ?? true,\n indicatorIds: f.indicatorIds ?? [],\n panning: f.panning ?? true,\n zooming: f.zooming ?? true,\n crosshair: f.crosshair ?? true,\n keyboard: f.keyboard ?? true,\n priceAxis: f.priceAxis ?? true,\n timeAxis: f.timeAxis ?? true,\n grid: f.grid ?? (options.grid?.visible ?? true),\n legend: f.legend ?? true,\n volume: f.volume ?? true,\n watermark: f.watermark ?? true,\n saveLoad: f.saveLoad ?? true,\n screenshot: f.screenshot ?? true,\n alerts: f.alerts ?? true,\n replay: f.replay ?? true,\n sessionBreaks: f.sessionBreaks ?? true,\n barCountdown: f.barCountdown ?? true,\n compareSymbols: f.compareSymbols ?? true,\n dataExport: f.dataExport ?? true,\n logScale: f.logScale ?? true,\n timeframes: f.timeframes ?? [],\n defaultTimeframeFavorites: f.defaultTimeframeFavorites ?? [],\n };\n\n container.style.position = 'relative';\n container.style.overflow = 'hidden';\n container.tabIndex = 0; // Allow keyboard events\n container.style.outline = 'none';\n\n // Initialize managers\n this.dataManager = new DataManager();\n this.themeManager = new ThemeManager(options.theme);\n this.layoutManager = new LayoutManager();\n this.indicatorEngine = new IndicatorEngine();\n this.pluginManager = new PluginManager(this.indicatorEngine);\n this.eventBus = new EventBus();\n\n registerBuiltInIndicators(this.indicatorEngine);\n\n // Drawing tools\n this.drawingManager = new DrawingManager();\n registerBuiltInDrawingTools(this.drawingManager);\n this.drawingRenderer = new DrawingRenderer(this.drawingManager);\n this.drawingManager.setRequestRender(() => {\n // Sync entire render context so drawings render with same viewport as candles\n this.syncRenderContext();\n this.engine.requestRender(LayerType.Overlay);\n this.scheduleAutoSave();\n });\n this.drawingManager.setEventCallback((event, data) => {\n this.eventBus.emit(event as ChartEventType, data);\n });\n // Undo/redo\n this.undoRedoManager = new UndoRedoManager();\n this.drawingManager.setUndoRedoManager(this.undoRedoManager);\n this.drawingManager.setDataGetter(() => this.dataManager.getData());\n this.drawingManager.setDisplayDataGetter(() => this.getDisplayData());\n // Magnet mode\n if (options.crosshair?.mode === 'magnet') {\n this.drawingManager.setMagnetMode('magnet');\n }\n\n // Trading\n this.tradingManager = new TradingManager();\n this.tradingRenderer = new TradingRenderer(this.tradingManager);\n this.tradingManager.setContainer(container);\n this.tradingManager.setRequestRender(() => this.engine.requestRender(LayerType.Overlay));\n this.tradingManager.setEventCallback((event, data) => {\n this.eventBus.emit(event as ChartEventType, data);\n });\n\n // Rendering\n this.engine = new RenderEngine(container);\n const size = this.engine.dprManager.getContainerSize();\n this.viewport = new Viewport(\n size.width,\n size.height,\n options.minBarSpacing ?? 2,\n options.maxBarSpacing ?? 30,\n options.rightMargin ?? 5,\n );\n this.layoutManager.resize(size.width, size.height);\n\n // Sync viewport + layout when the container resizes. Without this hook\n // the chart's viewport keeps its construction-time chartRect forever\n // (which is wrong if the container started at 0 or got resized since),\n // and `scrollToEnd` / clampOffset compute against stale dimensions —\n // chart sticks at the wrong offset and the user can't scroll to the\n // latest bar.\n this.engine.onContainerResize = (newSize) => {\n if (newSize.width <= 0 || newSize.height <= 0) return;\n const wasAtEnd = this.viewport.isAtEnd();\n this.viewport.resize(newSize.width, newSize.height);\n this.layoutManager.resize(newSize.width, newSize.height);\n // wasAtEnd carries the user's intent: if they were tracking the live\n // edge before the resize, keep them there afterwards. Otherwise leave\n // their scroll position alone.\n this.updateViewportAndRender(wasAtEnd);\n };\n\n // Chart renderer\n this.chartRenderer = this.createChartRenderer(options.chartType);\n this.gridRenderer = new GridRenderer();\n if (options.grid?.visible === false) this.gridRenderer.setVisible(false);\n this.priceAxis = new PriceAxis();\n this.timeAxis = new TimeAxis();\n\n // Crosshair\n this.crosshairHandler = new CrosshairHandler();\n if (options.crosshair?.mode) {\n this.crosshairHandler.setMode(options.crosshair.mode);\n }\n // Crosshair callback — fired via microtask AFTER render, only when bar changes.\n // No DOM writes, no layout reads, no extra render requests.\n this.crosshairHandler.setCallback((barIndex, point) => {\n if (barIndex !== null && point) {\n const data = this.dataManager.getData();\n const bar = barIndex < data.length ? data[barIndex] : undefined;\n\n // Update legend (canvas-rendered, will show on next UI paint)\n this.chartLegend.setHoverBar(bar ?? null);\n\n // Update tooltip (DOM, lightweight update only when bar changes)\n if (bar) {\n this.crosshairTooltip.show(point, bar, this.themeManager.getTheme(), this.cachedContainerSize());\n }\n\n // Emit for external consumers\n this.eventBus.emit('crosshairMove', { point, bar, barIndex });\n } else {\n this.crosshairTooltip.hide();\n this.chartLegend.setHoverBar(null);\n }\n });\n\n // Chart legend (OHLCV overlay)\n this.chartLegend = new ChartLegend();\n this.chartLegend.setChartType(options.chartType);\n\n // Watermark + Volume\n this.watermark = new Watermark();\n if (options.watermark) this.watermark.setConfig(options.watermark);\n this.volumeRenderer = new VolumeRenderer();\n\n // Bar countdown timer\n this.barCountdown = new BarCountdown();\n this.sessionBreaks = new SessionBreaks();\n this.compareRenderer = new CompareRenderer();\n\n // Apply session break config from options\n if (options.sessionBreaks) {\n this.sessionBreaks.setConfig({\n visible: options.sessionBreaks.visible ?? true,\n color: options.sessionBreaks.color,\n lineStyle: options.sessionBreaks.lineStyle,\n lineWidth: options.sessionBreaks.lineWidth,\n });\n } else if (options.features?.sessionBreaks !== false) {\n this.sessionBreaks.setVisible(true);\n }\n\n // Apply log scale from options\n if (options.logScale) {\n this.viewport.setLogScale(true);\n }\n\n // Animation\n this.animator = new Animator();\n\n // Crosshair tooltip (DOM)\n this.crosshairTooltip = new CrosshairTooltip();\n this.crosshairTooltip.create(container);\n\n // Keyboard navigation\n void new KeyboardHandler({\n scrollBars: (count) => {\n const barUnit = this.viewport.getState().barWidth + this.viewport.getState().barSpacing;\n this.viewport.scrollBy(count * barUnit);\n this.updateViewportAndRender();\n },\n zoom: (delta) => {\n const chartWidth = this.viewport.getState().chartRect.width;\n this.viewport.zoom(delta, chartWidth / 2);\n this.updateViewportAndRender();\n },\n goToStart: () => {\n this.viewport.scrollBy(-Infinity);\n this.updateViewportAndRender();\n },\n goToEnd: () => {\n this.viewport.scrollToEnd();\n this.updateViewportAndRender();\n },\n fitContent: () => this.fitContent(),\n });\n\n // Current price line (standalone, works without StreamManager)\n this.currentPriceLine = new CurrentPriceLine();\n\n // Alerts\n this.alertManager = new AlertManager();\n this.alertManager.setRequestRender(() => this.engine.requestRender(LayerType.Overlay));\n this.alertManager.on('triggered', (alert) => {\n this.eventBus.emit('dataUpdate', { alert: 'triggered', alertId: alert.id, price: alert.price, message: alert.message });\n });\n\n // Replay\n this.replayManager = new ReplayManager();\n\n // Interaction\n this.interactionManager = new InteractionManager(container);\n if (this.features.panning) {\n this.interactionManager.setPanHandler(\n new PanHandler((deltaX) => {\n this.viewport.scrollBy(deltaX);\n this.updateViewportAndRender();\n }),\n );\n }\n if (this.features.zooming) {\n this.interactionManager.setZoomHandler(\n new ZoomHandler((delta, centerX) => {\n this.viewport.zoom(delta, centerX);\n this.updateViewportAndRender();\n }),\n );\n }\n if (this.features.crosshair) {\n this.interactionManager.setCrosshairHandler(this.crosshairHandler);\n }\n if (this.features.drawings) {\n this.interactionManager.setDrawingManager(\n this.drawingManager,\n () => this.viewport.getState(),\n );\n }\n if (this.features.trading) {\n this.interactionManager.setTradingManager(\n this.tradingManager,\n () => this.viewport.getState(),\n );\n }\n this.interactionManager.setOverlayDirtyCallback(() => {\n this.engine.requestRender(LayerType.Overlay);\n // Also refresh UI layer for panel crosshair value labels\n if (this.layoutManager.getPanels().length > 0) {\n this.engine.requestRender(LayerType.UI);\n }\n });\n this.interactionManager.attach();\n\n // Set render context\n this.syncRenderContext();\n this.engine.start();\n }\n\n // --- Data ---\n\n setData(data: DataSeries): void {\n this.dataManager.setData(data);\n this.crosshairHandler.setData(this.dataManager.getData());\n this.displayDataCache = null;\n this.sessionBreaks.invalidateCache();\n this.indicatorEngine.recalculateAll(this.dataManager.getData());\n // Auto-set current price line from last bar's close\n if (data.length > 0) {\n this.currentPriceLine.setPrice(data[data.length - 1].close);\n }\n this.updateViewportAndRender(true);\n this.eventBus.emit('dataUpdate', { length: data.length });\n }\n\n appendBar(bar: OHLCBar): void {\n this.dataManager.appendBar(bar);\n this.crosshairHandler.setData(this.dataManager.getData());\n this.displayDataCache = null;\n if (this.autoScrollOnNewBar) this.viewport.scrollToEnd();\n this.indicatorEngine.recalculateAll(this.dataManager.getData());\n this.updateViewportAndRender();\n }\n\n updateLastBar(bar: OHLCBar): void {\n this.dataManager.updateLastBar(bar);\n this.currentPriceLine.setPrice(bar.close);\n // For non-transform chart types, the displayDataCache still points to the\n // same raw array (mutated in place), so no need to invalidate.\n // Only invalidate for transform types that produce derived arrays.\n if (this.options.chartType !== 'candlestick' && this.options.chartType !== 'line'\n && this.options.chartType !== 'area' && this.options.chartType !== 'bar'\n && this.options.chartType !== 'hollowCandle') {\n this.displayDataCache = null;\n }\n this.scheduleRender();\n }\n\n /** Merge a price tick into the current last bar (convenience for live feeds) */\n updateLastBarFromTick(tick: { price: number; volume?: number; time: number }): void {\n this.dataManager.updateLastBarFromTick(tick);\n this.currentPriceLine.setPrice(tick.price);\n if (this.options.chartType !== 'candlestick' && this.options.chartType !== 'line'\n && this.options.chartType !== 'area' && this.options.chartType !== 'bar'\n && this.options.chartType !== 'hollowCandle') {\n this.displayDataCache = null;\n }\n this.scheduleRender();\n }\n\n // --- Chart type ---\n\n setChartType(type: ChartType): void {\n this.options.chartType = type;\n this.chartRenderer = this.createChartRenderer(type);\n this.chartLegend.setChartType(type);\n this.displayDataCache = null;\n this.updateViewportAndRender(true);\n }\n\n // --- Indicators ---\n\n addIndicator(id: string, params: Record<string, number | string | boolean> = {}, position: PanelPosition = 'bottom'): string | null {\n if (!this.features.indicators) return null;\n if (this.features.indicatorIds.length > 0 && !this.features.indicatorIds.includes(id)) return null;\n const instanceId = this.indicatorEngine.addIndicator(id, params, this.dataManager.getData());\n const descriptor = this.indicatorEngine.getAvailableIndicators().find((d) => d.id === id);\n if (descriptor?.placement === 'panel') {\n this.layoutManager.addPanel(instanceId, position);\n }\n this.eventBus.emit('indicatorAdd', { instanceId, id });\n this.engine.requestRender();\n return instanceId;\n }\n\n updateIndicator(instanceId: string, params: Record<string, number | string | boolean>): void {\n this.indicatorEngine.updateIndicator(instanceId, params, this.dataManager.getData());\n this.engine.requestRender();\n }\n\n removeIndicator(instanceId: string): void {\n this.indicatorEngine.removeIndicator(instanceId);\n this.layoutManager.removePanel(instanceId);\n this.eventBus.emit('indicatorRemove', { instanceId });\n this.engine.requestRender();\n }\n\n getIndicatorOutput(instanceId: string): IndicatorOutput | null {\n return this.indicatorEngine.getOutput(instanceId);\n }\n\n registerIndicator(plugin: IndicatorPlugin): void {\n this.pluginManager.registerIndicator(plugin);\n }\n\n static indicators(): IndicatorDescriptor[] {\n const engine = new IndicatorEngine();\n registerBuiltInIndicators(engine);\n return engine.getAvailableIndicators();\n }\n\n // --- Panel layout ---\n\n setPanelPosition(instanceId: string, position: PanelPosition): void {\n this.layoutManager.setPanelPosition(instanceId, position);\n this.engine.requestRender();\n }\n\n setPanelSize(instanceId: string, size: number): void {\n this.layoutManager.setPanelSize(instanceId, size);\n this.engine.requestRender();\n }\n\n // --- Drawing tools ---\n\n setDrawingTool(type: DrawingToolType | null): void {\n if (!this.features.drawings) return;\n // If whitelist is set, check it\n if (type && this.features.drawingTools.length > 0 && !this.features.drawingTools.includes(type)) return;\n this.drawingManager.setActiveTool(type);\n }\n\n getDrawingTool(): DrawingToolType | null {\n return this.drawingManager.getActiveTool();\n }\n\n setDrawingStyle(style: Partial<DrawingStyle>): void {\n this.drawingManager.setStyle(style);\n }\n\n getDrawings(): DrawingState[] {\n return this.drawingManager.getDrawings();\n }\n\n setDrawings(drawings: DrawingState[]): void {\n this.drawingManager.setDrawings(drawings);\n }\n\n removeDrawing(id: string): void {\n this.drawingManager.removeDrawing(id);\n }\n\n clearDrawings(): void {\n this.drawingManager.clearDrawings();\n }\n\n registerDrawingTool(plugin: DrawingPlugin): void {\n this.drawingManager.register(plugin);\n }\n\n // --- Undo/Redo ---\n\n undo(): boolean {\n if (!this.features.drawingUndoRedo) return false;\n return this.drawingManager.undo();\n }\n\n redo(): boolean {\n if (!this.features.drawingUndoRedo) return false;\n return this.drawingManager.redo();\n }\n\n getUndoRedoState(): { canUndo: boolean; canRedo: boolean } {\n return this.undoRedoManager.getState();\n }\n\n // --- Drawing magnet ---\n\n setDrawingMagnet(enabled: boolean): void {\n this.drawingManager.setMagnetMode(enabled ? 'magnet' : 'none');\n }\n\n getDrawingMagnet(): boolean {\n return this.drawingManager.getMagnetMode() === 'magnet';\n }\n\n // --- Bulk drawing operations ---\n\n lockAllDrawings(): void {\n this.drawingManager.lockAllDrawings();\n }\n\n unlockAllDrawings(): void {\n this.drawingManager.unlockAllDrawings();\n }\n\n hideAllDrawings(): void {\n this.drawingManager.hideAllDrawings();\n }\n\n showAllDrawings(): void {\n this.drawingManager.showAllDrawings();\n }\n\n // --- Drawing duplication ---\n\n duplicateDrawing(id?: string): string | null {\n const targetId = id ?? this.drawingManager.getSelectedDrawingId();\n if (!targetId) return null;\n return this.drawingManager.duplicateDrawing(targetId);\n }\n\n // --- Data export ---\n\n exportVisibleData(format: 'csv' | 'json' = 'csv', filename?: string): void {\n const vp = this.viewport.getState();\n const data = this.dataManager.getData();\n const from = Math.max(0, vp.visibleRange.from);\n const to = Math.min(data.length - 1, vp.visibleRange.to);\n const slice = data.slice(from, to + 1);\n\n if (format === 'json') {\n const content = DataExporter.toJSON(slice);\n DataExporter.download(content, filename ?? 'chart-data.json', 'application/json');\n } else {\n const content = DataExporter.toCSV(slice);\n DataExporter.download(content, filename ?? 'chart-data.csv', 'text/csv');\n }\n }\n\n exportAllData(format: 'csv' | 'json' = 'csv', filename?: string): void {\n const data = this.dataManager.getData();\n if (format === 'json') {\n const content = DataExporter.toJSON(data);\n DataExporter.download(content, filename ?? 'chart-data.json', 'application/json');\n } else {\n const content = DataExporter.toCSV(data);\n DataExporter.download(content, filename ?? 'chart-data.csv', 'text/csv');\n }\n }\n\n // --- Auto-save ---\n\n setAutoSave(key: string, delayMs = 5000): void {\n this.autoSaveKey = key;\n this.autoSaveDelay = delayMs;\n }\n\n disableAutoSave(): void {\n this.autoSaveDelay = 0;\n this.autoSaveKey = null;\n if (this.autoSaveTimer) {\n clearTimeout(this.autoSaveTimer);\n this.autoSaveTimer = null;\n }\n }\n\n private scheduleAutoSave(): void {\n if (this.autoSaveDelay <= 0 || !this.autoSaveKey) return;\n if (this.autoSaveTimer) clearTimeout(this.autoSaveTimer);\n this.autoSaveTimer = setTimeout(() => {\n this.autoSaveTimer = null;\n if (this.autoSaveKey) {\n this.saveState(this.autoSaveKey);\n }\n }, this.autoSaveDelay);\n }\n\n // --- Indicator introspection ---\n\n getAvailableIndicators(): IndicatorDescriptor[] {\n return this.indicatorEngine.getAvailableIndicators();\n }\n\n getIndicatorInputs(id: string): { id: string; params: Record<string, unknown> } | null {\n const indicators = this.indicatorEngine.getAvailableIndicators();\n const desc = indicators.find(i => i.id === id);\n if (!desc) return null;\n return { id: desc.id, params: desc.defaultConfig };\n }\n\n /** Get all active indicator instances with their current params */\n getActiveIndicators(): { instanceId: string; id: string; params: Record<string, unknown>; descriptor: IndicatorDescriptor }[] {\n return this.indicatorEngine.getActiveIndicators();\n }\n\n /** Get current config for a specific indicator instance */\n getIndicatorConfig(instanceId: string): { id: string; params: Record<string, unknown> } | null {\n const config = this.indicatorEngine.getIndicatorConfig(instanceId);\n if (!config) return null;\n return { id: config.id, params: { ...config.params } };\n }\n\n /** Update indicator colors/line widths at runtime */\n updateIndicatorStyle(instanceId: string, style: { colors?: string[]; lineWidths?: number[]; opacity?: number }): void {\n this.indicatorEngine.updateIndicatorStyle(instanceId, style);\n this.engine.requestRender();\n }\n\n // --- Trading ---\n\n setOrders(orders: TradingOrder[]): void {\n if (!this.features.trading) return;\n this.tradingManager.setOrders(orders);\n }\n\n setPositions(positions: TradingPosition[]): void {\n if (!this.features.trading) return;\n this.tradingManager.setPositions(positions);\n }\n\n setDepthData(depth: DepthData | null): void {\n if (!this.features.trading) return;\n this.tradingManager.setDepthData(depth);\n }\n\n setCurrentPrice(price: number): void {\n this.tradingManager.setCurrentPrice(price);\n // Also update standalone price line (visible even without trading feature)\n this.currentPriceLine.setPrice(price);\n this.scheduleRender();\n if (this.features.alerts) this.alertManager.checkPrice(price);\n }\n\n setTradingConfig(config: Partial<TradingConfig>): void {\n if (!this.features.trading) return;\n this.tradingManager.setConfig(config);\n }\n\n // --- Real-time Streaming ---\n\n /**\n * Connect to a real-time data source.\n * Loads history, starts streaming, manages reconnection automatically.\n *\n * @example\n * import { BinanceAdapter } from '@tradecanvas/core';\n * chart.connect({\n * adapter: new BinanceAdapter(),\n * symbol: 'BTCUSDT',\n * timeframe: '1m',\n * });\n */\n async connect(config: StreamConfig): Promise<void> {\n this.disconnectStream();\n\n this.streamManager = new StreamManager();\n\n this.streamManager.on('snapshot', (bars) => {\n this.setData(bars);\n });\n\n this.streamManager.on('barClose', (bar) => {\n this.dataManager.appendBar(bar);\n this.crosshairHandler.setData(this.dataManager.getData());\n if (this.autoScrollOnNewBar) this.viewport.scrollToEnd();\n this.indicatorEngine.recalculateAll(this.dataManager.getData());\n this.updateViewportAndRender();\n });\n\n this.streamManager.on('barUpdate', (bar) => {\n this.dataManager.updateLastBar(bar);\n this.currentPriceLine.setPrice(bar.close);\n this.scheduleRender();\n });\n\n this.streamManager.on('priceChange', ({ price }) => {\n this.tradingManager.setCurrentPrice(price);\n this.currentPriceLine.setPrice(price);\n this.engine.requestRender(LayerType.Overlay);\n this.engine.requestRender(LayerType.UI);\n });\n\n this.streamManager.on('connectionChange', (info) => {\n this.eventBus.emit('dataUpdate', { connection: info });\n });\n\n this.streamManager.on('error', (err) => {\n this.eventBus.emit('dataUpdate', { error: err.message });\n });\n\n this.autoScrollOnNewBar = config.autoScroll !== false;\n\n await this.streamManager.connect(config);\n\n // Set up bar countdown timer based on timeframe\n const tfMs = this.timeframeToMs(config.timeframe);\n this.barCountdown.setTimeframeMs(tfMs);\n\n // Start countdown refresh interval\n if (this.countdownInterval) clearInterval(this.countdownInterval);\n this.countdownInterval = setInterval(() => {\n if (this.barCountdown.isVisible()) {\n this.engine.requestRender(LayerType.UI);\n }\n }, 1000);\n }\n\n /**\n * Switch symbol or timeframe on an active stream without full reconnect.\n */\n async switchStream(symbol: string, timeframe: TimeFrame): Promise<void> {\n if (!this.streamManager) return;\n await this.streamManager.switchTo(symbol, timeframe);\n }\n\n /**\n * Disconnect the real-time stream.\n */\n disconnectStream(): void {\n if (this.streamManager) {\n this.streamManager.dispose();\n this.streamManager = null;\n }\n }\n\n setBarCountdownVisible(visible: boolean): void {\n this.barCountdown.setVisible(visible);\n this.engine.requestRender(LayerType.UI);\n }\n\n setSessionBreaksVisible(visible: boolean): void {\n this.sessionBreaks.setVisible(visible);\n this.engine.requestRender(LayerType.Background);\n }\n\n // --- Compare symbols ---\n\n addCompareSymbol(id: string, label: string, data: DataSeries, color: string): void {\n this.compareRenderer.addSymbol({ id, label, data, color, visible: true });\n this.engine.requestRender(LayerType.Main);\n }\n\n removeCompareSymbol(id: string): void {\n this.compareRenderer.removeSymbol(id);\n this.engine.requestRender(LayerType.Main);\n }\n\n updateCompareData(id: string, data: DataSeries): void {\n this.compareRenderer.setSymbolData(id, data);\n this.engine.requestRender(LayerType.Main);\n }\n\n setCompareMode(mode: 'percent' | 'absolute'): void {\n this.compareRenderer.setMode(mode);\n this.engine.requestRender(LayerType.Main);\n }\n\n clearCompareSymbols(): void {\n this.compareRenderer.clear();\n this.engine.requestRender(LayerType.Main);\n }\n\n // --- Log scale ---\n\n setLogScale(enabled: boolean): void {\n this.viewport.setLogScale(enabled);\n this.updateViewportAndRender();\n }\n\n isLogScale(): boolean {\n return this.viewport.isLogScale();\n }\n\n setSessionBreaksConfig(config: { color?: string; lineStyle?: 'solid' | 'dashed' | 'dotted'; lineWidth?: number }): void {\n this.sessionBreaks.setConfig(config);\n this.engine.requestRender(LayerType.Background);\n }\n\n getConnectionState(): ConnectionState {\n return this.streamManager?.getConnectionState() ?? 'disconnected';\n }\n\n getConnectionInfo(): ConnectionInfo {\n return this.streamManager?.getConnectionInfo() ?? { state: 'disconnected' };\n }\n\n setAutoScroll(enabled: boolean): void {\n this.autoScrollOnNewBar = enabled;\n }\n\n // --- Viewport ---\n\n scrollTo(timestamp: number): void {\n const data = this.dataManager.getData();\n for (let i = 0; i < data.length; i++) {\n if (data[i].time >= timestamp) {\n const barUnit = this.viewport.getState().barWidth + this.viewport.getState().barSpacing;\n this.viewport.scrollBy(i * barUnit - this.viewport.getState().offset);\n this.updateViewportAndRender();\n return;\n }\n }\n }\n\n scrollToEnd(): void {\n this.viewport.scrollToEnd();\n this.updateViewportAndRender();\n }\n\n setVisibleRange(fromTimestamp: number, toTimestamp: number): void {\n const data = this.dataManager.getData();\n let fromIdx = 0;\n let toIdx = data.length - 1;\n for (let i = 0; i < data.length; i++) {\n if (data[i].time >= fromTimestamp) { fromIdx = i; break; }\n }\n for (let i = data.length - 1; i >= 0; i--) {\n if (data[i].time <= toTimestamp) { toIdx = i; break; }\n }\n const barCount = toIdx - fromIdx + 1;\n if (barCount > 0) {\n const chartWidth = this.viewport.getState().chartRect.width;\n const targetBarUnit = chartWidth / barCount;\n const newBarWidth = Math.max(2, targetBarUnit - this.viewport.getState().barSpacing);\n this.viewport.zoom(\n (newBarWidth - this.viewport.getState().barWidth) / this.viewport.getState().barWidth,\n chartWidth / 2,\n );\n }\n this.updateViewportAndRender();\n }\n\n zoomIn(): void {\n const chartWidth = this.viewport.getState().chartRect.width;\n this.viewport.zoom(0.2, chartWidth / 2);\n this.updateViewportAndRender();\n }\n\n zoomOut(): void {\n const chartWidth = this.viewport.getState().chartRect.width;\n this.viewport.zoom(-0.2, chartWidth / 2);\n this.updateViewportAndRender();\n }\n\n fitContent(): void {\n const data = this.dataManager.getData();\n if (data.length === 0) return;\n this.setVisibleRange(data[0].time, data[data.length - 1].time);\n }\n\n // --- Events ---\n\n on(type: ChartEventType, handler: (event: ChartEvent) => void): void {\n this.eventBus.on(type, handler);\n }\n\n off(type: ChartEventType, handler: (event: ChartEvent) => void): void {\n this.eventBus.off(type, handler);\n }\n\n enableTauriBridge(options?: Partial<TauriBridgeOptions>): void {\n this.eventBus.enableTauriBridge({ enabled: true, ...options });\n }\n\n disableTauriBridge(): void {\n this.eventBus.disableTauriBridge();\n }\n\n // --- Theme ---\n\n setTheme(themeOrName: ThemeName | Theme): void {\n this.themeManager.setTheme(themeOrName);\n this.syncRenderContext();\n this.container.style.backgroundColor = this.themeManager.getTheme().background;\n this.engine.requestRender();\n this.eventBus.emit('themeChange', { theme: themeOrName });\n }\n\n getTheme(): Theme {\n return this.themeManager.getTheme();\n }\n\n // --- Watermark ---\n\n setWatermark(text: string, opts?: { color?: string; fontSize?: number }): void {\n this.watermark.setConfig({ text, ...opts });\n this.engine.requestRender(LayerType.Background);\n }\n\n // --- Auto Scale ---\n\n setAutoScale(enabled: boolean): void {\n this.options.autoScale = enabled;\n this.updateViewportAndRender();\n }\n\n isAutoScale(): boolean {\n return this.options.autoScale !== false;\n }\n\n // --- Crosshair ---\n\n setCrosshairMode(mode: 'normal' | 'magnet' | 'hidden'): void {\n this.crosshairHandler.setMode(mode);\n this.engine.requestRender(LayerType.Overlay);\n }\n\n getCrosshairMode(): string {\n return this.crosshairHandler.getMode();\n }\n\n // --- Grid ---\n\n setGridVisible(visible: boolean): void {\n this.gridRenderer.setVisible(visible);\n this.engine.requestRender(LayerType.Background);\n }\n\n isGridVisible(): boolean {\n return this.gridRenderer.isVisible();\n }\n\n // --- Volume ---\n\n setVolumeVisible(visible: boolean): void {\n this.volumeRenderer.setVisible(visible);\n this.engine.requestRender(LayerType.Main);\n }\n\n // --- Tooltip ---\n\n setTooltipVisible(visible: boolean): void {\n if (!visible) this.crosshairTooltip.hide();\n }\n\n // --- Legend ---\n\n setLegend(config: Partial<import('@tradecanvas/core').LegendConfig>): void {\n this.chartLegend.setConfig(config);\n this.engine.requestRender(LayerType.UI);\n }\n\n setSymbolName(symbol: string): void {\n this.chartLegend.setSymbol(symbol);\n this.engine.requestRender(LayerType.UI);\n }\n\n // --- Screenshot ---\n\n screenshot(filename?: string): void {\n if (!this.features.screenshot) return;\n Screenshot.download(this.container, filename, this.themeManager.getTheme().background);\n }\n\n screenshotDataURL(): string | null {\n if (!this.features.screenshot) return null;\n return Screenshot.toDataURL(this.container, this.themeManager.getTheme().background);\n }\n\n async screenshotBlob(): Promise<Blob | null> {\n if (!this.features.screenshot) return null;\n return Screenshot.toBlob(this.container, this.themeManager.getTheme().background);\n }\n\n // --- Alerts ---\n\n addAlert(price: number, condition: import('@tradecanvas/core').AlertCondition = 'crossing', message?: string): string | null {\n if (!this.features.alerts) return null;\n const id = this.alertManager.addAlert(price, condition, message);\n this.scheduleAutoSave();\n return id;\n }\n\n removeAlert(id: string): void {\n this.alertManager.removeAlert(id);\n this.scheduleAutoSave();\n }\n\n getAlerts(): import('@tradecanvas/core').PriceAlert[] {\n return this.alertManager.getAlerts();\n }\n\n clearAlerts(): void {\n this.alertManager.clearAlerts();\n this.scheduleAutoSave();\n }\n\n saveAlerts(key: string): void {\n this.alertManager.saveToStorage(key);\n }\n\n loadAlerts(key: string): void {\n this.alertManager.loadFromStorage(key);\n this.engine.requestRender(LayerType.Overlay);\n }\n\n // --- Replay ---\n\n replay(config?: Partial<import('@tradecanvas/core').ReplayConfig>): void {\n if (!this.features.replay) return;\n const data = this.dataManager.getData();\n this.replayManager.load(data);\n this.replayManager.on('bar', ({ bar: _bar, index }) => {\n const slice = data.slice(0, index + 1);\n this.dataManager.setData(slice);\n this.crosshairHandler.setData(slice);\n this.indicatorEngine.recalculateAll(slice);\n this.updateViewportAndRender();\n });\n this.replayManager.play(config);\n }\n\n replayPause(): void { this.replayManager.pause(); }\n replayResume(): void { this.replayManager.resume(); }\n replayStop(): void { this.replayManager.stop(); }\n replaySeek(index: number): void { this.replayManager.seekTo(index); }\n setReplaySpeed(speed: number): void { this.replayManager.setSpeed(speed); }\n getReplayState(): 'playing' | 'paused' | 'stopped' { return this.replayManager.getState(); }\n getReplayProgress(): { current: number; total: number; percent: number } { return this.replayManager.getProgress(); }\n\n // --- Save / Load ---\n\n saveState(key?: string): string | null {\n if (!this.features.saveLoad) return null;\n const snapshot = ChartStateManager.capture(\n {\n getDrawings: () => this.getDrawings(),\n getTheme: () => this.getTheme(),\n getAlerts: () => this.getAlerts(),\n },\n { chartType: this.options.chartType },\n );\n const json = ChartStateManager.serialize(snapshot);\n if (key) ChartStateManager.saveToStorage(key, snapshot);\n return json;\n }\n\n loadState(json: string): void {\n if (!this.features.saveLoad) return;\n const snapshot = ChartStateManager.deserialize(json);\n if (snapshot.chartType) this.setChartType(snapshot.chartType);\n if (snapshot.drawings) this.setDrawings(snapshot.drawings);\n if (snapshot.theme) this.setTheme(snapshot.theme as any);\n if (snapshot.alerts) {\n this.clearAlerts();\n for (const a of snapshot.alerts) {\n this.addAlert(a.price, a.condition, a.message);\n }\n }\n }\n\n loadStateFromStorage(key: string): boolean {\n if (!this.features.saveLoad) return false;\n const snapshot = ChartStateManager.loadFromStorage(key);\n if (!snapshot) return false;\n this.loadState(ChartStateManager.serialize(snapshot));\n return true;\n }\n\n downloadState(filename?: string): void {\n if (!this.features.saveLoad) return;\n const snapshot = ChartStateManager.capture(\n { getDrawings: () => this.getDrawings(), getTheme: () => this.getTheme(), getAlerts: () => this.getAlerts() },\n { chartType: this.options.chartType },\n );\n ChartStateManager.downloadFile(snapshot, filename);\n }\n\n async loadStateFromFile(): Promise<void> {\n if (!this.features.saveLoad) return;\n const snapshot = await ChartStateManager.loadFromFile();\n this.loadState(ChartStateManager.serialize(snapshot));\n }\n\n // --- Locale ---\n\n setLocale(locale: Locale): void {\n setGlobalLocale(locale);\n this.engine.requestRender();\n }\n\n // --- Market ---\n\n setMarket(config: MarketConfig): void {\n this.marketConfig = config;\n\n // Apply market color scheme to theme\n if (config.colorScheme) {\n const base = this.themeManager.getTheme();\n const marketTheme: Theme = {\n ...base,\n candleUp: config.colorScheme.up,\n candleDown: config.colorScheme.down,\n candleUpWick: config.colorScheme.up,\n candleDownWick: config.colorScheme.down,\n volumeUp: config.colorScheme.up.replace(')', ', 0.3)').replace('rgb(', 'rgba(') || `${config.colorScheme.up}4D`,\n volumeDown: config.colorScheme.down.replace(')', ', 0.3)').replace('rgb(', 'rgba(') || `${config.colorScheme.down}4D`,\n };\n this.themeManager.setTheme(marketTheme);\n }\n\n // Apply price precision to trading, alerts, and price line\n if (config.pricePrecision !== undefined) {\n this.tradingManager.setConfig({ pricePrecision: config.pricePrecision });\n this.alertManager.setPricePrecision(config.pricePrecision);\n this.streamManager?.priceLine.setPricePrecision(config.pricePrecision);\n this.crosshairHandler.setPricePrecision(config.pricePrecision);\n }\n\n this.syncRenderContext();\n this.engine.requestRender();\n }\n\n getMarket(): MarketConfig | null {\n return this.marketConfig;\n }\n\n setPriceLimits(referencePrice: number): void {\n if (!this.marketConfig) return;\n const limits = computePriceLimits(referencePrice, this.marketConfig);\n if (limits) {\n this.marketConfig.priceLimits = {\n ...this.marketConfig.priceLimits!,\n referencePrice,\n };\n }\n this.engine.requestRender();\n }\n\n // --- Features ---\n\n /** Get the resolved feature configuration */\n getFeatures(): Readonly<Required<FeaturesConfig>> {\n return this.features;\n }\n\n /** Update feature flags at runtime. Only provided keys are changed. */\n setFeatures(patch: Partial<FeaturesConfig>): void {\n Object.assign(this.features, patch);\n\n // Apply immediate side-effects\n if (patch.crosshair === false) {\n this.crosshairTooltip.hide();\n }\n if (patch.grid !== undefined) {\n this.engine.requestRender(LayerType.Background);\n }\n if (patch.volume !== undefined) {\n this.volumeRenderer.setVisible(patch.volume);\n this.engine.requestRender(LayerType.Main);\n }\n if (patch.drawings === false) {\n this.drawingManager.setActiveTool(null);\n }\n if (patch.trading === false) {\n this.tradingManager.setOrders([]);\n this.tradingManager.setPositions([]);\n }\n\n this.engine.requestRender();\n }\n\n // --- Lifecycle ---\n\n resize(): void {\n const size = this.engine.dprManager.readContainerSize();\n if (size.width <= 0 || size.height <= 0) return;\n this.containerSizeCache = size;\n this.containerSizeCacheTime = Date.now();\n // Resize canvas layers immediately (don't wait for DPRManager's debounced callback)\n const dpr = this.engine.dprManager.getDpr();\n this.engine.layerManager.resize(size, dpr);\n // Check if viewport was at the end before resize\n const wasAtEnd = this.viewport.isAtEnd();\n this.viewport.resize(size.width, size.height);\n this.layoutManager.resize(size.width, size.height);\n this.updateViewportAndRender(wasAtEnd);\n this.eventBus.emit('resize', size);\n }\n\n destroy(): void {\n if (this.countdownInterval) clearInterval(this.countdownInterval);\n this.disableAutoSave();\n this.disconnectStream();\n this.interactionManager.detach();\n this.tradingManager.destroy();\n this.animator.dispose();\n this.crosshairTooltip.destroy();\n this.replayManager.dispose();\n this.undoRedoManager.clear();\n this.engine.destroy();\n this.eventBus.destroy();\n this.container.innerHTML = '';\n }\n\n // --- Internal ---\n\n private createChartRenderer(type: ChartType): ChartRendererInterface {\n switch (type) {\n case 'candlestick': return new CandlestickRenderer();\n case 'heikinAshi': return new CandlestickRenderer(); // Same renderer, different data\n case 'line': return new LineRenderer();\n case 'area': return new AreaRenderer();\n case 'bar': return new BarRenderer();\n case 'hollowCandle': return new HollowCandleRenderer();\n case 'baseline': return new BaselineRenderer();\n case 'renko': return new RenkoRenderer();\n case 'lineBreak': return new CandlestickRenderer(); // Candle renderer on transformed data\n case 'kagi': return new KagiRenderer();\n case 'pointAndFigure': return new PointAndFigureRenderer();\n default: return new CandlestickRenderer();\n }\n }\n\n /** Cached display data. Invalidated when raw data or chart type changes. */\n private getDisplayData(): DataSeries {\n if (this.displayDataCache) return this.displayDataCache;\n\n const raw = this.dataManager.getData();\n if (raw.length === 0) return raw;\n\n let result: DataSeries;\n switch (this.options.chartType) {\n case 'heikinAshi': result = toHeikinAshi(raw); break;\n case 'renko': result = toRenko(raw, { brickSize: 0, useATR: true, atrPeriod: 14 }); break;\n case 'lineBreak': result = toLineBreak(raw, 3); break;\n case 'kagi': result = toKagi(raw, 4); break;\n case 'pointAndFigure': {\n const avgPrice = raw.reduce((s, b) => s + b.close, 0) / raw.length;\n result = toPointAndFigure(raw, avgPrice * 0.01, 3);\n break;\n }\n default: result = raw;\n }\n this.displayDataCache = result;\n return result;\n }\n\n /** Lightweight render for streaming updates. No layout resolve, no indicator recalc. */\n private scheduleRender(): void {\n if (this.renderScheduled) return;\n this.renderScheduled = true;\n requestAnimationFrame(() => {\n this.renderScheduled = false;\n const displayData = this.getDisplayData();\n this.viewport.updateData(displayData, this.options.autoScale !== false);\n this.syncRenderContext();\n this.engine.requestRender();\n });\n }\n\n /** Full update: resolve layout, update viewport, sync context, request render. */\n private updateViewportAndRender(scrollToEnd = false): void {\n // Invalidate layout cache\n this.resolvedLayoutCache = null;\n this.panelInfoCache = null;\n\n const resolved = this.getResolvedLayout();\n this.viewport.setChartRect(resolved.mainChartRect);\n\n const displayData = this.getDisplayData();\n this.viewport.updateData(displayData, this.options.autoScale !== false);\n\n // Scroll to end AFTER updateData so dataLength is current\n if (scrollToEnd) this.viewport.scrollToEnd();\n\n this.syncRenderContext();\n this.engine.requestRender();\n }\n\n private getResolvedLayout() {\n if (!this.resolvedLayoutCache) {\n this.resolvedLayoutCache = this.layoutManager.resolve();\n }\n return this.resolvedLayoutCache;\n }\n\n /** Cache container size for 500ms to avoid layout thrashing on rapid calls */\n private cachedContainerSize(): { width: number; height: number } {\n const now = Date.now();\n if (!this.containerSizeCache || now - this.containerSizeCacheTime > 500) {\n this.containerSizeCache = this.engine.dprManager.getContainerSize();\n this.containerSizeCacheTime = now;\n }\n return this.containerSizeCache;\n }\n\n private buildPanelRenderInfos(): import('@tradecanvas/core').PanelRenderInfo[] {\n if (this.panelInfoCache) return this.panelInfoCache;\n\n const resolved = this.getResolvedLayout();\n const mainVP = this.viewport.getState();\n\n const panels = resolved.panels.map((panel) => {\n const output = this.indicatorEngine.getOutput(panel.config.id);\n let min = 0, max = 100;\n\n if (output) {\n let vMin = Infinity, vMax = -Infinity;\n const { from, to } = mainVP.visibleRange;\n let idx = 0;\n for (const [, val] of output.values) {\n if (idx >= from && idx <= to) {\n for (const key in val) {\n const v = val[key];\n if (v !== undefined) {\n if (v < vMin) vMin = v;\n if (v > vMax) vMax = v;\n }\n }\n }\n idx++;\n }\n if (vMin !== Infinity) {\n const range = vMax - vMin || 1;\n min = vMin - range * 0.1;\n max = vMax + range * 0.1;\n }\n }\n\n // Inset the indicator drawing area below the panel header (title + divider)\n const PANEL_HEADER_HEIGHT = 20;\n const insetRect = {\n x: panel.rect.x,\n y: panel.rect.y + PANEL_HEADER_HEIGHT,\n width: panel.rect.width,\n height: Math.max(0, panel.rect.height - PANEL_HEADER_HEIGHT),\n };\n\n return {\n instanceId: panel.config.id,\n rect: panel.rect,\n viewport: {\n ...mainVP,\n chartRect: insetRect,\n priceRange: { min, max },\n },\n };\n });\n\n this.panelInfoCache = panels;\n return panels;\n }\n\n private syncRenderContext(): void {\n const resolved = this.getResolvedLayout();\n const panels = this.features.indicators ? this.buildPanelRenderInfos() : [];\n\n // Compute where the time axis should render: below main chart + all bottom panels\n const bottomPanelHeight = resolved.panels\n .filter(p => p.config.position === 'bottom')\n .reduce((sum, p) => sum + p.rect.height, 0);\n const timeAxisY = resolved.mainChartRect.y + resolved.mainChartRect.height + bottomPanelHeight;\n\n this.engine.setRenderContext({\n chartRenderer: this.chartRenderer,\n gridRenderer: this.features.grid ? this.gridRenderer : null,\n priceAxis: this.features.priceAxis ? this.priceAxis : null,\n timeAxis: this.features.timeAxis ? this.timeAxis : null,\n crosshairHandler: this.features.crosshair ? this.crosshairHandler : null,\n indicatorEngine: this.features.indicators ? this.indicatorEngine : null,\n drawingRenderer: this.features.drawings ? this.drawingRenderer : null,\n tradingRenderer: this.features.trading ? this.tradingRenderer : null,\n currentPriceLine: this.streamManager?.priceLine ?? this.currentPriceLine,\n chartLegend: this.features.legend ? this.chartLegend : null,\n volumeRenderer: this.features.volume ? this.volumeRenderer : null,\n watermark: this.features.watermark ? this.watermark : null,\n barCountdown: this.barCountdown,\n sessionBreaks: this.sessionBreaks,\n compareRenderer: this.compareRenderer,\n panels,\n priceLimits: this.buildPriceLimits(),\n timeAxisY,\n viewport: this.viewport.getState(),\n theme: this.themeManager.getTheme(),\n data: this.getDisplayData(),\n });\n }\n\n private timeframeToMs(tf: string): number {\n const match = tf.match(/^(\\d+)([smhdwMy])$/);\n if (!match) return 0;\n const n = parseInt(match[1], 10);\n switch (match[2]) {\n case 's': return n * 1000;\n case 'm': return n * 60_000;\n case 'h': return n * 3_600_000;\n case 'd': return n * 86_400_000;\n case 'w': return n * 604_800_000;\n case 'M': return n * 2_592_000_000;\n default: return 0;\n }\n }\n\n private buildPriceLimits() {\n if (!this.marketConfig?.priceLimits?.enabled || !this.marketConfig.priceLimits.referencePrice) return null;\n const limits = computePriceLimits(this.marketConfig.priceLimits.referencePrice, this.marketConfig);\n if (!limits) return null;\n return {\n ...limits,\n colors: this.marketConfig.colorScheme ? {\n ceiling: this.marketConfig.colorScheme.ceiling,\n floor: this.marketConfig.colorScheme.floor,\n reference: this.marketConfig.colorScheme.reference,\n } : undefined,\n };\n }\n}\n"],"mappings":"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"}
|