@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.
- package/README.md +86 -4
- package/dist/Chart.d.ts +11 -0
- package/dist/Chart.d.ts.map +1 -1
- package/dist/{Chart-Cn_TSMO7.js → DragDropImporter-6QOjnfSj.js} +361 -85
- package/dist/DragDropImporter-6QOjnfSj.js.map +1 -0
- package/dist/DragDropImporter-CQ3EarQn.cjs +2 -0
- package/dist/DragDropImporter-CQ3EarQn.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -26
- package/dist/index.js.map +1 -1
- package/dist/io/DragDropImporter.d.ts +34 -0
- package/dist/io/DragDropImporter.d.ts.map +1 -0
- package/dist/io/index.d.ts +5 -0
- package/dist/io/index.d.ts.map +1 -0
- package/dist/io/parseOHLCV.d.ts +21 -0
- package/dist/io/parseOHLCV.d.ts.map +1 -0
- package/dist/widget/ChartWidget.d.ts +46 -1
- package/dist/widget/ChartWidget.d.ts.map +1 -1
- package/dist/widget/WidgetHotkeySheet.d.ts +20 -0
- package/dist/widget/WidgetHotkeySheet.d.ts.map +1 -0
- package/dist/widget/WidgetReplayBar.d.ts +41 -0
- package/dist/widget/WidgetReplayBar.d.ts.map +1 -0
- package/dist/widget/WidgetSettings.d.ts.map +1 -1
- package/dist/widget/WidgetSymbolSearch.d.ts +32 -0
- package/dist/widget/WidgetSymbolSearch.d.ts.map +1 -0
- package/dist/widget/WidgetToolbar.d.ts.map +1 -1
- package/dist/widget/WidgetWatchlist.d.ts +39 -0
- package/dist/widget/WidgetWatchlist.d.ts.map +1 -0
- package/dist/widget/index.cjs +1455 -877
- package/dist/widget/index.cjs.map +1 -1
- package/dist/widget/index.js +695 -92
- package/dist/widget/index.js.map +1 -1
- package/dist/widget/types.d.ts +19 -0
- package/dist/widget/types.d.ts.map +1 -1
- package/dist/widget/widgetConfig.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/Chart-Br_N-BCL.cjs +0 -2
- package/dist/Chart-Br_N-BCL.cjs.map +0 -1
- package/dist/Chart-Cn_TSMO7.js.map +0 -1
package/dist/widget/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DARK_THEME as
|
|
1
|
+
import { r as e, t } from "../DragDropImporter-6QOjnfSj.js";
|
|
2
|
+
import { DARK_THEME as n, LIGHT_THEME as r } from "@tradecanvas/commons";
|
|
3
3
|
//#region src/widget/widgetConfig.ts
|
|
4
|
-
var
|
|
4
|
+
var i = [
|
|
5
5
|
{
|
|
6
6
|
label: "1m",
|
|
7
7
|
value: "1m"
|
|
@@ -26,7 +26,7 @@ var r = [
|
|
|
26
26
|
label: "1D",
|
|
27
27
|
value: "1d"
|
|
28
28
|
}
|
|
29
|
-
],
|
|
29
|
+
], a = [
|
|
30
30
|
{
|
|
31
31
|
label: "Candlestick",
|
|
32
32
|
value: "candlestick"
|
|
@@ -75,7 +75,7 @@ var r = [
|
|
|
75
75
|
label: "Line + Markers",
|
|
76
76
|
value: "lineWithMarkers"
|
|
77
77
|
}
|
|
78
|
-
],
|
|
78
|
+
], o = [
|
|
79
79
|
{
|
|
80
80
|
label: "Lines",
|
|
81
81
|
tools: [
|
|
@@ -188,7 +188,7 @@ var r = [
|
|
|
188
188
|
value: "arrow"
|
|
189
189
|
}]
|
|
190
190
|
}
|
|
191
|
-
],
|
|
191
|
+
], s = [
|
|
192
192
|
{
|
|
193
193
|
id: "sma",
|
|
194
194
|
name: "SMA",
|
|
@@ -354,7 +354,7 @@ var r = [
|
|
|
354
354
|
name: "Volume Profile",
|
|
355
355
|
type: "panel"
|
|
356
356
|
}
|
|
357
|
-
],
|
|
357
|
+
], c = [
|
|
358
358
|
"sma",
|
|
359
359
|
"ema",
|
|
360
360
|
"bb",
|
|
@@ -365,12 +365,12 @@ var r = [
|
|
|
365
365
|
"atr",
|
|
366
366
|
"obv",
|
|
367
367
|
"ichimoku"
|
|
368
|
-
],
|
|
368
|
+
], l = [
|
|
369
369
|
"BTCUSDT",
|
|
370
370
|
"ETHUSDT",
|
|
371
371
|
"SOLUSDT",
|
|
372
372
|
"BNBUSDT"
|
|
373
|
-
],
|
|
373
|
+
], u = {
|
|
374
374
|
candleUpColor: "#26A69A",
|
|
375
375
|
candleDownColor: "#EF5350",
|
|
376
376
|
candleUpWick: "#26A69A",
|
|
@@ -379,26 +379,27 @@ var r = [
|
|
|
379
379
|
gridColor: "#1E222D",
|
|
380
380
|
gridVisible: !0,
|
|
381
381
|
volumeVisible: !0,
|
|
382
|
+
volumeProfileVisible: !1,
|
|
382
383
|
legendVisible: !0,
|
|
383
384
|
barCountdown: !0,
|
|
384
385
|
logScale: !1,
|
|
385
386
|
autoScale: !0,
|
|
386
387
|
crosshairMode: "magnet",
|
|
387
388
|
numberLocale: "en-US"
|
|
388
|
-
}, u = "/* === TradeCanvas Widget Styles === */\r\n\r\n.tcw-root {\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n height: 100%;\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\r\n font-size: 13px;\r\n color: #d1d4dc;\r\n background: #131722;\r\n position: relative;\r\n overflow: hidden;\r\n\r\n /* Dark theme tokens (default) */\r\n --tcw-bg: #131722;\r\n --tcw-bg-elevated: #1E222D;\r\n --tcw-border: #2A2E39;\r\n --tcw-text: #d1d4dc;\r\n --tcw-text-dim: #b2b5be;\r\n --tcw-text-muted: #787b86;\r\n --tcw-accent: #2962ff;\r\n --tcw-accent-dim: rgba(41,98,255,0.15);\r\n --tcw-accent-glow: rgba(41,98,255,0.12);\r\n --tcw-red: #ef5350;\r\n --tcw-green: #26a69a;\r\n --tcw-transition: 0.15s ease;\r\n --tcw-radius-lg: 8px;\r\n --tcw-font-mono: 'SF Mono', 'Fira Code', 'Consolas', monospace;\r\n --tcw-hover-bg: rgba(255,255,255,0.04);\r\n}\r\n\r\n.tcw-root[data-tcw-theme=\"light\"] {\r\n color: #131722;\r\n background: #ffffff;\r\n\r\n --tcw-bg: #ffffff;\r\n --tcw-bg-elevated: #f0f3fa;\r\n --tcw-border: #e0e3eb;\r\n --tcw-text: #131722;\r\n --tcw-text-dim: #434651;\r\n --tcw-text-muted: #787b86;\r\n --tcw-accent: #2962ff;\r\n --tcw-accent-dim: rgba(41,98,255,0.1);\r\n --tcw-accent-glow: rgba(41,98,255,0.08);\r\n --tcw-red: #ef5350;\r\n --tcw-green: #26a69a;\r\n --tcw-hover-bg: rgba(0,0,0,0.04);\r\n}\r\n\r\n/* === Toolbar === */\r\n\r\n.tcw-toolbar {\r\n display: flex;\r\n align-items: center;\r\n gap: 0;\r\n padding: 0 12px;\r\n height: 40px;\r\n border-bottom: 1px solid var(--tcw-border);\r\n background: var(--tcw-bg-elevated);\r\n flex-shrink: 0;\r\n position: relative;\r\n z-index: 20;\r\n}\r\n\r\n.tcw-toolbar-symbol {\r\n font-size: 13px;\r\n font-weight: 700;\r\n color: var(--tcw-text);\r\n padding: 0 10px;\r\n white-space: nowrap;\r\n letter-spacing: -0.01em;\r\n cursor: pointer;\r\n border: none;\r\n background: none;\r\n font-family: inherit;\r\n}\r\n\r\n.tcw-toolbar-sep {\r\n width: 1px;\r\n height: 20px;\r\n background: var(--tcw-border);\r\n flex-shrink: 0;\r\n}\r\n\r\n.tcw-toolbar-group {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n padding: 0 8px;\r\n}\r\n\r\n.tcw-toolbar-spacer {\r\n flex: 1;\r\n}\r\n\r\n.tcw-btn {\r\n padding: 4px 8px;\r\n font-size: 12px;\r\n font-family: inherit;\r\n border: none;\r\n border-radius: 4px;\r\n background: transparent;\r\n color: var(--tcw-text-dim);\r\n cursor: pointer;\r\n transition: all var(--tcw-transition);\r\n white-space: nowrap;\r\n line-height: 1;\r\n}\r\n\r\n.tcw-btn:hover {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-btn.tcw-active {\r\n background: var(--tcw-accent);\r\n color: white;\r\n}\r\n\r\n.tcw-btn-icon {\r\n width: 32px;\r\n height: 32px;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-family: inherit;\r\n border: none;\r\n border-radius: 4px;\r\n background: transparent;\r\n color: var(--tcw-text-muted);\r\n cursor: pointer;\r\n transition: all var(--tcw-transition);\r\n line-height: 1;\r\n position: relative;\r\n}\r\n\r\n.tcw-btn-icon:hover {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-badge-count {\r\n font-size: 10px;\r\n color: var(--tcw-accent);\r\n background: var(--tcw-accent-dim);\r\n padding: 0 4px;\r\n border-radius: 8px;\r\n font-weight: 600;\r\n}\r\n\r\n.tcw-indicator-chips {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n padding: 0 4px;\r\n flex-wrap: nowrap;\r\n overflow: hidden;\r\n}\r\n\r\n.tcw-indicator-chip {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 4px;\r\n padding: 2px 6px 2px 8px;\r\n font-size: 11px;\r\n font-weight: 500;\r\n background: var(--tcw-accent-dim);\r\n color: var(--tcw-accent);\r\n border-radius: 4px;\r\n white-space: nowrap;\r\n line-height: 1.4;\r\n}\r\n\r\n.tcw-chip-remove {\r\n cursor: pointer;\r\n opacity: 0.6;\r\n padding: 0 2px;\r\n transition: opacity var(--tcw-transition);\r\n border: none;\r\n background: none;\r\n color: inherit;\r\n display: inline-flex;\r\n align-items: center;\r\n}\r\n\r\n.tcw-chip-remove:hover {\r\n opacity: 1;\r\n}\r\n\r\n/* === Dropdown === */\r\n\r\n.tcw-dropdown-trigger {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 4px;\r\n padding: 4px 8px;\r\n font-size: 12px;\r\n font-family: inherit;\r\n border: none;\r\n border-radius: 4px;\r\n background: transparent;\r\n color: var(--tcw-text-dim);\r\n cursor: pointer;\r\n transition: all var(--tcw-transition);\r\n white-space: nowrap;\r\n line-height: 1;\r\n}\r\n\r\n.tcw-dropdown-trigger:hover {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-dropdown {\r\n position: absolute;\r\n top: 100%;\r\n margin-top: 4px;\r\n background: var(--tcw-bg-elevated);\r\n border: 1px solid var(--tcw-border);\r\n border-radius: var(--tcw-radius-lg);\r\n box-shadow: 0 8px 32px rgba(0,0,0,0.4);\r\n z-index: 50;\r\n padding: 4px 0;\r\n max-height: 400px;\r\n overflow-y: auto;\r\n}\r\n\r\n.tcw-dropdown-item {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 6px 12px;\r\n font-size: 12px;\r\n color: var(--tcw-text-dim);\r\n cursor: pointer;\r\n transition: background var(--tcw-transition), color var(--tcw-transition);\r\n width: 100%;\r\n border: none;\r\n background: none;\r\n font-family: inherit;\r\n text-align: left;\r\n}\r\n\r\n.tcw-dropdown-item:hover {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-dropdown-item.tcw-active {\r\n color: var(--tcw-accent);\r\n}\r\n\r\n.tcw-dropdown-label {\r\n text-transform: uppercase;\r\n font-size: 10px;\r\n color: var(--tcw-text-muted);\r\n letter-spacing: 0.05em;\r\n padding: 6px 12px;\r\n font-weight: 600;\r\n}\r\n\r\n.tcw-dropdown-divider {\r\n border-top: 1px solid var(--tcw-border);\r\n margin: 4px 0;\r\n}\r\n\r\n.tcw-tag {\r\n font-size: 10px;\r\n color: var(--tcw-text-muted);\r\n padding: 1px 5px;\r\n border-radius: 3px;\r\n background: var(--tcw-hover-bg);\r\n}\r\n\r\n/* === Body === */\r\n\r\n.tcw-body {\r\n display: flex;\r\n flex: 1;\r\n min-height: 0;\r\n}\r\n\r\n.tcw-chart-container {\r\n flex: 1;\r\n min-width: 0;\r\n min-height: 0;\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n/* === Sidebar === */\r\n\r\n.tcw-sidebar {\r\n width: 36px;\r\n flex-shrink: 0;\r\n background: var(--tcw-bg-elevated);\r\n border-right: 1px solid var(--tcw-border);\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n padding: 4px 0;\r\n overflow: visible;\r\n}\r\n\r\n.tcw-tool-group-wrap {\r\n position: relative;\r\n}\r\n\r\n.tcw-sidebar-btn {\r\n width: 36px;\r\n height: 32px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: none;\r\n background: transparent;\r\n color: var(--tcw-text-muted);\r\n cursor: pointer;\r\n font-family: inherit;\r\n transition: all var(--tcw-transition);\r\n position: relative;\r\n flex-shrink: 0;\r\n line-height: 1;\r\n}\r\n\r\n.tcw-sidebar-btn:hover {\r\n color: var(--tcw-text);\r\n background: var(--tcw-hover-bg);\r\n}\r\n\r\n.tcw-sidebar-btn.tcw-active {\r\n color: var(--tcw-accent);\r\n background: var(--tcw-accent-glow);\r\n}\r\n\r\n.tcw-sidebar-btn.tcw-danger:hover {\r\n color: var(--tcw-red);\r\n background: rgba(239,68,68,0.1);\r\n}\r\n\r\n.tcw-multi-dot {\r\n position: absolute;\r\n bottom: 2px;\r\n right: 2px;\r\n width: 4px;\r\n height: 4px;\r\n border-radius: 50%;\r\n background: var(--tcw-text-muted);\r\n}\r\n\r\n.tcw-sidebar-divider {\r\n width: 20px;\r\n height: 1px;\r\n background: var(--tcw-border);\r\n margin: 4px 0;\r\n flex-shrink: 0;\r\n}\r\n\r\n.tcw-sidebar-spacer {\r\n flex: 1;\r\n}\r\n\r\n/* === Flyout === */\r\n\r\n.tcw-flyout {\r\n position: absolute;\r\n left: 100%;\r\n top: 0;\r\n margin-left: 2px;\r\n min-width: 160px;\r\n background: var(--tcw-bg-elevated);\r\n border: 1px solid var(--tcw-border);\r\n border-radius: var(--tcw-radius-lg);\r\n box-shadow: 0 8px 32px rgba(0,0,0,0.4);\r\n z-index: 30;\r\n padding: 4px 0;\r\n}\r\n\r\n.tcw-flyout-header {\r\n text-transform: uppercase;\r\n font-size: 10px;\r\n color: var(--tcw-text-muted);\r\n letter-spacing: 0.05em;\r\n padding: 6px 12px;\r\n font-weight: 600;\r\n}\r\n\r\n.tcw-flyout-item {\r\n padding: 6px 12px;\r\n font-size: 12px;\r\n color: var(--tcw-text-dim);\r\n cursor: pointer;\r\n width: 100%;\r\n display: block;\r\n border: none;\r\n background: none;\r\n text-align: left;\r\n font-family: inherit;\r\n transition: background var(--tcw-transition), color var(--tcw-transition);\r\n}\r\n\r\n.tcw-flyout-item:hover {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-flyout-item.tcw-active {\r\n color: var(--tcw-accent);\r\n}\r\n\r\n/* === Modal === */\r\n\r\n.tcw-modal-backdrop {\r\n position: fixed;\r\n inset: 0;\r\n background: rgba(0,0,0,0.5);\r\n backdrop-filter: blur(4px);\r\n -webkit-backdrop-filter: blur(4px);\r\n z-index: 100;\r\n}\r\n\r\n.tcw-modal {\r\n position: fixed;\r\n z-index: 101;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n background: var(--tcw-bg-elevated);\r\n border: 1px solid var(--tcw-border);\r\n border-radius: var(--tcw-radius-lg);\r\n width: 480px;\r\n max-width: 90vw;\r\n max-height: 80vh;\r\n display: flex;\r\n flex-direction: column;\r\n box-shadow: 0 24px 64px rgba(0,0,0,0.5);\r\n}\r\n\r\n.tcw-modal-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 16px 20px;\r\n border-bottom: 1px solid var(--tcw-border);\r\n}\r\n\r\n.tcw-modal-header h3 {\r\n font-size: 15px;\r\n font-weight: 600;\r\n margin: 0;\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-modal-close {\r\n width: 28px;\r\n height: 28px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: none;\r\n background: transparent;\r\n color: var(--tcw-text-muted);\r\n cursor: pointer;\r\n border-radius: 4px;\r\n transition: all var(--tcw-transition);\r\n}\r\n\r\n.tcw-modal-close:hover {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-modal-tabs {\r\n display: flex;\r\n gap: 0;\r\n padding: 0 20px;\r\n border-bottom: 1px solid var(--tcw-border);\r\n}\r\n\r\n.tcw-modal-tab {\r\n padding: 10px 16px;\r\n font-size: 12px;\r\n font-weight: 500;\r\n color: var(--tcw-text-muted);\r\n border: none;\r\n background: none;\r\n cursor: pointer;\r\n border-bottom: 2px solid transparent;\r\n margin-bottom: -1px;\r\n transition: color var(--tcw-transition);\r\n font-family: inherit;\r\n text-transform: capitalize;\r\n}\r\n\r\n.tcw-modal-tab:hover {\r\n color: var(--tcw-text-dim);\r\n}\r\n\r\n.tcw-modal-tab.tcw-active {\r\n color: var(--tcw-accent);\r\n border-bottom-color: var(--tcw-accent);\r\n}\r\n\r\n.tcw-modal-body {\r\n padding: 20px;\r\n overflow-y: auto;\r\n flex: 1;\r\n}\r\n\r\n.tcw-settings-section {\r\n margin-bottom: 20px;\r\n}\r\n\r\n.tcw-settings-section:last-child {\r\n margin-bottom: 0;\r\n}\r\n\r\n.tcw-settings-section-title {\r\n font-size: 11px;\r\n font-weight: 600;\r\n text-transform: uppercase;\r\n letter-spacing: 0.05em;\r\n color: var(--tcw-text-muted);\r\n margin-bottom: 12px;\r\n}\r\n\r\n.tcw-settings-row {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 0;\r\n}\r\n\r\n.tcw-settings-row + .tcw-settings-row {\r\n border-top: 1px solid rgba(255,255,255,0.03);\r\n}\r\n\r\n.tcw-root[data-tcw-theme=\"light\"] .tcw-settings-row + .tcw-settings-row {\r\n border-top: 1px solid rgba(0,0,0,0.04);\r\n}\r\n\r\n.tcw-settings-label {\r\n font-size: 13px;\r\n color: var(--tcw-text-dim);\r\n}\r\n\r\n.tcw-color-picker-wrap {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n}\r\n\r\n.tcw-color-picker-wrap input[type='color'] {\r\n width: 28px;\r\n height: 28px;\r\n border: 1px solid var(--tcw-border);\r\n border-radius: 4px;\r\n background: none;\r\n cursor: pointer;\r\n padding: 2px;\r\n}\r\n\r\n.tcw-color-picker-wrap input[type='color']::-webkit-color-swatch-wrapper {\r\n padding: 0;\r\n}\r\n\r\n.tcw-color-picker-wrap input[type='color']::-webkit-color-swatch {\r\n border: none;\r\n border-radius: 2px;\r\n}\r\n\r\n.tcw-color-hex {\r\n font-size: 11px;\r\n font-family: var(--tcw-font-mono);\r\n color: var(--tcw-text-muted);\r\n min-width: 60px;\r\n}\r\n\r\n.tcw-toggle {\r\n width: 36px;\r\n height: 20px;\r\n background: rgba(255,255,255,0.1);\r\n border-radius: 10px;\r\n position: relative;\r\n cursor: pointer;\r\n transition: background var(--tcw-transition);\r\n border: none;\r\n padding: 0;\r\n flex-shrink: 0;\r\n}\r\n\r\n.tcw-toggle::after {\r\n content: '';\r\n position: absolute;\r\n top: 2px;\r\n left: 2px;\r\n width: 16px;\r\n height: 16px;\r\n border-radius: 50%;\r\n background: var(--tcw-text-muted);\r\n transition: all var(--tcw-transition);\r\n}\r\n\r\n.tcw-toggle.tcw-on {\r\n background: var(--tcw-accent);\r\n}\r\n\r\n.tcw-toggle.tcw-on::after {\r\n left: 18px;\r\n background: white;\r\n}\r\n\r\n.tcw-root[data-tcw-theme=\"light\"] .tcw-toggle {\r\n background: rgba(0,0,0,0.1);\r\n}\r\n\r\n.tcw-root[data-tcw-theme=\"light\"] .tcw-toggle::after {\r\n background: #888;\r\n}\r\n\r\n.tcw-root[data-tcw-theme=\"light\"] .tcw-toggle.tcw-on {\r\n background: var(--tcw-accent);\r\n}\r\n\r\n.tcw-root[data-tcw-theme=\"light\"] .tcw-toggle.tcw-on::after {\r\n background: white;\r\n}\r\n\r\n.tcw-settings-select {\r\n padding: 4px 8px;\r\n font-size: 12px;\r\n font-family: inherit;\r\n background: var(--tcw-bg);\r\n border: 1px solid var(--tcw-border);\r\n border-radius: 4px;\r\n color: var(--tcw-text);\r\n cursor: pointer;\r\n}\r\n\r\n.tcw-modal-footer {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 20px;\r\n border-top: 1px solid var(--tcw-border);\r\n}\r\n\r\n.tcw-reset-link {\r\n font-size: 12px;\r\n color: var(--tcw-text-muted);\r\n cursor: pointer;\r\n border: none;\r\n background: none;\r\n font-family: inherit;\r\n text-decoration: underline;\r\n text-underline-offset: 2px;\r\n transition: color var(--tcw-transition);\r\n}\r\n\r\n.tcw-reset-link:hover {\r\n color: var(--tcw-text-dim);\r\n}\r\n\r\n.tcw-done-btn {\r\n padding: 6px 16px;\r\n font-size: 12px;\r\n font-weight: 500;\r\n background: var(--tcw-accent);\r\n color: white;\r\n border: none;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n font-family: inherit;\r\n transition: background var(--tcw-transition);\r\n}\r\n\r\n.tcw-done-btn:hover {\r\n background: #2563eb;\r\n}\r\n\r\n/* === Status Bar === */\r\n\r\n.tcw-statusbar {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 6px 16px;\r\n border-top: 1px solid var(--tcw-border);\r\n background: var(--tcw-bg-elevated);\r\n font-size: 11px;\r\n color: var(--tcw-text-muted);\r\n flex-shrink: 0;\r\n}\r\n\r\n.tcw-status-indicator {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n}\r\n\r\n.tcw-status-dot {\r\n width: 6px;\r\n height: 6px;\r\n border-radius: 50%;\r\n background: var(--tcw-text-muted);\r\n transition: background 0.3s;\r\n}\r\n\r\n.tcw-status-dot.tcw-connected {\r\n background: var(--tcw-green);\r\n}\r\n\r\n.tcw-status-dot.tcw-error {\r\n background: var(--tcw-red);\r\n}\r\n\r\n/* === Command Palette === */\r\n\r\n.tcw-cmd-palette {\r\n position: fixed;\r\n z-index: 102;\r\n top: 20%;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n background: var(--tcw-bg-elevated);\r\n border: 1px solid var(--tcw-border);\r\n border-radius: var(--tcw-radius-lg);\r\n width: 520px;\r\n max-width: 90vw;\r\n max-height: 60vh;\r\n display: flex;\r\n flex-direction: column;\r\n box-shadow: 0 24px 64px rgba(0,0,0,0.5);\r\n overflow: hidden;\r\n}\r\n\r\n.tcw-cmd-header {\r\n display: flex;\r\n align-items: center;\r\n padding: 12px 16px;\r\n border-bottom: 1px solid var(--tcw-border);\r\n gap: 10px;\r\n}\r\n\r\n.tcw-cmd-icon {\r\n font-size: 18px;\r\n color: var(--tcw-text-muted);\r\n flex-shrink: 0;\r\n}\r\n\r\n.tcw-cmd-input {\r\n flex: 1;\r\n background: none;\r\n border: none;\r\n outline: none;\r\n font-size: 14px;\r\n font-family: inherit;\r\n color: var(--tcw-text);\r\n caret-color: var(--tcw-accent);\r\n}\r\n\r\n.tcw-cmd-input::placeholder {\r\n color: var(--tcw-text-muted);\r\n}\r\n\r\n.tcw-cmd-hint {\r\n font-size: 10px;\r\n color: var(--tcw-text-muted);\r\n border: 1px solid var(--tcw-border);\r\n padding: 2px 6px;\r\n border-radius: 3px;\r\n flex-shrink: 0;\r\n}\r\n\r\n.tcw-cmd-list {\r\n overflow-y: auto;\r\n flex: 1;\r\n padding: 4px 0;\r\n max-height: 360px;\r\n}\r\n\r\n.tcw-cmd-category {\r\n text-transform: uppercase;\r\n font-size: 10px;\r\n color: var(--tcw-text-muted);\r\n letter-spacing: 0.05em;\r\n padding: 8px 16px 4px;\r\n font-weight: 600;\r\n}\r\n\r\n.tcw-cmd-item {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 16px;\r\n font-size: 13px;\r\n color: var(--tcw-text-dim);\r\n cursor: pointer;\r\n width: 100%;\r\n border: none;\r\n background: none;\r\n font-family: inherit;\r\n text-align: left;\r\n transition: background 80ms ease;\r\n gap: 8px;\r\n}\r\n\r\n.tcw-cmd-item:hover,\r\n.tcw-cmd-item.tcw-selected {\r\n background: var(--tcw-hover-bg);\r\n color: var(--tcw-text);\r\n}\r\n\r\n.tcw-cmd-item.tcw-active .tcw-cmd-item-label {\r\n color: var(--tcw-accent);\r\n}\r\n\r\n.tcw-cmd-item-label {\r\n flex: 1;\r\n}\r\n\r\n.tcw-cmd-check {\r\n color: var(--tcw-accent);\r\n font-size: 14px;\r\n font-weight: 600;\r\n}\r\n\r\n.tcw-cmd-kbd {\r\n font-size: 10px;\r\n font-family: var(--tcw-font-mono);\r\n color: var(--tcw-text-muted);\r\n background: var(--tcw-bg);\r\n border: 1px solid var(--tcw-border);\r\n padding: 1px 5px;\r\n border-radius: 3px;\r\n}\r\n\r\n.tcw-cmd-empty {\r\n padding: 24px 16px;\r\n text-align: center;\r\n color: var(--tcw-text-muted);\r\n font-size: 13px;\r\n}\r\n\r\n.tcw-cmd-footer {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding: 8px 16px;\r\n border-top: 1px solid var(--tcw-border);\r\n font-size: 11px;\r\n color: var(--tcw-text-muted);\r\n}\r\n\r\n/* === Responsive === */\r\n\r\n@media (max-width: 768px) {\r\n .tcw-toolbar {\r\n padding: 0 8px;\r\n height: 36px;\r\n }\r\n .tcw-toolbar-sep {\r\n display: none;\r\n }\r\n .tcw-indicator-chips {\r\n display: none;\r\n }\r\n .tcw-sidebar {\r\n width: 32px;\r\n }\r\n .tcw-sidebar-btn {\r\n width: 32px;\r\n height: 28px;\r\n }\r\n}\r\n", d = 0, f = "tcw-styles";
|
|
389
|
-
function
|
|
390
|
-
if (
|
|
389
|
+
}, d = "/* === TradeCanvas Widget — Premium Styles === */\n\n.tcw-root {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, system-ui, sans-serif;\n font-feature-settings: 'cv11', 'ss01', 'ss03';\n font-size: 13px;\n line-height: 1.4;\n color: #d1d4dc;\n background: #0d0f17;\n position: relative;\n overflow: hidden;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n\n /* --- Dark theme tokens (default) --- */\n --tcw-bg: #0d0f17;\n --tcw-bg-surface: #131722;\n --tcw-bg-elevated: #1a1e2d;\n --tcw-bg-overlay: #20253480;\n --tcw-border: #2a2e39;\n --tcw-border-strong: #363a45;\n --tcw-text: #e9ebf0;\n --tcw-text-dim: #b2b5be;\n --tcw-text-muted: #6b6f7a;\n\n --tcw-accent: #4f88ff;\n --tcw-accent-hover: #6b9aff;\n --tcw-accent-soft: rgba(79, 136, 255, 0.14);\n --tcw-accent-glow: rgba(79, 136, 255, 0.22);\n --tcw-accent-line: rgba(79, 136, 255, 0.55);\n\n --tcw-red: #f23645;\n --tcw-red-soft: rgba(242, 54, 69, 0.12);\n --tcw-green: #26a17b;\n --tcw-green-soft: rgba(38, 161, 123, 0.12);\n --tcw-amber: #ff9f43;\n\n --tcw-hover-bg: rgba(255, 255, 255, 0.05);\n --tcw-active-bg: rgba(255, 255, 255, 0.08);\n --tcw-divider: rgba(255, 255, 255, 0.06);\n\n /* Motion */\n --tcw-ease: cubic-bezier(0.2, 0, 0, 1);\n --tcw-ease-out: cubic-bezier(0.16, 1, 0.3, 1);\n --tcw-dur-fast: 120ms;\n --tcw-dur-normal: 180ms;\n --tcw-dur-slow: 260ms;\n\n /* Shape */\n --tcw-radius-sm: 4px;\n --tcw-radius: 6px;\n --tcw-radius-lg: 10px;\n --tcw-radius-xl: 14px;\n\n /* Elevation */\n --tcw-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);\n --tcw-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.2);\n --tcw-shadow-lg: 0 12px 36px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3);\n --tcw-shadow-xl: 0 24px 64px rgba(0, 0, 0, 0.55), 0 12px 24px rgba(0, 0, 0, 0.35);\n --tcw-ring: 0 0 0 2px rgba(79, 136, 255, 0.45);\n\n /* Type */\n --tcw-font-mono: 'JetBrains Mono', 'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', ui-monospace, monospace;\n}\n\n.tcw-root[data-tcw-theme='light'] {\n color: #131722;\n background: #fcfcfd;\n\n --tcw-bg: #fcfcfd;\n --tcw-bg-surface: #ffffff;\n --tcw-bg-elevated: #ffffff;\n --tcw-bg-overlay: rgba(255, 255, 255, 0.75);\n --tcw-border: #e7e9ef;\n --tcw-border-strong: #d4d7e0;\n --tcw-text: #131722;\n --tcw-text-dim: #50545e;\n --tcw-text-muted: #8b8f99;\n\n --tcw-accent: #2962ff;\n --tcw-accent-hover: #1e4fd6;\n --tcw-accent-soft: rgba(41, 98, 255, 0.10);\n --tcw-accent-glow: rgba(41, 98, 255, 0.16);\n --tcw-accent-line: rgba(41, 98, 255, 0.45);\n\n --tcw-hover-bg: rgba(0, 0, 0, 0.04);\n --tcw-active-bg: rgba(41, 98, 255, 0.08);\n --tcw-divider: rgba(0, 0, 0, 0.06);\n\n --tcw-shadow-sm: 0 1px 2px rgba(20, 28, 56, 0.05);\n --tcw-shadow-md: 0 4px 12px rgba(20, 28, 56, 0.08), 0 1px 3px rgba(20, 28, 56, 0.04);\n --tcw-shadow-lg: 0 12px 36px rgba(20, 28, 56, 0.14), 0 4px 12px rgba(20, 28, 56, 0.08);\n --tcw-shadow-xl: 0 24px 64px rgba(20, 28, 56, 0.18), 0 12px 24px rgba(20, 28, 56, 0.1);\n}\n\n/* === Toolbar === */\n\n.tcw-toolbar {\n display: flex;\n align-items: center;\n gap: 0;\n padding: 0 10px;\n height: 44px;\n border-bottom: 1px solid var(--tcw-border);\n background:\n linear-gradient(180deg, var(--tcw-bg-elevated) 0%, var(--tcw-bg-surface) 100%);\n flex-shrink: 0;\n position: relative;\n z-index: 20;\n box-shadow: var(--tcw-shadow-sm);\n}\n\n.tcw-toolbar-symbol {\n font-size: 14px;\n font-weight: 650;\n color: var(--tcw-text);\n padding: 6px 12px;\n white-space: nowrap;\n letter-spacing: -0.015em;\n cursor: pointer;\n border: none;\n background: transparent;\n font-family: inherit;\n border-radius: var(--tcw-radius);\n transition: background var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-toolbar-symbol:hover {\n background: var(--tcw-hover-bg);\n}\n\n.tcw-toolbar-sep {\n width: 1px;\n height: 22px;\n background: var(--tcw-border);\n flex-shrink: 0;\n margin: 0 4px;\n}\n\n.tcw-toolbar-group {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 0 4px;\n}\n\n.tcw-toolbar-spacer {\n flex: 1;\n}\n\n.tcw-btn {\n padding: 6px 10px;\n font-size: 12px;\n font-weight: 500;\n font-family: inherit;\n border: none;\n border-radius: var(--tcw-radius);\n background: transparent;\n color: var(--tcw-text-dim);\n cursor: pointer;\n transition:\n background var(--tcw-dur-fast) var(--tcw-ease),\n color var(--tcw-dur-fast) var(--tcw-ease),\n transform var(--tcw-dur-fast) var(--tcw-ease);\n white-space: nowrap;\n line-height: 1;\n letter-spacing: -0.005em;\n}\n\n.tcw-btn:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-btn:active {\n transform: translateY(0.5px);\n}\n\n.tcw-btn.tcw-active {\n background: var(--tcw-accent-soft);\n color: var(--tcw-accent);\n font-weight: 600;\n box-shadow: inset 0 0 0 1px var(--tcw-accent-line);\n}\n\n.tcw-btn:focus-visible,\n.tcw-btn-icon:focus-visible,\n.tcw-sidebar-btn:focus-visible,\n.tcw-dropdown-trigger:focus-visible {\n outline: none;\n box-shadow: var(--tcw-ring);\n}\n\n.tcw-btn-icon {\n width: 32px;\n height: 32px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: inherit;\n border: none;\n border-radius: var(--tcw-radius);\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n transition:\n background var(--tcw-dur-fast) var(--tcw-ease),\n color var(--tcw-dur-fast) var(--tcw-ease);\n line-height: 1;\n position: relative;\n}\n\n.tcw-btn-icon:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-btn-icon svg {\n display: block;\n}\n\n.tcw-badge-count {\n font-size: 10px;\n font-weight: 600;\n color: var(--tcw-accent);\n background: var(--tcw-accent-soft);\n padding: 1px 5px;\n border-radius: 9px;\n font-family: var(--tcw-font-mono);\n}\n\n.tcw-indicator-chips {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 0 4px;\n flex-wrap: nowrap;\n overflow: hidden;\n}\n\n.tcw-indicator-chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 6px 3px 9px;\n font-size: 11px;\n font-weight: 500;\n background: var(--tcw-accent-soft);\n color: var(--tcw-accent);\n border-radius: 9999px;\n white-space: nowrap;\n line-height: 1.4;\n letter-spacing: -0.005em;\n border: 1px solid transparent;\n transition: border-color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-indicator-chip:hover {\n border-color: var(--tcw-accent-line);\n}\n\n.tcw-chip-remove {\n cursor: pointer;\n opacity: 0.55;\n padding: 0 2px;\n transition: opacity var(--tcw-dur-fast) var(--tcw-ease);\n border: none;\n background: transparent;\n color: inherit;\n display: inline-flex;\n align-items: center;\n}\n\n.tcw-chip-remove:hover {\n opacity: 1;\n}\n\n/* === Dropdown === */\n\n.tcw-dropdown-trigger {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 6px 10px;\n font-size: 12px;\n font-weight: 500;\n font-family: inherit;\n border: none;\n border-radius: var(--tcw-radius);\n background: transparent;\n color: var(--tcw-text-dim);\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n white-space: nowrap;\n line-height: 1;\n}\n\n.tcw-dropdown-trigger:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-dropdown {\n position: absolute;\n top: 100%;\n margin-top: 6px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-lg);\n box-shadow: var(--tcw-shadow-lg);\n z-index: 50;\n padding: 6px;\n max-height: 420px;\n overflow-y: auto;\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n animation: tcw-pop-in var(--tcw-dur-normal) var(--tcw-ease-out);\n}\n\n@keyframes tcw-pop-in {\n from { opacity: 0; transform: translateY(-4px) scale(0.98); }\n to { opacity: 1; transform: translateY(0) scale(1); }\n}\n\n.tcw-dropdown-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 7px 10px;\n font-size: 12.5px;\n color: var(--tcw-text-dim);\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n width: 100%;\n border: none;\n background: transparent;\n font-family: inherit;\n text-align: left;\n border-radius: var(--tcw-radius-sm);\n gap: 12px;\n}\n\n.tcw-dropdown-item:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-dropdown-item.tcw-active {\n color: var(--tcw-accent);\n background: var(--tcw-accent-soft);\n font-weight: 600;\n}\n\n.tcw-dropdown-label {\n text-transform: uppercase;\n font-size: 10px;\n color: var(--tcw-text-muted);\n letter-spacing: 0.08em;\n padding: 8px 10px 4px;\n font-weight: 600;\n}\n\n.tcw-dropdown-divider {\n border-top: 1px solid var(--tcw-divider);\n margin: 6px 4px;\n}\n\n.tcw-tag {\n font-size: 10px;\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--tcw-hover-bg);\n letter-spacing: 0.02em;\n}\n\n/* === Body === */\n\n.tcw-body {\n display: flex;\n flex: 1;\n min-height: 0;\n background: var(--tcw-bg);\n}\n\n.tcw-chart-container {\n flex: 1;\n min-width: 0;\n min-height: 0;\n width: 100%;\n height: 100%;\n position: relative;\n}\n\n/* === Sidebar === */\n\n.tcw-sidebar {\n width: 40px;\n flex-shrink: 0;\n background: linear-gradient(180deg, var(--tcw-bg-elevated) 0%, var(--tcw-bg-surface) 100%);\n border-right: 1px solid var(--tcw-border);\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 6px 0;\n overflow: visible;\n box-shadow: var(--tcw-shadow-sm);\n}\n\n.tcw-tool-group-wrap {\n position: relative;\n}\n\n.tcw-sidebar-btn {\n width: 32px;\n height: 32px;\n margin: 1px 0;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n font-family: inherit;\n transition:\n background var(--tcw-dur-fast) var(--tcw-ease),\n color var(--tcw-dur-fast) var(--tcw-ease);\n position: relative;\n flex-shrink: 0;\n line-height: 1;\n border-radius: var(--tcw-radius);\n}\n\n.tcw-sidebar-btn:hover {\n color: var(--tcw-text);\n background: var(--tcw-hover-bg);\n}\n\n.tcw-sidebar-btn.tcw-active {\n color: var(--tcw-accent);\n background: var(--tcw-accent-soft);\n box-shadow: inset 2px 0 0 var(--tcw-accent);\n}\n\n.tcw-sidebar-btn.tcw-danger:hover {\n color: var(--tcw-red);\n background: var(--tcw-red-soft);\n}\n\n.tcw-multi-dot {\n position: absolute;\n bottom: 3px;\n right: 3px;\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n opacity: 0.7;\n}\n\n.tcw-sidebar-divider {\n width: 22px;\n height: 1px;\n background: var(--tcw-divider);\n margin: 6px 0;\n flex-shrink: 0;\n}\n\n.tcw-sidebar-spacer {\n flex: 1;\n}\n\n/* === Flyout === */\n\n.tcw-flyout {\n position: absolute;\n left: 100%;\n top: 0;\n margin-left: 6px;\n min-width: 180px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-lg);\n box-shadow: var(--tcw-shadow-lg);\n z-index: 30;\n padding: 6px;\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n animation: tcw-slide-right var(--tcw-dur-normal) var(--tcw-ease-out);\n}\n\n@keyframes tcw-slide-right {\n from { opacity: 0; transform: translateX(-4px); }\n to { opacity: 1; transform: translateX(0); }\n}\n\n.tcw-flyout-header {\n text-transform: uppercase;\n font-size: 10px;\n color: var(--tcw-text-muted);\n letter-spacing: 0.08em;\n padding: 6px 10px 4px;\n font-weight: 600;\n}\n\n.tcw-flyout-item {\n padding: 7px 10px;\n font-size: 12.5px;\n color: var(--tcw-text-dim);\n cursor: pointer;\n width: 100%;\n display: block;\n border: none;\n background: transparent;\n text-align: left;\n font-family: inherit;\n border-radius: var(--tcw-radius-sm);\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-flyout-item:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-flyout-item.tcw-active {\n color: var(--tcw-accent);\n background: var(--tcw-accent-soft);\n font-weight: 600;\n}\n\n/* === Modal === */\n\n.tcw-modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(8, 10, 18, 0.55);\n backdrop-filter: blur(6px) saturate(140%);\n -webkit-backdrop-filter: blur(6px) saturate(140%);\n z-index: 100;\n animation: tcw-fade-in var(--tcw-dur-normal) var(--tcw-ease-out);\n}\n\n@keyframes tcw-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.tcw-modal {\n position: fixed;\n z-index: 101;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-xl);\n width: 520px;\n max-width: 92vw;\n max-height: 82vh;\n display: flex;\n flex-direction: column;\n box-shadow: var(--tcw-shadow-xl);\n animation: tcw-modal-in var(--tcw-dur-slow) var(--tcw-ease-out);\n}\n\n@keyframes tcw-modal-in {\n from { opacity: 0; transform: translate(-50%, -48%) scale(0.96); }\n to { opacity: 1; transform: translate(-50%, -50%) scale(1); }\n}\n\n.tcw-modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 22px;\n border-bottom: 1px solid var(--tcw-divider);\n}\n\n.tcw-modal-header h3 {\n font-size: 15px;\n font-weight: 650;\n margin: 0;\n color: var(--tcw-text);\n letter-spacing: -0.015em;\n}\n\n.tcw-modal-close {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--tcw-text-muted);\n cursor: pointer;\n border-radius: var(--tcw-radius);\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-modal-close:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-modal-tabs {\n display: flex;\n gap: 4px;\n padding: 0 18px;\n border-bottom: 1px solid var(--tcw-divider);\n}\n\n.tcw-modal-tab {\n padding: 11px 14px;\n font-size: 12px;\n font-weight: 500;\n color: var(--tcw-text-muted);\n border: none;\n background: transparent;\n cursor: pointer;\n border-bottom: 2px solid transparent;\n margin-bottom: -1px;\n transition: color var(--tcw-dur-fast) var(--tcw-ease), border-color var(--tcw-dur-fast) var(--tcw-ease);\n font-family: inherit;\n text-transform: capitalize;\n letter-spacing: -0.005em;\n}\n\n.tcw-modal-tab:hover {\n color: var(--tcw-text-dim);\n}\n\n.tcw-modal-tab.tcw-active {\n color: var(--tcw-accent);\n border-bottom-color: var(--tcw-accent);\n font-weight: 600;\n}\n\n.tcw-modal-body {\n padding: 20px 22px;\n overflow-y: auto;\n flex: 1;\n}\n\n.tcw-settings-section {\n margin-bottom: 22px;\n}\n\n.tcw-settings-section:last-child {\n margin-bottom: 0;\n}\n\n.tcw-settings-section-title {\n font-size: 10.5px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.09em;\n color: var(--tcw-text-muted);\n margin-bottom: 12px;\n}\n\n.tcw-settings-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 0;\n}\n\n.tcw-settings-row + .tcw-settings-row {\n border-top: 1px solid var(--tcw-divider);\n}\n\n.tcw-settings-label {\n font-size: 13px;\n color: var(--tcw-text-dim);\n letter-spacing: -0.005em;\n}\n\n.tcw-color-picker-wrap {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tcw-color-picker-wrap input[type='color'] {\n width: 28px;\n height: 28px;\n border: 1px solid var(--tcw-border-strong);\n border-radius: var(--tcw-radius-sm);\n background: transparent;\n cursor: pointer;\n padding: 2px;\n}\n\n.tcw-color-picker-wrap input[type='color']::-webkit-color-swatch-wrapper {\n padding: 0;\n}\n\n.tcw-color-picker-wrap input[type='color']::-webkit-color-swatch {\n border: none;\n border-radius: 2px;\n}\n\n.tcw-color-hex {\n font-size: 11px;\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n min-width: 64px;\n letter-spacing: 0.01em;\n}\n\n.tcw-toggle {\n width: 36px;\n height: 20px;\n background: rgba(255, 255, 255, 0.12);\n border-radius: 10px;\n position: relative;\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease);\n border: none;\n padding: 0;\n flex-shrink: 0;\n}\n\n.tcw-toggle::after {\n content: '';\n position: absolute;\n top: 2px;\n left: 2px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n transition:\n left var(--tcw-dur-normal) var(--tcw-ease-out),\n background var(--tcw-dur-fast) var(--tcw-ease);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);\n}\n\n.tcw-toggle.tcw-on {\n background: var(--tcw-accent);\n box-shadow: 0 0 0 2px var(--tcw-accent-glow);\n}\n\n.tcw-toggle.tcw-on::after {\n left: 18px;\n background: #fff;\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-toggle {\n background: rgba(0, 0, 0, 0.12);\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-toggle::after {\n background: #999;\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-toggle.tcw-on {\n background: var(--tcw-accent);\n}\n\n.tcw-root[data-tcw-theme='light'] .tcw-toggle.tcw-on::after {\n background: #fff;\n}\n\n.tcw-settings-select {\n padding: 6px 10px;\n font-size: 12px;\n font-family: inherit;\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius);\n color: var(--tcw-text);\n cursor: pointer;\n transition: border-color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-settings-select:hover {\n border-color: var(--tcw-border-strong);\n}\n\n.tcw-settings-select:focus-visible {\n outline: none;\n border-color: var(--tcw-accent);\n box-shadow: var(--tcw-ring);\n}\n\n.tcw-modal-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 14px 22px;\n border-top: 1px solid var(--tcw-divider);\n background: var(--tcw-bg-surface);\n border-radius: 0 0 var(--tcw-radius-xl) var(--tcw-radius-xl);\n}\n\n.tcw-reset-link {\n font-size: 12px;\n color: var(--tcw-text-muted);\n cursor: pointer;\n border: none;\n background: transparent;\n font-family: inherit;\n text-decoration: underline;\n text-underline-offset: 2px;\n text-decoration-color: var(--tcw-border-strong);\n transition: color var(--tcw-dur-fast) var(--tcw-ease), text-decoration-color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-reset-link:hover {\n color: var(--tcw-text-dim);\n text-decoration-color: currentColor;\n}\n\n.tcw-done-btn {\n padding: 8px 18px;\n font-size: 12.5px;\n font-weight: 600;\n background: var(--tcw-accent);\n color: #fff;\n border: none;\n border-radius: var(--tcw-radius);\n cursor: pointer;\n font-family: inherit;\n transition:\n background var(--tcw-dur-fast) var(--tcw-ease),\n transform var(--tcw-dur-fast) var(--tcw-ease),\n box-shadow var(--tcw-dur-fast) var(--tcw-ease);\n letter-spacing: -0.005em;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.15);\n}\n\n.tcw-done-btn:hover {\n background: var(--tcw-accent-hover);\n box-shadow: var(--tcw-shadow-md), 0 0 0 3px var(--tcw-accent-glow);\n}\n\n.tcw-done-btn:active {\n transform: translateY(0.5px);\n}\n\n/* === Status Bar === */\n\n.tcw-statusbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 7px 16px;\n border-top: 1px solid var(--tcw-border);\n background: var(--tcw-bg-surface);\n font-size: 11px;\n color: var(--tcw-text-muted);\n flex-shrink: 0;\n font-feature-settings: 'tnum';\n}\n\n.tcw-status-indicator {\n display: flex;\n align-items: center;\n gap: 7px;\n font-weight: 500;\n}\n\n.tcw-status-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--tcw-text-muted);\n transition: background var(--tcw-dur-normal) var(--tcw-ease), box-shadow var(--tcw-dur-normal) var(--tcw-ease);\n position: relative;\n}\n\n.tcw-status-dot.tcw-connected {\n background: var(--tcw-green);\n box-shadow: 0 0 0 3px rgba(38, 161, 123, 0.18);\n}\n\n.tcw-status-dot.tcw-connected::after {\n content: '';\n position: absolute;\n inset: -3px;\n border-radius: 50%;\n border: 2px solid var(--tcw-green);\n opacity: 0;\n animation: tcw-pulse 2.2s ease-out infinite;\n}\n\n@keyframes tcw-pulse {\n 0% { opacity: 0.6; transform: scale(0.6); }\n 100% { opacity: 0; transform: scale(2.2); }\n}\n\n.tcw-status-dot.tcw-error {\n background: var(--tcw-red);\n box-shadow: 0 0 0 3px rgba(242, 54, 69, 0.2);\n}\n\n/* === Command Palette === */\n\n.tcw-cmd-palette {\n position: fixed;\n z-index: 102;\n top: 18%;\n left: 50%;\n transform: translateX(-50%);\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius-xl);\n width: 560px;\n max-width: 92vw;\n max-height: 62vh;\n display: flex;\n flex-direction: column;\n box-shadow: var(--tcw-shadow-xl);\n overflow: hidden;\n backdrop-filter: blur(20px);\n -webkit-backdrop-filter: blur(20px);\n animation: tcw-modal-in var(--tcw-dur-slow) var(--tcw-ease-out);\n}\n\n.tcw-cmd-header {\n display: flex;\n align-items: center;\n padding: 14px 18px;\n border-bottom: 1px solid var(--tcw-divider);\n gap: 12px;\n}\n\n.tcw-cmd-icon {\n font-size: 18px;\n color: var(--tcw-text-muted);\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n}\n\n.tcw-cmd-input {\n flex: 1;\n background: transparent;\n border: none;\n outline: none;\n font-size: 14.5px;\n font-family: inherit;\n color: var(--tcw-text);\n caret-color: var(--tcw-accent);\n letter-spacing: -0.005em;\n}\n\n.tcw-cmd-input::placeholder {\n color: var(--tcw-text-muted);\n}\n\n.tcw-cmd-hint {\n font-size: 10px;\n color: var(--tcw-text-muted);\n font-family: var(--tcw-font-mono);\n border: 1px solid var(--tcw-border);\n background: var(--tcw-bg-surface);\n padding: 3px 7px;\n border-radius: 4px;\n flex-shrink: 0;\n box-shadow: inset 0 -1px 0 var(--tcw-border);\n}\n\n.tcw-cmd-list {\n overflow-y: auto;\n flex: 1;\n padding: 6px;\n max-height: 380px;\n}\n\n.tcw-cmd-category {\n text-transform: uppercase;\n font-size: 10px;\n color: var(--tcw-text-muted);\n letter-spacing: 0.09em;\n padding: 10px 10px 4px;\n font-weight: 600;\n}\n\n.tcw-cmd-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 9px 12px;\n font-size: 13px;\n color: var(--tcw-text-dim);\n cursor: pointer;\n width: 100%;\n border: none;\n background: transparent;\n font-family: inherit;\n text-align: left;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n gap: 10px;\n border-radius: var(--tcw-radius);\n letter-spacing: -0.005em;\n}\n\n.tcw-cmd-item:hover,\n.tcw-cmd-item.tcw-selected {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-cmd-item.tcw-selected {\n box-shadow: inset 2px 0 0 var(--tcw-accent);\n}\n\n.tcw-cmd-item.tcw-active .tcw-cmd-item-label {\n color: var(--tcw-accent);\n font-weight: 600;\n}\n\n.tcw-cmd-item-label {\n flex: 1;\n}\n\n.tcw-cmd-check {\n color: var(--tcw-accent);\n font-size: 14px;\n font-weight: 700;\n}\n\n.tcw-cmd-kbd {\n font-size: 10px;\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n padding: 2px 6px;\n border-radius: 4px;\n box-shadow: inset 0 -1px 0 var(--tcw-border);\n}\n\n.tcw-cmd-empty {\n padding: 32px 16px;\n text-align: center;\n color: var(--tcw-text-muted);\n font-size: 13px;\n}\n\n.tcw-cmd-footer {\n display: flex;\n align-items: center;\n gap: 18px;\n padding: 10px 18px;\n border-top: 1px solid var(--tcw-divider);\n font-size: 11px;\n color: var(--tcw-text-muted);\n background: var(--tcw-bg-surface);\n}\n\n/* === Watchlist === */\n\n.tcw-watchlist {\n width: 220px;\n flex-shrink: 0;\n background: var(--tcw-bg-surface);\n border-left: 1px solid var(--tcw-border);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-shadow: var(--tcw-shadow-sm);\n}\n\n.tcw-watchlist-header {\n padding: 10px 14px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n color: var(--tcw-text-muted);\n border-bottom: 1px solid var(--tcw-divider);\n}\n\n.tcw-watchlist-list {\n flex: 1;\n overflow-y: auto;\n padding: 4px 0;\n}\n\n.tcw-watchlist-row {\n display: grid;\n grid-template-columns: 1fr auto auto;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n transition: background var(--tcw-dur-fast) var(--tcw-ease);\n border-left: 2px solid transparent;\n outline: none;\n}\n\n.tcw-watchlist-row:hover {\n background: var(--tcw-hover-bg);\n}\n\n.tcw-watchlist-row:focus-visible {\n background: var(--tcw-hover-bg);\n border-left-color: var(--tcw-accent);\n}\n\n.tcw-watchlist-row.tcw-watchlist-active {\n background: var(--tcw-accent-soft);\n border-left-color: var(--tcw-accent);\n}\n\n.tcw-watchlist-symbol {\n font-size: 12.5px;\n font-weight: 600;\n color: var(--tcw-text);\n letter-spacing: -0.005em;\n white-space: nowrap;\n}\n\n.tcw-watchlist-spark {\n width: 56px;\n height: 22px;\n align-self: center;\n}\n\n.tcw-watchlist-stats {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 1px;\n font-variant-numeric: tabular-nums;\n font-family: var(--tcw-font-mono);\n}\n\n.tcw-watchlist-price {\n font-size: 12px;\n color: var(--tcw-text);\n font-weight: 500;\n}\n\n.tcw-watchlist-change {\n font-size: 10.5px;\n color: var(--tcw-text-muted);\n font-weight: 500;\n}\n\n.tcw-watchlist-change.tcw-up {\n color: var(--tcw-green);\n}\n\n.tcw-watchlist-change.tcw-down {\n color: var(--tcw-red);\n}\n\n@media (max-width: 768px) {\n .tcw-watchlist {\n display: none;\n }\n}\n\n/* === Toast === */\n\n.tcw-toast {\n position: absolute;\n bottom: 60px;\n left: 50%;\n transform: translate(-50%, 12px);\n z-index: 40;\n padding: 9px 14px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border-strong);\n border-radius: 9999px;\n box-shadow: var(--tcw-shadow-lg);\n font-size: 12.5px;\n font-weight: 500;\n color: var(--tcw-text);\n opacity: 0;\n transition: opacity var(--tcw-dur-normal) var(--tcw-ease-out), transform var(--tcw-dur-normal) var(--tcw-ease-out);\n pointer-events: none;\n max-width: calc(100% - 32px);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n letter-spacing: -0.005em;\n}\n\n.tcw-toast.tcw-toast-in {\n opacity: 1;\n transform: translate(-50%, 0);\n}\n\n.tcw-toast-error {\n border-color: var(--tcw-red);\n color: var(--tcw-red);\n}\n\n/* === Replay scrubber === */\n\n.tcw-replay-bar {\n position: absolute;\n left: 50%;\n bottom: 16px;\n transform: translateX(-50%);\n z-index: 25;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 10px;\n background: var(--tcw-bg-elevated);\n border: 1px solid var(--tcw-border);\n border-radius: 9999px;\n box-shadow: var(--tcw-shadow-lg);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n font-size: 12px;\n color: var(--tcw-text);\n animation: tcw-pop-in var(--tcw-dur-normal) var(--tcw-ease-out);\n}\n\n.tcw-replay-btn {\n width: 28px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n color: var(--tcw-text-dim);\n border-radius: 9999px;\n cursor: pointer;\n font-family: inherit;\n transition: background var(--tcw-dur-fast) var(--tcw-ease), color var(--tcw-dur-fast) var(--tcw-ease);\n}\n\n.tcw-replay-btn:hover {\n background: var(--tcw-hover-bg);\n color: var(--tcw-text);\n}\n\n.tcw-replay-btn.tcw-replay-play {\n background: var(--tcw-accent);\n color: #fff;\n width: 32px;\n height: 32px;\n box-shadow: 0 0 0 3px var(--tcw-accent-glow);\n}\n\n.tcw-replay-btn.tcw-replay-play:hover {\n background: var(--tcw-accent-hover);\n}\n\n.tcw-replay-scrubber {\n appearance: none;\n -webkit-appearance: none;\n width: 220px;\n height: 4px;\n background: var(--tcw-border-strong);\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n}\n\n.tcw-replay-scrubber::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--tcw-accent);\n border: 2px solid var(--tcw-bg-elevated);\n box-shadow: 0 0 0 1px var(--tcw-accent), 0 2px 6px rgba(0, 0, 0, 0.3);\n cursor: pointer;\n}\n\n.tcw-replay-scrubber::-moz-range-thumb {\n width: 14px;\n height: 14px;\n border-radius: 50%;\n background: var(--tcw-accent);\n border: 2px solid var(--tcw-bg-elevated);\n box-shadow: 0 0 0 1px var(--tcw-accent), 0 2px 6px rgba(0, 0, 0, 0.3);\n cursor: pointer;\n}\n\n.tcw-replay-progress {\n font-size: 11px;\n font-family: var(--tcw-font-mono);\n color: var(--tcw-text-muted);\n min-width: 64px;\n text-align: center;\n font-feature-settings: 'tnum';\n}\n\n.tcw-replay-speed {\n padding: 4px 8px;\n font-size: 11px;\n font-family: var(--tcw-font-mono);\n background: var(--tcw-bg-surface);\n border: 1px solid var(--tcw-border);\n border-radius: var(--tcw-radius);\n color: var(--tcw-text-dim);\n cursor: pointer;\n}\n\n.tcw-replay-speed:hover {\n border-color: var(--tcw-border-strong);\n}\n\n@media (max-width: 640px) {\n .tcw-replay-scrubber {\n width: 140px;\n }\n .tcw-replay-progress {\n display: none;\n }\n}\n\n/* === Hotkey sheet === */\n\n.tcw-hotkey-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 24px 32px;\n}\n\n.tcw-hotkey-section .tcw-settings-section-title {\n margin-bottom: 8px;\n}\n\n.tcw-hotkey-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 6px 0;\n border-bottom: 1px solid var(--tcw-divider);\n}\n\n.tcw-hotkey-row:last-child {\n border-bottom: none;\n}\n\n.tcw-hotkey-keys {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.tcw-hotkey-sep {\n font-size: 10px;\n color: var(--tcw-text-muted);\n}\n\n.tcw-hotkey-label {\n font-size: 12.5px;\n color: var(--tcw-text-dim);\n text-align: right;\n letter-spacing: -0.005em;\n}\n\n@media (max-width: 640px) {\n .tcw-hotkey-grid {\n grid-template-columns: 1fr;\n gap: 18px;\n }\n}\n\n/* === Scrollbar (subtle, premium feel) === */\n\n.tcw-dropdown::-webkit-scrollbar,\n.tcw-modal-body::-webkit-scrollbar,\n.tcw-cmd-list::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n.tcw-dropdown::-webkit-scrollbar-track,\n.tcw-modal-body::-webkit-scrollbar-track,\n.tcw-cmd-list::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.tcw-dropdown::-webkit-scrollbar-thumb,\n.tcw-modal-body::-webkit-scrollbar-thumb,\n.tcw-cmd-list::-webkit-scrollbar-thumb {\n background: var(--tcw-border-strong);\n border-radius: 4px;\n border: 2px solid transparent;\n background-clip: padding-box;\n}\n\n.tcw-dropdown::-webkit-scrollbar-thumb:hover,\n.tcw-modal-body::-webkit-scrollbar-thumb:hover,\n.tcw-cmd-list::-webkit-scrollbar-thumb:hover {\n background: var(--tcw-text-muted);\n background-clip: padding-box;\n border: 2px solid transparent;\n}\n\n/* === Responsive === */\n\n@media (max-width: 768px) {\n .tcw-toolbar {\n padding: 0 6px;\n height: 40px;\n }\n .tcw-toolbar-sep {\n display: none;\n }\n .tcw-indicator-chips {\n display: none;\n }\n .tcw-sidebar {\n width: 36px;\n }\n .tcw-sidebar-btn {\n width: 28px;\n height: 28px;\n }\n .tcw-modal {\n width: 94vw;\n border-radius: var(--tcw-radius-lg);\n }\n .tcw-cmd-palette {\n width: 94vw;\n border-radius: var(--tcw-radius-lg);\n }\n}\n\n/* === Reduced motion === */\n\n@media (prefers-reduced-motion: reduce) {\n .tcw-root *,\n .tcw-root *::before,\n .tcw-root *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n", f = 0, p = "tcw-styles";
|
|
390
|
+
function m() {
|
|
391
|
+
if (f++, f > 1 || document.getElementById(p)) return;
|
|
391
392
|
let e = document.createElement("style");
|
|
392
|
-
e.id =
|
|
393
|
+
e.id = p, e.textContent = d, document.head.appendChild(e);
|
|
393
394
|
}
|
|
394
|
-
function
|
|
395
|
-
if (
|
|
396
|
-
let e = document.getElementById(
|
|
395
|
+
function h() {
|
|
396
|
+
if (f--, f > 0) return;
|
|
397
|
+
let e = document.getElementById(p);
|
|
397
398
|
e && e.remove();
|
|
398
399
|
}
|
|
399
400
|
//#endregion
|
|
400
401
|
//#region src/widget/icons.ts
|
|
401
|
-
var
|
|
402
|
+
var g = {
|
|
402
403
|
cursor: "<path d=\"M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z\"/><path d=\"M13 13l6 6\"/>",
|
|
403
404
|
trendingUp: "<polyline points=\"22 7 13.5 15.5 8.5 10.5 2 17\"/><polyline points=\"16 7 22 7 22 13\"/>",
|
|
404
405
|
minus: "<path d=\"M5 12h14\"/>",
|
|
@@ -425,13 +426,13 @@ var h = {
|
|
|
425
426
|
stop: "<rect width=\"14\" height=\"14\" x=\"5\" y=\"5\" rx=\"1\"/>",
|
|
426
427
|
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\"/>"
|
|
427
428
|
};
|
|
428
|
-
function
|
|
429
|
-
let n =
|
|
429
|
+
function _(e, t = 14) {
|
|
430
|
+
let n = g[e];
|
|
430
431
|
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>` : "";
|
|
431
432
|
}
|
|
432
433
|
//#endregion
|
|
433
434
|
//#region src/widget/WidgetDropdown.ts
|
|
434
|
-
var
|
|
435
|
+
var v = class {
|
|
435
436
|
trigger;
|
|
436
437
|
panel;
|
|
437
438
|
_isOpen = !1;
|
|
@@ -462,7 +463,7 @@ var _ = class {
|
|
|
462
463
|
destroy() {
|
|
463
464
|
this.trigger.removeEventListener("click", this.onTriggerClick), document.removeEventListener("mousedown", this.onOutsideClick), document.removeEventListener("keydown", this.onEscapeKey), this.panel.remove();
|
|
464
465
|
}
|
|
465
|
-
},
|
|
466
|
+
}, y = class {
|
|
466
467
|
config;
|
|
467
468
|
callbacks;
|
|
468
469
|
el;
|
|
@@ -487,11 +488,14 @@ var _ = class {
|
|
|
487
488
|
let a = document.createElement("div");
|
|
488
489
|
a.style.position = "relative", a.style.display = "inline-flex";
|
|
489
490
|
let o = document.createElement("button");
|
|
490
|
-
o.className = "tcw-dropdown-trigger", o.dataset.role = "charttype", a.appendChild(o), n.appendChild(a), this.chartTypeDropdown = new
|
|
491
|
+
o.className = "tcw-dropdown-trigger", o.dataset.role = "charttype", a.appendChild(o), n.appendChild(a), this.chartTypeDropdown = new v(a, { width: "160px" }), this.buildChartTypeMenu(), n.appendChild(this.sep());
|
|
491
492
|
let s = document.createElement("div");
|
|
492
493
|
s.style.position = "relative", s.style.display = "inline-flex";
|
|
493
494
|
let c = document.createElement("button");
|
|
494
|
-
c.className = "tcw-dropdown-trigger", c.dataset.role = "indicators", s.appendChild(c), n.appendChild(s), this.indicatorDropdown = new
|
|
495
|
+
if (c.className = "tcw-dropdown-trigger", c.dataset.role = "indicators", s.appendChild(c), n.appendChild(s), this.indicatorDropdown = new v(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) {
|
|
496
|
+
let e = this.iconBtn("play", "Bar replay", t.onToggleReplay);
|
|
497
|
+
e.dataset.role = "replay", n.appendChild(e);
|
|
498
|
+
}
|
|
495
499
|
let l = this.iconBtn("camera", "Screenshot", t.onScreenshot);
|
|
496
500
|
n.appendChild(l);
|
|
497
501
|
let u = this.iconBtn("settings", "Chart Settings", t.onSettings);
|
|
@@ -527,11 +531,11 @@ var _ = class {
|
|
|
527
531
|
let n = this.el.querySelector("[data-role=\"charttype\"]");
|
|
528
532
|
if (n) {
|
|
529
533
|
let t = this.config.chartTypes.find((t) => t.value === e.chartType)?.label ?? "Candles";
|
|
530
|
-
n.innerHTML = `${
|
|
534
|
+
n.innerHTML = `${_("barChart", 14)} ${t} ${_("chevronDown", 12)}`;
|
|
531
535
|
}
|
|
532
536
|
let r = this.el.querySelector("[data-role=\"indicators\"]");
|
|
533
537
|
if (r) {
|
|
534
|
-
let t = e.activeIndicators.size, n = `${
|
|
538
|
+
let t = e.activeIndicators.size, n = `${_("trendingUp", 14)} Indicators`;
|
|
535
539
|
t > 0 && (n += ` <span class="tcw-badge-count">${t}</span>`), r.innerHTML = n;
|
|
536
540
|
}
|
|
537
541
|
if (this.chipsContainer) {
|
|
@@ -543,10 +547,10 @@ var _ = class {
|
|
|
543
547
|
let n = document.createElement("span");
|
|
544
548
|
n.textContent = e.label, t.appendChild(n);
|
|
545
549
|
let r = document.createElement("button");
|
|
546
|
-
r.className = "tcw-chip-remove", r.innerHTML =
|
|
550
|
+
r.className = "tcw-chip-remove", r.innerHTML = _("x", 10), r.addEventListener("click", () => this.callbacks.onRemoveIndicator(e.instanceId)), t.appendChild(r), this.chipsContainer.appendChild(t);
|
|
547
551
|
}
|
|
548
552
|
}
|
|
549
|
-
this.themeBtn && (this.themeBtn.innerHTML = e.isDark ?
|
|
553
|
+
this.themeBtn && (this.themeBtn.innerHTML = e.isDark ? _("moon", 14) : _("sun", 14));
|
|
550
554
|
}
|
|
551
555
|
getActiveIndicatorList(e) {
|
|
552
556
|
let t = [];
|
|
@@ -567,12 +571,12 @@ var _ = class {
|
|
|
567
571
|
}
|
|
568
572
|
iconBtn(e, t, n) {
|
|
569
573
|
let r = document.createElement("button");
|
|
570
|
-
return r.className = "tcw-btn-icon", r.title = t, r.innerHTML =
|
|
574
|
+
return r.className = "tcw-btn-icon", r.title = t, r.innerHTML = _(e, 14), r.addEventListener("click", n), r;
|
|
571
575
|
}
|
|
572
576
|
destroy() {
|
|
573
577
|
this.chartTypeDropdown?.destroy(), this.indicatorDropdown?.destroy(), this.el.remove();
|
|
574
578
|
}
|
|
575
|
-
},
|
|
579
|
+
}, b = [
|
|
576
580
|
"trendingUp",
|
|
577
581
|
"minus",
|
|
578
582
|
"penLine",
|
|
@@ -581,7 +585,7 @@ var _ = class {
|
|
|
581
585
|
"gitBranch",
|
|
582
586
|
"ruler",
|
|
583
587
|
"type"
|
|
584
|
-
],
|
|
588
|
+
], x = class {
|
|
585
589
|
config;
|
|
586
590
|
callbacks;
|
|
587
591
|
el;
|
|
@@ -595,24 +599,24 @@ var _ = class {
|
|
|
595
599
|
}
|
|
596
600
|
build() {
|
|
597
601
|
let { config: e, callbacks: t, el: n } = this;
|
|
598
|
-
this.cursorBtn = document.createElement("button"), this.cursorBtn.className = "tcw-sidebar-btn", this.cursorBtn.title = "Cursor", this.cursorBtn.innerHTML =
|
|
602
|
+
this.cursorBtn = document.createElement("button"), this.cursorBtn.className = "tcw-sidebar-btn", this.cursorBtn.title = "Cursor", this.cursorBtn.innerHTML = _("cursor", 14), this.cursorBtn.addEventListener("click", t.onCancelDrawing), n.appendChild(this.cursorBtn), n.appendChild(this.divider()), e.drawingToolGroups.forEach((e, r) => {
|
|
599
603
|
let i = document.createElement("div");
|
|
600
604
|
i.className = "tcw-tool-group-wrap";
|
|
601
605
|
let a = document.createElement("button");
|
|
602
|
-
if (a.className = "tcw-sidebar-btn", a.title = e.label, a.innerHTML =
|
|
606
|
+
if (a.className = "tcw-sidebar-btn", a.title = e.label, a.innerHTML = _(b[r] ?? "square", 14), e.tools.length > 1) {
|
|
603
607
|
let e = document.createElement("span");
|
|
604
608
|
e.className = "tcw-multi-dot", a.appendChild(e);
|
|
605
609
|
}
|
|
606
610
|
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);
|
|
607
611
|
});
|
|
608
612
|
let r = document.createElement("div");
|
|
609
|
-
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 =
|
|
613
|
+
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 = _("magnet", 14), this.magnetBtn.addEventListener("click", t.onToggleMagnet), n.appendChild(this.magnetBtn);
|
|
610
614
|
let i = document.createElement("button");
|
|
611
|
-
i.className = "tcw-sidebar-btn", i.title = "Undo", i.innerHTML =
|
|
615
|
+
i.className = "tcw-sidebar-btn", i.title = "Undo", i.innerHTML = _("undo", 14), i.addEventListener("click", t.onUndo), n.appendChild(i);
|
|
612
616
|
let a = document.createElement("button");
|
|
613
|
-
a.className = "tcw-sidebar-btn", a.title = "Redo", a.innerHTML =
|
|
617
|
+
a.className = "tcw-sidebar-btn", a.title = "Redo", a.innerHTML = _("redo", 14), a.addEventListener("click", t.onRedo), n.appendChild(a);
|
|
614
618
|
let o = document.createElement("button");
|
|
615
|
-
o.className = "tcw-sidebar-btn tcw-danger", o.title = "Clear all", o.innerHTML =
|
|
619
|
+
o.className = "tcw-sidebar-btn tcw-danger", o.title = "Clear all", o.innerHTML = _("trash", 14), o.addEventListener("click", t.onClearDrawings), n.appendChild(o);
|
|
616
620
|
}
|
|
617
621
|
showFlyout(e) {
|
|
618
622
|
let t = this.config.drawingToolGroups[e];
|
|
@@ -652,11 +656,11 @@ var _ = class {
|
|
|
652
656
|
destroy() {
|
|
653
657
|
this.hideFlyout(), this.el.remove();
|
|
654
658
|
}
|
|
655
|
-
},
|
|
659
|
+
}, S = [
|
|
656
660
|
"style",
|
|
657
661
|
"display",
|
|
658
662
|
"scale"
|
|
659
|
-
],
|
|
663
|
+
], C = class {
|
|
660
664
|
callbacks;
|
|
661
665
|
backdrop = null;
|
|
662
666
|
modal = null;
|
|
@@ -682,12 +686,12 @@ var _ = class {
|
|
|
682
686
|
let t = document.createElement("h3");
|
|
683
687
|
t.textContent = "Chart Settings", e.appendChild(t);
|
|
684
688
|
let n = document.createElement("button");
|
|
685
|
-
n.className = "tcw-modal-close", n.innerHTML =
|
|
689
|
+
n.className = "tcw-modal-close", n.innerHTML = _("x", 16), n.addEventListener("click", () => {
|
|
686
690
|
this.callbacks.onClose(), this.close();
|
|
687
691
|
}), e.appendChild(n), this.modal.appendChild(e);
|
|
688
692
|
let r = document.createElement("div");
|
|
689
693
|
r.className = "tcw-modal-tabs", this.tabButtons = [];
|
|
690
|
-
for (let e of
|
|
694
|
+
for (let e of S) {
|
|
691
695
|
let t = document.createElement("button");
|
|
692
696
|
t.className = "tcw-modal-tab", t.textContent = e, t.dataset.tab = e, e === this.currentTab && t.classList.add("tcw-active"), t.addEventListener("click", () => {
|
|
693
697
|
this.currentTab = e, this.tabButtons.forEach((t) => t.classList.toggle("tcw-active", t.dataset.tab === e)), this.renderTabContent();
|
|
@@ -730,7 +734,7 @@ var _ = class {
|
|
|
730
734
|
renderDisplayTab() {
|
|
731
735
|
if (!this.bodyEl || !this.currentSettings) return;
|
|
732
736
|
let e = this.currentSettings, t = this.section();
|
|
733
|
-
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, [
|
|
737
|
+
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, [
|
|
734
738
|
{
|
|
735
739
|
label: "Magnet",
|
|
736
740
|
value: "magnet"
|
|
@@ -827,7 +831,7 @@ var _ = class {
|
|
|
827
831
|
destroy() {
|
|
828
832
|
this.close();
|
|
829
833
|
}
|
|
830
|
-
},
|
|
834
|
+
}, w = class {
|
|
831
835
|
el;
|
|
832
836
|
dotEl;
|
|
833
837
|
messageEl;
|
|
@@ -843,7 +847,7 @@ var _ = class {
|
|
|
843
847
|
destroy() {
|
|
844
848
|
this.el.remove();
|
|
845
849
|
}
|
|
846
|
-
},
|
|
850
|
+
}, T = class {
|
|
847
851
|
backdrop = null;
|
|
848
852
|
modal = null;
|
|
849
853
|
input = null;
|
|
@@ -968,7 +972,470 @@ var _ = class {
|
|
|
968
972
|
destroy() {
|
|
969
973
|
this.close();
|
|
970
974
|
}
|
|
971
|
-
},
|
|
975
|
+
}, E = class {
|
|
976
|
+
backdrop = null;
|
|
977
|
+
modal = null;
|
|
978
|
+
input = null;
|
|
979
|
+
list = null;
|
|
980
|
+
symbols = [];
|
|
981
|
+
current = "";
|
|
982
|
+
filtered = [];
|
|
983
|
+
selectedIndex = 0;
|
|
984
|
+
callbacks;
|
|
985
|
+
boundKeydown;
|
|
986
|
+
constructor(e) {
|
|
987
|
+
this.callbacks = e, this.boundKeydown = this.handleKeydown.bind(this);
|
|
988
|
+
}
|
|
989
|
+
open(e, t) {
|
|
990
|
+
if (this.backdrop) return;
|
|
991
|
+
this.symbols = e, this.current = t, this.filtered = e.map((e) => ({
|
|
992
|
+
symbol: e,
|
|
993
|
+
score: 0
|
|
994
|
+
})), 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";
|
|
995
|
+
let n = document.createElement("div");
|
|
996
|
+
n.className = "tcw-cmd-header";
|
|
997
|
+
let r = document.createElement("span");
|
|
998
|
+
r.className = "tcw-cmd-icon", r.innerHTML = A(), 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);
|
|
999
|
+
let i = document.createElement("span");
|
|
1000
|
+
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);
|
|
1001
|
+
let a = document.createElement("div");
|
|
1002
|
+
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);
|
|
1003
|
+
}
|
|
1004
|
+
close() {
|
|
1005
|
+
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();
|
|
1006
|
+
}
|
|
1007
|
+
isOpen() {
|
|
1008
|
+
return this.backdrop !== null;
|
|
1009
|
+
}
|
|
1010
|
+
destroy() {
|
|
1011
|
+
this.close();
|
|
1012
|
+
}
|
|
1013
|
+
filter() {
|
|
1014
|
+
let e = (this.input?.value ?? "").toUpperCase().trim();
|
|
1015
|
+
e ? this.filtered = this.symbols.map((t) => ({
|
|
1016
|
+
symbol: t,
|
|
1017
|
+
score: D(t.toUpperCase(), e)
|
|
1018
|
+
})).filter((e) => e.score > 0).sort((e, t) => t.score - e.score) : this.filtered = this.symbols.map((e) => ({
|
|
1019
|
+
symbol: e,
|
|
1020
|
+
score: 0
|
|
1021
|
+
})), this.selectedIndex = 0, this.renderList();
|
|
1022
|
+
}
|
|
1023
|
+
renderList() {
|
|
1024
|
+
if (!this.list) return;
|
|
1025
|
+
if (this.list.innerHTML = "", this.filtered.length === 0) {
|
|
1026
|
+
let e = document.createElement("div");
|
|
1027
|
+
e.className = "tcw-cmd-empty", e.textContent = "No symbols match", this.list.appendChild(e);
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
let e = (this.input?.value ?? "").toUpperCase().trim();
|
|
1031
|
+
for (let t = 0; t < this.filtered.length; t++) {
|
|
1032
|
+
let { symbol: n } = this.filtered[t], r = document.createElement("button");
|
|
1033
|
+
r.className = "tcw-cmd-item", t === this.selectedIndex && r.classList.add("tcw-selected"), n === this.current && r.classList.add("tcw-active");
|
|
1034
|
+
let i = document.createElement("span");
|
|
1035
|
+
if (i.className = "tcw-cmd-item-label", i.innerHTML = O(n, e), r.appendChild(i), n === this.current) {
|
|
1036
|
+
let e = document.createElement("span");
|
|
1037
|
+
e.className = "tcw-cmd-check", e.textContent = "✓", r.appendChild(e);
|
|
1038
|
+
}
|
|
1039
|
+
r.addEventListener("click", () => this.pick(t)), r.addEventListener("mouseenter", () => {
|
|
1040
|
+
this.selectedIndex = t, this.updateSelection();
|
|
1041
|
+
}), this.list.appendChild(r);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
updateSelection() {
|
|
1045
|
+
if (!this.list) return;
|
|
1046
|
+
let e = this.list.querySelectorAll(".tcw-cmd-item");
|
|
1047
|
+
e.forEach((e, t) => e.classList.toggle("tcw-selected", t === this.selectedIndex)), e[this.selectedIndex]?.scrollIntoView({ block: "nearest" });
|
|
1048
|
+
}
|
|
1049
|
+
pick(e) {
|
|
1050
|
+
let t = this.filtered[e];
|
|
1051
|
+
t && (this.callbacks.onPick(t.symbol), this.close());
|
|
1052
|
+
}
|
|
1053
|
+
handleKeydown(e) {
|
|
1054
|
+
switch (e.key) {
|
|
1055
|
+
case "Escape":
|
|
1056
|
+
e.preventDefault(), this.close();
|
|
1057
|
+
break;
|
|
1058
|
+
case "ArrowDown":
|
|
1059
|
+
e.preventDefault(), this.filtered.length > 0 && (this.selectedIndex = (this.selectedIndex + 1) % this.filtered.length, this.updateSelection());
|
|
1060
|
+
break;
|
|
1061
|
+
case "ArrowUp":
|
|
1062
|
+
e.preventDefault(), this.filtered.length > 0 && (this.selectedIndex = (this.selectedIndex - 1 + this.filtered.length) % this.filtered.length, this.updateSelection());
|
|
1063
|
+
break;
|
|
1064
|
+
case "Enter":
|
|
1065
|
+
e.preventDefault(), this.pick(this.selectedIndex);
|
|
1066
|
+
break;
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
};
|
|
1070
|
+
function D(e, t) {
|
|
1071
|
+
if (e === t) return 1e3;
|
|
1072
|
+
if (e.startsWith(t)) return 500 + (50 - Math.min(50, e.length - t.length));
|
|
1073
|
+
if (e.includes(t)) return 200 + (50 - Math.min(50, e.length - t.length));
|
|
1074
|
+
let n = 0, r = -1, i = 0;
|
|
1075
|
+
for (let a = 0; a < e.length && n < t.length; a++) e[a] === t[n] && (r >= 0 && (i += a - r - 1), r = a, n++);
|
|
1076
|
+
return n < t.length ? 0 : 100 - Math.min(99, i);
|
|
1077
|
+
}
|
|
1078
|
+
function O(e, t) {
|
|
1079
|
+
if (!t) return k(e);
|
|
1080
|
+
let n = e.toUpperCase(), r = "", i = 0;
|
|
1081
|
+
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">${k(e[a])}</mark>`, i++) : r += k(e[a]);
|
|
1082
|
+
return r;
|
|
1083
|
+
}
|
|
1084
|
+
function k(e) {
|
|
1085
|
+
return e.replace(/[&<>"']/g, (e) => ({
|
|
1086
|
+
"&": "&",
|
|
1087
|
+
"<": "<",
|
|
1088
|
+
">": ">",
|
|
1089
|
+
"\"": """,
|
|
1090
|
+
"'": "'"
|
|
1091
|
+
})[e]);
|
|
1092
|
+
}
|
|
1093
|
+
function A() {
|
|
1094
|
+
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>";
|
|
1095
|
+
}
|
|
1096
|
+
//#endregion
|
|
1097
|
+
//#region src/widget/WidgetHotkeySheet.ts
|
|
1098
|
+
var j = typeof navigator < "u" && /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent) ? "⌘" : "Ctrl", M = [
|
|
1099
|
+
{
|
|
1100
|
+
title: "Search & navigation",
|
|
1101
|
+
entries: [
|
|
1102
|
+
{
|
|
1103
|
+
keys: [j, "K"],
|
|
1104
|
+
label: "Command palette"
|
|
1105
|
+
},
|
|
1106
|
+
{
|
|
1107
|
+
keys: [j, "P"],
|
|
1108
|
+
label: "Symbol search"
|
|
1109
|
+
},
|
|
1110
|
+
{
|
|
1111
|
+
keys: ["?"],
|
|
1112
|
+
label: "Show this sheet"
|
|
1113
|
+
}
|
|
1114
|
+
]
|
|
1115
|
+
},
|
|
1116
|
+
{
|
|
1117
|
+
title: "Chart manipulation",
|
|
1118
|
+
entries: [
|
|
1119
|
+
{
|
|
1120
|
+
keys: ["Shift", "Drag"],
|
|
1121
|
+
label: "Measure tool (bars × price Δ)"
|
|
1122
|
+
},
|
|
1123
|
+
{
|
|
1124
|
+
keys: ["Drag", "Price axis"],
|
|
1125
|
+
label: "Compress / expand vertical scale"
|
|
1126
|
+
},
|
|
1127
|
+
{
|
|
1128
|
+
keys: ["Drag", "Time axis"],
|
|
1129
|
+
label: "Zoom time axis"
|
|
1130
|
+
},
|
|
1131
|
+
{
|
|
1132
|
+
keys: ["Double-click", "Price axis"],
|
|
1133
|
+
label: "Re-enable auto-scale"
|
|
1134
|
+
},
|
|
1135
|
+
{
|
|
1136
|
+
keys: ["Double-click", "Time axis"],
|
|
1137
|
+
label: "Fit content"
|
|
1138
|
+
},
|
|
1139
|
+
{
|
|
1140
|
+
keys: ["Scroll"],
|
|
1141
|
+
label: "Zoom around cursor"
|
|
1142
|
+
}
|
|
1143
|
+
]
|
|
1144
|
+
},
|
|
1145
|
+
{
|
|
1146
|
+
title: "Keyboard",
|
|
1147
|
+
entries: [
|
|
1148
|
+
{
|
|
1149
|
+
keys: ["←", "→"],
|
|
1150
|
+
label: "Pan one bar"
|
|
1151
|
+
},
|
|
1152
|
+
{
|
|
1153
|
+
keys: ["+", "−"],
|
|
1154
|
+
label: "Zoom in / out"
|
|
1155
|
+
},
|
|
1156
|
+
{
|
|
1157
|
+
keys: ["Home"],
|
|
1158
|
+
label: "Scroll to start"
|
|
1159
|
+
},
|
|
1160
|
+
{
|
|
1161
|
+
keys: ["End"],
|
|
1162
|
+
label: "Scroll to end (live edge)"
|
|
1163
|
+
},
|
|
1164
|
+
{
|
|
1165
|
+
keys: ["F"],
|
|
1166
|
+
label: "Fit content"
|
|
1167
|
+
}
|
|
1168
|
+
]
|
|
1169
|
+
},
|
|
1170
|
+
{
|
|
1171
|
+
title: "Drawing",
|
|
1172
|
+
entries: [
|
|
1173
|
+
{
|
|
1174
|
+
keys: [j, "Z"],
|
|
1175
|
+
label: "Undo"
|
|
1176
|
+
},
|
|
1177
|
+
{
|
|
1178
|
+
keys: [
|
|
1179
|
+
j,
|
|
1180
|
+
"Shift",
|
|
1181
|
+
"Z"
|
|
1182
|
+
],
|
|
1183
|
+
label: "Redo"
|
|
1184
|
+
},
|
|
1185
|
+
{
|
|
1186
|
+
keys: ["Esc"],
|
|
1187
|
+
label: "Cancel active drawing"
|
|
1188
|
+
}
|
|
1189
|
+
]
|
|
1190
|
+
}
|
|
1191
|
+
], N = class {
|
|
1192
|
+
backdrop = null;
|
|
1193
|
+
modal = null;
|
|
1194
|
+
callbacks;
|
|
1195
|
+
boundKeydown;
|
|
1196
|
+
constructor(e) {
|
|
1197
|
+
this.callbacks = e, this.boundKeydown = (e) => {
|
|
1198
|
+
e.key === "Escape" && (e.preventDefault(), this.close());
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
open() {
|
|
1202
|
+
if (this.backdrop) return;
|
|
1203
|
+
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";
|
|
1204
|
+
let e = document.createElement("div");
|
|
1205
|
+
e.className = "tcw-modal-header", e.innerHTML = "<h3>Keyboard shortcuts</h3>";
|
|
1206
|
+
let t = document.createElement("button");
|
|
1207
|
+
t.className = "tcw-modal-close", t.setAttribute("aria-label", "Close"), t.innerHTML = "×", t.addEventListener("click", () => this.close()), e.appendChild(t), this.modal.appendChild(e);
|
|
1208
|
+
let n = document.createElement("div");
|
|
1209
|
+
n.className = "tcw-modal-body";
|
|
1210
|
+
let r = document.createElement("div");
|
|
1211
|
+
r.className = "tcw-hotkey-grid";
|
|
1212
|
+
for (let e of M) {
|
|
1213
|
+
let t = document.createElement("section");
|
|
1214
|
+
t.className = "tcw-hotkey-section";
|
|
1215
|
+
let n = document.createElement("div");
|
|
1216
|
+
n.className = "tcw-settings-section-title", n.textContent = e.title, t.appendChild(n);
|
|
1217
|
+
for (let n of e.entries) {
|
|
1218
|
+
let e = document.createElement("div");
|
|
1219
|
+
e.className = "tcw-hotkey-row";
|
|
1220
|
+
let r = document.createElement("div");
|
|
1221
|
+
r.className = "tcw-hotkey-keys";
|
|
1222
|
+
for (let e = 0; e < n.keys.length; e++) {
|
|
1223
|
+
if (e > 0) {
|
|
1224
|
+
let e = document.createElement("span");
|
|
1225
|
+
e.className = "tcw-hotkey-sep", e.textContent = "+", r.appendChild(e);
|
|
1226
|
+
}
|
|
1227
|
+
let t = document.createElement("kbd");
|
|
1228
|
+
t.className = "tcw-cmd-kbd", t.textContent = n.keys[e], r.appendChild(t);
|
|
1229
|
+
}
|
|
1230
|
+
e.appendChild(r);
|
|
1231
|
+
let i = document.createElement("span");
|
|
1232
|
+
i.className = "tcw-hotkey-label", i.textContent = n.label, e.appendChild(i), t.appendChild(e);
|
|
1233
|
+
}
|
|
1234
|
+
r.appendChild(t);
|
|
1235
|
+
}
|
|
1236
|
+
n.appendChild(r), this.modal.appendChild(n);
|
|
1237
|
+
let i = document.createElement("div");
|
|
1238
|
+
i.className = "tcw-modal-footer", i.innerHTML = "<span style=\"font-size:11px;color:var(--tcw-text-muted)\">Press ? anytime to show this sheet</span>";
|
|
1239
|
+
let a = document.createElement("button");
|
|
1240
|
+
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);
|
|
1241
|
+
}
|
|
1242
|
+
close() {
|
|
1243
|
+
document.removeEventListener("keydown", this.boundKeydown), this.backdrop?.remove(), this.modal?.remove(), this.backdrop = null, this.modal = null, this.callbacks.onClose();
|
|
1244
|
+
}
|
|
1245
|
+
isOpen() {
|
|
1246
|
+
return this.backdrop !== null;
|
|
1247
|
+
}
|
|
1248
|
+
destroy() {
|
|
1249
|
+
this.close();
|
|
1250
|
+
}
|
|
1251
|
+
}, P = [
|
|
1252
|
+
.5,
|
|
1253
|
+
1,
|
|
1254
|
+
2,
|
|
1255
|
+
5,
|
|
1256
|
+
10,
|
|
1257
|
+
20,
|
|
1258
|
+
50,
|
|
1259
|
+
100
|
|
1260
|
+
], F = class {
|
|
1261
|
+
root = null;
|
|
1262
|
+
scrubber = null;
|
|
1263
|
+
progressLabel = null;
|
|
1264
|
+
playBtn = null;
|
|
1265
|
+
state = "stopped";
|
|
1266
|
+
total = 0;
|
|
1267
|
+
speed = 5;
|
|
1268
|
+
callbacks;
|
|
1269
|
+
constructor(e) {
|
|
1270
|
+
this.callbacks = e;
|
|
1271
|
+
}
|
|
1272
|
+
mount(e, t) {
|
|
1273
|
+
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());
|
|
1274
|
+
}
|
|
1275
|
+
unmount() {
|
|
1276
|
+
this.root?.remove(), this.root = null, this.scrubber = null, this.progressLabel = null, this.playBtn = null, this.state = "stopped";
|
|
1277
|
+
}
|
|
1278
|
+
isMounted() {
|
|
1279
|
+
return this.root !== null;
|
|
1280
|
+
}
|
|
1281
|
+
setState(e) {
|
|
1282
|
+
this.state = e, this.syncUi();
|
|
1283
|
+
}
|
|
1284
|
+
setProgress(e, t) {
|
|
1285
|
+
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}`);
|
|
1286
|
+
}
|
|
1287
|
+
destroy() {
|
|
1288
|
+
this.unmount();
|
|
1289
|
+
}
|
|
1290
|
+
markup() {
|
|
1291
|
+
let e = P.map((e) => `<option value="${e}"${e === this.speed ? " selected" : ""}>${e}× bars/s</option>`).join("");
|
|
1292
|
+
return `
|
|
1293
|
+
<button class="tcw-replay-btn" data-act="close" title="Exit replay" aria-label="Exit replay">${B()}</button>
|
|
1294
|
+
<button class="tcw-replay-btn" data-act="stepBack" title="Step back" aria-label="Step back">${R()}</button>
|
|
1295
|
+
<button class="tcw-replay-btn tcw-replay-play" data-act="play" title="Play / pause" aria-label="Play / pause">${I()}</button>
|
|
1296
|
+
<button class="tcw-replay-btn" data-act="stepForward" title="Step forward" aria-label="Step forward">${z()}</button>
|
|
1297
|
+
<input type="range" class="tcw-replay-scrubber" data-act="seek" min="0" max="${Math.max(0, this.total - 1)}" value="0" step="1" />
|
|
1298
|
+
<span class="tcw-replay-progress" data-tcw="progress">1 / ${this.total}</span>
|
|
1299
|
+
<select class="tcw-replay-speed" data-act="speed">${e}</select>
|
|
1300
|
+
`;
|
|
1301
|
+
}
|
|
1302
|
+
wireEvents() {
|
|
1303
|
+
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", () => {
|
|
1304
|
+
this.state === "playing" ? this.callbacks.onPause() : this.callbacks.onPlay();
|
|
1305
|
+
}), this.scrubber?.addEventListener("input", () => {
|
|
1306
|
+
let e = Number(this.scrubber.value);
|
|
1307
|
+
this.callbacks.onSeek(e);
|
|
1308
|
+
}), this.root.querySelector("[data-act=\"speed\"]")?.addEventListener("change", (e) => {
|
|
1309
|
+
let t = Number(e.target.value);
|
|
1310
|
+
this.speed = t, this.callbacks.onSpeedChange(t);
|
|
1311
|
+
}));
|
|
1312
|
+
}
|
|
1313
|
+
syncUi() {
|
|
1314
|
+
this.playBtn && (this.playBtn.innerHTML = this.state === "playing" ? L() : I(), this.playBtn.title = this.state === "playing" ? "Pause" : "Play");
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
1317
|
+
function I() {
|
|
1318
|
+
return "<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7L8 5z\"/></svg>";
|
|
1319
|
+
}
|
|
1320
|
+
function L() {
|
|
1321
|
+
return "<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M6 5h4v14H6zM14 5h4v14h-4z\"/></svg>";
|
|
1322
|
+
}
|
|
1323
|
+
function R() {
|
|
1324
|
+
return "<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M6 6h2v12H6zM20 6L9 12l11 6V6z\"/></svg>";
|
|
1325
|
+
}
|
|
1326
|
+
function z() {
|
|
1327
|
+
return "<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M4 6l11 6L4 18V6zM16 6h2v12h-2z\"/></svg>";
|
|
1328
|
+
}
|
|
1329
|
+
function B() {
|
|
1330
|
+
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>";
|
|
1331
|
+
}
|
|
1332
|
+
//#endregion
|
|
1333
|
+
//#region src/widget/WidgetWatchlist.ts
|
|
1334
|
+
var V = class {
|
|
1335
|
+
el;
|
|
1336
|
+
listEl;
|
|
1337
|
+
rowMap = /* @__PURE__ */ new Map();
|
|
1338
|
+
entries = /* @__PURE__ */ new Map();
|
|
1339
|
+
active = null;
|
|
1340
|
+
callbacks;
|
|
1341
|
+
constructor(e, t, n) {
|
|
1342
|
+
this.callbacks = n, this.el = document.createElement("div"), this.el.className = "tcw-watchlist";
|
|
1343
|
+
let r = document.createElement("div");
|
|
1344
|
+
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);
|
|
1345
|
+
for (let e of t) this.entries.set(e, { symbol: e }), this.appendRow(e);
|
|
1346
|
+
e.appendChild(this.el);
|
|
1347
|
+
}
|
|
1348
|
+
setSymbols(e) {
|
|
1349
|
+
let t = new Set(e);
|
|
1350
|
+
for (let e of this.rowMap.keys()) t.has(e) || this.removeRow(e);
|
|
1351
|
+
for (let t of e) this.rowMap.has(t) || (this.entries.set(t, this.entries.get(t) ?? { symbol: t }), this.appendRow(t));
|
|
1352
|
+
}
|
|
1353
|
+
setActive(e) {
|
|
1354
|
+
if (this.active === e) return;
|
|
1355
|
+
this.active && this.rowMap.has(this.active) && this.rowMap.get(this.active).row.classList.remove("tcw-watchlist-active"), this.active = e;
|
|
1356
|
+
let t = this.rowMap.get(e);
|
|
1357
|
+
t && t.row.classList.add("tcw-watchlist-active");
|
|
1358
|
+
}
|
|
1359
|
+
setEntry(e, t) {
|
|
1360
|
+
let n = {
|
|
1361
|
+
...this.entries.get(e) ?? { symbol: e },
|
|
1362
|
+
...t
|
|
1363
|
+
};
|
|
1364
|
+
this.entries.set(e, n), this.renderRow(e);
|
|
1365
|
+
}
|
|
1366
|
+
destroy() {
|
|
1367
|
+
this.el.remove(), this.rowMap.clear(), this.entries.clear();
|
|
1368
|
+
}
|
|
1369
|
+
appendRow(e) {
|
|
1370
|
+
let t = document.createElement("div");
|
|
1371
|
+
t.className = "tcw-watchlist-row", t.tabIndex = 0;
|
|
1372
|
+
let n = document.createElement("div");
|
|
1373
|
+
n.className = "tcw-watchlist-symbol", n.textContent = H(e);
|
|
1374
|
+
let r = document.createElement("canvas");
|
|
1375
|
+
r.className = "tcw-watchlist-spark", r.width = 64, r.height = 22;
|
|
1376
|
+
let i = document.createElement("div");
|
|
1377
|
+
i.className = "tcw-watchlist-stats";
|
|
1378
|
+
let a = document.createElement("span");
|
|
1379
|
+
a.className = "tcw-watchlist-price", a.textContent = "—";
|
|
1380
|
+
let o = document.createElement("span");
|
|
1381
|
+
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) => {
|
|
1382
|
+
(t.key === "Enter" || t.key === " ") && (t.preventDefault(), this.callbacks.onSelect(e));
|
|
1383
|
+
}), this.listEl.appendChild(t), this.rowMap.set(e, {
|
|
1384
|
+
row: t,
|
|
1385
|
+
priceEl: a,
|
|
1386
|
+
changeEl: o,
|
|
1387
|
+
sparkCanvas: r
|
|
1388
|
+
}), e === this.active && t.classList.add("tcw-watchlist-active");
|
|
1389
|
+
}
|
|
1390
|
+
removeRow(e) {
|
|
1391
|
+
let t = this.rowMap.get(e);
|
|
1392
|
+
t && (t.row.remove(), this.rowMap.delete(e));
|
|
1393
|
+
}
|
|
1394
|
+
renderRow(e) {
|
|
1395
|
+
let t = this.rowMap.get(e), n = this.entries.get(e);
|
|
1396
|
+
if (!(!t || !n)) {
|
|
1397
|
+
if (n.lastPrice !== void 0 && (t.priceEl.textContent = U(n.lastPrice)), n.lastPrice !== void 0 && n.refPrice !== void 0 && n.refPrice !== 0) {
|
|
1398
|
+
let e = n.lastPrice - n.refPrice, r = e / n.refPrice * 100, i = e >= 0 ? "+" : "";
|
|
1399
|
+
t.changeEl.textContent = `${i}${r.toFixed(2)}%`, t.changeEl.className = `tcw-watchlist-change ${e >= 0 ? "tcw-up" : "tcw-down"}`;
|
|
1400
|
+
} else t.changeEl.textContent = "";
|
|
1401
|
+
n.sparkline && n.sparkline.length >= 2 && W(t.sparkCanvas, n.sparkline, n.refPrice ?? n.sparkline[0]);
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
};
|
|
1405
|
+
function H(e) {
|
|
1406
|
+
for (let t of [
|
|
1407
|
+
"USDT",
|
|
1408
|
+
"USD",
|
|
1409
|
+
"BTC",
|
|
1410
|
+
"ETH",
|
|
1411
|
+
"EUR"
|
|
1412
|
+
]) if (e.length > t.length && e.endsWith(t)) return e.slice(0, -t.length) + "/" + t;
|
|
1413
|
+
return e;
|
|
1414
|
+
}
|
|
1415
|
+
function U(e) {
|
|
1416
|
+
if (e === 0) return "0";
|
|
1417
|
+
let t = Math.abs(e);
|
|
1418
|
+
return t >= 1e3 ? e.toFixed(2) : t >= 1 ? e.toFixed(4) : e.toPrecision(4);
|
|
1419
|
+
}
|
|
1420
|
+
function W(e, t, n) {
|
|
1421
|
+
let r = e.getContext("2d");
|
|
1422
|
+
if (!r) return;
|
|
1423
|
+
let i = window.devicePixelRatio || 1;
|
|
1424
|
+
e.width !== e.clientWidth * i && (e.width = (e.clientWidth || 64) * i, e.height = (e.clientHeight || 22) * i);
|
|
1425
|
+
let a = e.width, o = e.height, s = Infinity, c = -Infinity;
|
|
1426
|
+
for (let e of t) e < s && (s = e), e > c && (c = e);
|
|
1427
|
+
let l = Math.max(c - s, 1e-9), u = t[t.length - 1] >= n ? "#26a17b" : "#f23645";
|
|
1428
|
+
r.clearRect(0, 0, a, o), r.lineWidth = 1.4 * i, r.strokeStyle = u, r.beginPath();
|
|
1429
|
+
let d = a / (t.length - 1);
|
|
1430
|
+
for (let e = 0; e < t.length; e++) {
|
|
1431
|
+
let n = e * d, i = o - (t[e] - s) / l * (o - 4) - 2;
|
|
1432
|
+
e === 0 ? r.moveTo(n, i) : r.lineTo(n, i);
|
|
1433
|
+
}
|
|
1434
|
+
r.stroke();
|
|
1435
|
+
}
|
|
1436
|
+
//#endregion
|
|
1437
|
+
//#region src/widget/ChartWidget.ts
|
|
1438
|
+
var G = class {
|
|
972
1439
|
chart;
|
|
973
1440
|
state;
|
|
974
1441
|
toolbar = null;
|
|
@@ -976,36 +1443,50 @@ var _ = class {
|
|
|
976
1443
|
settings = null;
|
|
977
1444
|
statusBar = null;
|
|
978
1445
|
commandPalette = null;
|
|
1446
|
+
symbolSearch = null;
|
|
1447
|
+
hotkeySheet = null;
|
|
1448
|
+
replayBar = null;
|
|
1449
|
+
dragDrop = null;
|
|
1450
|
+
watchlist = null;
|
|
1451
|
+
watchlistSparkBuffer = /* @__PURE__ */ new Map();
|
|
1452
|
+
sessionRefPrice = null;
|
|
1453
|
+
watchlistInterval = null;
|
|
1454
|
+
replayOriginalData = null;
|
|
1455
|
+
replayPollInterval = null;
|
|
1456
|
+
replaySpeed = 5;
|
|
1457
|
+
layoutKeyPrefix = null;
|
|
1458
|
+
layoutDebounceMs = 1500;
|
|
1459
|
+
activeLayoutKey = null;
|
|
979
1460
|
root;
|
|
980
1461
|
chartContainer;
|
|
981
1462
|
destroyed = !1;
|
|
982
1463
|
options;
|
|
983
|
-
symbolIndex = 0;
|
|
984
1464
|
symbols;
|
|
985
1465
|
settingsState;
|
|
986
1466
|
adapter = null;
|
|
987
1467
|
boundGlobalKeydown = null;
|
|
988
|
-
constructor(
|
|
989
|
-
this.options =
|
|
990
|
-
|
|
1468
|
+
constructor(n, r = {}) {
|
|
1469
|
+
if (this.options = r, this.symbols = r.symbols ?? l, this.settingsState = { ...u }, r.persistLayouts) {
|
|
1470
|
+
let e = r.persistLayouts === !0 ? {} : r.persistLayouts;
|
|
1471
|
+
this.layoutKeyPrefix = e.keyPrefix ?? "tcw:layout:", this.layoutDebounceMs = e.debounceMs ?? 1500;
|
|
1472
|
+
}
|
|
1473
|
+
let d = this.resolveIsDark(r.theme), f = this.resolveTheme(r.theme);
|
|
991
1474
|
this.state = {
|
|
992
|
-
symbol:
|
|
993
|
-
timeframe:
|
|
994
|
-
chartType:
|
|
995
|
-
isDark:
|
|
1475
|
+
symbol: r.symbol ?? this.symbols[0] ?? "BTCUSDT",
|
|
1476
|
+
timeframe: r.timeframe ?? "5m",
|
|
1477
|
+
chartType: r.chartOptions?.chartType ?? "candlestick",
|
|
1478
|
+
isDark: d,
|
|
996
1479
|
activeIndicators: /* @__PURE__ */ new Map(),
|
|
997
1480
|
activeTool: null,
|
|
998
1481
|
magnetEnabled: !0,
|
|
999
1482
|
connectionState: "connecting",
|
|
1000
1483
|
connectionMessage: "Connecting..."
|
|
1001
|
-
}
|
|
1002
|
-
let f = this.symbols.indexOf(this.state.symbol);
|
|
1003
|
-
f >= 0 && (this.symbolIndex = f), p(), this.root = document.createElement("div"), this.root.className = "tcw-root", this.root.dataset.tcwTheme = u ? "dark" : "light", t.appendChild(this.root), n.toolbar !== !1 && (this.toolbar = new v(this.root, {
|
|
1484
|
+
}, m(), this.root = document.createElement("div"), this.root.className = "tcw-root", this.root.dataset.tcwTheme = d ? "dark" : "light", n.appendChild(this.root), r.toolbar !== !1 && (this.toolbar = new y(this.root, {
|
|
1004
1485
|
symbols: this.symbols,
|
|
1005
|
-
timeframes:
|
|
1006
|
-
chartTypes:
|
|
1007
|
-
indicators:
|
|
1008
|
-
popularIndicatorIds:
|
|
1486
|
+
timeframes: r.timeframes ? i.filter((e) => r.timeframes.includes(e.value)) : i,
|
|
1487
|
+
chartTypes: r.chartTypes ? a.filter((e) => r.chartTypes.includes(e.value)) : a,
|
|
1488
|
+
indicators: s,
|
|
1489
|
+
popularIndicatorIds: c
|
|
1009
1490
|
}, {
|
|
1010
1491
|
onSymbolClick: () => this.handleSymbolClick(),
|
|
1011
1492
|
onTimeframe: (e) => this.handleTimeframe(e),
|
|
@@ -1014,10 +1495,11 @@ var _ = class {
|
|
|
1014
1495
|
onRemoveIndicator: (e) => this.handleRemoveIndicator(e),
|
|
1015
1496
|
onScreenshot: () => this.chart.screenshot(),
|
|
1016
1497
|
onSettings: () => this.openSettings(),
|
|
1017
|
-
onToggleTheme: () => this.handleToggleTheme()
|
|
1498
|
+
onToggleTheme: () => this.handleToggleTheme(),
|
|
1499
|
+
onToggleReplay: () => this.toggleReplay()
|
|
1018
1500
|
}));
|
|
1019
|
-
let
|
|
1020
|
-
|
|
1501
|
+
let p = document.createElement("div");
|
|
1502
|
+
p.className = "tcw-body", r.drawingTools !== !1 && (this.sidebar = new x(p, { drawingToolGroups: o }, {
|
|
1021
1503
|
onDrawingTool: (e) => this.handleDrawingTool(e),
|
|
1022
1504
|
onCancelDrawing: () => this.handleCancelDrawing(),
|
|
1023
1505
|
onToggleMagnet: () => this.handleToggleMagnet(),
|
|
@@ -1029,9 +1511,11 @@ var _ = class {
|
|
|
1029
1511
|
activeTool: null
|
|
1030
1512
|
}, this.updateUI();
|
|
1031
1513
|
}
|
|
1032
|
-
})), this.chartContainer = document.createElement("div"), this.chartContainer.className = "tcw-chart-container",
|
|
1514
|
+
})), this.chartContainer = document.createElement("div"), this.chartContainer.className = "tcw-chart-container", p.appendChild(this.chartContainer), r.watchlist && (this.watchlist = new V(p, this.symbols, { onSelect: (e) => {
|
|
1515
|
+
this.setSymbol(e);
|
|
1516
|
+
} }), this.watchlist.setActive(this.state.symbol)), this.root.appendChild(p), this.chart = new e(this.chartContainer, {
|
|
1033
1517
|
chartType: this.state.chartType,
|
|
1034
|
-
theme:
|
|
1518
|
+
theme: f,
|
|
1035
1519
|
autoScale: !0,
|
|
1036
1520
|
crosshair: { mode: "magnet" },
|
|
1037
1521
|
features: {
|
|
@@ -1039,8 +1523,8 @@ var _ = class {
|
|
|
1039
1523
|
drawingMagnet: !0,
|
|
1040
1524
|
drawingUndoRedo: !0,
|
|
1041
1525
|
indicators: !0,
|
|
1042
|
-
trading:
|
|
1043
|
-
tradingContextMenu:
|
|
1526
|
+
trading: r.trading !== !1,
|
|
1527
|
+
tradingContextMenu: r.trading !== !1,
|
|
1044
1528
|
volume: !0,
|
|
1045
1529
|
legend: !0,
|
|
1046
1530
|
crosshair: !0,
|
|
@@ -1051,12 +1535,24 @@ var _ = class {
|
|
|
1051
1535
|
logScale: !0,
|
|
1052
1536
|
watermark: !0
|
|
1053
1537
|
},
|
|
1054
|
-
...
|
|
1055
|
-
}),
|
|
1538
|
+
...r.chartOptions
|
|
1539
|
+
}), r.dragDropImport !== !1 && (this.dragDrop = new t(this.chartContainer, {
|
|
1540
|
+
onData: (e, t, n) => {
|
|
1541
|
+
this.chart.setData(e), this.toast(`Loaded ${t.data.length} bars from ${n.name}` + (t.skipped > 0 ? ` (${t.skipped} skipped)` : ""));
|
|
1542
|
+
},
|
|
1543
|
+
onError: (e, t) => {
|
|
1544
|
+
this.toast(`${t.name}: ${e.message}`, "error");
|
|
1545
|
+
}
|
|
1546
|
+
}), this.dragDrop.attach()), r.statusBar !== !1 && (this.statusBar = new w(this.root)), r.settings !== !1 && (this.settings = new C({
|
|
1056
1547
|
onChange: (e) => this.applySettings(e),
|
|
1057
1548
|
onReset: () => this.resetSettings(),
|
|
1058
1549
|
onClose: () => {}
|
|
1059
|
-
})), this.
|
|
1550
|
+
})), this.symbolSearch = new E({
|
|
1551
|
+
onPick: (e) => {
|
|
1552
|
+
this.setSymbol(e);
|
|
1553
|
+
},
|
|
1554
|
+
onClose: () => {}
|
|
1555
|
+
}), this.hotkeySheet = new N({ onClose: () => {} }), this.commandPalette = new T({
|
|
1060
1556
|
onIndicator: (e) => this.handleAddIndicator(e),
|
|
1061
1557
|
onChartType: (e) => this.handleChartType(e),
|
|
1062
1558
|
onDrawingTool: (e) => this.handleDrawingTool(e),
|
|
@@ -1064,16 +1560,39 @@ var _ = class {
|
|
|
1064
1560
|
onAction: (e) => this.handleAction(e),
|
|
1065
1561
|
onClose: () => {}
|
|
1066
1562
|
}), this.boundGlobalKeydown = (e) => {
|
|
1067
|
-
(e.ctrlKey || e.metaKey) && e.key === "k"
|
|
1068
|
-
|
|
1563
|
+
if ((e.ctrlKey || e.metaKey) && e.key === "k") e.preventDefault(), this.toggleCommandPalette();
|
|
1564
|
+
else if ((e.ctrlKey || e.metaKey) && (e.key === "p" || e.key === "P")) e.preventDefault(), this.symbolSearch?.open(this.symbols, this.state.symbol);
|
|
1565
|
+
else if (e.key === "?" && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
1566
|
+
let t = document.activeElement;
|
|
1567
|
+
if (t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable)) return;
|
|
1568
|
+
e.preventDefault(), this.hotkeySheet?.open();
|
|
1569
|
+
}
|
|
1570
|
+
}, document.addEventListener("keydown", this.boundGlobalKeydown), r.adapter && (this.adapter = r.adapter, this.connectStream()), this.watchlist && (this.watchlistInterval = setInterval(() => this.tickWatchlist(), 1e3)), this.updateUI(), r.onReady?.(this.chart);
|
|
1571
|
+
}
|
|
1572
|
+
setSymbols(e) {
|
|
1573
|
+
this.symbols = e, this.watchlist?.setSymbols(e);
|
|
1069
1574
|
}
|
|
1070
1575
|
async setSymbol(e) {
|
|
1071
|
-
this.state = {
|
|
1576
|
+
this.flushActiveLayout(), this.state = {
|
|
1072
1577
|
...this.state,
|
|
1073
1578
|
symbol: e
|
|
1074
|
-
};
|
|
1075
|
-
|
|
1076
|
-
|
|
1579
|
+
}, this.sessionRefPrice = null, this.options.onSymbolChange?.(e), this.updateUI(), this.watchlist?.setActive(e), this.adapter && await this.connectStream();
|
|
1580
|
+
}
|
|
1581
|
+
setWatchlistEntry(e, t) {
|
|
1582
|
+
this.watchlist?.setEntry(e, t);
|
|
1583
|
+
}
|
|
1584
|
+
tickWatchlist() {
|
|
1585
|
+
if (!this.watchlist) return;
|
|
1586
|
+
let e = this.chart.getData();
|
|
1587
|
+
if (e.length === 0) return;
|
|
1588
|
+
let t = e[e.length - 1];
|
|
1589
|
+
this.sessionRefPrice === null && (this.sessionRefPrice = e[0].open);
|
|
1590
|
+
let n = this.watchlistSparkBuffer.get(this.state.symbol) ?? [];
|
|
1591
|
+
n.push(t.close), n.length > 40 && n.shift(), this.watchlistSparkBuffer.set(this.state.symbol, n), this.watchlist.setEntry(this.state.symbol, {
|
|
1592
|
+
lastPrice: t.close,
|
|
1593
|
+
refPrice: this.sessionRefPrice,
|
|
1594
|
+
sparkline: n.slice()
|
|
1595
|
+
});
|
|
1077
1596
|
}
|
|
1078
1597
|
async setTimeframe(e) {
|
|
1079
1598
|
this.state = {
|
|
@@ -1092,15 +1611,10 @@ var _ = class {
|
|
|
1092
1611
|
return this.chart;
|
|
1093
1612
|
}
|
|
1094
1613
|
destroy() {
|
|
1095
|
-
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(),
|
|
1614
|
+
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(), h());
|
|
1096
1615
|
}
|
|
1097
1616
|
handleSymbolClick() {
|
|
1098
|
-
this.
|
|
1099
|
-
let e = this.symbols[this.symbolIndex];
|
|
1100
|
-
this.state = {
|
|
1101
|
-
...this.state,
|
|
1102
|
-
symbol: e
|
|
1103
|
-
}, this.options.onSymbolChange?.(e), this.updateUI(), this.adapter && this.connectStream();
|
|
1617
|
+
this.symbolSearch?.open(this.symbols, this.state.symbol);
|
|
1104
1618
|
}
|
|
1105
1619
|
handleTimeframe(e) {
|
|
1106
1620
|
this.state = {
|
|
@@ -1156,25 +1670,25 @@ var _ = class {
|
|
|
1156
1670
|
}
|
|
1157
1671
|
buildCommandItems() {
|
|
1158
1672
|
let e = [];
|
|
1159
|
-
for (let t of
|
|
1673
|
+
for (let t of s) e.push({
|
|
1160
1674
|
id: t.id,
|
|
1161
1675
|
label: t.name,
|
|
1162
1676
|
category: "indicator",
|
|
1163
1677
|
active: this.state.activeIndicators.has(t.id)
|
|
1164
1678
|
});
|
|
1165
|
-
for (let t of
|
|
1679
|
+
for (let t of a) e.push({
|
|
1166
1680
|
id: t.value,
|
|
1167
1681
|
label: t.label,
|
|
1168
1682
|
category: "chartType",
|
|
1169
1683
|
active: this.state.chartType === t.value
|
|
1170
1684
|
});
|
|
1171
|
-
for (let t of
|
|
1685
|
+
for (let t of o) for (let n of t.tools) e.push({
|
|
1172
1686
|
id: n.value,
|
|
1173
1687
|
label: n.label,
|
|
1174
1688
|
category: "drawing",
|
|
1175
1689
|
active: this.state.activeTool === n.value
|
|
1176
1690
|
});
|
|
1177
|
-
for (let t of
|
|
1691
|
+
for (let t of i) e.push({
|
|
1178
1692
|
id: t.value,
|
|
1179
1693
|
label: t.label,
|
|
1180
1694
|
category: "timeframe",
|
|
@@ -1242,7 +1756,7 @@ var _ = class {
|
|
|
1242
1756
|
this.state = {
|
|
1243
1757
|
...this.state,
|
|
1244
1758
|
isDark: e
|
|
1245
|
-
}, this.root.dataset.tcwTheme = e ? "dark" : "light", this.chart.setTheme(e ?
|
|
1759
|
+
}, this.root.dataset.tcwTheme = e ? "dark" : "light", this.chart.setTheme(e ? n : r), this.chart.setWatermark(this.state.symbol.replace("USDT", " / USDT"), {
|
|
1246
1760
|
fontSize: 48,
|
|
1247
1761
|
color: e ? "rgba(255,255,255,0.03)" : "rgba(0,0,0,0.03)"
|
|
1248
1762
|
}), this.updateUI();
|
|
@@ -1250,16 +1764,105 @@ var _ = class {
|
|
|
1250
1764
|
openSettings() {
|
|
1251
1765
|
this.settings?.open(this.settingsState);
|
|
1252
1766
|
}
|
|
1767
|
+
toast(e, t = "info") {
|
|
1768
|
+
let n = document.createElement("div");
|
|
1769
|
+
n.className = `tcw-toast ${t === "error" ? "tcw-toast-error" : ""}`, n.textContent = e, this.root.appendChild(n), requestAnimationFrame(() => n.classList.add("tcw-toast-in")), setTimeout(() => {
|
|
1770
|
+
n.classList.remove("tcw-toast-in"), n.addEventListener("transitionend", () => n.remove(), { once: !0 }), setTimeout(() => n.remove(), 400);
|
|
1771
|
+
}, 3500);
|
|
1772
|
+
}
|
|
1773
|
+
clearSavedLayout(e) {
|
|
1774
|
+
if (!this.layoutKeyPrefix) return;
|
|
1775
|
+
let t = e ?? this.state.symbol;
|
|
1776
|
+
try {
|
|
1777
|
+
localStorage.removeItem(this.layoutKeyPrefix + t);
|
|
1778
|
+
} catch {}
|
|
1779
|
+
}
|
|
1780
|
+
applySymbolLayout(e) {
|
|
1781
|
+
if (!this.layoutKeyPrefix) return;
|
|
1782
|
+
let t = this.layoutKeyPrefix + e;
|
|
1783
|
+
this.activeLayoutKey = t;
|
|
1784
|
+
try {
|
|
1785
|
+
this.chart.loadStateFromStorage(t) && this.rebuildActiveIndicatorsMapFromChart();
|
|
1786
|
+
} catch {}
|
|
1787
|
+
this.chart.setAutoSave(t, this.layoutDebounceMs);
|
|
1788
|
+
}
|
|
1789
|
+
flushActiveLayout() {
|
|
1790
|
+
if (this.activeLayoutKey) {
|
|
1791
|
+
try {
|
|
1792
|
+
this.chart.saveState(this.activeLayoutKey);
|
|
1793
|
+
} catch {}
|
|
1794
|
+
this.chart.disableAutoSave(), this.activeLayoutKey = null;
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
rebuildActiveIndicatorsMapFromChart() {
|
|
1798
|
+
let e = /* @__PURE__ */ new Map();
|
|
1799
|
+
for (let t of this.chart.getActiveIndicators()) e.set(t.id, t.instanceId);
|
|
1800
|
+
this.state = {
|
|
1801
|
+
...this.state,
|
|
1802
|
+
activeIndicators: e
|
|
1803
|
+
}, this.updateUI();
|
|
1804
|
+
}
|
|
1805
|
+
toggleReplay() {
|
|
1806
|
+
this.replayBar?.isMounted() ? this.exitReplay() : this.enterReplay();
|
|
1807
|
+
}
|
|
1808
|
+
enterReplay() {
|
|
1809
|
+
let e = this.chart.getData();
|
|
1810
|
+
e.length < 2 || (this.replayOriginalData = e.slice(), this.replayBar = new F({
|
|
1811
|
+
onPlay: () => {
|
|
1812
|
+
this.chart.getReplayState() === "paused" ? this.chart.replayResume() : this.chart.replay({
|
|
1813
|
+
speed: this.replaySpeed,
|
|
1814
|
+
interval: 200
|
|
1815
|
+
}), this.replayBar?.setState("playing");
|
|
1816
|
+
},
|
|
1817
|
+
onPause: () => {
|
|
1818
|
+
this.chart.replayPause(), this.replayBar?.setState("paused");
|
|
1819
|
+
},
|
|
1820
|
+
onStop: () => {
|
|
1821
|
+
this.chart.replayStop(), this.replayBar?.setState("paused");
|
|
1822
|
+
},
|
|
1823
|
+
onStepBack: () => {
|
|
1824
|
+
let e = this.chart.getReplayProgress();
|
|
1825
|
+
this.chart.getReplayState() === "playing" && this.chart.replayPause(), this.chart.replaySeek(Math.max(0, e.current - 1)), this.replayBar?.setState("paused");
|
|
1826
|
+
},
|
|
1827
|
+
onStepForward: () => {
|
|
1828
|
+
let e = this.chart.getReplayProgress();
|
|
1829
|
+
this.chart.getReplayState() === "playing" && this.chart.replayPause(), this.chart.replaySeek(Math.min(e.total - 1, e.current + 1)), this.replayBar?.setState("paused");
|
|
1830
|
+
},
|
|
1831
|
+
onSeek: (e) => {
|
|
1832
|
+
this.chart.getReplayState() === "playing" && this.chart.replayPause(), this.chart.replaySeek(e), this.replayBar?.setState("paused");
|
|
1833
|
+
},
|
|
1834
|
+
onSpeedChange: (e) => {
|
|
1835
|
+
this.replaySpeed = e, this.chart.setReplaySpeed(e);
|
|
1836
|
+
},
|
|
1837
|
+
onClose: () => this.exitReplay()
|
|
1838
|
+
}), this.replayBar.mount(this.chartContainer, {
|
|
1839
|
+
total: e.length,
|
|
1840
|
+
speed: this.replaySpeed
|
|
1841
|
+
}), this.chart.replay({
|
|
1842
|
+
speed: this.replaySpeed,
|
|
1843
|
+
interval: 200,
|
|
1844
|
+
startIndex: 1
|
|
1845
|
+
}), this.chart.replayPause(), this.replayBar.setState("paused"), this.replayPollInterval = setInterval(() => {
|
|
1846
|
+
if (!this.replayBar?.isMounted()) return;
|
|
1847
|
+
let e = this.chart.getReplayProgress();
|
|
1848
|
+
this.replayBar.setProgress(e.current, e.total);
|
|
1849
|
+
let t = this.chart.getReplayState();
|
|
1850
|
+
t === "stopped" ? this.replayBar.setState("paused") : this.replayBar.setState(t);
|
|
1851
|
+
}, 150));
|
|
1852
|
+
}
|
|
1853
|
+
exitReplay() {
|
|
1854
|
+
this.replayPollInterval &&= (clearInterval(this.replayPollInterval), null), this.chart.replayStop(), this.replayBar?.unmount(), this.replayBar = null, this.replayOriginalData &&= (this.chart.setData(this.replayOriginalData), null);
|
|
1855
|
+
}
|
|
1253
1856
|
applySettings(e) {
|
|
1254
1857
|
this.settingsState = {
|
|
1255
1858
|
...this.settingsState,
|
|
1256
1859
|
...e
|
|
1257
|
-
}, 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);
|
|
1860
|
+
}, 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);
|
|
1258
1861
|
let t = { ...this.chart.getTheme() }, n = !1;
|
|
1259
1862
|
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);
|
|
1260
1863
|
}
|
|
1261
1864
|
resetSettings() {
|
|
1262
|
-
this.settingsState = { ...
|
|
1865
|
+
this.settingsState = { ...u }, this.applySettings(this.settingsState);
|
|
1263
1866
|
}
|
|
1264
1867
|
async connectStream() {
|
|
1265
1868
|
if (this.adapter) {
|
|
@@ -1277,7 +1880,7 @@ var _ = class {
|
|
|
1277
1880
|
}), this.chart.setWatermark(this.state.symbol.replace("USDT", " / USDT"), {
|
|
1278
1881
|
fontSize: 48,
|
|
1279
1882
|
color: this.state.isDark ? "rgba(255,255,255,0.03)" : "rgba(0,0,0,0.03)"
|
|
1280
|
-
}), this.state = {
|
|
1883
|
+
}), this.applySymbolLayout(this.state.symbol), this.state = {
|
|
1281
1884
|
...this.state,
|
|
1282
1885
|
connectionState: "connected",
|
|
1283
1886
|
connectionMessage: "Live"
|
|
@@ -1304,7 +1907,7 @@ var _ = class {
|
|
|
1304
1907
|
return e === void 0 || e === "dark" ? !0 : e === "light" ? !1 : typeof e == "object" && e.background ? this.isColorDark(e.background) : !0;
|
|
1305
1908
|
}
|
|
1306
1909
|
resolveTheme(e) {
|
|
1307
|
-
return e === void 0 || e === "dark" ?
|
|
1910
|
+
return e === void 0 || e === "dark" ? n : e === "light" ? r : typeof e == "object" ? e : n;
|
|
1308
1911
|
}
|
|
1309
1912
|
isColorDark(e) {
|
|
1310
1913
|
if (e.startsWith("#") && e.length >= 7) {
|
|
@@ -1315,6 +1918,6 @@ var _ = class {
|
|
|
1315
1918
|
}
|
|
1316
1919
|
};
|
|
1317
1920
|
//#endregion
|
|
1318
|
-
export {
|
|
1921
|
+
export { G as ChartWidget };
|
|
1319
1922
|
|
|
1320
1923
|
//# sourceMappingURL=index.js.map
|