@tradecanvas/chart 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +86 -4
  2. package/dist/Chart.d.ts +11 -0
  3. package/dist/Chart.d.ts.map +1 -1
  4. package/dist/{Chart-Cn_TSMO7.js → DragDropImporter-6QOjnfSj.js} +361 -85
  5. package/dist/DragDropImporter-6QOjnfSj.js.map +1 -0
  6. package/dist/DragDropImporter-CQ3EarQn.cjs +2 -0
  7. package/dist/DragDropImporter-CQ3EarQn.cjs.map +1 -0
  8. package/dist/index.cjs +1 -1
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.ts +2 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +26 -26
  13. package/dist/index.js.map +1 -1
  14. package/dist/io/DragDropImporter.d.ts +34 -0
  15. package/dist/io/DragDropImporter.d.ts.map +1 -0
  16. package/dist/io/index.d.ts +5 -0
  17. package/dist/io/index.d.ts.map +1 -0
  18. package/dist/io/parseOHLCV.d.ts +21 -0
  19. package/dist/io/parseOHLCV.d.ts.map +1 -0
  20. package/dist/widget/ChartWidget.d.ts +46 -1
  21. package/dist/widget/ChartWidget.d.ts.map +1 -1
  22. package/dist/widget/WidgetHotkeySheet.d.ts +20 -0
  23. package/dist/widget/WidgetHotkeySheet.d.ts.map +1 -0
  24. package/dist/widget/WidgetReplayBar.d.ts +41 -0
  25. package/dist/widget/WidgetReplayBar.d.ts.map +1 -0
  26. package/dist/widget/WidgetSettings.d.ts.map +1 -1
  27. package/dist/widget/WidgetSymbolSearch.d.ts +32 -0
  28. package/dist/widget/WidgetSymbolSearch.d.ts.map +1 -0
  29. package/dist/widget/WidgetToolbar.d.ts.map +1 -1
  30. package/dist/widget/WidgetWatchlist.d.ts +39 -0
  31. package/dist/widget/WidgetWatchlist.d.ts.map +1 -0
  32. package/dist/widget/index.cjs +1455 -877
  33. package/dist/widget/index.cjs.map +1 -1
  34. package/dist/widget/index.js +695 -92
  35. package/dist/widget/index.js.map +1 -1
  36. package/dist/widget/types.d.ts +19 -0
  37. package/dist/widget/types.d.ts.map +1 -1
  38. package/dist/widget/widgetConfig.d.ts.map +1 -1
  39. package/package.json +3 -3
  40. package/dist/Chart-Br_N-BCL.cjs +0 -2
  41. package/dist/Chart-Br_N-BCL.cjs.map +0 -1
  42. package/dist/Chart-Cn_TSMO7.js.map +0 -1
@@ -1,878 +1,1456 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../Chart-Br_N-BCL.cjs`);let t=require(`@tradecanvas/commons`);var n=[{label:`1m`,value:`1m`},{label:`5m`,value:`5m`},{label:`15m`,value:`15m`},{label:`1H`,value:`1h`},{label:`4H`,value:`4h`},{label:`1D`,value:`1d`}],r=[{label:`Candlestick`,value:`candlestick`},{label:`Line`,value:`line`},{label:`Area`,value:`area`},{label:`Bar`,value:`bar`},{label:`Heikin-Ashi`,value:`heikinAshi`},{label:`Hollow Candle`,value:`hollowCandle`},{label:`Baseline`,value:`baseline`},{label:`Volume Candles`,value:`volumeCandles`},{label:`Equivolume`,value:`equivolume`},{label:`HLC Area`,value:`hlcArea`},{label:`Step Line`,value:`stepLine`},{label:`Line + Markers`,value:`lineWithMarkers`}],i=[{label:`Lines`,tools:[{label:`Trend Line`,value:`trendLine`},{label:`Ray`,value:`ray`},{label:`Extended Line`,value:`extendedLine`}]},{label:`Horizontal/Vertical`,tools:[{label:`Horizontal Line`,value:`horizontalLine`},{label:`Vertical Line`,value:`verticalLine`}]},{label:`Channels`,tools:[{label:`Parallel Channel`,value:`parallelChannel`},{label:`Regression Channel`,value:`regressionChannel`}]},{label:`Fibonacci`,tools:[{label:`Fib Retracement`,value:`fibRetracement`},{label:`Fib Extension`,value:`fibExtension`}]},{label:`Shapes`,tools:[{label:`Rectangle`,value:`rectangle`},{label:`Ellipse`,value:`ellipse`},{label:`Triangle`,value:`triangle`}]},{label:`Gann & Advanced`,tools:[{label:`Pitchfork`,value:`pitchfork`},{label:`Gann Fan`,value:`gannFan`},{label:`Gann Box`,value:`gannBox`},{label:`Elliott Wave`,value:`elliottWave`}]},{label:`Measure`,tools:[{label:`Price Range`,value:`priceRange`},{label:`Date Range`,value:`dateRange`},{label:`Measure`,value:`measure`}]},{label:`Annotation`,tools:[{label:`Text`,value:`text`},{label:`Arrow`,value:`arrow`}]}],a=[{id:`sma`,name:`SMA`,type:`overlay`},{id:`ema`,name:`EMA`,type:`overlay`},{id:`hma`,name:`Hull MA`,type:`overlay`},{id:`bb`,name:`Bollinger Bands`,type:`overlay`},{id:`vwap`,name:`VWAP`,type:`overlay`},{id:`avwap`,name:`Anchored VWAP`,type:`overlay`},{id:`ichimoku`,name:`Ichimoku Cloud`,type:`overlay`},{id:`psar`,name:`Parabolic SAR`,type:`overlay`},{id:`supertrend`,name:`Supertrend`,type:`overlay`},{id:`keltner`,name:`Keltner Channel`,type:`overlay`},{id:`donchian`,name:`Donchian Channel`,type:`overlay`},{id:`pivots`,name:`Pivot Points`,type:`overlay`},{id:`zigzag`,name:`ZigZag`,type:`overlay`},{id:`lrc`,name:`Linear Regression Channel`,type:`overlay`},{id:`rsi`,name:`RSI`,type:`panel`},{id:`macd`,name:`MACD`,type:`panel`},{id:`stochastic`,name:`Stochastic`,type:`panel`},{id:`atr`,name:`ATR`,type:`panel`},{id:`adx`,name:`ADX`,type:`panel`},{id:`obv`,name:`OBV`,type:`panel`},{id:`williamsR`,name:`Williams %R`,type:`panel`},{id:`cci`,name:`CCI`,type:`panel`},{id:`mfi`,name:`MFI`,type:`panel`},{id:`roc`,name:`ROC`,type:`panel`},{id:`tsi`,name:`TSI`,type:`panel`},{id:`cmf`,name:`CMF`,type:`panel`},{id:`aroon`,name:`Aroon`,type:`panel`},{id:`stddev`,name:`Std Deviation`,type:`panel`},{id:`vroc`,name:`Volume ROC`,type:`panel`},{id:`ad`,name:`Acc/Dist`,type:`panel`},{id:`ao`,name:`Awesome Oscillator`,type:`panel`},{id:`chaikinOsc`,name:`Chaikin Oscillator`,type:`panel`},{id:`volumeProfile`,name:`Volume Profile`,type:`panel`}],o=[`sma`,`ema`,`bb`,`rsi`,`macd`,`stochastic`,`vwap`,`atr`,`obv`,`ichimoku`],s=[`BTCUSDT`,`ETHUSDT`,`SOLUSDT`,`BNBUSDT`],c={candleUpColor:`#26A69A`,candleDownColor:`#EF5350`,candleUpWick:`#26A69A`,candleDownWick:`#EF5350`,backgroundColor:`#131722`,gridColor:`#1E222D`,gridVisible:!0,volumeVisible:!0,legendVisible:!0,barCountdown:!0,logScale:!1,autoScale:!0,crosshairMode:`magnet`,numberLocale:`en-US`},l=`/* === TradeCanvas Widget Styles === */\r
2
- \r
3
- .tcw-root {\r
4
- display: flex;\r
5
- flex-direction: column;\r
6
- width: 100%;\r
7
- height: 100%;\r
8
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\r
9
- font-size: 13px;\r
10
- color: #d1d4dc;\r
11
- background: #131722;\r
12
- position: relative;\r
13
- overflow: hidden;\r
14
- \r
15
- /* Dark theme tokens (default) */\r
16
- --tcw-bg: #131722;\r
17
- --tcw-bg-elevated: #1E222D;\r
18
- --tcw-border: #2A2E39;\r
19
- --tcw-text: #d1d4dc;\r
20
- --tcw-text-dim: #b2b5be;\r
21
- --tcw-text-muted: #787b86;\r
22
- --tcw-accent: #2962ff;\r
23
- --tcw-accent-dim: rgba(41,98,255,0.15);\r
24
- --tcw-accent-glow: rgba(41,98,255,0.12);\r
25
- --tcw-red: #ef5350;\r
26
- --tcw-green: #26a69a;\r
27
- --tcw-transition: 0.15s ease;\r
28
- --tcw-radius-lg: 8px;\r
29
- --tcw-font-mono: 'SF Mono', 'Fira Code', 'Consolas', monospace;\r
30
- --tcw-hover-bg: rgba(255,255,255,0.04);\r
31
- }\r
32
- \r
33
- .tcw-root[data-tcw-theme="light"] {\r
34
- color: #131722;\r
35
- background: #ffffff;\r
36
- \r
37
- --tcw-bg: #ffffff;\r
38
- --tcw-bg-elevated: #f0f3fa;\r
39
- --tcw-border: #e0e3eb;\r
40
- --tcw-text: #131722;\r
41
- --tcw-text-dim: #434651;\r
42
- --tcw-text-muted: #787b86;\r
43
- --tcw-accent: #2962ff;\r
44
- --tcw-accent-dim: rgba(41,98,255,0.1);\r
45
- --tcw-accent-glow: rgba(41,98,255,0.08);\r
46
- --tcw-red: #ef5350;\r
47
- --tcw-green: #26a69a;\r
48
- --tcw-hover-bg: rgba(0,0,0,0.04);\r
49
- }\r
50
- \r
51
- /* === Toolbar === */\r
52
- \r
53
- .tcw-toolbar {\r
54
- display: flex;\r
55
- align-items: center;\r
56
- gap: 0;\r
57
- padding: 0 12px;\r
58
- height: 40px;\r
59
- border-bottom: 1px solid var(--tcw-border);\r
60
- background: var(--tcw-bg-elevated);\r
61
- flex-shrink: 0;\r
62
- position: relative;\r
63
- z-index: 20;\r
64
- }\r
65
- \r
66
- .tcw-toolbar-symbol {\r
67
- font-size: 13px;\r
68
- font-weight: 700;\r
69
- color: var(--tcw-text);\r
70
- padding: 0 10px;\r
71
- white-space: nowrap;\r
72
- letter-spacing: -0.01em;\r
73
- cursor: pointer;\r
74
- border: none;\r
75
- background: none;\r
76
- font-family: inherit;\r
77
- }\r
78
- \r
79
- .tcw-toolbar-sep {\r
80
- width: 1px;\r
81
- height: 20px;\r
82
- background: var(--tcw-border);\r
83
- flex-shrink: 0;\r
84
- }\r
85
- \r
86
- .tcw-toolbar-group {\r
87
- display: flex;\r
88
- align-items: center;\r
89
- gap: 2px;\r
90
- padding: 0 8px;\r
91
- }\r
92
- \r
93
- .tcw-toolbar-spacer {\r
94
- flex: 1;\r
95
- }\r
96
- \r
97
- .tcw-btn {\r
98
- padding: 4px 8px;\r
99
- font-size: 12px;\r
100
- font-family: inherit;\r
101
- border: none;\r
102
- border-radius: 4px;\r
103
- background: transparent;\r
104
- color: var(--tcw-text-dim);\r
105
- cursor: pointer;\r
106
- transition: all var(--tcw-transition);\r
107
- white-space: nowrap;\r
108
- line-height: 1;\r
109
- }\r
110
- \r
111
- .tcw-btn:hover {\r
112
- background: var(--tcw-hover-bg);\r
113
- color: var(--tcw-text);\r
114
- }\r
115
- \r
116
- .tcw-btn.tcw-active {\r
117
- background: var(--tcw-accent);\r
118
- color: white;\r
119
- }\r
120
- \r
121
- .tcw-btn-icon {\r
122
- width: 32px;\r
123
- height: 32px;\r
124
- display: inline-flex;\r
125
- align-items: center;\r
126
- justify-content: center;\r
127
- font-family: inherit;\r
128
- border: none;\r
129
- border-radius: 4px;\r
130
- background: transparent;\r
131
- color: var(--tcw-text-muted);\r
132
- cursor: pointer;\r
133
- transition: all var(--tcw-transition);\r
134
- line-height: 1;\r
135
- position: relative;\r
136
- }\r
137
- \r
138
- .tcw-btn-icon:hover {\r
139
- background: var(--tcw-hover-bg);\r
140
- color: var(--tcw-text);\r
141
- }\r
142
- \r
143
- .tcw-badge-count {\r
144
- font-size: 10px;\r
145
- color: var(--tcw-accent);\r
146
- background: var(--tcw-accent-dim);\r
147
- padding: 0 4px;\r
148
- border-radius: 8px;\r
149
- font-weight: 600;\r
150
- }\r
151
- \r
152
- .tcw-indicator-chips {\r
153
- display: flex;\r
154
- align-items: center;\r
155
- gap: 4px;\r
156
- padding: 0 4px;\r
157
- flex-wrap: nowrap;\r
158
- overflow: hidden;\r
159
- }\r
160
- \r
161
- .tcw-indicator-chip {\r
162
- display: inline-flex;\r
163
- align-items: center;\r
164
- gap: 4px;\r
165
- padding: 2px 6px 2px 8px;\r
166
- font-size: 11px;\r
167
- font-weight: 500;\r
168
- background: var(--tcw-accent-dim);\r
169
- color: var(--tcw-accent);\r
170
- border-radius: 4px;\r
171
- white-space: nowrap;\r
172
- line-height: 1.4;\r
173
- }\r
174
- \r
175
- .tcw-chip-remove {\r
176
- cursor: pointer;\r
177
- opacity: 0.6;\r
178
- padding: 0 2px;\r
179
- transition: opacity var(--tcw-transition);\r
180
- border: none;\r
181
- background: none;\r
182
- color: inherit;\r
183
- display: inline-flex;\r
184
- align-items: center;\r
185
- }\r
186
- \r
187
- .tcw-chip-remove:hover {\r
188
- opacity: 1;\r
189
- }\r
190
- \r
191
- /* === Dropdown === */\r
192
- \r
193
- .tcw-dropdown-trigger {\r
194
- display: inline-flex;\r
195
- align-items: center;\r
196
- gap: 4px;\r
197
- padding: 4px 8px;\r
198
- font-size: 12px;\r
199
- font-family: inherit;\r
200
- border: none;\r
201
- border-radius: 4px;\r
202
- background: transparent;\r
203
- color: var(--tcw-text-dim);\r
204
- cursor: pointer;\r
205
- transition: all var(--tcw-transition);\r
206
- white-space: nowrap;\r
207
- line-height: 1;\r
208
- }\r
209
- \r
210
- .tcw-dropdown-trigger:hover {\r
211
- background: var(--tcw-hover-bg);\r
212
- color: var(--tcw-text);\r
213
- }\r
214
- \r
215
- .tcw-dropdown {\r
216
- position: absolute;\r
217
- top: 100%;\r
218
- margin-top: 4px;\r
219
- background: var(--tcw-bg-elevated);\r
220
- border: 1px solid var(--tcw-border);\r
221
- border-radius: var(--tcw-radius-lg);\r
222
- box-shadow: 0 8px 32px rgba(0,0,0,0.4);\r
223
- z-index: 50;\r
224
- padding: 4px 0;\r
225
- max-height: 400px;\r
226
- overflow-y: auto;\r
227
- }\r
228
- \r
229
- .tcw-dropdown-item {\r
230
- display: flex;\r
231
- align-items: center;\r
232
- justify-content: space-between;\r
233
- padding: 6px 12px;\r
234
- font-size: 12px;\r
235
- color: var(--tcw-text-dim);\r
236
- cursor: pointer;\r
237
- transition: background var(--tcw-transition), color var(--tcw-transition);\r
238
- width: 100%;\r
239
- border: none;\r
240
- background: none;\r
241
- font-family: inherit;\r
242
- text-align: left;\r
243
- }\r
244
- \r
245
- .tcw-dropdown-item:hover {\r
246
- background: var(--tcw-hover-bg);\r
247
- color: var(--tcw-text);\r
248
- }\r
249
- \r
250
- .tcw-dropdown-item.tcw-active {\r
251
- color: var(--tcw-accent);\r
252
- }\r
253
- \r
254
- .tcw-dropdown-label {\r
255
- text-transform: uppercase;\r
256
- font-size: 10px;\r
257
- color: var(--tcw-text-muted);\r
258
- letter-spacing: 0.05em;\r
259
- padding: 6px 12px;\r
260
- font-weight: 600;\r
261
- }\r
262
- \r
263
- .tcw-dropdown-divider {\r
264
- border-top: 1px solid var(--tcw-border);\r
265
- margin: 4px 0;\r
266
- }\r
267
- \r
268
- .tcw-tag {\r
269
- font-size: 10px;\r
270
- color: var(--tcw-text-muted);\r
271
- padding: 1px 5px;\r
272
- border-radius: 3px;\r
273
- background: var(--tcw-hover-bg);\r
274
- }\r
275
- \r
276
- /* === Body === */\r
277
- \r
278
- .tcw-body {\r
279
- display: flex;\r
280
- flex: 1;\r
281
- min-height: 0;\r
282
- }\r
283
- \r
284
- .tcw-chart-container {\r
285
- flex: 1;\r
286
- min-width: 0;\r
287
- min-height: 0;\r
288
- width: 100%;\r
289
- height: 100%;\r
290
- }\r
291
- \r
292
- /* === Sidebar === */\r
293
- \r
294
- .tcw-sidebar {\r
295
- width: 36px;\r
296
- flex-shrink: 0;\r
297
- background: var(--tcw-bg-elevated);\r
298
- border-right: 1px solid var(--tcw-border);\r
299
- display: flex;\r
300
- flex-direction: column;\r
301
- align-items: center;\r
302
- padding: 4px 0;\r
303
- overflow: visible;\r
304
- }\r
305
- \r
306
- .tcw-tool-group-wrap {\r
307
- position: relative;\r
308
- }\r
309
- \r
310
- .tcw-sidebar-btn {\r
311
- width: 36px;\r
312
- height: 32px;\r
313
- display: flex;\r
314
- align-items: center;\r
315
- justify-content: center;\r
316
- border: none;\r
317
- background: transparent;\r
318
- color: var(--tcw-text-muted);\r
319
- cursor: pointer;\r
320
- font-family: inherit;\r
321
- transition: all var(--tcw-transition);\r
322
- position: relative;\r
323
- flex-shrink: 0;\r
324
- line-height: 1;\r
325
- }\r
326
- \r
327
- .tcw-sidebar-btn:hover {\r
328
- color: var(--tcw-text);\r
329
- background: var(--tcw-hover-bg);\r
330
- }\r
331
- \r
332
- .tcw-sidebar-btn.tcw-active {\r
333
- color: var(--tcw-accent);\r
334
- background: var(--tcw-accent-glow);\r
335
- }\r
336
- \r
337
- .tcw-sidebar-btn.tcw-danger:hover {\r
338
- color: var(--tcw-red);\r
339
- background: rgba(239,68,68,0.1);\r
340
- }\r
341
- \r
342
- .tcw-multi-dot {\r
343
- position: absolute;\r
344
- bottom: 2px;\r
345
- right: 2px;\r
346
- width: 4px;\r
347
- height: 4px;\r
348
- border-radius: 50%;\r
349
- background: var(--tcw-text-muted);\r
350
- }\r
351
- \r
352
- .tcw-sidebar-divider {\r
353
- width: 20px;\r
354
- height: 1px;\r
355
- background: var(--tcw-border);\r
356
- margin: 4px 0;\r
357
- flex-shrink: 0;\r
358
- }\r
359
- \r
360
- .tcw-sidebar-spacer {\r
361
- flex: 1;\r
362
- }\r
363
- \r
364
- /* === Flyout === */\r
365
- \r
366
- .tcw-flyout {\r
367
- position: absolute;\r
368
- left: 100%;\r
369
- top: 0;\r
370
- margin-left: 2px;\r
371
- min-width: 160px;\r
372
- background: var(--tcw-bg-elevated);\r
373
- border: 1px solid var(--tcw-border);\r
374
- border-radius: var(--tcw-radius-lg);\r
375
- box-shadow: 0 8px 32px rgba(0,0,0,0.4);\r
376
- z-index: 30;\r
377
- padding: 4px 0;\r
378
- }\r
379
- \r
380
- .tcw-flyout-header {\r
381
- text-transform: uppercase;\r
382
- font-size: 10px;\r
383
- color: var(--tcw-text-muted);\r
384
- letter-spacing: 0.05em;\r
385
- padding: 6px 12px;\r
386
- font-weight: 600;\r
387
- }\r
388
- \r
389
- .tcw-flyout-item {\r
390
- padding: 6px 12px;\r
391
- font-size: 12px;\r
392
- color: var(--tcw-text-dim);\r
393
- cursor: pointer;\r
394
- width: 100%;\r
395
- display: block;\r
396
- border: none;\r
397
- background: none;\r
398
- text-align: left;\r
399
- font-family: inherit;\r
400
- transition: background var(--tcw-transition), color var(--tcw-transition);\r
401
- }\r
402
- \r
403
- .tcw-flyout-item:hover {\r
404
- background: var(--tcw-hover-bg);\r
405
- color: var(--tcw-text);\r
406
- }\r
407
- \r
408
- .tcw-flyout-item.tcw-active {\r
409
- color: var(--tcw-accent);\r
410
- }\r
411
- \r
412
- /* === Modal === */\r
413
- \r
414
- .tcw-modal-backdrop {\r
415
- position: fixed;\r
416
- inset: 0;\r
417
- background: rgba(0,0,0,0.5);\r
418
- backdrop-filter: blur(4px);\r
419
- -webkit-backdrop-filter: blur(4px);\r
420
- z-index: 100;\r
421
- }\r
422
- \r
423
- .tcw-modal {\r
424
- position: fixed;\r
425
- z-index: 101;\r
426
- top: 50%;\r
427
- left: 50%;\r
428
- transform: translate(-50%, -50%);\r
429
- background: var(--tcw-bg-elevated);\r
430
- border: 1px solid var(--tcw-border);\r
431
- border-radius: var(--tcw-radius-lg);\r
432
- width: 480px;\r
433
- max-width: 90vw;\r
434
- max-height: 80vh;\r
435
- display: flex;\r
436
- flex-direction: column;\r
437
- box-shadow: 0 24px 64px rgba(0,0,0,0.5);\r
438
- }\r
439
- \r
440
- .tcw-modal-header {\r
441
- display: flex;\r
442
- align-items: center;\r
443
- justify-content: space-between;\r
444
- padding: 16px 20px;\r
445
- border-bottom: 1px solid var(--tcw-border);\r
446
- }\r
447
- \r
448
- .tcw-modal-header h3 {\r
449
- font-size: 15px;\r
450
- font-weight: 600;\r
451
- margin: 0;\r
452
- color: var(--tcw-text);\r
453
- }\r
454
- \r
455
- .tcw-modal-close {\r
456
- width: 28px;\r
457
- height: 28px;\r
458
- display: flex;\r
459
- align-items: center;\r
460
- justify-content: center;\r
461
- border: none;\r
462
- background: transparent;\r
463
- color: var(--tcw-text-muted);\r
464
- cursor: pointer;\r
465
- border-radius: 4px;\r
466
- transition: all var(--tcw-transition);\r
467
- }\r
468
- \r
469
- .tcw-modal-close:hover {\r
470
- background: var(--tcw-hover-bg);\r
471
- color: var(--tcw-text);\r
472
- }\r
473
- \r
474
- .tcw-modal-tabs {\r
475
- display: flex;\r
476
- gap: 0;\r
477
- padding: 0 20px;\r
478
- border-bottom: 1px solid var(--tcw-border);\r
479
- }\r
480
- \r
481
- .tcw-modal-tab {\r
482
- padding: 10px 16px;\r
483
- font-size: 12px;\r
484
- font-weight: 500;\r
485
- color: var(--tcw-text-muted);\r
486
- border: none;\r
487
- background: none;\r
488
- cursor: pointer;\r
489
- border-bottom: 2px solid transparent;\r
490
- margin-bottom: -1px;\r
491
- transition: color var(--tcw-transition);\r
492
- font-family: inherit;\r
493
- text-transform: capitalize;\r
494
- }\r
495
- \r
496
- .tcw-modal-tab:hover {\r
497
- color: var(--tcw-text-dim);\r
498
- }\r
499
- \r
500
- .tcw-modal-tab.tcw-active {\r
501
- color: var(--tcw-accent);\r
502
- border-bottom-color: var(--tcw-accent);\r
503
- }\r
504
- \r
505
- .tcw-modal-body {\r
506
- padding: 20px;\r
507
- overflow-y: auto;\r
508
- flex: 1;\r
509
- }\r
510
- \r
511
- .tcw-settings-section {\r
512
- margin-bottom: 20px;\r
513
- }\r
514
- \r
515
- .tcw-settings-section:last-child {\r
516
- margin-bottom: 0;\r
517
- }\r
518
- \r
519
- .tcw-settings-section-title {\r
520
- font-size: 11px;\r
521
- font-weight: 600;\r
522
- text-transform: uppercase;\r
523
- letter-spacing: 0.05em;\r
524
- color: var(--tcw-text-muted);\r
525
- margin-bottom: 12px;\r
526
- }\r
527
- \r
528
- .tcw-settings-row {\r
529
- display: flex;\r
530
- align-items: center;\r
531
- justify-content: space-between;\r
532
- padding: 8px 0;\r
533
- }\r
534
- \r
535
- .tcw-settings-row + .tcw-settings-row {\r
536
- border-top: 1px solid rgba(255,255,255,0.03);\r
537
- }\r
538
- \r
539
- .tcw-root[data-tcw-theme="light"] .tcw-settings-row + .tcw-settings-row {\r
540
- border-top: 1px solid rgba(0,0,0,0.04);\r
541
- }\r
542
- \r
543
- .tcw-settings-label {\r
544
- font-size: 13px;\r
545
- color: var(--tcw-text-dim);\r
546
- }\r
547
- \r
548
- .tcw-color-picker-wrap {\r
549
- display: flex;\r
550
- align-items: center;\r
551
- gap: 6px;\r
552
- }\r
553
- \r
554
- .tcw-color-picker-wrap input[type='color'] {\r
555
- width: 28px;\r
556
- height: 28px;\r
557
- border: 1px solid var(--tcw-border);\r
558
- border-radius: 4px;\r
559
- background: none;\r
560
- cursor: pointer;\r
561
- padding: 2px;\r
562
- }\r
563
- \r
564
- .tcw-color-picker-wrap input[type='color']::-webkit-color-swatch-wrapper {\r
565
- padding: 0;\r
566
- }\r
567
- \r
568
- .tcw-color-picker-wrap input[type='color']::-webkit-color-swatch {\r
569
- border: none;\r
570
- border-radius: 2px;\r
571
- }\r
572
- \r
573
- .tcw-color-hex {\r
574
- font-size: 11px;\r
575
- font-family: var(--tcw-font-mono);\r
576
- color: var(--tcw-text-muted);\r
577
- min-width: 60px;\r
578
- }\r
579
- \r
580
- .tcw-toggle {\r
581
- width: 36px;\r
582
- height: 20px;\r
583
- background: rgba(255,255,255,0.1);\r
584
- border-radius: 10px;\r
585
- position: relative;\r
586
- cursor: pointer;\r
587
- transition: background var(--tcw-transition);\r
588
- border: none;\r
589
- padding: 0;\r
590
- flex-shrink: 0;\r
591
- }\r
592
- \r
593
- .tcw-toggle::after {\r
594
- content: '';\r
595
- position: absolute;\r
596
- top: 2px;\r
597
- left: 2px;\r
598
- width: 16px;\r
599
- height: 16px;\r
600
- border-radius: 50%;\r
601
- background: var(--tcw-text-muted);\r
602
- transition: all var(--tcw-transition);\r
603
- }\r
604
- \r
605
- .tcw-toggle.tcw-on {\r
606
- background: var(--tcw-accent);\r
607
- }\r
608
- \r
609
- .tcw-toggle.tcw-on::after {\r
610
- left: 18px;\r
611
- background: white;\r
612
- }\r
613
- \r
614
- .tcw-root[data-tcw-theme="light"] .tcw-toggle {\r
615
- background: rgba(0,0,0,0.1);\r
616
- }\r
617
- \r
618
- .tcw-root[data-tcw-theme="light"] .tcw-toggle::after {\r
619
- background: #888;\r
620
- }\r
621
- \r
622
- .tcw-root[data-tcw-theme="light"] .tcw-toggle.tcw-on {\r
623
- background: var(--tcw-accent);\r
624
- }\r
625
- \r
626
- .tcw-root[data-tcw-theme="light"] .tcw-toggle.tcw-on::after {\r
627
- background: white;\r
628
- }\r
629
- \r
630
- .tcw-settings-select {\r
631
- padding: 4px 8px;\r
632
- font-size: 12px;\r
633
- font-family: inherit;\r
634
- background: var(--tcw-bg);\r
635
- border: 1px solid var(--tcw-border);\r
636
- border-radius: 4px;\r
637
- color: var(--tcw-text);\r
638
- cursor: pointer;\r
639
- }\r
640
- \r
641
- .tcw-modal-footer {\r
642
- display: flex;\r
643
- align-items: center;\r
644
- justify-content: space-between;\r
645
- padding: 12px 20px;\r
646
- border-top: 1px solid var(--tcw-border);\r
647
- }\r
648
- \r
649
- .tcw-reset-link {\r
650
- font-size: 12px;\r
651
- color: var(--tcw-text-muted);\r
652
- cursor: pointer;\r
653
- border: none;\r
654
- background: none;\r
655
- font-family: inherit;\r
656
- text-decoration: underline;\r
657
- text-underline-offset: 2px;\r
658
- transition: color var(--tcw-transition);\r
659
- }\r
660
- \r
661
- .tcw-reset-link:hover {\r
662
- color: var(--tcw-text-dim);\r
663
- }\r
664
- \r
665
- .tcw-done-btn {\r
666
- padding: 6px 16px;\r
667
- font-size: 12px;\r
668
- font-weight: 500;\r
669
- background: var(--tcw-accent);\r
670
- color: white;\r
671
- border: none;\r
672
- border-radius: 4px;\r
673
- cursor: pointer;\r
674
- font-family: inherit;\r
675
- transition: background var(--tcw-transition);\r
676
- }\r
677
- \r
678
- .tcw-done-btn:hover {\r
679
- background: #2563eb;\r
680
- }\r
681
- \r
682
- /* === Status Bar === */\r
683
- \r
684
- .tcw-statusbar {\r
685
- display: flex;\r
686
- align-items: center;\r
687
- justify-content: space-between;\r
688
- padding: 6px 16px;\r
689
- border-top: 1px solid var(--tcw-border);\r
690
- background: var(--tcw-bg-elevated);\r
691
- font-size: 11px;\r
692
- color: var(--tcw-text-muted);\r
693
- flex-shrink: 0;\r
694
- }\r
695
- \r
696
- .tcw-status-indicator {\r
697
- display: flex;\r
698
- align-items: center;\r
699
- gap: 6px;\r
700
- }\r
701
- \r
702
- .tcw-status-dot {\r
703
- width: 6px;\r
704
- height: 6px;\r
705
- border-radius: 50%;\r
706
- background: var(--tcw-text-muted);\r
707
- transition: background 0.3s;\r
708
- }\r
709
- \r
710
- .tcw-status-dot.tcw-connected {\r
711
- background: var(--tcw-green);\r
712
- }\r
713
- \r
714
- .tcw-status-dot.tcw-error {\r
715
- background: var(--tcw-red);\r
716
- }\r
717
- \r
718
- /* === Command Palette === */\r
719
- \r
720
- .tcw-cmd-palette {\r
721
- position: fixed;\r
722
- z-index: 102;\r
723
- top: 20%;\r
724
- left: 50%;\r
725
- transform: translateX(-50%);\r
726
- background: var(--tcw-bg-elevated);\r
727
- border: 1px solid var(--tcw-border);\r
728
- border-radius: var(--tcw-radius-lg);\r
729
- width: 520px;\r
730
- max-width: 90vw;\r
731
- max-height: 60vh;\r
732
- display: flex;\r
733
- flex-direction: column;\r
734
- box-shadow: 0 24px 64px rgba(0,0,0,0.5);\r
735
- overflow: hidden;\r
736
- }\r
737
- \r
738
- .tcw-cmd-header {\r
739
- display: flex;\r
740
- align-items: center;\r
741
- padding: 12px 16px;\r
742
- border-bottom: 1px solid var(--tcw-border);\r
743
- gap: 10px;\r
744
- }\r
745
- \r
746
- .tcw-cmd-icon {\r
747
- font-size: 18px;\r
748
- color: var(--tcw-text-muted);\r
749
- flex-shrink: 0;\r
750
- }\r
751
- \r
752
- .tcw-cmd-input {\r
753
- flex: 1;\r
754
- background: none;\r
755
- border: none;\r
756
- outline: none;\r
757
- font-size: 14px;\r
758
- font-family: inherit;\r
759
- color: var(--tcw-text);\r
760
- caret-color: var(--tcw-accent);\r
761
- }\r
762
- \r
763
- .tcw-cmd-input::placeholder {\r
764
- color: var(--tcw-text-muted);\r
765
- }\r
766
- \r
767
- .tcw-cmd-hint {\r
768
- font-size: 10px;\r
769
- color: var(--tcw-text-muted);\r
770
- border: 1px solid var(--tcw-border);\r
771
- padding: 2px 6px;\r
772
- border-radius: 3px;\r
773
- flex-shrink: 0;\r
774
- }\r
775
- \r
776
- .tcw-cmd-list {\r
777
- overflow-y: auto;\r
778
- flex: 1;\r
779
- padding: 4px 0;\r
780
- max-height: 360px;\r
781
- }\r
782
- \r
783
- .tcw-cmd-category {\r
784
- text-transform: uppercase;\r
785
- font-size: 10px;\r
786
- color: var(--tcw-text-muted);\r
787
- letter-spacing: 0.05em;\r
788
- padding: 8px 16px 4px;\r
789
- font-weight: 600;\r
790
- }\r
791
- \r
792
- .tcw-cmd-item {\r
793
- display: flex;\r
794
- align-items: center;\r
795
- justify-content: space-between;\r
796
- padding: 8px 16px;\r
797
- font-size: 13px;\r
798
- color: var(--tcw-text-dim);\r
799
- cursor: pointer;\r
800
- width: 100%;\r
801
- border: none;\r
802
- background: none;\r
803
- font-family: inherit;\r
804
- text-align: left;\r
805
- transition: background 80ms ease;\r
806
- gap: 8px;\r
807
- }\r
808
- \r
809
- .tcw-cmd-item:hover,\r
810
- .tcw-cmd-item.tcw-selected {\r
811
- background: var(--tcw-hover-bg);\r
812
- color: var(--tcw-text);\r
813
- }\r
814
- \r
815
- .tcw-cmd-item.tcw-active .tcw-cmd-item-label {\r
816
- color: var(--tcw-accent);\r
817
- }\r
818
- \r
819
- .tcw-cmd-item-label {\r
820
- flex: 1;\r
821
- }\r
822
- \r
823
- .tcw-cmd-check {\r
824
- color: var(--tcw-accent);\r
825
- font-size: 14px;\r
826
- font-weight: 600;\r
827
- }\r
828
- \r
829
- .tcw-cmd-kbd {\r
830
- font-size: 10px;\r
831
- font-family: var(--tcw-font-mono);\r
832
- color: var(--tcw-text-muted);\r
833
- background: var(--tcw-bg);\r
834
- border: 1px solid var(--tcw-border);\r
835
- padding: 1px 5px;\r
836
- border-radius: 3px;\r
837
- }\r
838
- \r
839
- .tcw-cmd-empty {\r
840
- padding: 24px 16px;\r
841
- text-align: center;\r
842
- color: var(--tcw-text-muted);\r
843
- font-size: 13px;\r
844
- }\r
845
- \r
846
- .tcw-cmd-footer {\r
847
- display: flex;\r
848
- align-items: center;\r
849
- gap: 16px;\r
850
- padding: 8px 16px;\r
851
- border-top: 1px solid var(--tcw-border);\r
852
- font-size: 11px;\r
853
- color: var(--tcw-text-muted);\r
854
- }\r
855
- \r
856
- /* === Responsive === */\r
857
- \r
858
- @media (max-width: 768px) {\r
859
- .tcw-toolbar {\r
860
- padding: 0 8px;\r
861
- height: 36px;\r
862
- }\r
863
- .tcw-toolbar-sep {\r
864
- display: none;\r
865
- }\r
866
- .tcw-indicator-chips {\r
867
- display: none;\r
868
- }\r
869
- .tcw-sidebar {\r
870
- width: 32px;\r
871
- }\r
872
- .tcw-sidebar-btn {\r
873
- width: 32px;\r
874
- height: 28px;\r
875
- }\r
876
- }\r
877
- `,u=0,d=`tcw-styles`;function f(){if(u++,u>1||document.getElementById(d))return;let e=document.createElement(`style`);e.id=d,e.textContent=l,document.head.appendChild(e)}function p(){if(u--,u>0)return;let e=document.getElementById(d);e&&e.remove()}var m={cursor:`<path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/><path d="M13 13l6 6"/>`,trendingUp:`<polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/>`,minus:`<path d="M5 12h14"/>`,penLine:`<path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/>`,hash:`<line x1="4" y1="9" x2="20" y2="9"/><line x1="4" y1="15" x2="20" y2="15"/><line x1="10" y1="3" x2="8" y2="21"/><line x1="16" y1="3" x2="14" y2="21"/>`,square:`<rect width="18" height="18" x="3" y="3" rx="2"/>`,gitBranch:`<line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/>`,ruler:`<path d="M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Z"/><path d="m14.5 12.5 2-2"/><path d="m11.5 9.5 2-2"/><path d="m8.5 6.5 2-2"/><path d="m17.5 15.5 2-2"/>`,type:`<polyline points="4 7 4 4 20 4 20 7"/><line x1="9" y1="20" x2="15" y2="20"/><line x1="12" y1="4" x2="12" y2="20"/>`,magnet:`<path d="m6 15-4-4 6.75-6.77a7.79 7.79 0 0 1 11 11L13 22l-4-4 6.39-6.36a2.14 2.14 0 0 0-3-3L6 15"/><path d="m5 8 4 4"/><path d="m12 15 4 4"/>`,undo:`<path d="M3 7v6h6"/><path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"/>`,redo:`<path d="M21 7v6h-6"/><path d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13"/>`,trash:`<path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/>`,camera:`<path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3"/>`,settings:`<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>`,moon:`<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>`,sun:`<circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/>`,chevronDown:`<path d="m6 9 6 6 6-6"/>`,chevronUp:`<path d="m18 15-6-6-6 6"/>`,barChart:`<line x1="12" y1="20" x2="12" y2="10"/><line x1="18" y1="20" x2="18" y2="4"/><line x1="6" y1="20" x2="6" y2="16"/>`,x:`<path d="M18 6 6 18"/><path d="m6 6 12 12"/>`,play:`<polygon points="6 3 20 12 6 21 6 3"/>`,pause:`<rect width="4" height="16" x="6" y="4"/><rect width="4" height="16" x="14" y="4"/>`,stop:`<rect width="14" height="14" x="5" y="5" rx="1"/>`,receipt:`<path d="M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1Z"/><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8"/><path d="M12 17.5v-11"/>`};function h(e,t=14){let n=m[e];return n?`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${n}</svg>`:``}var g=class{trigger;panel;_isOpen=!1;onOutsideClick;onEscapeKey;onTriggerClick;constructor(e,t={}){this.trigger=e,this.panel=document.createElement(`div`),this.panel.className=`tcw-dropdown`,this.panel.style.width=t.width??`200px`,t.align===`right`?this.panel.style.right=`0`:this.panel.style.left=`0`,this.panel.style.display=`none`,e.style.position=`relative`,e.appendChild(this.panel),this.onTriggerClick=()=>{this._isOpen?this.close():this.open()},this.onOutsideClick=e=>{this.trigger.contains(e.target)||this.close()},this.onEscapeKey=e=>{e.key===`Escape`&&this.close()},e.addEventListener(`click`,this.onTriggerClick)}setContent(e){this.panel.innerHTML=e}open(){this._isOpen||(this._isOpen=!0,this.panel.style.display=``,document.addEventListener(`mousedown`,this.onOutsideClick),document.addEventListener(`keydown`,this.onEscapeKey))}close(){this._isOpen&&(this._isOpen=!1,this.panel.style.display=`none`,document.removeEventListener(`mousedown`,this.onOutsideClick),document.removeEventListener(`keydown`,this.onEscapeKey))}isOpen(){return this._isOpen}destroy(){this.trigger.removeEventListener(`click`,this.onTriggerClick),document.removeEventListener(`mousedown`,this.onOutsideClick),document.removeEventListener(`keydown`,this.onEscapeKey),this.panel.remove()}},_=class{config;callbacks;el;chartTypeDropdown=null;indicatorDropdown=null;tfButtons=[];chipsContainer=null;themeBtn=null;constructor(e,t,n){this.config=t,this.callbacks=n,this.el=document.createElement(`div`),this.el.className=`tcw-toolbar`,this.build(),e.appendChild(this.el)}build(){let{config:e,callbacks:t,el:n}=this,r=document.createElement(`button`);r.className=`tcw-toolbar-symbol`,r.dataset.role=`symbol`,r.addEventListener(`click`,t.onSymbolClick),n.appendChild(r),n.appendChild(this.sep());let i=document.createElement(`div`);i.className=`tcw-toolbar-group`;for(let n of e.timeframes){let e=document.createElement(`button`);e.className=`tcw-btn`,e.textContent=n.label,e.dataset.tf=n.value,e.addEventListener(`click`,()=>t.onTimeframe(n.value)),i.appendChild(e),this.tfButtons.push(e)}n.appendChild(i),n.appendChild(this.sep());let a=document.createElement(`div`);a.style.position=`relative`,a.style.display=`inline-flex`;let o=document.createElement(`button`);o.className=`tcw-dropdown-trigger`,o.dataset.role=`charttype`,a.appendChild(o),n.appendChild(a),this.chartTypeDropdown=new g(a,{width:`160px`}),this.buildChartTypeMenu(),n.appendChild(this.sep());let s=document.createElement(`div`);s.style.position=`relative`,s.style.display=`inline-flex`;let c=document.createElement(`button`);c.className=`tcw-dropdown-trigger`,c.dataset.role=`indicators`,s.appendChild(c),n.appendChild(s),this.indicatorDropdown=new g(s,{width:`280px`}),this.buildIndicatorMenu(),this.chipsContainer=document.createElement(`div`),this.chipsContainer.className=`tcw-indicator-chips`,n.appendChild(this.chipsContainer),n.appendChild(this.spacer());let l=this.iconBtn(`camera`,`Screenshot`,t.onScreenshot);n.appendChild(l);let u=this.iconBtn(`settings`,`Chart Settings`,t.onSettings);n.appendChild(u),this.themeBtn=this.iconBtn(`moon`,`Toggle theme`,t.onToggleTheme),this.themeBtn.dataset.role=`theme`,n.appendChild(this.themeBtn)}buildChartTypeMenu(){if(!this.chartTypeDropdown)return;let e=this.config.chartTypes.map(e=>`<button class="tcw-dropdown-item" data-ct="${e.value}">${e.label}</button>`).join(``);this.chartTypeDropdown.setContent(e),this.chartTypeDropdown.panel.querySelectorAll(`.tcw-dropdown-item`).forEach(e=>{e.addEventListener(`click`,e=>{let t=e.currentTarget.dataset.ct;this.callbacks.onChartType(t),this.chartTypeDropdown?.close()})})}buildIndicatorMenu(){if(!this.indicatorDropdown)return;let{indicators:e,popularIndicatorIds:t}=this.config,n=e.filter(e=>t.includes(e.id)),r=e.filter(e=>!t.includes(e.id)),i=`<div class="tcw-dropdown-label">Popular</div>`;for(let e of n)i+=`<button class="tcw-dropdown-item" data-ind="${e.id}"><span>${e.name}</span><span class="tcw-tag">${e.type}</span></button>`;i+=`<div class="tcw-dropdown-divider"></div>`,i+=`<div class="tcw-dropdown-label">All</div>`;for(let e of r)i+=`<button class="tcw-dropdown-item" data-ind="${e.id}"><span>${e.name}</span><span class="tcw-tag">${e.type}</span></button>`;this.indicatorDropdown.setContent(i),this.indicatorDropdown.panel.querySelectorAll(`.tcw-dropdown-item[data-ind]`).forEach(e=>{e.addEventListener(`click`,e=>{let t=e.currentTarget.dataset.ind;this.callbacks.onAddIndicator(t)})})}update(e){let t=this.el.querySelector(`[data-role="symbol"]`);t&&(t.textContent=e.symbol);for(let t of this.tfButtons)t.classList.toggle(`tcw-active`,t.dataset.tf===e.timeframe);let n=this.el.querySelector(`[data-role="charttype"]`);if(n){let t=this.config.chartTypes.find(t=>t.value===e.chartType)?.label??`Candles`;n.innerHTML=`${h(`barChart`,14)} ${t} ${h(`chevronDown`,12)}`}let r=this.el.querySelector(`[data-role="indicators"]`);if(r){let t=e.activeIndicators.size,n=`${h(`trendingUp`,14)} Indicators`;t>0&&(n+=` <span class="tcw-badge-count">${t}</span>`),r.innerHTML=n}if(this.chipsContainer){let t=this.getActiveIndicatorList(e);this.chipsContainer.innerHTML=``;for(let e of t){let t=document.createElement(`div`);t.className=`tcw-indicator-chip`;let n=document.createElement(`span`);n.textContent=e.label,t.appendChild(n);let r=document.createElement(`button`);r.className=`tcw-chip-remove`,r.innerHTML=h(`x`,10),r.addEventListener(`click`,()=>this.callbacks.onRemoveIndicator(e.instanceId)),t.appendChild(r),this.chipsContainer.appendChild(t)}}this.themeBtn&&(this.themeBtn.innerHTML=e.isDark?h(`moon`,14):h(`sun`,14))}getActiveIndicatorList(e){let t=[];for(let[n,r]of e.activeIndicators.entries())t.push({instanceId:r,id:n,label:n.toUpperCase()});return t}sep(){let e=document.createElement(`span`);return e.className=`tcw-toolbar-sep`,e}spacer(){let e=document.createElement(`span`);return e.className=`tcw-toolbar-spacer`,e}iconBtn(e,t,n){let r=document.createElement(`button`);return r.className=`tcw-btn-icon`,r.title=t,r.innerHTML=h(e,14),r.addEventListener(`click`,n),r}destroy(){this.chartTypeDropdown?.destroy(),this.indicatorDropdown?.destroy(),this.el.remove()}},v=[`trendingUp`,`minus`,`penLine`,`hash`,`square`,`gitBranch`,`ruler`,`type`],y=class{config;callbacks;el;groupWraps=[];groupButtons=[];cursorBtn=null;magnetBtn=null;flyoutEl=null;constructor(e,t,n){this.config=t,this.callbacks=n,this.el=document.createElement(`div`),this.el.className=`tcw-sidebar`,this.build(),e.appendChild(this.el)}build(){let{config:e,callbacks:t,el:n}=this;this.cursorBtn=document.createElement(`button`),this.cursorBtn.className=`tcw-sidebar-btn`,this.cursorBtn.title=`Cursor`,this.cursorBtn.innerHTML=h(`cursor`,14),this.cursorBtn.addEventListener(`click`,t.onCancelDrawing),n.appendChild(this.cursorBtn),n.appendChild(this.divider()),e.drawingToolGroups.forEach((e,r)=>{let i=document.createElement(`div`);i.className=`tcw-tool-group-wrap`;let a=document.createElement(`button`);if(a.className=`tcw-sidebar-btn`,a.title=e.label,a.innerHTML=h(v[r]??`square`,14),e.tools.length>1){let e=document.createElement(`span`);e.className=`tcw-multi-dot`,a.appendChild(e)}a.addEventListener(`click`,()=>t.onDrawingTool(e.tools[0].value)),i.appendChild(a),i.addEventListener(`mouseenter`,()=>this.showFlyout(r)),i.addEventListener(`mouseleave`,()=>this.hideFlyout()),n.appendChild(i),this.groupWraps.push(i),this.groupButtons.push(a)});let r=document.createElement(`div`);r.className=`tcw-sidebar-spacer`,n.appendChild(r),n.appendChild(this.divider()),this.magnetBtn=document.createElement(`button`),this.magnetBtn.className=`tcw-sidebar-btn`,this.magnetBtn.title=`Magnet`,this.magnetBtn.innerHTML=h(`magnet`,14),this.magnetBtn.addEventListener(`click`,t.onToggleMagnet),n.appendChild(this.magnetBtn);let i=document.createElement(`button`);i.className=`tcw-sidebar-btn`,i.title=`Undo`,i.innerHTML=h(`undo`,14),i.addEventListener(`click`,t.onUndo),n.appendChild(i);let a=document.createElement(`button`);a.className=`tcw-sidebar-btn`,a.title=`Redo`,a.innerHTML=h(`redo`,14),a.addEventListener(`click`,t.onRedo),n.appendChild(a);let o=document.createElement(`button`);o.className=`tcw-sidebar-btn tcw-danger`,o.title=`Clear all`,o.innerHTML=h(`trash`,14),o.addEventListener(`click`,t.onClearDrawings),n.appendChild(o)}showFlyout(e){let t=this.config.drawingToolGroups[e];if(!t||t.tools.length<=1)return;this.hideFlyout();let n=document.createElement(`div`);n.className=`tcw-flyout`;let r=document.createElement(`div`);r.className=`tcw-flyout-header`,r.textContent=t.label,n.appendChild(r);for(let e of t.tools){let t=document.createElement(`button`);t.className=`tcw-flyout-item`,t.textContent=e.label,t.dataset.toolValue=e.value,t.addEventListener(`click`,()=>{this.callbacks.onDrawingTool(e.value),this.hideFlyout()}),n.appendChild(t)}this.flyoutEl=n,this.groupWraps[e].appendChild(n)}hideFlyout(){this.flyoutEl&&=(this.flyoutEl.remove(),null)}update(e){this.cursorBtn&&this.cursorBtn.classList.toggle(`tcw-active`,e.activeTool===null);let{drawingToolGroups:t}=this.config;for(let n=0;n<t.length;n++){let r=t[n].tools.some(t=>t.value===e.activeTool);this.groupButtons[n].classList.toggle(`tcw-active`,r)}this.flyoutEl&&this.flyoutEl.querySelectorAll(`.tcw-flyout-item`).forEach(t=>{let n=t;n.classList.toggle(`tcw-active`,n.dataset.toolValue===e.activeTool)}),this.magnetBtn&&(this.magnetBtn.classList.toggle(`tcw-active`,e.magnetEnabled),this.magnetBtn.title=e.magnetEnabled?`Magnet ON`:`Magnet OFF`)}divider(){let e=document.createElement(`div`);return e.className=`tcw-sidebar-divider`,e}destroy(){this.hideFlyout(),this.el.remove()}},b=[`style`,`display`,`scale`],x=class{callbacks;backdrop=null;modal=null;currentTab=`style`;currentSettings=null;bodyEl=null;tabButtons=[];constructor(e){this.callbacks=e}open(e){this.currentSettings={...e},this.currentTab=`style`,this.buildModal()}close(){this.backdrop?.remove(),this.modal?.remove(),this.backdrop=null,this.modal=null,this.bodyEl=null,this.tabButtons=[]}buildModal(){this.backdrop=document.createElement(`div`),this.backdrop.className=`tcw-modal-backdrop`,this.backdrop.addEventListener(`click`,()=>{this.callbacks.onClose(),this.close()}),document.body.appendChild(this.backdrop),this.modal=document.createElement(`div`),this.modal.className=`tcw-modal`;let e=document.createElement(`div`);e.className=`tcw-modal-header`;let t=document.createElement(`h3`);t.textContent=`Chart Settings`,e.appendChild(t);let n=document.createElement(`button`);n.className=`tcw-modal-close`,n.innerHTML=h(`x`,16),n.addEventListener(`click`,()=>{this.callbacks.onClose(),this.close()}),e.appendChild(n),this.modal.appendChild(e);let r=document.createElement(`div`);r.className=`tcw-modal-tabs`,this.tabButtons=[];for(let e of b){let t=document.createElement(`button`);t.className=`tcw-modal-tab`,t.textContent=e,t.dataset.tab=e,e===this.currentTab&&t.classList.add(`tcw-active`),t.addEventListener(`click`,()=>{this.currentTab=e,this.tabButtons.forEach(t=>t.classList.toggle(`tcw-active`,t.dataset.tab===e)),this.renderTabContent()}),r.appendChild(t),this.tabButtons.push(t)}this.modal.appendChild(r),this.bodyEl=document.createElement(`div`),this.bodyEl.className=`tcw-modal-body`,this.modal.appendChild(this.bodyEl),this.renderTabContent();let i=document.createElement(`div`);i.className=`tcw-modal-footer`;let a=document.createElement(`button`);a.className=`tcw-reset-link`,a.textContent=`Reset to defaults`,a.addEventListener(`click`,()=>this.callbacks.onReset()),i.appendChild(a);let o=document.createElement(`button`);o.className=`tcw-done-btn`,o.textContent=`Done`,o.addEventListener(`click`,()=>{this.callbacks.onClose(),this.close()}),i.appendChild(o),this.modal.appendChild(i),document.body.appendChild(this.modal);let s=e=>{e.key===`Escape`&&(document.removeEventListener(`keydown`,s),this.callbacks.onClose(),this.close())};document.addEventListener(`keydown`,s)}renderTabContent(){if(!(!this.bodyEl||!this.currentSettings))switch(this.bodyEl.innerHTML=``,this.currentTab){case`style`:this.renderStyleTab();break;case`display`:this.renderDisplayTab();break;case`scale`:this.renderScaleTab();break}}renderStyleTab(){if(!this.bodyEl||!this.currentSettings)return;let e=this.currentSettings,t=this.section(`Candle Colors`);t.appendChild(this.colorRow(`Up Body`,e.candleUpColor,e=>this.patch({candleUpColor:e}))),t.appendChild(this.colorRow(`Down Body`,e.candleDownColor,e=>this.patch({candleDownColor:e}))),t.appendChild(this.colorRow(`Up Wick`,e.candleUpWick,e=>this.patch({candleUpWick:e}))),t.appendChild(this.colorRow(`Down Wick`,e.candleDownWick,e=>this.patch({candleDownWick:e}))),this.bodyEl.appendChild(t);let n=this.section(`Background`);n.appendChild(this.colorRow(`Background`,e.backgroundColor,e=>this.patch({backgroundColor:e}))),n.appendChild(this.colorRow(`Grid`,e.gridColor,e=>this.patch({gridColor:e}))),this.bodyEl.appendChild(n)}renderDisplayTab(){if(!this.bodyEl||!this.currentSettings)return;let e=this.currentSettings,t=this.section();t.appendChild(this.toggleRow(`Grid Lines`,e.gridVisible,e=>this.patch({gridVisible:e}))),t.appendChild(this.toggleRow(`Volume`,e.volumeVisible,e=>this.patch({volumeVisible:e}))),t.appendChild(this.toggleRow(`OHLC Legend`,e.legendVisible,e=>this.patch({legendVisible:e}))),t.appendChild(this.toggleRow(`Bar Countdown`,e.barCountdown,e=>this.patch({barCountdown:e}))),t.appendChild(this.selectRow(`Crosshair Mode`,e.crosshairMode,[{label:`Magnet`,value:`magnet`},{label:`Normal`,value:`normal`},{label:`Hidden`,value:`hidden`}],e=>this.patch({crosshairMode:e}))),t.appendChild(this.selectRow(`Number Locale`,e.numberLocale,[{label:`en-US (65,234.00)`,value:`en-US`},{label:`de-DE (65.234,00)`,value:`de-DE`},{label:`fr-FR (65 234,00)`,value:`fr-FR`},{label:`vi-VN (65.234,00)`,value:`vi-VN`},{label:`en-IN (65,234.00)`,value:`en-IN`},{label:`ja-JP (65,234.00)`,value:`ja-JP`}],e=>this.patch({numberLocale:e}))),this.bodyEl.appendChild(t)}renderScaleTab(){if(!this.bodyEl||!this.currentSettings)return;let e=this.currentSettings,t=this.section();t.appendChild(this.toggleRow(`Auto Scale`,e.autoScale,e=>this.patch({autoScale:e}))),t.appendChild(this.toggleRow(`Log Scale`,e.logScale,e=>this.patch({logScale:e}))),this.bodyEl.appendChild(t)}patch(e){this.currentSettings&&Object.assign(this.currentSettings,e),this.callbacks.onChange(e)}section(e){let t=document.createElement(`div`);if(t.className=`tcw-settings-section`,e){let n=document.createElement(`div`);n.className=`tcw-settings-section-title`,n.textContent=e,t.appendChild(n)}return t}colorRow(e,t,n){let r=document.createElement(`div`);r.className=`tcw-settings-row`;let i=document.createElement(`span`);i.className=`tcw-settings-label`,i.textContent=e,r.appendChild(i);let a=document.createElement(`div`);a.className=`tcw-color-picker-wrap`;let o=document.createElement(`input`);o.type=`color`,o.value=t;let s=document.createElement(`span`);return s.className=`tcw-color-hex`,s.textContent=t,o.addEventListener(`input`,()=>{s.textContent=o.value,n(o.value)}),a.appendChild(o),a.appendChild(s),r.appendChild(a),r}toggleRow(e,t,n){let r=document.createElement(`div`);r.className=`tcw-settings-row`;let i=document.createElement(`span`);i.className=`tcw-settings-label`,i.textContent=e,r.appendChild(i);let a=document.createElement(`button`);return a.className=`tcw-toggle${t?` tcw-on`:``}`,a.addEventListener(`click`,()=>{let e=!a.classList.contains(`tcw-on`);a.classList.toggle(`tcw-on`,e),n(e)}),r.appendChild(a),r}selectRow(e,t,n,r){let i=document.createElement(`div`);i.className=`tcw-settings-row`;let a=document.createElement(`span`);a.className=`tcw-settings-label`,a.textContent=e,i.appendChild(a);let o=document.createElement(`select`);o.className=`tcw-settings-select`;for(let e of n){let n=document.createElement(`option`);n.value=e.value,n.textContent=e.label,e.value===t&&(n.selected=!0),o.appendChild(n)}return o.addEventListener(`change`,()=>r(o.value)),i.appendChild(o),i}destroy(){this.close()}},S=class{el;dotEl;messageEl;infoEl;constructor(e){this.el=document.createElement(`div`),this.el.className=`tcw-statusbar`;let t=document.createElement(`div`);t.className=`tcw-status-indicator`,this.dotEl=document.createElement(`span`),this.dotEl.className=`tcw-status-dot`,t.appendChild(this.dotEl),this.messageEl=document.createElement(`span`),t.appendChild(this.messageEl),this.el.appendChild(t),this.infoEl=document.createElement(`span`),this.el.appendChild(this.infoEl),e.appendChild(this.el)}update(e){this.dotEl.className=`tcw-status-dot`,e.connectionState===`connected`?this.dotEl.classList.add(`tcw-connected`):e.connectionState===`error`&&this.dotEl.classList.add(`tcw-error`),this.messageEl.textContent=e.message,this.infoEl.textContent=`${e.symbol} ${e.timeframe}`}destroy(){this.el.remove()}},C=class{backdrop=null;modal=null;input=null;list=null;items=[];filtered=[];selectedIndex=0;callbacks;boundKeydown;constructor(e){this.callbacks=e,this.boundKeydown=this.handleKeydown.bind(this)}open(e){if(this.backdrop)return;this.items=e,this.filtered=e,this.selectedIndex=0,this.backdrop=document.createElement(`div`),this.backdrop.className=`tcw-modal-backdrop`,this.backdrop.addEventListener(`click`,()=>this.close()),this.modal=document.createElement(`div`),this.modal.className=`tcw-cmd-palette`;let t=document.createElement(`div`);t.className=`tcw-cmd-header`;let n=document.createElement(`span`);n.className=`tcw-cmd-icon`,n.textContent=`⌕`,t.appendChild(n),this.input=document.createElement(`input`),this.input.className=`tcw-cmd-input`,this.input.type=`text`,this.input.placeholder=`Search indicators, chart types, tools...`,this.input.addEventListener(`input`,()=>this.filter()),t.appendChild(this.input);let r=document.createElement(`span`);r.className=`tcw-cmd-hint`,r.textContent=`ESC`,t.appendChild(r),this.modal.appendChild(t),this.list=document.createElement(`div`),this.list.className=`tcw-cmd-list`,this.modal.appendChild(this.list);let i=document.createElement(`div`);i.className=`tcw-cmd-footer`,i.innerHTML=`<span>↑↓ Navigate</span><span>⏎ Select</span><span>Esc Close</span>`,this.modal.appendChild(i),document.body.appendChild(this.backdrop),document.body.appendChild(this.modal),this.renderList(),this.input.focus(),document.addEventListener(`keydown`,this.boundKeydown)}close(){document.removeEventListener(`keydown`,this.boundKeydown),this.backdrop?.remove(),this.modal?.remove(),this.backdrop=null,this.modal=null,this.input=null,this.list=null,this.callbacks.onClose()}isOpen(){return this.backdrop!==null}filter(){let e=this.input?.value.toLowerCase().trim()??``;e?this.filtered=this.items.filter(t=>t.label.toLowerCase().includes(e)||t.category.toLowerCase().includes(e)||t.id.toLowerCase().includes(e)):this.filtered=this.items,this.selectedIndex=0,this.renderList()}renderList(){if(!this.list)return;if(this.list.innerHTML=``,this.filtered.length===0){let e=document.createElement(`div`);e.className=`tcw-cmd-empty`,e.textContent=`No results found`,this.list.appendChild(e);return}let e=``;for(let t=0;t<this.filtered.length;t++){let n=this.filtered[t];if(n.category!==e){e=n.category;let t=document.createElement(`div`);t.className=`tcw-cmd-category`,t.textContent=this.categoryLabel(e),this.list.appendChild(t)}let r=document.createElement(`button`);r.className=`tcw-cmd-item`,t===this.selectedIndex&&r.classList.add(`tcw-selected`),n.active&&r.classList.add(`tcw-active`),r.dataset.index=String(t);let i=document.createElement(`span`);if(i.className=`tcw-cmd-item-label`,i.textContent=n.label,r.appendChild(i),n.active){let e=document.createElement(`span`);e.className=`tcw-cmd-check`,e.textContent=`✓`,r.appendChild(e)}if(n.shortcut){let e=document.createElement(`kbd`);e.className=`tcw-cmd-kbd`,e.textContent=n.shortcut,r.appendChild(e)}r.addEventListener(`click`,()=>this.select(t)),r.addEventListener(`mouseenter`,()=>{this.selectedIndex=t,this.updateSelection()}),this.list.appendChild(r)}}updateSelection(){if(!this.list)return;let e=this.list.querySelectorAll(`.tcw-cmd-item`);e.forEach((e,t)=>{e.classList.toggle(`tcw-selected`,t===this.selectedIndex)}),e[this.selectedIndex]?.scrollIntoView({block:`nearest`})}select(e){let t=this.filtered[e];if(t){switch(t.category){case`indicator`:this.callbacks.onIndicator(t.id);break;case`chartType`:this.callbacks.onChartType(t.id);break;case`drawing`:this.callbacks.onDrawingTool(t.id);break;case`timeframe`:this.callbacks.onTimeframe(t.id);break;case`action`:this.callbacks.onAction(t.id);break}this.close()}}handleKeydown(e){switch(e.key){case`Escape`:e.preventDefault(),this.close();break;case`ArrowDown`:e.preventDefault(),this.filtered.length>0&&(this.selectedIndex=(this.selectedIndex+1)%this.filtered.length,this.updateSelection());break;case`ArrowUp`:e.preventDefault(),this.filtered.length>0&&(this.selectedIndex=(this.selectedIndex-1+this.filtered.length)%this.filtered.length,this.updateSelection());break;case`Enter`:e.preventDefault(),this.select(this.selectedIndex);break}}categoryLabel(e){switch(e){case`indicator`:return`Indicators`;case`chartType`:return`Chart Types`;case`drawing`:return`Drawing Tools`;case`timeframe`:return`Timeframes`;case`action`:return`Actions`;default:return e}}destroy(){this.close()}},w=class{chart;state;toolbar=null;sidebar=null;settings=null;statusBar=null;commandPalette=null;root;chartContainer;destroyed=!1;options;symbolIndex=0;symbols;settingsState;adapter=null;boundGlobalKeydown=null;constructor(t,l={}){this.options=l,this.symbols=l.symbols??s,this.settingsState={...c};let u=this.resolveIsDark(l.theme),d=this.resolveTheme(l.theme);this.state={symbol:l.symbol??this.symbols[0]??`BTCUSDT`,timeframe:l.timeframe??`5m`,chartType:l.chartOptions?.chartType??`candlestick`,isDark:u,activeIndicators:new Map,activeTool:null,magnetEnabled:!0,connectionState:`connecting`,connectionMessage:`Connecting...`};let p=this.symbols.indexOf(this.state.symbol);p>=0&&(this.symbolIndex=p),f(),this.root=document.createElement(`div`),this.root.className=`tcw-root`,this.root.dataset.tcwTheme=u?`dark`:`light`,t.appendChild(this.root),l.toolbar!==!1&&(this.toolbar=new _(this.root,{symbols:this.symbols,timeframes:l.timeframes?n.filter(e=>l.timeframes.includes(e.value)):n,chartTypes:l.chartTypes?r.filter(e=>l.chartTypes.includes(e.value)):r,indicators:a,popularIndicatorIds:o},{onSymbolClick:()=>this.handleSymbolClick(),onTimeframe:e=>this.handleTimeframe(e),onChartType:e=>this.handleChartType(e),onAddIndicator:e=>this.handleAddIndicator(e),onRemoveIndicator:e=>this.handleRemoveIndicator(e),onScreenshot:()=>this.chart.screenshot(),onSettings:()=>this.openSettings(),onToggleTheme:()=>this.handleToggleTheme()}));let m=document.createElement(`div`);m.className=`tcw-body`,l.drawingTools!==!1&&(this.sidebar=new y(m,{drawingToolGroups:i},{onDrawingTool:e=>this.handleDrawingTool(e),onCancelDrawing:()=>this.handleCancelDrawing(),onToggleMagnet:()=>this.handleToggleMagnet(),onUndo:()=>this.chart.undo(),onRedo:()=>this.chart.redo(),onClearDrawings:()=>{this.chart.clearDrawings(),this.state={...this.state,activeTool:null},this.updateUI()}})),this.chartContainer=document.createElement(`div`),this.chartContainer.className=`tcw-chart-container`,m.appendChild(this.chartContainer),this.root.appendChild(m),this.chart=new e.t(this.chartContainer,{chartType:this.state.chartType,theme:d,autoScale:!0,crosshair:{mode:`magnet`},features:{drawings:!0,drawingMagnet:!0,drawingUndoRedo:!0,indicators:!0,trading:l.trading!==!1,tradingContextMenu:l.trading!==!1,volume:!0,legend:!0,crosshair:!0,keyboard:!0,screenshot:!0,alerts:!0,barCountdown:!0,logScale:!0,watermark:!0},...l.chartOptions}),l.statusBar!==!1&&(this.statusBar=new S(this.root)),l.settings!==!1&&(this.settings=new x({onChange:e=>this.applySettings(e),onReset:()=>this.resetSettings(),onClose:()=>{}})),this.commandPalette=new C({onIndicator:e=>this.handleAddIndicator(e),onChartType:e=>this.handleChartType(e),onDrawingTool:e=>this.handleDrawingTool(e),onTimeframe:e=>this.handleTimeframe(e),onAction:e=>this.handleAction(e),onClose:()=>{}}),this.boundGlobalKeydown=e=>{(e.ctrlKey||e.metaKey)&&e.key===`k`&&(e.preventDefault(),this.toggleCommandPalette())},document.addEventListener(`keydown`,this.boundGlobalKeydown),l.adapter&&(this.adapter=l.adapter,this.connectStream()),this.updateUI(),l.onReady?.(this.chart)}async setSymbol(e){this.state={...this.state,symbol:e};let t=this.symbols.indexOf(e);t>=0&&(this.symbolIndex=t),this.options.onSymbolChange?.(e),this.updateUI(),this.adapter&&await this.connectStream()}async setTimeframe(e){this.state={...this.state,timeframe:e},this.options.onTimeframeChange?.(e),this.updateUI(),this.adapter&&await this.connectStream()}setTheme(e){let t=this.resolveIsDark(e),n=this.resolveTheme(e);this.state={...this.state,isDark:t},this.root.dataset.tcwTheme=t?`dark`:`light`,this.chart.setTheme(n),this.updateUI()}getChart(){return this.chart}destroy(){this.destroyed||(this.destroyed=!0,this.boundGlobalKeydown&&document.removeEventListener(`keydown`,this.boundGlobalKeydown),this.commandPalette?.destroy(),this.toolbar?.destroy(),this.sidebar?.destroy(),this.settings?.destroy(),this.statusBar?.destroy(),this.chart.destroy(),this.root.remove(),p())}handleSymbolClick(){this.symbolIndex=(this.symbolIndex+1)%this.symbols.length;let e=this.symbols[this.symbolIndex];this.state={...this.state,symbol:e},this.options.onSymbolChange?.(e),this.updateUI(),this.adapter&&this.connectStream()}handleTimeframe(e){this.state={...this.state,timeframe:e},this.options.onTimeframeChange?.(e),this.updateUI(),this.adapter&&this.connectStream()}handleChartType(e){this.state={...this.state,chartType:e},this.chart.setChartType(e),this.updateUI()}handleAddIndicator(e){if(this.state.activeIndicators.has(e)){let t=this.state.activeIndicators.get(e);this.chart.removeIndicator(t);let n=new Map(this.state.activeIndicators);n.delete(e),this.state={...this.state,activeIndicators:n}}else{let t=this.chart.addIndicator(e);if(t){let n=new Map(this.state.activeIndicators);n.set(e,t),this.state={...this.state,activeIndicators:n}}}this.updateUI()}handleRemoveIndicator(e){this.chart.removeIndicator(e);let t=new Map(this.state.activeIndicators);for(let[n,r]of t.entries())if(r===e){t.delete(n);break}this.state={...this.state,activeIndicators:t},this.updateUI()}toggleCommandPalette(){if(this.commandPalette?.isOpen()){this.commandPalette.close();return}this.commandPalette?.open(this.buildCommandItems())}buildCommandItems(){let e=[];for(let t of a)e.push({id:t.id,label:t.name,category:`indicator`,active:this.state.activeIndicators.has(t.id)});for(let t of r)e.push({id:t.value,label:t.label,category:`chartType`,active:this.state.chartType===t.value});for(let t of i)for(let n of t.tools)e.push({id:n.value,label:n.label,category:`drawing`,active:this.state.activeTool===n.value});for(let t of n)e.push({id:t.value,label:t.label,category:`timeframe`,active:this.state.timeframe===t.value});return e.push({id:`screenshot`,label:`Screenshot`,category:`action`,shortcut:``},{id:`toggleTheme`,label:`Toggle Theme`,category:`action`},{id:`settings`,label:`Settings`,category:`action`},{id:`clearDrawings`,label:`Clear All Drawings`,category:`action`}),e}handleAction(e){switch(e){case`screenshot`:this.chart.screenshot();break;case`toggleTheme`:this.handleToggleTheme();break;case`settings`:this.openSettings();break;case`clearDrawings`:this.chart.clearDrawings(),this.state={...this.state,activeTool:null},this.updateUI();break}}handleDrawingTool(e){this.state={...this.state,activeTool:e},this.chart.setDrawingTool(e),this.updateUI()}handleCancelDrawing(){this.state={...this.state,activeTool:null},this.chart.setDrawingTool(null),this.updateUI()}handleToggleMagnet(){let e=!this.state.magnetEnabled;this.state={...this.state,magnetEnabled:e},this.chart.setDrawingMagnet(e),this.updateUI()}handleToggleTheme(){let e=!this.state.isDark;this.state={...this.state,isDark:e},this.root.dataset.tcwTheme=e?`dark`:`light`,this.chart.setTheme(e?t.DARK_THEME:t.LIGHT_THEME),this.chart.setWatermark(this.state.symbol.replace(`USDT`,` / USDT`),{fontSize:48,color:e?`rgba(255,255,255,0.03)`:`rgba(0,0,0,0.03)`}),this.updateUI()}openSettings(){this.settings?.open(this.settingsState)}applySettings(e){this.settingsState={...this.settingsState,...e},e.gridVisible!==void 0&&this.chart.setGridVisible(e.gridVisible),e.volumeVisible!==void 0&&this.chart.setVolumeVisible(e.volumeVisible),e.crosshairMode!==void 0&&this.chart.setCrosshairMode(e.crosshairMode),e.autoScale!==void 0&&this.chart.setAutoScale(e.autoScale),e.logScale!==void 0&&this.chart.setLogScale(e.logScale),e.numberLocale!==void 0&&this.chart.setNumberLocale(e.numberLocale);let t={...this.chart.getTheme()},n=!1;e.candleUpColor!==void 0&&(t.candleUp=e.candleUpColor,n=!0),e.candleDownColor!==void 0&&(t.candleDown=e.candleDownColor,n=!0),e.candleUpWick!==void 0&&(t.candleUpWick=e.candleUpWick,n=!0),e.candleDownWick!==void 0&&(t.candleDownWick=e.candleDownWick,n=!0),e.backgroundColor!==void 0&&(t.background=e.backgroundColor,n=!0),e.gridColor!==void 0&&(t.grid=e.gridColor,n=!0),n&&this.chart.setTheme(t)}resetSettings(){this.settingsState={...c},this.applySettings(this.settingsState)}async connectStream(){if(this.adapter){this.state={...this.state,connectionState:`connecting`,connectionMessage:`Connecting...`},this.updateUI();try{this.chart.disconnectStream(),await this.chart.connect({adapter:this.adapter,symbol:this.state.symbol,timeframe:this.state.timeframe,historyLimit:this.options.historyLimit??500}),this.chart.setWatermark(this.state.symbol.replace(`USDT`,` / USDT`),{fontSize:48,color:this.state.isDark?`rgba(255,255,255,0.03)`:`rgba(0,0,0,0.03)`}),this.state={...this.state,connectionState:`connected`,connectionMessage:`Live`}}catch(e){this.state={...this.state,connectionState:`error`,connectionMessage:e instanceof Error?e.message:`Connection failed`}}this.updateUI()}}updateUI(){this.toolbar?.update(this.state),this.sidebar?.update(this.state),this.statusBar?.update({connectionState:this.state.connectionState,message:this.state.connectionMessage,symbol:this.state.symbol,timeframe:this.state.timeframe})}resolveIsDark(e){return e===void 0||e===`dark`?!0:e===`light`?!1:typeof e==`object`&&e.background?this.isColorDark(e.background):!0}resolveTheme(e){return e===void 0||e===`dark`?t.DARK_THEME:e===`light`?t.LIGHT_THEME:typeof e==`object`?e:t.DARK_THEME}isColorDark(e){if(e.startsWith(`#`)&&e.length>=7){let t=parseInt(e.slice(1,3),16),n=parseInt(e.slice(3,5),16),r=parseInt(e.slice(5,7),16);return t+n+r<384}return!0}};exports.ChartWidget=w;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../DragDropImporter-CQ3EarQn.cjs`);let t=require(`@tradecanvas/commons`);var n=[{label:`1m`,value:`1m`},{label:`5m`,value:`5m`},{label:`15m`,value:`15m`},{label:`1H`,value:`1h`},{label:`4H`,value:`4h`},{label:`1D`,value:`1d`}],r=[{label:`Candlestick`,value:`candlestick`},{label:`Line`,value:`line`},{label:`Area`,value:`area`},{label:`Bar`,value:`bar`},{label:`Heikin-Ashi`,value:`heikinAshi`},{label:`Hollow Candle`,value:`hollowCandle`},{label:`Baseline`,value:`baseline`},{label:`Volume Candles`,value:`volumeCandles`},{label:`Equivolume`,value:`equivolume`},{label:`HLC Area`,value:`hlcArea`},{label:`Step Line`,value:`stepLine`},{label:`Line + Markers`,value:`lineWithMarkers`}],i=[{label:`Lines`,tools:[{label:`Trend Line`,value:`trendLine`},{label:`Ray`,value:`ray`},{label:`Extended Line`,value:`extendedLine`}]},{label:`Horizontal/Vertical`,tools:[{label:`Horizontal Line`,value:`horizontalLine`},{label:`Vertical Line`,value:`verticalLine`}]},{label:`Channels`,tools:[{label:`Parallel Channel`,value:`parallelChannel`},{label:`Regression Channel`,value:`regressionChannel`}]},{label:`Fibonacci`,tools:[{label:`Fib Retracement`,value:`fibRetracement`},{label:`Fib Extension`,value:`fibExtension`}]},{label:`Shapes`,tools:[{label:`Rectangle`,value:`rectangle`},{label:`Ellipse`,value:`ellipse`},{label:`Triangle`,value:`triangle`}]},{label:`Gann & Advanced`,tools:[{label:`Pitchfork`,value:`pitchfork`},{label:`Gann Fan`,value:`gannFan`},{label:`Gann Box`,value:`gannBox`},{label:`Elliott Wave`,value:`elliottWave`}]},{label:`Measure`,tools:[{label:`Price Range`,value:`priceRange`},{label:`Date Range`,value:`dateRange`},{label:`Measure`,value:`measure`}]},{label:`Annotation`,tools:[{label:`Text`,value:`text`},{label:`Arrow`,value:`arrow`}]}],a=[{id:`sma`,name:`SMA`,type:`overlay`},{id:`ema`,name:`EMA`,type:`overlay`},{id:`hma`,name:`Hull MA`,type:`overlay`},{id:`bb`,name:`Bollinger Bands`,type:`overlay`},{id:`vwap`,name:`VWAP`,type:`overlay`},{id:`avwap`,name:`Anchored VWAP`,type:`overlay`},{id:`ichimoku`,name:`Ichimoku Cloud`,type:`overlay`},{id:`psar`,name:`Parabolic SAR`,type:`overlay`},{id:`supertrend`,name:`Supertrend`,type:`overlay`},{id:`keltner`,name:`Keltner Channel`,type:`overlay`},{id:`donchian`,name:`Donchian Channel`,type:`overlay`},{id:`pivots`,name:`Pivot Points`,type:`overlay`},{id:`zigzag`,name:`ZigZag`,type:`overlay`},{id:`lrc`,name:`Linear Regression Channel`,type:`overlay`},{id:`rsi`,name:`RSI`,type:`panel`},{id:`macd`,name:`MACD`,type:`panel`},{id:`stochastic`,name:`Stochastic`,type:`panel`},{id:`atr`,name:`ATR`,type:`panel`},{id:`adx`,name:`ADX`,type:`panel`},{id:`obv`,name:`OBV`,type:`panel`},{id:`williamsR`,name:`Williams %R`,type:`panel`},{id:`cci`,name:`CCI`,type:`panel`},{id:`mfi`,name:`MFI`,type:`panel`},{id:`roc`,name:`ROC`,type:`panel`},{id:`tsi`,name:`TSI`,type:`panel`},{id:`cmf`,name:`CMF`,type:`panel`},{id:`aroon`,name:`Aroon`,type:`panel`},{id:`stddev`,name:`Std Deviation`,type:`panel`},{id:`vroc`,name:`Volume ROC`,type:`panel`},{id:`ad`,name:`Acc/Dist`,type:`panel`},{id:`ao`,name:`Awesome Oscillator`,type:`panel`},{id:`chaikinOsc`,name:`Chaikin Oscillator`,type:`panel`},{id:`volumeProfile`,name:`Volume Profile`,type:`panel`}],o=[`sma`,`ema`,`bb`,`rsi`,`macd`,`stochastic`,`vwap`,`atr`,`obv`,`ichimoku`],s=[`BTCUSDT`,`ETHUSDT`,`SOLUSDT`,`BNBUSDT`],c={candleUpColor:`#26A69A`,candleDownColor:`#EF5350`,candleUpWick:`#26A69A`,candleDownWick:`#EF5350`,backgroundColor:`#131722`,gridColor:`#1E222D`,gridVisible:!0,volumeVisible:!0,volumeProfileVisible:!1,legendVisible:!0,barCountdown:!0,logScale:!1,autoScale:!0,crosshairMode:`magnet`,numberLocale:`en-US`},l=`/* === TradeCanvas Widget — Premium Styles === */
2
+
3
+ .tcw-root {
4
+ display: flex;
5
+ flex-direction: column;
6
+ width: 100%;
7
+ height: 100%;
8
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, system-ui, sans-serif;
9
+ font-feature-settings: 'cv11', 'ss01', 'ss03';
10
+ font-size: 13px;
11
+ line-height: 1.4;
12
+ color: #d1d4dc;
13
+ background: #0d0f17;
14
+ position: relative;
15
+ overflow: hidden;
16
+ -webkit-font-smoothing: antialiased;
17
+ -moz-osx-font-smoothing: grayscale;
18
+
19
+ /* --- Dark theme tokens (default) --- */
20
+ --tcw-bg: #0d0f17;
21
+ --tcw-bg-surface: #131722;
22
+ --tcw-bg-elevated: #1a1e2d;
23
+ --tcw-bg-overlay: #20253480;
24
+ --tcw-border: #2a2e39;
25
+ --tcw-border-strong: #363a45;
26
+ --tcw-text: #e9ebf0;
27
+ --tcw-text-dim: #b2b5be;
28
+ --tcw-text-muted: #6b6f7a;
29
+
30
+ --tcw-accent: #4f88ff;
31
+ --tcw-accent-hover: #6b9aff;
32
+ --tcw-accent-soft: rgba(79, 136, 255, 0.14);
33
+ --tcw-accent-glow: rgba(79, 136, 255, 0.22);
34
+ --tcw-accent-line: rgba(79, 136, 255, 0.55);
35
+
36
+ --tcw-red: #f23645;
37
+ --tcw-red-soft: rgba(242, 54, 69, 0.12);
38
+ --tcw-green: #26a17b;
39
+ --tcw-green-soft: rgba(38, 161, 123, 0.12);
40
+ --tcw-amber: #ff9f43;
41
+
42
+ --tcw-hover-bg: rgba(255, 255, 255, 0.05);
43
+ --tcw-active-bg: rgba(255, 255, 255, 0.08);
44
+ --tcw-divider: rgba(255, 255, 255, 0.06);
45
+
46
+ /* Motion */
47
+ --tcw-ease: cubic-bezier(0.2, 0, 0, 1);
48
+ --tcw-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
49
+ --tcw-dur-fast: 120ms;
50
+ --tcw-dur-normal: 180ms;
51
+ --tcw-dur-slow: 260ms;
52
+
53
+ /* Shape */
54
+ --tcw-radius-sm: 4px;
55
+ --tcw-radius: 6px;
56
+ --tcw-radius-lg: 10px;
57
+ --tcw-radius-xl: 14px;
58
+
59
+ /* Elevation */
60
+ --tcw-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
61
+ --tcw-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.2);
62
+ --tcw-shadow-lg: 0 12px 36px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3);
63
+ --tcw-shadow-xl: 0 24px 64px rgba(0, 0, 0, 0.55), 0 12px 24px rgba(0, 0, 0, 0.35);
64
+ --tcw-ring: 0 0 0 2px rgba(79, 136, 255, 0.45);
65
+
66
+ /* Type */
67
+ --tcw-font-mono: 'JetBrains Mono', 'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', ui-monospace, monospace;
68
+ }
69
+
70
+ .tcw-root[data-tcw-theme='light'] {
71
+ color: #131722;
72
+ background: #fcfcfd;
73
+
74
+ --tcw-bg: #fcfcfd;
75
+ --tcw-bg-surface: #ffffff;
76
+ --tcw-bg-elevated: #ffffff;
77
+ --tcw-bg-overlay: rgba(255, 255, 255, 0.75);
78
+ --tcw-border: #e7e9ef;
79
+ --tcw-border-strong: #d4d7e0;
80
+ --tcw-text: #131722;
81
+ --tcw-text-dim: #50545e;
82
+ --tcw-text-muted: #8b8f99;
83
+
84
+ --tcw-accent: #2962ff;
85
+ --tcw-accent-hover: #1e4fd6;
86
+ --tcw-accent-soft: rgba(41, 98, 255, 0.10);
87
+ --tcw-accent-glow: rgba(41, 98, 255, 0.16);
88
+ --tcw-accent-line: rgba(41, 98, 255, 0.45);
89
+
90
+ --tcw-hover-bg: rgba(0, 0, 0, 0.04);
91
+ --tcw-active-bg: rgba(41, 98, 255, 0.08);
92
+ --tcw-divider: rgba(0, 0, 0, 0.06);
93
+
94
+ --tcw-shadow-sm: 0 1px 2px rgba(20, 28, 56, 0.05);
95
+ --tcw-shadow-md: 0 4px 12px rgba(20, 28, 56, 0.08), 0 1px 3px rgba(20, 28, 56, 0.04);
96
+ --tcw-shadow-lg: 0 12px 36px rgba(20, 28, 56, 0.14), 0 4px 12px rgba(20, 28, 56, 0.08);
97
+ --tcw-shadow-xl: 0 24px 64px rgba(20, 28, 56, 0.18), 0 12px 24px rgba(20, 28, 56, 0.1);
98
+ }
99
+
100
+ /* === Toolbar === */
101
+
102
+ .tcw-toolbar {
103
+ display: flex;
104
+ align-items: center;
105
+ gap: 0;
106
+ padding: 0 10px;
107
+ height: 44px;
108
+ border-bottom: 1px solid var(--tcw-border);
109
+ background:
110
+ linear-gradient(180deg, var(--tcw-bg-elevated) 0%, var(--tcw-bg-surface) 100%);
111
+ flex-shrink: 0;
112
+ position: relative;
113
+ z-index: 20;
114
+ box-shadow: var(--tcw-shadow-sm);
115
+ }
116
+
117
+ .tcw-toolbar-symbol {
118
+ font-size: 14px;
119
+ font-weight: 650;
120
+ color: var(--tcw-text);
121
+ padding: 6px 12px;
122
+ white-space: nowrap;
123
+ letter-spacing: -0.015em;
124
+ cursor: pointer;
125
+ border: none;
126
+ background: transparent;
127
+ font-family: inherit;
128
+ border-radius: var(--tcw-radius);
129
+ transition: background var(--tcw-dur-fast) var(--tcw-ease);
130
+ }
131
+
132
+ .tcw-toolbar-symbol:hover {
133
+ background: var(--tcw-hover-bg);
134
+ }
135
+
136
+ .tcw-toolbar-sep {
137
+ width: 1px;
138
+ height: 22px;
139
+ background: var(--tcw-border);
140
+ flex-shrink: 0;
141
+ margin: 0 4px;
142
+ }
143
+
144
+ .tcw-toolbar-group {
145
+ display: flex;
146
+ align-items: center;
147
+ gap: 2px;
148
+ padding: 0 4px;
149
+ }
150
+
151
+ .tcw-toolbar-spacer {
152
+ flex: 1;
153
+ }
154
+
155
+ .tcw-btn {
156
+ padding: 6px 10px;
157
+ font-size: 12px;
158
+ font-weight: 500;
159
+ font-family: inherit;
160
+ border: none;
161
+ border-radius: var(--tcw-radius);
162
+ background: transparent;
163
+ color: var(--tcw-text-dim);
164
+ cursor: pointer;
165
+ transition:
166
+ background var(--tcw-dur-fast) var(--tcw-ease),
167
+ color var(--tcw-dur-fast) var(--tcw-ease),
168
+ transform var(--tcw-dur-fast) var(--tcw-ease);
169
+ white-space: nowrap;
170
+ line-height: 1;
171
+ letter-spacing: -0.005em;
172
+ }
173
+
174
+ .tcw-btn:hover {
175
+ background: var(--tcw-hover-bg);
176
+ color: var(--tcw-text);
177
+ }
178
+
179
+ .tcw-btn:active {
180
+ transform: translateY(0.5px);
181
+ }
182
+
183
+ .tcw-btn.tcw-active {
184
+ background: var(--tcw-accent-soft);
185
+ color: var(--tcw-accent);
186
+ font-weight: 600;
187
+ box-shadow: inset 0 0 0 1px var(--tcw-accent-line);
188
+ }
189
+
190
+ .tcw-btn:focus-visible,
191
+ .tcw-btn-icon:focus-visible,
192
+ .tcw-sidebar-btn:focus-visible,
193
+ .tcw-dropdown-trigger:focus-visible {
194
+ outline: none;
195
+ box-shadow: var(--tcw-ring);
196
+ }
197
+
198
+ .tcw-btn-icon {
199
+ width: 32px;
200
+ height: 32px;
201
+ display: inline-flex;
202
+ align-items: center;
203
+ justify-content: center;
204
+ font-family: inherit;
205
+ border: none;
206
+ border-radius: var(--tcw-radius);
207
+ background: transparent;
208
+ color: var(--tcw-text-muted);
209
+ cursor: pointer;
210
+ transition:
211
+ background var(--tcw-dur-fast) var(--tcw-ease),
212
+ color var(--tcw-dur-fast) var(--tcw-ease);
213
+ line-height: 1;
214
+ position: relative;
215
+ }
216
+
217
+ .tcw-btn-icon:hover {
218
+ background: var(--tcw-hover-bg);
219
+ color: var(--tcw-text);
220
+ }
221
+
222
+ .tcw-btn-icon svg {
223
+ display: block;
224
+ }
225
+
226
+ .tcw-badge-count {
227
+ font-size: 10px;
228
+ font-weight: 600;
229
+ color: var(--tcw-accent);
230
+ background: var(--tcw-accent-soft);
231
+ padding: 1px 5px;
232
+ border-radius: 9px;
233
+ font-family: var(--tcw-font-mono);
234
+ }
235
+
236
+ .tcw-indicator-chips {
237
+ display: flex;
238
+ align-items: center;
239
+ gap: 4px;
240
+ padding: 0 4px;
241
+ flex-wrap: nowrap;
242
+ overflow: hidden;
243
+ }
244
+
245
+ .tcw-indicator-chip {
246
+ display: inline-flex;
247
+ align-items: center;
248
+ gap: 4px;
249
+ padding: 3px 6px 3px 9px;
250
+ font-size: 11px;
251
+ font-weight: 500;
252
+ background: var(--tcw-accent-soft);
253
+ color: var(--tcw-accent);
254
+ border-radius: 9999px;
255
+ white-space: nowrap;
256
+ line-height: 1.4;
257
+ letter-spacing: -0.005em;
258
+ border: 1px solid transparent;
259
+ transition: border-color var(--tcw-dur-fast) var(--tcw-ease);
260
+ }
261
+
262
+ .tcw-indicator-chip:hover {
263
+ border-color: var(--tcw-accent-line);
264
+ }
265
+
266
+ .tcw-chip-remove {
267
+ cursor: pointer;
268
+ opacity: 0.55;
269
+ padding: 0 2px;
270
+ transition: opacity var(--tcw-dur-fast) var(--tcw-ease);
271
+ border: none;
272
+ background: transparent;
273
+ color: inherit;
274
+ display: inline-flex;
275
+ align-items: center;
276
+ }
277
+
278
+ .tcw-chip-remove:hover {
279
+ opacity: 1;
280
+ }
281
+
282
+ /* === Dropdown === */
283
+
284
+ .tcw-dropdown-trigger {
285
+ display: inline-flex;
286
+ align-items: center;
287
+ gap: 4px;
288
+ padding: 6px 10px;
289
+ font-size: 12px;
290
+ font-weight: 500;
291
+ font-family: inherit;
292
+ border: none;
293
+ border-radius: var(--tcw-radius);
294
+ background: transparent;
295
+ color: var(--tcw-text-dim);
296
+ cursor: pointer;
297
+ transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);
298
+ white-space: nowrap;
299
+ line-height: 1;
300
+ }
301
+
302
+ .tcw-dropdown-trigger:hover {
303
+ background: var(--tcw-hover-bg);
304
+ color: var(--tcw-text);
305
+ }
306
+
307
+ .tcw-dropdown {
308
+ position: absolute;
309
+ top: 100%;
310
+ margin-top: 6px;
311
+ background: var(--tcw-bg-elevated);
312
+ border: 1px solid var(--tcw-border);
313
+ border-radius: var(--tcw-radius-lg);
314
+ box-shadow: var(--tcw-shadow-lg);
315
+ z-index: 50;
316
+ padding: 6px;
317
+ max-height: 420px;
318
+ overflow-y: auto;
319
+ backdrop-filter: blur(12px);
320
+ -webkit-backdrop-filter: blur(12px);
321
+ animation: tcw-pop-in var(--tcw-dur-normal) var(--tcw-ease-out);
322
+ }
323
+
324
+ @keyframes tcw-pop-in {
325
+ from { opacity: 0; transform: translateY(-4px) scale(0.98); }
326
+ to { opacity: 1; transform: translateY(0) scale(1); }
327
+ }
328
+
329
+ .tcw-dropdown-item {
330
+ display: flex;
331
+ align-items: center;
332
+ justify-content: space-between;
333
+ padding: 7px 10px;
334
+ font-size: 12.5px;
335
+ color: var(--tcw-text-dim);
336
+ cursor: pointer;
337
+ transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);
338
+ width: 100%;
339
+ border: none;
340
+ background: transparent;
341
+ font-family: inherit;
342
+ text-align: left;
343
+ border-radius: var(--tcw-radius-sm);
344
+ gap: 12px;
345
+ }
346
+
347
+ .tcw-dropdown-item:hover {
348
+ background: var(--tcw-hover-bg);
349
+ color: var(--tcw-text);
350
+ }
351
+
352
+ .tcw-dropdown-item.tcw-active {
353
+ color: var(--tcw-accent);
354
+ background: var(--tcw-accent-soft);
355
+ font-weight: 600;
356
+ }
357
+
358
+ .tcw-dropdown-label {
359
+ text-transform: uppercase;
360
+ font-size: 10px;
361
+ color: var(--tcw-text-muted);
362
+ letter-spacing: 0.08em;
363
+ padding: 8px 10px 4px;
364
+ font-weight: 600;
365
+ }
366
+
367
+ .tcw-dropdown-divider {
368
+ border-top: 1px solid var(--tcw-divider);
369
+ margin: 6px 4px;
370
+ }
371
+
372
+ .tcw-tag {
373
+ font-size: 10px;
374
+ font-family: var(--tcw-font-mono);
375
+ color: var(--tcw-text-muted);
376
+ padding: 2px 6px;
377
+ border-radius: 4px;
378
+ background: var(--tcw-hover-bg);
379
+ letter-spacing: 0.02em;
380
+ }
381
+
382
+ /* === Body === */
383
+
384
+ .tcw-body {
385
+ display: flex;
386
+ flex: 1;
387
+ min-height: 0;
388
+ background: var(--tcw-bg);
389
+ }
390
+
391
+ .tcw-chart-container {
392
+ flex: 1;
393
+ min-width: 0;
394
+ min-height: 0;
395
+ width: 100%;
396
+ height: 100%;
397
+ position: relative;
398
+ }
399
+
400
+ /* === Sidebar === */
401
+
402
+ .tcw-sidebar {
403
+ width: 40px;
404
+ flex-shrink: 0;
405
+ background: linear-gradient(180deg, var(--tcw-bg-elevated) 0%, var(--tcw-bg-surface) 100%);
406
+ border-right: 1px solid var(--tcw-border);
407
+ display: flex;
408
+ flex-direction: column;
409
+ align-items: center;
410
+ padding: 6px 0;
411
+ overflow: visible;
412
+ box-shadow: var(--tcw-shadow-sm);
413
+ }
414
+
415
+ .tcw-tool-group-wrap {
416
+ position: relative;
417
+ }
418
+
419
+ .tcw-sidebar-btn {
420
+ width: 32px;
421
+ height: 32px;
422
+ margin: 1px 0;
423
+ display: flex;
424
+ align-items: center;
425
+ justify-content: center;
426
+ border: none;
427
+ background: transparent;
428
+ color: var(--tcw-text-muted);
429
+ cursor: pointer;
430
+ font-family: inherit;
431
+ transition:
432
+ background var(--tcw-dur-fast) var(--tcw-ease),
433
+ color var(--tcw-dur-fast) var(--tcw-ease);
434
+ position: relative;
435
+ flex-shrink: 0;
436
+ line-height: 1;
437
+ border-radius: var(--tcw-radius);
438
+ }
439
+
440
+ .tcw-sidebar-btn:hover {
441
+ color: var(--tcw-text);
442
+ background: var(--tcw-hover-bg);
443
+ }
444
+
445
+ .tcw-sidebar-btn.tcw-active {
446
+ color: var(--tcw-accent);
447
+ background: var(--tcw-accent-soft);
448
+ box-shadow: inset 2px 0 0 var(--tcw-accent);
449
+ }
450
+
451
+ .tcw-sidebar-btn.tcw-danger:hover {
452
+ color: var(--tcw-red);
453
+ background: var(--tcw-red-soft);
454
+ }
455
+
456
+ .tcw-multi-dot {
457
+ position: absolute;
458
+ bottom: 3px;
459
+ right: 3px;
460
+ width: 4px;
461
+ height: 4px;
462
+ border-radius: 50%;
463
+ background: var(--tcw-text-muted);
464
+ opacity: 0.7;
465
+ }
466
+
467
+ .tcw-sidebar-divider {
468
+ width: 22px;
469
+ height: 1px;
470
+ background: var(--tcw-divider);
471
+ margin: 6px 0;
472
+ flex-shrink: 0;
473
+ }
474
+
475
+ .tcw-sidebar-spacer {
476
+ flex: 1;
477
+ }
478
+
479
+ /* === Flyout === */
480
+
481
+ .tcw-flyout {
482
+ position: absolute;
483
+ left: 100%;
484
+ top: 0;
485
+ margin-left: 6px;
486
+ min-width: 180px;
487
+ background: var(--tcw-bg-elevated);
488
+ border: 1px solid var(--tcw-border);
489
+ border-radius: var(--tcw-radius-lg);
490
+ box-shadow: var(--tcw-shadow-lg);
491
+ z-index: 30;
492
+ padding: 6px;
493
+ backdrop-filter: blur(12px);
494
+ -webkit-backdrop-filter: blur(12px);
495
+ animation: tcw-slide-right var(--tcw-dur-normal) var(--tcw-ease-out);
496
+ }
497
+
498
+ @keyframes tcw-slide-right {
499
+ from { opacity: 0; transform: translateX(-4px); }
500
+ to { opacity: 1; transform: translateX(0); }
501
+ }
502
+
503
+ .tcw-flyout-header {
504
+ text-transform: uppercase;
505
+ font-size: 10px;
506
+ color: var(--tcw-text-muted);
507
+ letter-spacing: 0.08em;
508
+ padding: 6px 10px 4px;
509
+ font-weight: 600;
510
+ }
511
+
512
+ .tcw-flyout-item {
513
+ padding: 7px 10px;
514
+ font-size: 12.5px;
515
+ color: var(--tcw-text-dim);
516
+ cursor: pointer;
517
+ width: 100%;
518
+ display: block;
519
+ border: none;
520
+ background: transparent;
521
+ text-align: left;
522
+ font-family: inherit;
523
+ border-radius: var(--tcw-radius-sm);
524
+ transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);
525
+ }
526
+
527
+ .tcw-flyout-item:hover {
528
+ background: var(--tcw-hover-bg);
529
+ color: var(--tcw-text);
530
+ }
531
+
532
+ .tcw-flyout-item.tcw-active {
533
+ color: var(--tcw-accent);
534
+ background: var(--tcw-accent-soft);
535
+ font-weight: 600;
536
+ }
537
+
538
+ /* === Modal === */
539
+
540
+ .tcw-modal-backdrop {
541
+ position: fixed;
542
+ inset: 0;
543
+ background: rgba(8, 10, 18, 0.55);
544
+ backdrop-filter: blur(6px) saturate(140%);
545
+ -webkit-backdrop-filter: blur(6px) saturate(140%);
546
+ z-index: 100;
547
+ animation: tcw-fade-in var(--tcw-dur-normal) var(--tcw-ease-out);
548
+ }
549
+
550
+ @keyframes tcw-fade-in {
551
+ from { opacity: 0; }
552
+ to { opacity: 1; }
553
+ }
554
+
555
+ .tcw-modal {
556
+ position: fixed;
557
+ z-index: 101;
558
+ top: 50%;
559
+ left: 50%;
560
+ transform: translate(-50%, -50%);
561
+ background: var(--tcw-bg-elevated);
562
+ border: 1px solid var(--tcw-border);
563
+ border-radius: var(--tcw-radius-xl);
564
+ width: 520px;
565
+ max-width: 92vw;
566
+ max-height: 82vh;
567
+ display: flex;
568
+ flex-direction: column;
569
+ box-shadow: var(--tcw-shadow-xl);
570
+ animation: tcw-modal-in var(--tcw-dur-slow) var(--tcw-ease-out);
571
+ }
572
+
573
+ @keyframes tcw-modal-in {
574
+ from { opacity: 0; transform: translate(-50%, -48%) scale(0.96); }
575
+ to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
576
+ }
577
+
578
+ .tcw-modal-header {
579
+ display: flex;
580
+ align-items: center;
581
+ justify-content: space-between;
582
+ padding: 18px 22px;
583
+ border-bottom: 1px solid var(--tcw-divider);
584
+ }
585
+
586
+ .tcw-modal-header h3 {
587
+ font-size: 15px;
588
+ font-weight: 650;
589
+ margin: 0;
590
+ color: var(--tcw-text);
591
+ letter-spacing: -0.015em;
592
+ }
593
+
594
+ .tcw-modal-close {
595
+ width: 28px;
596
+ height: 28px;
597
+ display: flex;
598
+ align-items: center;
599
+ justify-content: center;
600
+ border: none;
601
+ background: transparent;
602
+ color: var(--tcw-text-muted);
603
+ cursor: pointer;
604
+ border-radius: var(--tcw-radius);
605
+ transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);
606
+ }
607
+
608
+ .tcw-modal-close:hover {
609
+ background: var(--tcw-hover-bg);
610
+ color: var(--tcw-text);
611
+ }
612
+
613
+ .tcw-modal-tabs {
614
+ display: flex;
615
+ gap: 4px;
616
+ padding: 0 18px;
617
+ border-bottom: 1px solid var(--tcw-divider);
618
+ }
619
+
620
+ .tcw-modal-tab {
621
+ padding: 11px 14px;
622
+ font-size: 12px;
623
+ font-weight: 500;
624
+ color: var(--tcw-text-muted);
625
+ border: none;
626
+ background: transparent;
627
+ cursor: pointer;
628
+ border-bottom: 2px solid transparent;
629
+ margin-bottom: -1px;
630
+ transition: color var(--tcw-dur-fast) var(--tcw-ease), border-color var(--tcw-dur-fast) var(--tcw-ease);
631
+ font-family: inherit;
632
+ text-transform: capitalize;
633
+ letter-spacing: -0.005em;
634
+ }
635
+
636
+ .tcw-modal-tab:hover {
637
+ color: var(--tcw-text-dim);
638
+ }
639
+
640
+ .tcw-modal-tab.tcw-active {
641
+ color: var(--tcw-accent);
642
+ border-bottom-color: var(--tcw-accent);
643
+ font-weight: 600;
644
+ }
645
+
646
+ .tcw-modal-body {
647
+ padding: 20px 22px;
648
+ overflow-y: auto;
649
+ flex: 1;
650
+ }
651
+
652
+ .tcw-settings-section {
653
+ margin-bottom: 22px;
654
+ }
655
+
656
+ .tcw-settings-section:last-child {
657
+ margin-bottom: 0;
658
+ }
659
+
660
+ .tcw-settings-section-title {
661
+ font-size: 10.5px;
662
+ font-weight: 600;
663
+ text-transform: uppercase;
664
+ letter-spacing: 0.09em;
665
+ color: var(--tcw-text-muted);
666
+ margin-bottom: 12px;
667
+ }
668
+
669
+ .tcw-settings-row {
670
+ display: flex;
671
+ align-items: center;
672
+ justify-content: space-between;
673
+ padding: 10px 0;
674
+ }
675
+
676
+ .tcw-settings-row + .tcw-settings-row {
677
+ border-top: 1px solid var(--tcw-divider);
678
+ }
679
+
680
+ .tcw-settings-label {
681
+ font-size: 13px;
682
+ color: var(--tcw-text-dim);
683
+ letter-spacing: -0.005em;
684
+ }
685
+
686
+ .tcw-color-picker-wrap {
687
+ display: flex;
688
+ align-items: center;
689
+ gap: 8px;
690
+ }
691
+
692
+ .tcw-color-picker-wrap input[type='color'] {
693
+ width: 28px;
694
+ height: 28px;
695
+ border: 1px solid var(--tcw-border-strong);
696
+ border-radius: var(--tcw-radius-sm);
697
+ background: transparent;
698
+ cursor: pointer;
699
+ padding: 2px;
700
+ }
701
+
702
+ .tcw-color-picker-wrap input[type='color']::-webkit-color-swatch-wrapper {
703
+ padding: 0;
704
+ }
705
+
706
+ .tcw-color-picker-wrap input[type='color']::-webkit-color-swatch {
707
+ border: none;
708
+ border-radius: 2px;
709
+ }
710
+
711
+ .tcw-color-hex {
712
+ font-size: 11px;
713
+ font-family: var(--tcw-font-mono);
714
+ color: var(--tcw-text-muted);
715
+ min-width: 64px;
716
+ letter-spacing: 0.01em;
717
+ }
718
+
719
+ .tcw-toggle {
720
+ width: 36px;
721
+ height: 20px;
722
+ background: rgba(255, 255, 255, 0.12);
723
+ border-radius: 10px;
724
+ position: relative;
725
+ cursor: pointer;
726
+ transition: background var(--tcw-dur-fast) var(--tcw-ease);
727
+ border: none;
728
+ padding: 0;
729
+ flex-shrink: 0;
730
+ }
731
+
732
+ .tcw-toggle::after {
733
+ content: '';
734
+ position: absolute;
735
+ top: 2px;
736
+ left: 2px;
737
+ width: 16px;
738
+ height: 16px;
739
+ border-radius: 50%;
740
+ background: var(--tcw-text-muted);
741
+ transition:
742
+ left var(--tcw-dur-normal) var(--tcw-ease-out),
743
+ background var(--tcw-dur-fast) var(--tcw-ease);
744
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
745
+ }
746
+
747
+ .tcw-toggle.tcw-on {
748
+ background: var(--tcw-accent);
749
+ box-shadow: 0 0 0 2px var(--tcw-accent-glow);
750
+ }
751
+
752
+ .tcw-toggle.tcw-on::after {
753
+ left: 18px;
754
+ background: #fff;
755
+ }
756
+
757
+ .tcw-root[data-tcw-theme='light'] .tcw-toggle {
758
+ background: rgba(0, 0, 0, 0.12);
759
+ }
760
+
761
+ .tcw-root[data-tcw-theme='light'] .tcw-toggle::after {
762
+ background: #999;
763
+ }
764
+
765
+ .tcw-root[data-tcw-theme='light'] .tcw-toggle.tcw-on {
766
+ background: var(--tcw-accent);
767
+ }
768
+
769
+ .tcw-root[data-tcw-theme='light'] .tcw-toggle.tcw-on::after {
770
+ background: #fff;
771
+ }
772
+
773
+ .tcw-settings-select {
774
+ padding: 6px 10px;
775
+ font-size: 12px;
776
+ font-family: inherit;
777
+ background: var(--tcw-bg-surface);
778
+ border: 1px solid var(--tcw-border);
779
+ border-radius: var(--tcw-radius);
780
+ color: var(--tcw-text);
781
+ cursor: pointer;
782
+ transition: border-color var(--tcw-dur-fast) var(--tcw-ease);
783
+ }
784
+
785
+ .tcw-settings-select:hover {
786
+ border-color: var(--tcw-border-strong);
787
+ }
788
+
789
+ .tcw-settings-select:focus-visible {
790
+ outline: none;
791
+ border-color: var(--tcw-accent);
792
+ box-shadow: var(--tcw-ring);
793
+ }
794
+
795
+ .tcw-modal-footer {
796
+ display: flex;
797
+ align-items: center;
798
+ justify-content: space-between;
799
+ padding: 14px 22px;
800
+ border-top: 1px solid var(--tcw-divider);
801
+ background: var(--tcw-bg-surface);
802
+ border-radius: 0 0 var(--tcw-radius-xl) var(--tcw-radius-xl);
803
+ }
804
+
805
+ .tcw-reset-link {
806
+ font-size: 12px;
807
+ color: var(--tcw-text-muted);
808
+ cursor: pointer;
809
+ border: none;
810
+ background: transparent;
811
+ font-family: inherit;
812
+ text-decoration: underline;
813
+ text-underline-offset: 2px;
814
+ text-decoration-color: var(--tcw-border-strong);
815
+ transition: color var(--tcw-dur-fast) var(--tcw-ease), text-decoration-color var(--tcw-dur-fast) var(--tcw-ease);
816
+ }
817
+
818
+ .tcw-reset-link:hover {
819
+ color: var(--tcw-text-dim);
820
+ text-decoration-color: currentColor;
821
+ }
822
+
823
+ .tcw-done-btn {
824
+ padding: 8px 18px;
825
+ font-size: 12.5px;
826
+ font-weight: 600;
827
+ background: var(--tcw-accent);
828
+ color: #fff;
829
+ border: none;
830
+ border-radius: var(--tcw-radius);
831
+ cursor: pointer;
832
+ font-family: inherit;
833
+ transition:
834
+ background var(--tcw-dur-fast) var(--tcw-ease),
835
+ transform var(--tcw-dur-fast) var(--tcw-ease),
836
+ box-shadow var(--tcw-dur-fast) var(--tcw-ease);
837
+ letter-spacing: -0.005em;
838
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.15);
839
+ }
840
+
841
+ .tcw-done-btn:hover {
842
+ background: var(--tcw-accent-hover);
843
+ box-shadow: var(--tcw-shadow-md), 0 0 0 3px var(--tcw-accent-glow);
844
+ }
845
+
846
+ .tcw-done-btn:active {
847
+ transform: translateY(0.5px);
848
+ }
849
+
850
+ /* === Status Bar === */
851
+
852
+ .tcw-statusbar {
853
+ display: flex;
854
+ align-items: center;
855
+ justify-content: space-between;
856
+ padding: 7px 16px;
857
+ border-top: 1px solid var(--tcw-border);
858
+ background: var(--tcw-bg-surface);
859
+ font-size: 11px;
860
+ color: var(--tcw-text-muted);
861
+ flex-shrink: 0;
862
+ font-feature-settings: 'tnum';
863
+ }
864
+
865
+ .tcw-status-indicator {
866
+ display: flex;
867
+ align-items: center;
868
+ gap: 7px;
869
+ font-weight: 500;
870
+ }
871
+
872
+ .tcw-status-dot {
873
+ width: 7px;
874
+ height: 7px;
875
+ border-radius: 50%;
876
+ background: var(--tcw-text-muted);
877
+ transition: background var(--tcw-dur-normal) var(--tcw-ease), box-shadow var(--tcw-dur-normal) var(--tcw-ease);
878
+ position: relative;
879
+ }
880
+
881
+ .tcw-status-dot.tcw-connected {
882
+ background: var(--tcw-green);
883
+ box-shadow: 0 0 0 3px rgba(38, 161, 123, 0.18);
884
+ }
885
+
886
+ .tcw-status-dot.tcw-connected::after {
887
+ content: '';
888
+ position: absolute;
889
+ inset: -3px;
890
+ border-radius: 50%;
891
+ border: 2px solid var(--tcw-green);
892
+ opacity: 0;
893
+ animation: tcw-pulse 2.2s ease-out infinite;
894
+ }
895
+
896
+ @keyframes tcw-pulse {
897
+ 0% { opacity: 0.6; transform: scale(0.6); }
898
+ 100% { opacity: 0; transform: scale(2.2); }
899
+ }
900
+
901
+ .tcw-status-dot.tcw-error {
902
+ background: var(--tcw-red);
903
+ box-shadow: 0 0 0 3px rgba(242, 54, 69, 0.2);
904
+ }
905
+
906
+ /* === Command Palette === */
907
+
908
+ .tcw-cmd-palette {
909
+ position: fixed;
910
+ z-index: 102;
911
+ top: 18%;
912
+ left: 50%;
913
+ transform: translateX(-50%);
914
+ background: var(--tcw-bg-elevated);
915
+ border: 1px solid var(--tcw-border);
916
+ border-radius: var(--tcw-radius-xl);
917
+ width: 560px;
918
+ max-width: 92vw;
919
+ max-height: 62vh;
920
+ display: flex;
921
+ flex-direction: column;
922
+ box-shadow: var(--tcw-shadow-xl);
923
+ overflow: hidden;
924
+ backdrop-filter: blur(20px);
925
+ -webkit-backdrop-filter: blur(20px);
926
+ animation: tcw-modal-in var(--tcw-dur-slow) var(--tcw-ease-out);
927
+ }
928
+
929
+ .tcw-cmd-header {
930
+ display: flex;
931
+ align-items: center;
932
+ padding: 14px 18px;
933
+ border-bottom: 1px solid var(--tcw-divider);
934
+ gap: 12px;
935
+ }
936
+
937
+ .tcw-cmd-icon {
938
+ font-size: 18px;
939
+ color: var(--tcw-text-muted);
940
+ flex-shrink: 0;
941
+ display: inline-flex;
942
+ align-items: center;
943
+ }
944
+
945
+ .tcw-cmd-input {
946
+ flex: 1;
947
+ background: transparent;
948
+ border: none;
949
+ outline: none;
950
+ font-size: 14.5px;
951
+ font-family: inherit;
952
+ color: var(--tcw-text);
953
+ caret-color: var(--tcw-accent);
954
+ letter-spacing: -0.005em;
955
+ }
956
+
957
+ .tcw-cmd-input::placeholder {
958
+ color: var(--tcw-text-muted);
959
+ }
960
+
961
+ .tcw-cmd-hint {
962
+ font-size: 10px;
963
+ color: var(--tcw-text-muted);
964
+ font-family: var(--tcw-font-mono);
965
+ border: 1px solid var(--tcw-border);
966
+ background: var(--tcw-bg-surface);
967
+ padding: 3px 7px;
968
+ border-radius: 4px;
969
+ flex-shrink: 0;
970
+ box-shadow: inset 0 -1px 0 var(--tcw-border);
971
+ }
972
+
973
+ .tcw-cmd-list {
974
+ overflow-y: auto;
975
+ flex: 1;
976
+ padding: 6px;
977
+ max-height: 380px;
978
+ }
979
+
980
+ .tcw-cmd-category {
981
+ text-transform: uppercase;
982
+ font-size: 10px;
983
+ color: var(--tcw-text-muted);
984
+ letter-spacing: 0.09em;
985
+ padding: 10px 10px 4px;
986
+ font-weight: 600;
987
+ }
988
+
989
+ .tcw-cmd-item {
990
+ display: flex;
991
+ align-items: center;
992
+ justify-content: space-between;
993
+ padding: 9px 12px;
994
+ font-size: 13px;
995
+ color: var(--tcw-text-dim);
996
+ cursor: pointer;
997
+ width: 100%;
998
+ border: none;
999
+ background: transparent;
1000
+ font-family: inherit;
1001
+ text-align: left;
1002
+ transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);
1003
+ gap: 10px;
1004
+ border-radius: var(--tcw-radius);
1005
+ letter-spacing: -0.005em;
1006
+ }
1007
+
1008
+ .tcw-cmd-item:hover,
1009
+ .tcw-cmd-item.tcw-selected {
1010
+ background: var(--tcw-hover-bg);
1011
+ color: var(--tcw-text);
1012
+ }
1013
+
1014
+ .tcw-cmd-item.tcw-selected {
1015
+ box-shadow: inset 2px 0 0 var(--tcw-accent);
1016
+ }
1017
+
1018
+ .tcw-cmd-item.tcw-active .tcw-cmd-item-label {
1019
+ color: var(--tcw-accent);
1020
+ font-weight: 600;
1021
+ }
1022
+
1023
+ .tcw-cmd-item-label {
1024
+ flex: 1;
1025
+ }
1026
+
1027
+ .tcw-cmd-check {
1028
+ color: var(--tcw-accent);
1029
+ font-size: 14px;
1030
+ font-weight: 700;
1031
+ }
1032
+
1033
+ .tcw-cmd-kbd {
1034
+ font-size: 10px;
1035
+ font-family: var(--tcw-font-mono);
1036
+ color: var(--tcw-text-muted);
1037
+ background: var(--tcw-bg-surface);
1038
+ border: 1px solid var(--tcw-border);
1039
+ padding: 2px 6px;
1040
+ border-radius: 4px;
1041
+ box-shadow: inset 0 -1px 0 var(--tcw-border);
1042
+ }
1043
+
1044
+ .tcw-cmd-empty {
1045
+ padding: 32px 16px;
1046
+ text-align: center;
1047
+ color: var(--tcw-text-muted);
1048
+ font-size: 13px;
1049
+ }
1050
+
1051
+ .tcw-cmd-footer {
1052
+ display: flex;
1053
+ align-items: center;
1054
+ gap: 18px;
1055
+ padding: 10px 18px;
1056
+ border-top: 1px solid var(--tcw-divider);
1057
+ font-size: 11px;
1058
+ color: var(--tcw-text-muted);
1059
+ background: var(--tcw-bg-surface);
1060
+ }
1061
+
1062
+ /* === Watchlist === */
1063
+
1064
+ .tcw-watchlist {
1065
+ width: 220px;
1066
+ flex-shrink: 0;
1067
+ background: var(--tcw-bg-surface);
1068
+ border-left: 1px solid var(--tcw-border);
1069
+ display: flex;
1070
+ flex-direction: column;
1071
+ overflow: hidden;
1072
+ box-shadow: var(--tcw-shadow-sm);
1073
+ }
1074
+
1075
+ .tcw-watchlist-header {
1076
+ padding: 10px 14px;
1077
+ font-size: 11px;
1078
+ font-weight: 600;
1079
+ text-transform: uppercase;
1080
+ letter-spacing: 0.08em;
1081
+ color: var(--tcw-text-muted);
1082
+ border-bottom: 1px solid var(--tcw-divider);
1083
+ }
1084
+
1085
+ .tcw-watchlist-list {
1086
+ flex: 1;
1087
+ overflow-y: auto;
1088
+ padding: 4px 0;
1089
+ }
1090
+
1091
+ .tcw-watchlist-row {
1092
+ display: grid;
1093
+ grid-template-columns: 1fr auto auto;
1094
+ align-items: center;
1095
+ gap: 8px;
1096
+ padding: 8px 12px;
1097
+ cursor: pointer;
1098
+ transition: background var(--tcw-dur-fast) var(--tcw-ease);
1099
+ border-left: 2px solid transparent;
1100
+ outline: none;
1101
+ }
1102
+
1103
+ .tcw-watchlist-row:hover {
1104
+ background: var(--tcw-hover-bg);
1105
+ }
1106
+
1107
+ .tcw-watchlist-row:focus-visible {
1108
+ background: var(--tcw-hover-bg);
1109
+ border-left-color: var(--tcw-accent);
1110
+ }
1111
+
1112
+ .tcw-watchlist-row.tcw-watchlist-active {
1113
+ background: var(--tcw-accent-soft);
1114
+ border-left-color: var(--tcw-accent);
1115
+ }
1116
+
1117
+ .tcw-watchlist-symbol {
1118
+ font-size: 12.5px;
1119
+ font-weight: 600;
1120
+ color: var(--tcw-text);
1121
+ letter-spacing: -0.005em;
1122
+ white-space: nowrap;
1123
+ }
1124
+
1125
+ .tcw-watchlist-spark {
1126
+ width: 56px;
1127
+ height: 22px;
1128
+ align-self: center;
1129
+ }
1130
+
1131
+ .tcw-watchlist-stats {
1132
+ display: flex;
1133
+ flex-direction: column;
1134
+ align-items: flex-end;
1135
+ gap: 1px;
1136
+ font-variant-numeric: tabular-nums;
1137
+ font-family: var(--tcw-font-mono);
1138
+ }
1139
+
1140
+ .tcw-watchlist-price {
1141
+ font-size: 12px;
1142
+ color: var(--tcw-text);
1143
+ font-weight: 500;
1144
+ }
1145
+
1146
+ .tcw-watchlist-change {
1147
+ font-size: 10.5px;
1148
+ color: var(--tcw-text-muted);
1149
+ font-weight: 500;
1150
+ }
1151
+
1152
+ .tcw-watchlist-change.tcw-up {
1153
+ color: var(--tcw-green);
1154
+ }
1155
+
1156
+ .tcw-watchlist-change.tcw-down {
1157
+ color: var(--tcw-red);
1158
+ }
1159
+
1160
+ @media (max-width: 768px) {
1161
+ .tcw-watchlist {
1162
+ display: none;
1163
+ }
1164
+ }
1165
+
1166
+ /* === Toast === */
1167
+
1168
+ .tcw-toast {
1169
+ position: absolute;
1170
+ bottom: 60px;
1171
+ left: 50%;
1172
+ transform: translate(-50%, 12px);
1173
+ z-index: 40;
1174
+ padding: 9px 14px;
1175
+ background: var(--tcw-bg-elevated);
1176
+ border: 1px solid var(--tcw-border-strong);
1177
+ border-radius: 9999px;
1178
+ box-shadow: var(--tcw-shadow-lg);
1179
+ font-size: 12.5px;
1180
+ font-weight: 500;
1181
+ color: var(--tcw-text);
1182
+ opacity: 0;
1183
+ transition: opacity var(--tcw-dur-normal) var(--tcw-ease-out), transform var(--tcw-dur-normal) var(--tcw-ease-out);
1184
+ pointer-events: none;
1185
+ max-width: calc(100% - 32px);
1186
+ white-space: nowrap;
1187
+ overflow: hidden;
1188
+ text-overflow: ellipsis;
1189
+ letter-spacing: -0.005em;
1190
+ }
1191
+
1192
+ .tcw-toast.tcw-toast-in {
1193
+ opacity: 1;
1194
+ transform: translate(-50%, 0);
1195
+ }
1196
+
1197
+ .tcw-toast-error {
1198
+ border-color: var(--tcw-red);
1199
+ color: var(--tcw-red);
1200
+ }
1201
+
1202
+ /* === Replay scrubber === */
1203
+
1204
+ .tcw-replay-bar {
1205
+ position: absolute;
1206
+ left: 50%;
1207
+ bottom: 16px;
1208
+ transform: translateX(-50%);
1209
+ z-index: 25;
1210
+ display: flex;
1211
+ align-items: center;
1212
+ gap: 6px;
1213
+ padding: 6px 10px;
1214
+ background: var(--tcw-bg-elevated);
1215
+ border: 1px solid var(--tcw-border);
1216
+ border-radius: 9999px;
1217
+ box-shadow: var(--tcw-shadow-lg);
1218
+ backdrop-filter: blur(12px);
1219
+ -webkit-backdrop-filter: blur(12px);
1220
+ font-size: 12px;
1221
+ color: var(--tcw-text);
1222
+ animation: tcw-pop-in var(--tcw-dur-normal) var(--tcw-ease-out);
1223
+ }
1224
+
1225
+ .tcw-replay-btn {
1226
+ width: 28px;
1227
+ height: 28px;
1228
+ display: inline-flex;
1229
+ align-items: center;
1230
+ justify-content: center;
1231
+ border: none;
1232
+ background: transparent;
1233
+ color: var(--tcw-text-dim);
1234
+ border-radius: 9999px;
1235
+ cursor: pointer;
1236
+ font-family: inherit;
1237
+ transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);
1238
+ }
1239
+
1240
+ .tcw-replay-btn:hover {
1241
+ background: var(--tcw-hover-bg);
1242
+ color: var(--tcw-text);
1243
+ }
1244
+
1245
+ .tcw-replay-btn.tcw-replay-play {
1246
+ background: var(--tcw-accent);
1247
+ color: #fff;
1248
+ width: 32px;
1249
+ height: 32px;
1250
+ box-shadow: 0 0 0 3px var(--tcw-accent-glow);
1251
+ }
1252
+
1253
+ .tcw-replay-btn.tcw-replay-play:hover {
1254
+ background: var(--tcw-accent-hover);
1255
+ }
1256
+
1257
+ .tcw-replay-scrubber {
1258
+ appearance: none;
1259
+ -webkit-appearance: none;
1260
+ width: 220px;
1261
+ height: 4px;
1262
+ background: var(--tcw-border-strong);
1263
+ border-radius: 2px;
1264
+ outline: none;
1265
+ cursor: pointer;
1266
+ }
1267
+
1268
+ .tcw-replay-scrubber::-webkit-slider-thumb {
1269
+ -webkit-appearance: none;
1270
+ appearance: none;
1271
+ width: 14px;
1272
+ height: 14px;
1273
+ border-radius: 50%;
1274
+ background: var(--tcw-accent);
1275
+ border: 2px solid var(--tcw-bg-elevated);
1276
+ box-shadow: 0 0 0 1px var(--tcw-accent), 0 2px 6px rgba(0, 0, 0, 0.3);
1277
+ cursor: pointer;
1278
+ }
1279
+
1280
+ .tcw-replay-scrubber::-moz-range-thumb {
1281
+ width: 14px;
1282
+ height: 14px;
1283
+ border-radius: 50%;
1284
+ background: var(--tcw-accent);
1285
+ border: 2px solid var(--tcw-bg-elevated);
1286
+ box-shadow: 0 0 0 1px var(--tcw-accent), 0 2px 6px rgba(0, 0, 0, 0.3);
1287
+ cursor: pointer;
1288
+ }
1289
+
1290
+ .tcw-replay-progress {
1291
+ font-size: 11px;
1292
+ font-family: var(--tcw-font-mono);
1293
+ color: var(--tcw-text-muted);
1294
+ min-width: 64px;
1295
+ text-align: center;
1296
+ font-feature-settings: 'tnum';
1297
+ }
1298
+
1299
+ .tcw-replay-speed {
1300
+ padding: 4px 8px;
1301
+ font-size: 11px;
1302
+ font-family: var(--tcw-font-mono);
1303
+ background: var(--tcw-bg-surface);
1304
+ border: 1px solid var(--tcw-border);
1305
+ border-radius: var(--tcw-radius);
1306
+ color: var(--tcw-text-dim);
1307
+ cursor: pointer;
1308
+ }
1309
+
1310
+ .tcw-replay-speed:hover {
1311
+ border-color: var(--tcw-border-strong);
1312
+ }
1313
+
1314
+ @media (max-width: 640px) {
1315
+ .tcw-replay-scrubber {
1316
+ width: 140px;
1317
+ }
1318
+ .tcw-replay-progress {
1319
+ display: none;
1320
+ }
1321
+ }
1322
+
1323
+ /* === Hotkey sheet === */
1324
+
1325
+ .tcw-hotkey-grid {
1326
+ display: grid;
1327
+ grid-template-columns: 1fr 1fr;
1328
+ gap: 24px 32px;
1329
+ }
1330
+
1331
+ .tcw-hotkey-section .tcw-settings-section-title {
1332
+ margin-bottom: 8px;
1333
+ }
1334
+
1335
+ .tcw-hotkey-row {
1336
+ display: flex;
1337
+ align-items: center;
1338
+ justify-content: space-between;
1339
+ gap: 12px;
1340
+ padding: 6px 0;
1341
+ border-bottom: 1px solid var(--tcw-divider);
1342
+ }
1343
+
1344
+ .tcw-hotkey-row:last-child {
1345
+ border-bottom: none;
1346
+ }
1347
+
1348
+ .tcw-hotkey-keys {
1349
+ display: flex;
1350
+ align-items: center;
1351
+ gap: 4px;
1352
+ flex-shrink: 0;
1353
+ }
1354
+
1355
+ .tcw-hotkey-sep {
1356
+ font-size: 10px;
1357
+ color: var(--tcw-text-muted);
1358
+ }
1359
+
1360
+ .tcw-hotkey-label {
1361
+ font-size: 12.5px;
1362
+ color: var(--tcw-text-dim);
1363
+ text-align: right;
1364
+ letter-spacing: -0.005em;
1365
+ }
1366
+
1367
+ @media (max-width: 640px) {
1368
+ .tcw-hotkey-grid {
1369
+ grid-template-columns: 1fr;
1370
+ gap: 18px;
1371
+ }
1372
+ }
1373
+
1374
+ /* === Scrollbar (subtle, premium feel) === */
1375
+
1376
+ .tcw-dropdown::-webkit-scrollbar,
1377
+ .tcw-modal-body::-webkit-scrollbar,
1378
+ .tcw-cmd-list::-webkit-scrollbar {
1379
+ width: 8px;
1380
+ height: 8px;
1381
+ }
1382
+
1383
+ .tcw-dropdown::-webkit-scrollbar-track,
1384
+ .tcw-modal-body::-webkit-scrollbar-track,
1385
+ .tcw-cmd-list::-webkit-scrollbar-track {
1386
+ background: transparent;
1387
+ }
1388
+
1389
+ .tcw-dropdown::-webkit-scrollbar-thumb,
1390
+ .tcw-modal-body::-webkit-scrollbar-thumb,
1391
+ .tcw-cmd-list::-webkit-scrollbar-thumb {
1392
+ background: var(--tcw-border-strong);
1393
+ border-radius: 4px;
1394
+ border: 2px solid transparent;
1395
+ background-clip: padding-box;
1396
+ }
1397
+
1398
+ .tcw-dropdown::-webkit-scrollbar-thumb:hover,
1399
+ .tcw-modal-body::-webkit-scrollbar-thumb:hover,
1400
+ .tcw-cmd-list::-webkit-scrollbar-thumb:hover {
1401
+ background: var(--tcw-text-muted);
1402
+ background-clip: padding-box;
1403
+ border: 2px solid transparent;
1404
+ }
1405
+
1406
+ /* === Responsive === */
1407
+
1408
+ @media (max-width: 768px) {
1409
+ .tcw-toolbar {
1410
+ padding: 0 6px;
1411
+ height: 40px;
1412
+ }
1413
+ .tcw-toolbar-sep {
1414
+ display: none;
1415
+ }
1416
+ .tcw-indicator-chips {
1417
+ display: none;
1418
+ }
1419
+ .tcw-sidebar {
1420
+ width: 36px;
1421
+ }
1422
+ .tcw-sidebar-btn {
1423
+ width: 28px;
1424
+ height: 28px;
1425
+ }
1426
+ .tcw-modal {
1427
+ width: 94vw;
1428
+ border-radius: var(--tcw-radius-lg);
1429
+ }
1430
+ .tcw-cmd-palette {
1431
+ width: 94vw;
1432
+ border-radius: var(--tcw-radius-lg);
1433
+ }
1434
+ }
1435
+
1436
+ /* === Reduced motion === */
1437
+
1438
+ @media (prefers-reduced-motion: reduce) {
1439
+ .tcw-root *,
1440
+ .tcw-root *::before,
1441
+ .tcw-root *::after {
1442
+ animation-duration: 0.01ms !important;
1443
+ animation-iteration-count: 1 !important;
1444
+ transition-duration: 0.01ms !important;
1445
+ }
1446
+ }
1447
+ `,u=0,d=`tcw-styles`;function f(){if(u++,u>1||document.getElementById(d))return;let e=document.createElement(`style`);e.id=d,e.textContent=l,document.head.appendChild(e)}function p(){if(u--,u>0)return;let e=document.getElementById(d);e&&e.remove()}var m={cursor:`<path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/><path d="M13 13l6 6"/>`,trendingUp:`<polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/>`,minus:`<path d="M5 12h14"/>`,penLine:`<path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/>`,hash:`<line x1="4" y1="9" x2="20" y2="9"/><line x1="4" y1="15" x2="20" y2="15"/><line x1="10" y1="3" x2="8" y2="21"/><line x1="16" y1="3" x2="14" y2="21"/>`,square:`<rect width="18" height="18" x="3" y="3" rx="2"/>`,gitBranch:`<line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/>`,ruler:`<path d="M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Z"/><path d="m14.5 12.5 2-2"/><path d="m11.5 9.5 2-2"/><path d="m8.5 6.5 2-2"/><path d="m17.5 15.5 2-2"/>`,type:`<polyline points="4 7 4 4 20 4 20 7"/><line x1="9" y1="20" x2="15" y2="20"/><line x1="12" y1="4" x2="12" y2="20"/>`,magnet:`<path d="m6 15-4-4 6.75-6.77a7.79 7.79 0 0 1 11 11L13 22l-4-4 6.39-6.36a2.14 2.14 0 0 0-3-3L6 15"/><path d="m5 8 4 4"/><path d="m12 15 4 4"/>`,undo:`<path d="M3 7v6h6"/><path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"/>`,redo:`<path d="M21 7v6h-6"/><path d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13"/>`,trash:`<path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/>`,camera:`<path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3"/>`,settings:`<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>`,moon:`<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>`,sun:`<circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/>`,chevronDown:`<path d="m6 9 6 6 6-6"/>`,chevronUp:`<path d="m18 15-6-6-6 6"/>`,barChart:`<line x1="12" y1="20" x2="12" y2="10"/><line x1="18" y1="20" x2="18" y2="4"/><line x1="6" y1="20" x2="6" y2="16"/>`,x:`<path d="M18 6 6 18"/><path d="m6 6 12 12"/>`,play:`<polygon points="6 3 20 12 6 21 6 3"/>`,pause:`<rect width="4" height="16" x="6" y="4"/><rect width="4" height="16" x="14" y="4"/>`,stop:`<rect width="14" height="14" x="5" y="5" rx="1"/>`,receipt:`<path d="M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1Z"/><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8"/><path d="M12 17.5v-11"/>`};function h(e,t=14){let n=m[e];return n?`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${n}</svg>`:``}var g=class{trigger;panel;_isOpen=!1;onOutsideClick;onEscapeKey;onTriggerClick;constructor(e,t={}){this.trigger=e,this.panel=document.createElement(`div`),this.panel.className=`tcw-dropdown`,this.panel.style.width=t.width??`200px`,t.align===`right`?this.panel.style.right=`0`:this.panel.style.left=`0`,this.panel.style.display=`none`,e.style.position=`relative`,e.appendChild(this.panel),this.onTriggerClick=()=>{this._isOpen?this.close():this.open()},this.onOutsideClick=e=>{this.trigger.contains(e.target)||this.close()},this.onEscapeKey=e=>{e.key===`Escape`&&this.close()},e.addEventListener(`click`,this.onTriggerClick)}setContent(e){this.panel.innerHTML=e}open(){this._isOpen||(this._isOpen=!0,this.panel.style.display=``,document.addEventListener(`mousedown`,this.onOutsideClick),document.addEventListener(`keydown`,this.onEscapeKey))}close(){this._isOpen&&(this._isOpen=!1,this.panel.style.display=`none`,document.removeEventListener(`mousedown`,this.onOutsideClick),document.removeEventListener(`keydown`,this.onEscapeKey))}isOpen(){return this._isOpen}destroy(){this.trigger.removeEventListener(`click`,this.onTriggerClick),document.removeEventListener(`mousedown`,this.onOutsideClick),document.removeEventListener(`keydown`,this.onEscapeKey),this.panel.remove()}},_=class{config;callbacks;el;chartTypeDropdown=null;indicatorDropdown=null;tfButtons=[];chipsContainer=null;themeBtn=null;constructor(e,t,n){this.config=t,this.callbacks=n,this.el=document.createElement(`div`),this.el.className=`tcw-toolbar`,this.build(),e.appendChild(this.el)}build(){let{config:e,callbacks:t,el:n}=this,r=document.createElement(`button`);r.className=`tcw-toolbar-symbol`,r.dataset.role=`symbol`,r.addEventListener(`click`,t.onSymbolClick),n.appendChild(r),n.appendChild(this.sep());let i=document.createElement(`div`);i.className=`tcw-toolbar-group`;for(let n of e.timeframes){let e=document.createElement(`button`);e.className=`tcw-btn`,e.textContent=n.label,e.dataset.tf=n.value,e.addEventListener(`click`,()=>t.onTimeframe(n.value)),i.appendChild(e),this.tfButtons.push(e)}n.appendChild(i),n.appendChild(this.sep());let a=document.createElement(`div`);a.style.position=`relative`,a.style.display=`inline-flex`;let o=document.createElement(`button`);o.className=`tcw-dropdown-trigger`,o.dataset.role=`charttype`,a.appendChild(o),n.appendChild(a),this.chartTypeDropdown=new g(a,{width:`160px`}),this.buildChartTypeMenu(),n.appendChild(this.sep());let s=document.createElement(`div`);s.style.position=`relative`,s.style.display=`inline-flex`;let c=document.createElement(`button`);if(c.className=`tcw-dropdown-trigger`,c.dataset.role=`indicators`,s.appendChild(c),n.appendChild(s),this.indicatorDropdown=new g(s,{width:`280px`}),this.buildIndicatorMenu(),this.chipsContainer=document.createElement(`div`),this.chipsContainer.className=`tcw-indicator-chips`,n.appendChild(this.chipsContainer),n.appendChild(this.spacer()),t.onToggleReplay){let e=this.iconBtn(`play`,`Bar replay`,t.onToggleReplay);e.dataset.role=`replay`,n.appendChild(e)}let l=this.iconBtn(`camera`,`Screenshot`,t.onScreenshot);n.appendChild(l);let u=this.iconBtn(`settings`,`Chart Settings`,t.onSettings);n.appendChild(u),this.themeBtn=this.iconBtn(`moon`,`Toggle theme`,t.onToggleTheme),this.themeBtn.dataset.role=`theme`,n.appendChild(this.themeBtn)}buildChartTypeMenu(){if(!this.chartTypeDropdown)return;let e=this.config.chartTypes.map(e=>`<button class="tcw-dropdown-item" data-ct="${e.value}">${e.label}</button>`).join(``);this.chartTypeDropdown.setContent(e),this.chartTypeDropdown.panel.querySelectorAll(`.tcw-dropdown-item`).forEach(e=>{e.addEventListener(`click`,e=>{let t=e.currentTarget.dataset.ct;this.callbacks.onChartType(t),this.chartTypeDropdown?.close()})})}buildIndicatorMenu(){if(!this.indicatorDropdown)return;let{indicators:e,popularIndicatorIds:t}=this.config,n=e.filter(e=>t.includes(e.id)),r=e.filter(e=>!t.includes(e.id)),i=`<div class="tcw-dropdown-label">Popular</div>`;for(let e of n)i+=`<button class="tcw-dropdown-item" data-ind="${e.id}"><span>${e.name}</span><span class="tcw-tag">${e.type}</span></button>`;i+=`<div class="tcw-dropdown-divider"></div>`,i+=`<div class="tcw-dropdown-label">All</div>`;for(let e of r)i+=`<button class="tcw-dropdown-item" data-ind="${e.id}"><span>${e.name}</span><span class="tcw-tag">${e.type}</span></button>`;this.indicatorDropdown.setContent(i),this.indicatorDropdown.panel.querySelectorAll(`.tcw-dropdown-item[data-ind]`).forEach(e=>{e.addEventListener(`click`,e=>{let t=e.currentTarget.dataset.ind;this.callbacks.onAddIndicator(t)})})}update(e){let t=this.el.querySelector(`[data-role="symbol"]`);t&&(t.textContent=e.symbol);for(let t of this.tfButtons)t.classList.toggle(`tcw-active`,t.dataset.tf===e.timeframe);let n=this.el.querySelector(`[data-role="charttype"]`);if(n){let t=this.config.chartTypes.find(t=>t.value===e.chartType)?.label??`Candles`;n.innerHTML=`${h(`barChart`,14)} ${t} ${h(`chevronDown`,12)}`}let r=this.el.querySelector(`[data-role="indicators"]`);if(r){let t=e.activeIndicators.size,n=`${h(`trendingUp`,14)} Indicators`;t>0&&(n+=` <span class="tcw-badge-count">${t}</span>`),r.innerHTML=n}if(this.chipsContainer){let t=this.getActiveIndicatorList(e);this.chipsContainer.innerHTML=``;for(let e of t){let t=document.createElement(`div`);t.className=`tcw-indicator-chip`;let n=document.createElement(`span`);n.textContent=e.label,t.appendChild(n);let r=document.createElement(`button`);r.className=`tcw-chip-remove`,r.innerHTML=h(`x`,10),r.addEventListener(`click`,()=>this.callbacks.onRemoveIndicator(e.instanceId)),t.appendChild(r),this.chipsContainer.appendChild(t)}}this.themeBtn&&(this.themeBtn.innerHTML=e.isDark?h(`moon`,14):h(`sun`,14))}getActiveIndicatorList(e){let t=[];for(let[n,r]of e.activeIndicators.entries())t.push({instanceId:r,id:n,label:n.toUpperCase()});return t}sep(){let e=document.createElement(`span`);return e.className=`tcw-toolbar-sep`,e}spacer(){let e=document.createElement(`span`);return e.className=`tcw-toolbar-spacer`,e}iconBtn(e,t,n){let r=document.createElement(`button`);return r.className=`tcw-btn-icon`,r.title=t,r.innerHTML=h(e,14),r.addEventListener(`click`,n),r}destroy(){this.chartTypeDropdown?.destroy(),this.indicatorDropdown?.destroy(),this.el.remove()}},v=[`trendingUp`,`minus`,`penLine`,`hash`,`square`,`gitBranch`,`ruler`,`type`],y=class{config;callbacks;el;groupWraps=[];groupButtons=[];cursorBtn=null;magnetBtn=null;flyoutEl=null;constructor(e,t,n){this.config=t,this.callbacks=n,this.el=document.createElement(`div`),this.el.className=`tcw-sidebar`,this.build(),e.appendChild(this.el)}build(){let{config:e,callbacks:t,el:n}=this;this.cursorBtn=document.createElement(`button`),this.cursorBtn.className=`tcw-sidebar-btn`,this.cursorBtn.title=`Cursor`,this.cursorBtn.innerHTML=h(`cursor`,14),this.cursorBtn.addEventListener(`click`,t.onCancelDrawing),n.appendChild(this.cursorBtn),n.appendChild(this.divider()),e.drawingToolGroups.forEach((e,r)=>{let i=document.createElement(`div`);i.className=`tcw-tool-group-wrap`;let a=document.createElement(`button`);if(a.className=`tcw-sidebar-btn`,a.title=e.label,a.innerHTML=h(v[r]??`square`,14),e.tools.length>1){let e=document.createElement(`span`);e.className=`tcw-multi-dot`,a.appendChild(e)}a.addEventListener(`click`,()=>t.onDrawingTool(e.tools[0].value)),i.appendChild(a),i.addEventListener(`mouseenter`,()=>this.showFlyout(r)),i.addEventListener(`mouseleave`,()=>this.hideFlyout()),n.appendChild(i),this.groupWraps.push(i),this.groupButtons.push(a)});let r=document.createElement(`div`);r.className=`tcw-sidebar-spacer`,n.appendChild(r),n.appendChild(this.divider()),this.magnetBtn=document.createElement(`button`),this.magnetBtn.className=`tcw-sidebar-btn`,this.magnetBtn.title=`Magnet`,this.magnetBtn.innerHTML=h(`magnet`,14),this.magnetBtn.addEventListener(`click`,t.onToggleMagnet),n.appendChild(this.magnetBtn);let i=document.createElement(`button`);i.className=`tcw-sidebar-btn`,i.title=`Undo`,i.innerHTML=h(`undo`,14),i.addEventListener(`click`,t.onUndo),n.appendChild(i);let a=document.createElement(`button`);a.className=`tcw-sidebar-btn`,a.title=`Redo`,a.innerHTML=h(`redo`,14),a.addEventListener(`click`,t.onRedo),n.appendChild(a);let o=document.createElement(`button`);o.className=`tcw-sidebar-btn tcw-danger`,o.title=`Clear all`,o.innerHTML=h(`trash`,14),o.addEventListener(`click`,t.onClearDrawings),n.appendChild(o)}showFlyout(e){let t=this.config.drawingToolGroups[e];if(!t||t.tools.length<=1)return;this.hideFlyout();let n=document.createElement(`div`);n.className=`tcw-flyout`;let r=document.createElement(`div`);r.className=`tcw-flyout-header`,r.textContent=t.label,n.appendChild(r);for(let e of t.tools){let t=document.createElement(`button`);t.className=`tcw-flyout-item`,t.textContent=e.label,t.dataset.toolValue=e.value,t.addEventListener(`click`,()=>{this.callbacks.onDrawingTool(e.value),this.hideFlyout()}),n.appendChild(t)}this.flyoutEl=n,this.groupWraps[e].appendChild(n)}hideFlyout(){this.flyoutEl&&=(this.flyoutEl.remove(),null)}update(e){this.cursorBtn&&this.cursorBtn.classList.toggle(`tcw-active`,e.activeTool===null);let{drawingToolGroups:t}=this.config;for(let n=0;n<t.length;n++){let r=t[n].tools.some(t=>t.value===e.activeTool);this.groupButtons[n].classList.toggle(`tcw-active`,r)}this.flyoutEl&&this.flyoutEl.querySelectorAll(`.tcw-flyout-item`).forEach(t=>{let n=t;n.classList.toggle(`tcw-active`,n.dataset.toolValue===e.activeTool)}),this.magnetBtn&&(this.magnetBtn.classList.toggle(`tcw-active`,e.magnetEnabled),this.magnetBtn.title=e.magnetEnabled?`Magnet ON`:`Magnet OFF`)}divider(){let e=document.createElement(`div`);return e.className=`tcw-sidebar-divider`,e}destroy(){this.hideFlyout(),this.el.remove()}},b=[`style`,`display`,`scale`],x=class{callbacks;backdrop=null;modal=null;currentTab=`style`;currentSettings=null;bodyEl=null;tabButtons=[];constructor(e){this.callbacks=e}open(e){this.currentSettings={...e},this.currentTab=`style`,this.buildModal()}close(){this.backdrop?.remove(),this.modal?.remove(),this.backdrop=null,this.modal=null,this.bodyEl=null,this.tabButtons=[]}buildModal(){this.backdrop=document.createElement(`div`),this.backdrop.className=`tcw-modal-backdrop`,this.backdrop.addEventListener(`click`,()=>{this.callbacks.onClose(),this.close()}),document.body.appendChild(this.backdrop),this.modal=document.createElement(`div`),this.modal.className=`tcw-modal`;let e=document.createElement(`div`);e.className=`tcw-modal-header`;let t=document.createElement(`h3`);t.textContent=`Chart Settings`,e.appendChild(t);let n=document.createElement(`button`);n.className=`tcw-modal-close`,n.innerHTML=h(`x`,16),n.addEventListener(`click`,()=>{this.callbacks.onClose(),this.close()}),e.appendChild(n),this.modal.appendChild(e);let r=document.createElement(`div`);r.className=`tcw-modal-tabs`,this.tabButtons=[];for(let e of b){let t=document.createElement(`button`);t.className=`tcw-modal-tab`,t.textContent=e,t.dataset.tab=e,e===this.currentTab&&t.classList.add(`tcw-active`),t.addEventListener(`click`,()=>{this.currentTab=e,this.tabButtons.forEach(t=>t.classList.toggle(`tcw-active`,t.dataset.tab===e)),this.renderTabContent()}),r.appendChild(t),this.tabButtons.push(t)}this.modal.appendChild(r),this.bodyEl=document.createElement(`div`),this.bodyEl.className=`tcw-modal-body`,this.modal.appendChild(this.bodyEl),this.renderTabContent();let i=document.createElement(`div`);i.className=`tcw-modal-footer`;let a=document.createElement(`button`);a.className=`tcw-reset-link`,a.textContent=`Reset to defaults`,a.addEventListener(`click`,()=>this.callbacks.onReset()),i.appendChild(a);let o=document.createElement(`button`);o.className=`tcw-done-btn`,o.textContent=`Done`,o.addEventListener(`click`,()=>{this.callbacks.onClose(),this.close()}),i.appendChild(o),this.modal.appendChild(i),document.body.appendChild(this.modal);let s=e=>{e.key===`Escape`&&(document.removeEventListener(`keydown`,s),this.callbacks.onClose(),this.close())};document.addEventListener(`keydown`,s)}renderTabContent(){if(!(!this.bodyEl||!this.currentSettings))switch(this.bodyEl.innerHTML=``,this.currentTab){case`style`:this.renderStyleTab();break;case`display`:this.renderDisplayTab();break;case`scale`:this.renderScaleTab();break}}renderStyleTab(){if(!this.bodyEl||!this.currentSettings)return;let e=this.currentSettings,t=this.section(`Candle Colors`);t.appendChild(this.colorRow(`Up Body`,e.candleUpColor,e=>this.patch({candleUpColor:e}))),t.appendChild(this.colorRow(`Down Body`,e.candleDownColor,e=>this.patch({candleDownColor:e}))),t.appendChild(this.colorRow(`Up Wick`,e.candleUpWick,e=>this.patch({candleUpWick:e}))),t.appendChild(this.colorRow(`Down Wick`,e.candleDownWick,e=>this.patch({candleDownWick:e}))),this.bodyEl.appendChild(t);let n=this.section(`Background`);n.appendChild(this.colorRow(`Background`,e.backgroundColor,e=>this.patch({backgroundColor:e}))),n.appendChild(this.colorRow(`Grid`,e.gridColor,e=>this.patch({gridColor:e}))),this.bodyEl.appendChild(n)}renderDisplayTab(){if(!this.bodyEl||!this.currentSettings)return;let e=this.currentSettings,t=this.section();t.appendChild(this.toggleRow(`Grid Lines`,e.gridVisible,e=>this.patch({gridVisible:e}))),t.appendChild(this.toggleRow(`Volume`,e.volumeVisible,e=>this.patch({volumeVisible:e}))),t.appendChild(this.toggleRow(`Volume Profile`,e.volumeProfileVisible,e=>this.patch({volumeProfileVisible:e}))),t.appendChild(this.toggleRow(`OHLC Legend`,e.legendVisible,e=>this.patch({legendVisible:e}))),t.appendChild(this.toggleRow(`Bar Countdown`,e.barCountdown,e=>this.patch({barCountdown:e}))),t.appendChild(this.selectRow(`Crosshair Mode`,e.crosshairMode,[{label:`Magnet`,value:`magnet`},{label:`Normal`,value:`normal`},{label:`Hidden`,value:`hidden`}],e=>this.patch({crosshairMode:e}))),t.appendChild(this.selectRow(`Number Locale`,e.numberLocale,[{label:`en-US (65,234.00)`,value:`en-US`},{label:`de-DE (65.234,00)`,value:`de-DE`},{label:`fr-FR (65 234,00)`,value:`fr-FR`},{label:`vi-VN (65.234,00)`,value:`vi-VN`},{label:`en-IN (65,234.00)`,value:`en-IN`},{label:`ja-JP (65,234.00)`,value:`ja-JP`}],e=>this.patch({numberLocale:e}))),this.bodyEl.appendChild(t)}renderScaleTab(){if(!this.bodyEl||!this.currentSettings)return;let e=this.currentSettings,t=this.section();t.appendChild(this.toggleRow(`Auto Scale`,e.autoScale,e=>this.patch({autoScale:e}))),t.appendChild(this.toggleRow(`Log Scale`,e.logScale,e=>this.patch({logScale:e}))),this.bodyEl.appendChild(t)}patch(e){this.currentSettings&&Object.assign(this.currentSettings,e),this.callbacks.onChange(e)}section(e){let t=document.createElement(`div`);if(t.className=`tcw-settings-section`,e){let n=document.createElement(`div`);n.className=`tcw-settings-section-title`,n.textContent=e,t.appendChild(n)}return t}colorRow(e,t,n){let r=document.createElement(`div`);r.className=`tcw-settings-row`;let i=document.createElement(`span`);i.className=`tcw-settings-label`,i.textContent=e,r.appendChild(i);let a=document.createElement(`div`);a.className=`tcw-color-picker-wrap`;let o=document.createElement(`input`);o.type=`color`,o.value=t;let s=document.createElement(`span`);return s.className=`tcw-color-hex`,s.textContent=t,o.addEventListener(`input`,()=>{s.textContent=o.value,n(o.value)}),a.appendChild(o),a.appendChild(s),r.appendChild(a),r}toggleRow(e,t,n){let r=document.createElement(`div`);r.className=`tcw-settings-row`;let i=document.createElement(`span`);i.className=`tcw-settings-label`,i.textContent=e,r.appendChild(i);let a=document.createElement(`button`);return a.className=`tcw-toggle${t?` tcw-on`:``}`,a.addEventListener(`click`,()=>{let e=!a.classList.contains(`tcw-on`);a.classList.toggle(`tcw-on`,e),n(e)}),r.appendChild(a),r}selectRow(e,t,n,r){let i=document.createElement(`div`);i.className=`tcw-settings-row`;let a=document.createElement(`span`);a.className=`tcw-settings-label`,a.textContent=e,i.appendChild(a);let o=document.createElement(`select`);o.className=`tcw-settings-select`;for(let e of n){let n=document.createElement(`option`);n.value=e.value,n.textContent=e.label,e.value===t&&(n.selected=!0),o.appendChild(n)}return o.addEventListener(`change`,()=>r(o.value)),i.appendChild(o),i}destroy(){this.close()}},S=class{el;dotEl;messageEl;infoEl;constructor(e){this.el=document.createElement(`div`),this.el.className=`tcw-statusbar`;let t=document.createElement(`div`);t.className=`tcw-status-indicator`,this.dotEl=document.createElement(`span`),this.dotEl.className=`tcw-status-dot`,t.appendChild(this.dotEl),this.messageEl=document.createElement(`span`),t.appendChild(this.messageEl),this.el.appendChild(t),this.infoEl=document.createElement(`span`),this.el.appendChild(this.infoEl),e.appendChild(this.el)}update(e){this.dotEl.className=`tcw-status-dot`,e.connectionState===`connected`?this.dotEl.classList.add(`tcw-connected`):e.connectionState===`error`&&this.dotEl.classList.add(`tcw-error`),this.messageEl.textContent=e.message,this.infoEl.textContent=`${e.symbol} ${e.timeframe}`}destroy(){this.el.remove()}},C=class{backdrop=null;modal=null;input=null;list=null;items=[];filtered=[];selectedIndex=0;callbacks;boundKeydown;constructor(e){this.callbacks=e,this.boundKeydown=this.handleKeydown.bind(this)}open(e){if(this.backdrop)return;this.items=e,this.filtered=e,this.selectedIndex=0,this.backdrop=document.createElement(`div`),this.backdrop.className=`tcw-modal-backdrop`,this.backdrop.addEventListener(`click`,()=>this.close()),this.modal=document.createElement(`div`),this.modal.className=`tcw-cmd-palette`;let t=document.createElement(`div`);t.className=`tcw-cmd-header`;let n=document.createElement(`span`);n.className=`tcw-cmd-icon`,n.textContent=`⌕`,t.appendChild(n),this.input=document.createElement(`input`),this.input.className=`tcw-cmd-input`,this.input.type=`text`,this.input.placeholder=`Search indicators, chart types, tools...`,this.input.addEventListener(`input`,()=>this.filter()),t.appendChild(this.input);let r=document.createElement(`span`);r.className=`tcw-cmd-hint`,r.textContent=`ESC`,t.appendChild(r),this.modal.appendChild(t),this.list=document.createElement(`div`),this.list.className=`tcw-cmd-list`,this.modal.appendChild(this.list);let i=document.createElement(`div`);i.className=`tcw-cmd-footer`,i.innerHTML=`<span>↑↓ Navigate</span><span>⏎ Select</span><span>Esc Close</span>`,this.modal.appendChild(i),document.body.appendChild(this.backdrop),document.body.appendChild(this.modal),this.renderList(),this.input.focus(),document.addEventListener(`keydown`,this.boundKeydown)}close(){document.removeEventListener(`keydown`,this.boundKeydown),this.backdrop?.remove(),this.modal?.remove(),this.backdrop=null,this.modal=null,this.input=null,this.list=null,this.callbacks.onClose()}isOpen(){return this.backdrop!==null}filter(){let e=this.input?.value.toLowerCase().trim()??``;e?this.filtered=this.items.filter(t=>t.label.toLowerCase().includes(e)||t.category.toLowerCase().includes(e)||t.id.toLowerCase().includes(e)):this.filtered=this.items,this.selectedIndex=0,this.renderList()}renderList(){if(!this.list)return;if(this.list.innerHTML=``,this.filtered.length===0){let e=document.createElement(`div`);e.className=`tcw-cmd-empty`,e.textContent=`No results found`,this.list.appendChild(e);return}let e=``;for(let t=0;t<this.filtered.length;t++){let n=this.filtered[t];if(n.category!==e){e=n.category;let t=document.createElement(`div`);t.className=`tcw-cmd-category`,t.textContent=this.categoryLabel(e),this.list.appendChild(t)}let r=document.createElement(`button`);r.className=`tcw-cmd-item`,t===this.selectedIndex&&r.classList.add(`tcw-selected`),n.active&&r.classList.add(`tcw-active`),r.dataset.index=String(t);let i=document.createElement(`span`);if(i.className=`tcw-cmd-item-label`,i.textContent=n.label,r.appendChild(i),n.active){let e=document.createElement(`span`);e.className=`tcw-cmd-check`,e.textContent=`✓`,r.appendChild(e)}if(n.shortcut){let e=document.createElement(`kbd`);e.className=`tcw-cmd-kbd`,e.textContent=n.shortcut,r.appendChild(e)}r.addEventListener(`click`,()=>this.select(t)),r.addEventListener(`mouseenter`,()=>{this.selectedIndex=t,this.updateSelection()}),this.list.appendChild(r)}}updateSelection(){if(!this.list)return;let e=this.list.querySelectorAll(`.tcw-cmd-item`);e.forEach((e,t)=>{e.classList.toggle(`tcw-selected`,t===this.selectedIndex)}),e[this.selectedIndex]?.scrollIntoView({block:`nearest`})}select(e){let t=this.filtered[e];if(t){switch(t.category){case`indicator`:this.callbacks.onIndicator(t.id);break;case`chartType`:this.callbacks.onChartType(t.id);break;case`drawing`:this.callbacks.onDrawingTool(t.id);break;case`timeframe`:this.callbacks.onTimeframe(t.id);break;case`action`:this.callbacks.onAction(t.id);break}this.close()}}handleKeydown(e){switch(e.key){case`Escape`:e.preventDefault(),this.close();break;case`ArrowDown`:e.preventDefault(),this.filtered.length>0&&(this.selectedIndex=(this.selectedIndex+1)%this.filtered.length,this.updateSelection());break;case`ArrowUp`:e.preventDefault(),this.filtered.length>0&&(this.selectedIndex=(this.selectedIndex-1+this.filtered.length)%this.filtered.length,this.updateSelection());break;case`Enter`:e.preventDefault(),this.select(this.selectedIndex);break}}categoryLabel(e){switch(e){case`indicator`:return`Indicators`;case`chartType`:return`Chart Types`;case`drawing`:return`Drawing Tools`;case`timeframe`:return`Timeframes`;case`action`:return`Actions`;default:return e}}destroy(){this.close()}},w=class{backdrop=null;modal=null;input=null;list=null;symbols=[];current=``;filtered=[];selectedIndex=0;callbacks;boundKeydown;constructor(e){this.callbacks=e,this.boundKeydown=this.handleKeydown.bind(this)}open(e,t){if(this.backdrop)return;this.symbols=e,this.current=t,this.filtered=e.map(e=>({symbol:e,score:0})),this.selectedIndex=Math.max(0,e.indexOf(t)),this.backdrop=document.createElement(`div`),this.backdrop.className=`tcw-modal-backdrop`,this.backdrop.addEventListener(`click`,()=>this.close()),this.modal=document.createElement(`div`),this.modal.className=`tcw-cmd-palette`;let n=document.createElement(`div`);n.className=`tcw-cmd-header`;let r=document.createElement(`span`);r.className=`tcw-cmd-icon`,r.innerHTML=O(),n.appendChild(r),this.input=document.createElement(`input`),this.input.className=`tcw-cmd-input`,this.input.type=`text`,this.input.placeholder=`Search symbol… (e.g. BTC, ETH, AAPL)`,this.input.autocomplete=`off`,this.input.spellcheck=!1,this.input.addEventListener(`input`,()=>this.filter()),n.appendChild(this.input);let i=document.createElement(`span`);i.className=`tcw-cmd-hint`,i.textContent=`ESC`,n.appendChild(i),this.modal.appendChild(n),this.list=document.createElement(`div`),this.list.className=`tcw-cmd-list`,this.modal.appendChild(this.list);let a=document.createElement(`div`);a.className=`tcw-cmd-footer`,a.innerHTML=`<span>↑↓ Navigate</span><span>⏎ Open</span><span>Esc Close</span>`,this.modal.appendChild(a),document.body.appendChild(this.backdrop),document.body.appendChild(this.modal),this.renderList(),this.input.focus(),document.addEventListener(`keydown`,this.boundKeydown)}close(){document.removeEventListener(`keydown`,this.boundKeydown),this.backdrop?.remove(),this.modal?.remove(),this.backdrop=null,this.modal=null,this.input=null,this.list=null,this.callbacks.onClose()}isOpen(){return this.backdrop!==null}destroy(){this.close()}filter(){let e=(this.input?.value??``).toUpperCase().trim();e?this.filtered=this.symbols.map(t=>({symbol:t,score:T(t.toUpperCase(),e)})).filter(e=>e.score>0).sort((e,t)=>t.score-e.score):this.filtered=this.symbols.map(e=>({symbol:e,score:0})),this.selectedIndex=0,this.renderList()}renderList(){if(!this.list)return;if(this.list.innerHTML=``,this.filtered.length===0){let e=document.createElement(`div`);e.className=`tcw-cmd-empty`,e.textContent=`No symbols match`,this.list.appendChild(e);return}let e=(this.input?.value??``).toUpperCase().trim();for(let t=0;t<this.filtered.length;t++){let{symbol:n}=this.filtered[t],r=document.createElement(`button`);r.className=`tcw-cmd-item`,t===this.selectedIndex&&r.classList.add(`tcw-selected`),n===this.current&&r.classList.add(`tcw-active`);let i=document.createElement(`span`);if(i.className=`tcw-cmd-item-label`,i.innerHTML=E(n,e),r.appendChild(i),n===this.current){let e=document.createElement(`span`);e.className=`tcw-cmd-check`,e.textContent=`✓`,r.appendChild(e)}r.addEventListener(`click`,()=>this.pick(t)),r.addEventListener(`mouseenter`,()=>{this.selectedIndex=t,this.updateSelection()}),this.list.appendChild(r)}}updateSelection(){if(!this.list)return;let e=this.list.querySelectorAll(`.tcw-cmd-item`);e.forEach((e,t)=>e.classList.toggle(`tcw-selected`,t===this.selectedIndex)),e[this.selectedIndex]?.scrollIntoView({block:`nearest`})}pick(e){let t=this.filtered[e];t&&(this.callbacks.onPick(t.symbol),this.close())}handleKeydown(e){switch(e.key){case`Escape`:e.preventDefault(),this.close();break;case`ArrowDown`:e.preventDefault(),this.filtered.length>0&&(this.selectedIndex=(this.selectedIndex+1)%this.filtered.length,this.updateSelection());break;case`ArrowUp`:e.preventDefault(),this.filtered.length>0&&(this.selectedIndex=(this.selectedIndex-1+this.filtered.length)%this.filtered.length,this.updateSelection());break;case`Enter`:e.preventDefault(),this.pick(this.selectedIndex);break}}};function T(e,t){if(e===t)return 1e3;if(e.startsWith(t))return 500+(50-Math.min(50,e.length-t.length));if(e.includes(t))return 200+(50-Math.min(50,e.length-t.length));let n=0,r=-1,i=0;for(let a=0;a<e.length&&n<t.length;a++)e[a]===t[n]&&(r>=0&&(i+=a-r-1),r=a,n++);return n<t.length?0:100-Math.min(99,i)}function E(e,t){if(!t)return D(e);let n=e.toUpperCase(),r=``,i=0;for(let a=0;a<e.length;a++)i<t.length&&n[a]===t[i]?(r+=`<mark style="background:transparent;color:var(--tcw-accent);font-weight:700">${D(e[a])}</mark>`,i++):r+=D(e[a]);return r}function D(e){return e.replace(/[&<>"']/g,e=>({"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`})[e])}function O(){return`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>`}var k=typeof navigator<`u`&&/mac|iphone|ipad|ipod/i.test(navigator.platform||navigator.userAgent)?`⌘`:`Ctrl`,A=[{title:`Search & navigation`,entries:[{keys:[k,`K`],label:`Command palette`},{keys:[k,`P`],label:`Symbol search`},{keys:[`?`],label:`Show this sheet`}]},{title:`Chart manipulation`,entries:[{keys:[`Shift`,`Drag`],label:`Measure tool (bars × price Δ)`},{keys:[`Drag`,`Price axis`],label:`Compress / expand vertical scale`},{keys:[`Drag`,`Time axis`],label:`Zoom time axis`},{keys:[`Double-click`,`Price axis`],label:`Re-enable auto-scale`},{keys:[`Double-click`,`Time axis`],label:`Fit content`},{keys:[`Scroll`],label:`Zoom around cursor`}]},{title:`Keyboard`,entries:[{keys:[`←`,`→`],label:`Pan one bar`},{keys:[`+`,`−`],label:`Zoom in / out`},{keys:[`Home`],label:`Scroll to start`},{keys:[`End`],label:`Scroll to end (live edge)`},{keys:[`F`],label:`Fit content`}]},{title:`Drawing`,entries:[{keys:[k,`Z`],label:`Undo`},{keys:[k,`Shift`,`Z`],label:`Redo`},{keys:[`Esc`],label:`Cancel active drawing`}]}],j=class{backdrop=null;modal=null;callbacks;boundKeydown;constructor(e){this.callbacks=e,this.boundKeydown=e=>{e.key===`Escape`&&(e.preventDefault(),this.close())}}open(){if(this.backdrop)return;this.backdrop=document.createElement(`div`),this.backdrop.className=`tcw-modal-backdrop`,this.backdrop.addEventListener(`click`,()=>this.close()),this.modal=document.createElement(`div`),this.modal.className=`tcw-modal tcw-hotkey-sheet`,this.modal.style.width=`640px`;let e=document.createElement(`div`);e.className=`tcw-modal-header`,e.innerHTML=`<h3>Keyboard shortcuts</h3>`;let t=document.createElement(`button`);t.className=`tcw-modal-close`,t.setAttribute(`aria-label`,`Close`),t.innerHTML=`×`,t.addEventListener(`click`,()=>this.close()),e.appendChild(t),this.modal.appendChild(e);let n=document.createElement(`div`);n.className=`tcw-modal-body`;let r=document.createElement(`div`);r.className=`tcw-hotkey-grid`;for(let e of A){let t=document.createElement(`section`);t.className=`tcw-hotkey-section`;let n=document.createElement(`div`);n.className=`tcw-settings-section-title`,n.textContent=e.title,t.appendChild(n);for(let n of e.entries){let e=document.createElement(`div`);e.className=`tcw-hotkey-row`;let r=document.createElement(`div`);r.className=`tcw-hotkey-keys`;for(let e=0;e<n.keys.length;e++){if(e>0){let e=document.createElement(`span`);e.className=`tcw-hotkey-sep`,e.textContent=`+`,r.appendChild(e)}let t=document.createElement(`kbd`);t.className=`tcw-cmd-kbd`,t.textContent=n.keys[e],r.appendChild(t)}e.appendChild(r);let i=document.createElement(`span`);i.className=`tcw-hotkey-label`,i.textContent=n.label,e.appendChild(i),t.appendChild(e)}r.appendChild(t)}n.appendChild(r),this.modal.appendChild(n);let i=document.createElement(`div`);i.className=`tcw-modal-footer`,i.innerHTML=`<span style="font-size:11px;color:var(--tcw-text-muted)">Press ? anytime to show this sheet</span>`;let a=document.createElement(`button`);a.className=`tcw-done-btn`,a.textContent=`Got it`,a.addEventListener(`click`,()=>this.close()),i.appendChild(a),this.modal.appendChild(i),document.body.appendChild(this.backdrop),document.body.appendChild(this.modal),document.addEventListener(`keydown`,this.boundKeydown)}close(){document.removeEventListener(`keydown`,this.boundKeydown),this.backdrop?.remove(),this.modal?.remove(),this.backdrop=null,this.modal=null,this.callbacks.onClose()}isOpen(){return this.backdrop!==null}destroy(){this.close()}},M=[.5,1,2,5,10,20,50,100],N=class{root=null;scrubber=null;progressLabel=null;playBtn=null;state=`stopped`;total=0;speed=5;callbacks;constructor(e){this.callbacks=e}mount(e,t){this.root||(this.total=Math.max(0,t.total),this.speed=t.speed??5,this.state=`paused`,this.root=document.createElement(`div`),this.root.className=`tcw-replay-bar`,this.root.innerHTML=this.markup(),e.appendChild(this.root),this.wireEvents(),this.syncUi())}unmount(){this.root?.remove(),this.root=null,this.scrubber=null,this.progressLabel=null,this.playBtn=null,this.state=`stopped`}isMounted(){return this.root!==null}setState(e){this.state=e,this.syncUi()}setProgress(e,t){this.total=t,this.scrubber&&(this.scrubber.max=String(Math.max(0,t-1)),this.scrubber.value=String(e)),this.progressLabel&&(this.progressLabel.textContent=`${e+1} / ${t}`)}destroy(){this.unmount()}markup(){let e=M.map(e=>`<option value="${e}"${e===this.speed?` selected`:``}>${e}× bars/s</option>`).join(``);return`
1448
+ <button class="tcw-replay-btn" data-act="close" title="Exit replay" aria-label="Exit replay">${R()}</button>
1449
+ <button class="tcw-replay-btn" data-act="stepBack" title="Step back" aria-label="Step back">${I()}</button>
1450
+ <button class="tcw-replay-btn tcw-replay-play" data-act="play" title="Play / pause" aria-label="Play / pause">${P()}</button>
1451
+ <button class="tcw-replay-btn" data-act="stepForward" title="Step forward" aria-label="Step forward">${L()}</button>
1452
+ <input type="range" class="tcw-replay-scrubber" data-act="seek" min="0" max="${Math.max(0,this.total-1)}" value="0" step="1" />
1453
+ <span class="tcw-replay-progress" data-tcw="progress">1 / ${this.total}</span>
1454
+ <select class="tcw-replay-speed" data-act="speed">${e}</select>
1455
+ `}wireEvents(){this.root&&(this.scrubber=this.root.querySelector(`input[data-act="seek"]`),this.progressLabel=this.root.querySelector(`[data-tcw="progress"]`),this.playBtn=this.root.querySelector(`button[data-act="play"]`),this.root.querySelector(`[data-act="close"]`)?.addEventListener(`click`,()=>this.callbacks.onClose()),this.root.querySelector(`[data-act="stepBack"]`)?.addEventListener(`click`,()=>this.callbacks.onStepBack()),this.root.querySelector(`[data-act="stepForward"]`)?.addEventListener(`click`,()=>this.callbacks.onStepForward()),this.playBtn?.addEventListener(`click`,()=>{this.state===`playing`?this.callbacks.onPause():this.callbacks.onPlay()}),this.scrubber?.addEventListener(`input`,()=>{let e=Number(this.scrubber.value);this.callbacks.onSeek(e)}),this.root.querySelector(`[data-act="speed"]`)?.addEventListener(`change`,e=>{let t=Number(e.target.value);this.speed=t,this.callbacks.onSpeedChange(t)}))}syncUi(){this.playBtn&&(this.playBtn.innerHTML=this.state===`playing`?F():P(),this.playBtn.title=this.state===`playing`?`Pause`:`Play`)}};function P(){return`<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7L8 5z"/></svg>`}function F(){return`<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M6 5h4v14H6zM14 5h4v14h-4z"/></svg>`}function I(){return`<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M6 6h2v12H6zM20 6L9 12l11 6V6z"/></svg>`}function L(){return`<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M4 6l11 6L4 18V6zM16 6h2v12h-2z"/></svg>`}function R(){return`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6L6 18M6 6l12 12"/></svg>`}var z=class{el;listEl;rowMap=new Map;entries=new Map;active=null;callbacks;constructor(e,t,n){this.callbacks=n,this.el=document.createElement(`div`),this.el.className=`tcw-watchlist`;let r=document.createElement(`div`);r.className=`tcw-watchlist-header`,r.textContent=`Watchlist`,this.el.appendChild(r),this.listEl=document.createElement(`div`),this.listEl.className=`tcw-watchlist-list`,this.el.appendChild(this.listEl);for(let e of t)this.entries.set(e,{symbol:e}),this.appendRow(e);e.appendChild(this.el)}setSymbols(e){let t=new Set(e);for(let e of this.rowMap.keys())t.has(e)||this.removeRow(e);for(let t of e)this.rowMap.has(t)||(this.entries.set(t,this.entries.get(t)??{symbol:t}),this.appendRow(t))}setActive(e){if(this.active===e)return;this.active&&this.rowMap.has(this.active)&&this.rowMap.get(this.active).row.classList.remove(`tcw-watchlist-active`),this.active=e;let t=this.rowMap.get(e);t&&t.row.classList.add(`tcw-watchlist-active`)}setEntry(e,t){let n={...this.entries.get(e)??{symbol:e},...t};this.entries.set(e,n),this.renderRow(e)}destroy(){this.el.remove(),this.rowMap.clear(),this.entries.clear()}appendRow(e){let t=document.createElement(`div`);t.className=`tcw-watchlist-row`,t.tabIndex=0;let n=document.createElement(`div`);n.className=`tcw-watchlist-symbol`,n.textContent=B(e);let r=document.createElement(`canvas`);r.className=`tcw-watchlist-spark`,r.width=64,r.height=22;let i=document.createElement(`div`);i.className=`tcw-watchlist-stats`;let a=document.createElement(`span`);a.className=`tcw-watchlist-price`,a.textContent=`—`;let o=document.createElement(`span`);o.className=`tcw-watchlist-change`,o.textContent=``,i.appendChild(a),i.appendChild(o),t.appendChild(n),t.appendChild(r),t.appendChild(i),t.addEventListener(`click`,()=>this.callbacks.onSelect(e)),t.addEventListener(`keydown`,t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),this.callbacks.onSelect(e))}),this.listEl.appendChild(t),this.rowMap.set(e,{row:t,priceEl:a,changeEl:o,sparkCanvas:r}),e===this.active&&t.classList.add(`tcw-watchlist-active`)}removeRow(e){let t=this.rowMap.get(e);t&&(t.row.remove(),this.rowMap.delete(e))}renderRow(e){let t=this.rowMap.get(e),n=this.entries.get(e);if(!(!t||!n)){if(n.lastPrice!==void 0&&(t.priceEl.textContent=V(n.lastPrice)),n.lastPrice!==void 0&&n.refPrice!==void 0&&n.refPrice!==0){let e=n.lastPrice-n.refPrice,r=e/n.refPrice*100,i=e>=0?`+`:``;t.changeEl.textContent=`${i}${r.toFixed(2)}%`,t.changeEl.className=`tcw-watchlist-change ${e>=0?`tcw-up`:`tcw-down`}`}else t.changeEl.textContent=``;n.sparkline&&n.sparkline.length>=2&&H(t.sparkCanvas,n.sparkline,n.refPrice??n.sparkline[0])}}};function B(e){for(let t of[`USDT`,`USD`,`BTC`,`ETH`,`EUR`])if(e.length>t.length&&e.endsWith(t))return e.slice(0,-t.length)+`/`+t;return e}function V(e){if(e===0)return`0`;let t=Math.abs(e);return t>=1e3?e.toFixed(2):t>=1?e.toFixed(4):e.toPrecision(4)}function H(e,t,n){let r=e.getContext(`2d`);if(!r)return;let i=window.devicePixelRatio||1;e.width!==e.clientWidth*i&&(e.width=(e.clientWidth||64)*i,e.height=(e.clientHeight||22)*i);let a=e.width,o=e.height,s=1/0,c=-1/0;for(let e of t)e<s&&(s=e),e>c&&(c=e);let l=Math.max(c-s,1e-9),u=t[t.length-1]>=n?`#26a17b`:`#f23645`;r.clearRect(0,0,a,o),r.lineWidth=1.4*i,r.strokeStyle=u,r.beginPath();let d=a/(t.length-1);for(let e=0;e<t.length;e++){let n=e*d,i=o-(t[e]-s)/l*(o-4)-2;e===0?r.moveTo(n,i):r.lineTo(n,i)}r.stroke()}var U=class{chart;state;toolbar=null;sidebar=null;settings=null;statusBar=null;commandPalette=null;symbolSearch=null;hotkeySheet=null;replayBar=null;dragDrop=null;watchlist=null;watchlistSparkBuffer=new Map;sessionRefPrice=null;watchlistInterval=null;replayOriginalData=null;replayPollInterval=null;replaySpeed=5;layoutKeyPrefix=null;layoutDebounceMs=1500;activeLayoutKey=null;root;chartContainer;destroyed=!1;options;symbols;settingsState;adapter=null;boundGlobalKeydown=null;constructor(t,l={}){if(this.options=l,this.symbols=l.symbols??s,this.settingsState={...c},l.persistLayouts){let e=l.persistLayouts===!0?{}:l.persistLayouts;this.layoutKeyPrefix=e.keyPrefix??`tcw:layout:`,this.layoutDebounceMs=e.debounceMs??1500}let u=this.resolveIsDark(l.theme),d=this.resolveTheme(l.theme);this.state={symbol:l.symbol??this.symbols[0]??`BTCUSDT`,timeframe:l.timeframe??`5m`,chartType:l.chartOptions?.chartType??`candlestick`,isDark:u,activeIndicators:new Map,activeTool:null,magnetEnabled:!0,connectionState:`connecting`,connectionMessage:`Connecting...`},f(),this.root=document.createElement(`div`),this.root.className=`tcw-root`,this.root.dataset.tcwTheme=u?`dark`:`light`,t.appendChild(this.root),l.toolbar!==!1&&(this.toolbar=new _(this.root,{symbols:this.symbols,timeframes:l.timeframes?n.filter(e=>l.timeframes.includes(e.value)):n,chartTypes:l.chartTypes?r.filter(e=>l.chartTypes.includes(e.value)):r,indicators:a,popularIndicatorIds:o},{onSymbolClick:()=>this.handleSymbolClick(),onTimeframe:e=>this.handleTimeframe(e),onChartType:e=>this.handleChartType(e),onAddIndicator:e=>this.handleAddIndicator(e),onRemoveIndicator:e=>this.handleRemoveIndicator(e),onScreenshot:()=>this.chart.screenshot(),onSettings:()=>this.openSettings(),onToggleTheme:()=>this.handleToggleTheme(),onToggleReplay:()=>this.toggleReplay()}));let p=document.createElement(`div`);p.className=`tcw-body`,l.drawingTools!==!1&&(this.sidebar=new y(p,{drawingToolGroups:i},{onDrawingTool:e=>this.handleDrawingTool(e),onCancelDrawing:()=>this.handleCancelDrawing(),onToggleMagnet:()=>this.handleToggleMagnet(),onUndo:()=>this.chart.undo(),onRedo:()=>this.chart.redo(),onClearDrawings:()=>{this.chart.clearDrawings(),this.state={...this.state,activeTool:null},this.updateUI()}})),this.chartContainer=document.createElement(`div`),this.chartContainer.className=`tcw-chart-container`,p.appendChild(this.chartContainer),l.watchlist&&(this.watchlist=new z(p,this.symbols,{onSelect:e=>{this.setSymbol(e)}}),this.watchlist.setActive(this.state.symbol)),this.root.appendChild(p),this.chart=new e.r(this.chartContainer,{chartType:this.state.chartType,theme:d,autoScale:!0,crosshair:{mode:`magnet`},features:{drawings:!0,drawingMagnet:!0,drawingUndoRedo:!0,indicators:!0,trading:l.trading!==!1,tradingContextMenu:l.trading!==!1,volume:!0,legend:!0,crosshair:!0,keyboard:!0,screenshot:!0,alerts:!0,barCountdown:!0,logScale:!0,watermark:!0},...l.chartOptions}),l.dragDropImport!==!1&&(this.dragDrop=new e.t(this.chartContainer,{onData:(e,t,n)=>{this.chart.setData(e),this.toast(`Loaded ${t.data.length} bars from ${n.name}`+(t.skipped>0?` (${t.skipped} skipped)`:``))},onError:(e,t)=>{this.toast(`${t.name}: ${e.message}`,`error`)}}),this.dragDrop.attach()),l.statusBar!==!1&&(this.statusBar=new S(this.root)),l.settings!==!1&&(this.settings=new x({onChange:e=>this.applySettings(e),onReset:()=>this.resetSettings(),onClose:()=>{}})),this.symbolSearch=new w({onPick:e=>{this.setSymbol(e)},onClose:()=>{}}),this.hotkeySheet=new j({onClose:()=>{}}),this.commandPalette=new C({onIndicator:e=>this.handleAddIndicator(e),onChartType:e=>this.handleChartType(e),onDrawingTool:e=>this.handleDrawingTool(e),onTimeframe:e=>this.handleTimeframe(e),onAction:e=>this.handleAction(e),onClose:()=>{}}),this.boundGlobalKeydown=e=>{if((e.ctrlKey||e.metaKey)&&e.key===`k`)e.preventDefault(),this.toggleCommandPalette();else if((e.ctrlKey||e.metaKey)&&(e.key===`p`||e.key===`P`))e.preventDefault(),this.symbolSearch?.open(this.symbols,this.state.symbol);else if(e.key===`?`&&!e.ctrlKey&&!e.metaKey&&!e.altKey){let t=document.activeElement;if(t&&(t.tagName===`INPUT`||t.tagName===`TEXTAREA`||t.isContentEditable))return;e.preventDefault(),this.hotkeySheet?.open()}},document.addEventListener(`keydown`,this.boundGlobalKeydown),l.adapter&&(this.adapter=l.adapter,this.connectStream()),this.watchlist&&(this.watchlistInterval=setInterval(()=>this.tickWatchlist(),1e3)),this.updateUI(),l.onReady?.(this.chart)}setSymbols(e){this.symbols=e,this.watchlist?.setSymbols(e)}async setSymbol(e){this.flushActiveLayout(),this.state={...this.state,symbol:e},this.sessionRefPrice=null,this.options.onSymbolChange?.(e),this.updateUI(),this.watchlist?.setActive(e),this.adapter&&await this.connectStream()}setWatchlistEntry(e,t){this.watchlist?.setEntry(e,t)}tickWatchlist(){if(!this.watchlist)return;let e=this.chart.getData();if(e.length===0)return;let t=e[e.length-1];this.sessionRefPrice===null&&(this.sessionRefPrice=e[0].open);let n=this.watchlistSparkBuffer.get(this.state.symbol)??[];n.push(t.close),n.length>40&&n.shift(),this.watchlistSparkBuffer.set(this.state.symbol,n),this.watchlist.setEntry(this.state.symbol,{lastPrice:t.close,refPrice:this.sessionRefPrice,sparkline:n.slice()})}async setTimeframe(e){this.state={...this.state,timeframe:e},this.options.onTimeframeChange?.(e),this.updateUI(),this.adapter&&await this.connectStream()}setTheme(e){let t=this.resolveIsDark(e),n=this.resolveTheme(e);this.state={...this.state,isDark:t},this.root.dataset.tcwTheme=t?`dark`:`light`,this.chart.setTheme(n),this.updateUI()}getChart(){return this.chart}destroy(){this.destroyed||(this.destroyed=!0,this.boundGlobalKeydown&&document.removeEventListener(`keydown`,this.boundGlobalKeydown),this.flushActiveLayout(),this.commandPalette?.destroy(),this.symbolSearch?.destroy(),this.hotkeySheet?.destroy(),this.replayPollInterval&&clearInterval(this.replayPollInterval),this.replayBar?.destroy(),this.dragDrop?.detach(),this.watchlistInterval&&clearInterval(this.watchlistInterval),this.watchlist?.destroy(),this.toolbar?.destroy(),this.sidebar?.destroy(),this.settings?.destroy(),this.statusBar?.destroy(),this.chart.destroy(),this.root.remove(),p())}handleSymbolClick(){this.symbolSearch?.open(this.symbols,this.state.symbol)}handleTimeframe(e){this.state={...this.state,timeframe:e},this.options.onTimeframeChange?.(e),this.updateUI(),this.adapter&&this.connectStream()}handleChartType(e){this.state={...this.state,chartType:e},this.chart.setChartType(e),this.updateUI()}handleAddIndicator(e){if(this.state.activeIndicators.has(e)){let t=this.state.activeIndicators.get(e);this.chart.removeIndicator(t);let n=new Map(this.state.activeIndicators);n.delete(e),this.state={...this.state,activeIndicators:n}}else{let t=this.chart.addIndicator(e);if(t){let n=new Map(this.state.activeIndicators);n.set(e,t),this.state={...this.state,activeIndicators:n}}}this.updateUI()}handleRemoveIndicator(e){this.chart.removeIndicator(e);let t=new Map(this.state.activeIndicators);for(let[n,r]of t.entries())if(r===e){t.delete(n);break}this.state={...this.state,activeIndicators:t},this.updateUI()}toggleCommandPalette(){if(this.commandPalette?.isOpen()){this.commandPalette.close();return}this.commandPalette?.open(this.buildCommandItems())}buildCommandItems(){let e=[];for(let t of a)e.push({id:t.id,label:t.name,category:`indicator`,active:this.state.activeIndicators.has(t.id)});for(let t of r)e.push({id:t.value,label:t.label,category:`chartType`,active:this.state.chartType===t.value});for(let t of i)for(let n of t.tools)e.push({id:n.value,label:n.label,category:`drawing`,active:this.state.activeTool===n.value});for(let t of n)e.push({id:t.value,label:t.label,category:`timeframe`,active:this.state.timeframe===t.value});return e.push({id:`screenshot`,label:`Screenshot`,category:`action`,shortcut:``},{id:`toggleTheme`,label:`Toggle Theme`,category:`action`},{id:`settings`,label:`Settings`,category:`action`},{id:`clearDrawings`,label:`Clear All Drawings`,category:`action`}),e}handleAction(e){switch(e){case`screenshot`:this.chart.screenshot();break;case`toggleTheme`:this.handleToggleTheme();break;case`settings`:this.openSettings();break;case`clearDrawings`:this.chart.clearDrawings(),this.state={...this.state,activeTool:null},this.updateUI();break}}handleDrawingTool(e){this.state={...this.state,activeTool:e},this.chart.setDrawingTool(e),this.updateUI()}handleCancelDrawing(){this.state={...this.state,activeTool:null},this.chart.setDrawingTool(null),this.updateUI()}handleToggleMagnet(){let e=!this.state.magnetEnabled;this.state={...this.state,magnetEnabled:e},this.chart.setDrawingMagnet(e),this.updateUI()}handleToggleTheme(){let e=!this.state.isDark;this.state={...this.state,isDark:e},this.root.dataset.tcwTheme=e?`dark`:`light`,this.chart.setTheme(e?t.DARK_THEME:t.LIGHT_THEME),this.chart.setWatermark(this.state.symbol.replace(`USDT`,` / USDT`),{fontSize:48,color:e?`rgba(255,255,255,0.03)`:`rgba(0,0,0,0.03)`}),this.updateUI()}openSettings(){this.settings?.open(this.settingsState)}toast(e,t=`info`){let n=document.createElement(`div`);n.className=`tcw-toast ${t===`error`?`tcw-toast-error`:``}`,n.textContent=e,this.root.appendChild(n),requestAnimationFrame(()=>n.classList.add(`tcw-toast-in`)),setTimeout(()=>{n.classList.remove(`tcw-toast-in`),n.addEventListener(`transitionend`,()=>n.remove(),{once:!0}),setTimeout(()=>n.remove(),400)},3500)}clearSavedLayout(e){if(!this.layoutKeyPrefix)return;let t=e??this.state.symbol;try{localStorage.removeItem(this.layoutKeyPrefix+t)}catch{}}applySymbolLayout(e){if(!this.layoutKeyPrefix)return;let t=this.layoutKeyPrefix+e;this.activeLayoutKey=t;try{this.chart.loadStateFromStorage(t)&&this.rebuildActiveIndicatorsMapFromChart()}catch{}this.chart.setAutoSave(t,this.layoutDebounceMs)}flushActiveLayout(){if(this.activeLayoutKey){try{this.chart.saveState(this.activeLayoutKey)}catch{}this.chart.disableAutoSave(),this.activeLayoutKey=null}}rebuildActiveIndicatorsMapFromChart(){let e=new Map;for(let t of this.chart.getActiveIndicators())e.set(t.id,t.instanceId);this.state={...this.state,activeIndicators:e},this.updateUI()}toggleReplay(){this.replayBar?.isMounted()?this.exitReplay():this.enterReplay()}enterReplay(){let e=this.chart.getData();e.length<2||(this.replayOriginalData=e.slice(),this.replayBar=new N({onPlay:()=>{this.chart.getReplayState()===`paused`?this.chart.replayResume():this.chart.replay({speed:this.replaySpeed,interval:200}),this.replayBar?.setState(`playing`)},onPause:()=>{this.chart.replayPause(),this.replayBar?.setState(`paused`)},onStop:()=>{this.chart.replayStop(),this.replayBar?.setState(`paused`)},onStepBack:()=>{let e=this.chart.getReplayProgress();this.chart.getReplayState()===`playing`&&this.chart.replayPause(),this.chart.replaySeek(Math.max(0,e.current-1)),this.replayBar?.setState(`paused`)},onStepForward:()=>{let e=this.chart.getReplayProgress();this.chart.getReplayState()===`playing`&&this.chart.replayPause(),this.chart.replaySeek(Math.min(e.total-1,e.current+1)),this.replayBar?.setState(`paused`)},onSeek:e=>{this.chart.getReplayState()===`playing`&&this.chart.replayPause(),this.chart.replaySeek(e),this.replayBar?.setState(`paused`)},onSpeedChange:e=>{this.replaySpeed=e,this.chart.setReplaySpeed(e)},onClose:()=>this.exitReplay()}),this.replayBar.mount(this.chartContainer,{total:e.length,speed:this.replaySpeed}),this.chart.replay({speed:this.replaySpeed,interval:200,startIndex:1}),this.chart.replayPause(),this.replayBar.setState(`paused`),this.replayPollInterval=setInterval(()=>{if(!this.replayBar?.isMounted())return;let e=this.chart.getReplayProgress();this.replayBar.setProgress(e.current,e.total);let t=this.chart.getReplayState();t===`stopped`?this.replayBar.setState(`paused`):this.replayBar.setState(t)},150))}exitReplay(){this.replayPollInterval&&=(clearInterval(this.replayPollInterval),null),this.chart.replayStop(),this.replayBar?.unmount(),this.replayBar=null,this.replayOriginalData&&=(this.chart.setData(this.replayOriginalData),null)}applySettings(e){this.settingsState={...this.settingsState,...e},e.gridVisible!==void 0&&this.chart.setGridVisible(e.gridVisible),e.volumeVisible!==void 0&&this.chart.setVolumeVisible(e.volumeVisible),e.volumeProfileVisible!==void 0&&this.chart.setVolumeProfileVisible(e.volumeProfileVisible),e.crosshairMode!==void 0&&this.chart.setCrosshairMode(e.crosshairMode),e.autoScale!==void 0&&this.chart.setAutoScale(e.autoScale),e.logScale!==void 0&&this.chart.setLogScale(e.logScale),e.numberLocale!==void 0&&this.chart.setNumberLocale(e.numberLocale);let t={...this.chart.getTheme()},n=!1;e.candleUpColor!==void 0&&(t.candleUp=e.candleUpColor,n=!0),e.candleDownColor!==void 0&&(t.candleDown=e.candleDownColor,n=!0),e.candleUpWick!==void 0&&(t.candleUpWick=e.candleUpWick,n=!0),e.candleDownWick!==void 0&&(t.candleDownWick=e.candleDownWick,n=!0),e.backgroundColor!==void 0&&(t.background=e.backgroundColor,n=!0),e.gridColor!==void 0&&(t.grid=e.gridColor,n=!0),n&&this.chart.setTheme(t)}resetSettings(){this.settingsState={...c},this.applySettings(this.settingsState)}async connectStream(){if(this.adapter){this.state={...this.state,connectionState:`connecting`,connectionMessage:`Connecting...`},this.updateUI();try{this.chart.disconnectStream(),await this.chart.connect({adapter:this.adapter,symbol:this.state.symbol,timeframe:this.state.timeframe,historyLimit:this.options.historyLimit??500}),this.chart.setWatermark(this.state.symbol.replace(`USDT`,` / USDT`),{fontSize:48,color:this.state.isDark?`rgba(255,255,255,0.03)`:`rgba(0,0,0,0.03)`}),this.applySymbolLayout(this.state.symbol),this.state={...this.state,connectionState:`connected`,connectionMessage:`Live`}}catch(e){this.state={...this.state,connectionState:`error`,connectionMessage:e instanceof Error?e.message:`Connection failed`}}this.updateUI()}}updateUI(){this.toolbar?.update(this.state),this.sidebar?.update(this.state),this.statusBar?.update({connectionState:this.state.connectionState,message:this.state.connectionMessage,symbol:this.state.symbol,timeframe:this.state.timeframe})}resolveIsDark(e){return e===void 0||e===`dark`?!0:e===`light`?!1:typeof e==`object`&&e.background?this.isColorDark(e.background):!0}resolveTheme(e){return e===void 0||e===`dark`?t.DARK_THEME:e===`light`?t.LIGHT_THEME:typeof e==`object`?e:t.DARK_THEME}isColorDark(e){if(e.startsWith(`#`)&&e.length>=7){let t=parseInt(e.slice(1,3),16),n=parseInt(e.slice(3,5),16),r=parseInt(e.slice(5,7),16);return t+n+r<384}return!0}};exports.ChartWidget=U;
878
1456
  //# sourceMappingURL=index.cjs.map