@luxalgo/vela 0.6.8 → 0.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DataProvider-BsQM2WNH.d.cts → DataProvider-8Z95Q-RJ.d.cts} +1 -1
- package/dist/{DataProvider-BSLlBpB9.d.ts → DataProvider-DExJrfut.d.ts} +1 -1
- package/dist/{chunk-2R7BANEM.js → chunk-62SVGONC.js} +2 -2
- package/dist/{chunk-SQETIBFU.js → chunk-6WDDVMBJ.js} +502 -139
- package/dist/{chunk-L3I2CCYO.js → chunk-EQCHJZOT.js} +49 -2
- package/dist/{chunk-OICPLNU7.js → chunk-FCVIG7JG.js} +188 -2
- package/dist/{chunk-N7LGMKCE.js → chunk-STHSKXOR.js} +107 -84
- package/dist/{chunk-PN5KWFZ4.js → chunk-WFSZBX3R.js} +2 -2
- package/dist/{contributions-Vw-Hm58R.d.cts → contributions-C1U2Krwg.d.cts} +99 -7
- package/dist/{contributions-DLLdV9jD.d.ts → contributions-D7PVZO2i.d.ts} +99 -7
- package/dist/index.cjs +709 -144
- package/dist/index.d.cts +12 -7
- package/dist/index.d.ts +12 -7
- package/dist/index.js +4 -4
- package/dist/{options-BaVTMXaO.d.ts → options-FM0peknS.d.cts} +84 -7
- package/dist/{options-BaVTMXaO.d.cts → options-FM0peknS.d.ts} +84 -7
- package/dist/{plugin-CC7rBrOY.d.ts → plugin-7bkF32Rk.d.ts} +3 -3
- package/dist/{plugin-BnJgjLAy.d.cts → plugin-DfVqBz9p.d.cts} +3 -3
- package/dist/plugin.cjs +18 -2
- package/dist/plugin.d.cts +4 -4
- package/dist/plugin.d.ts +4 -4
- package/dist/plugin.js +2 -2
- package/dist/providers/binance.d.cts +2 -2
- package/dist/providers/binance.d.ts +2 -2
- package/dist/providers/coinbase.d.cts +2 -2
- package/dist/providers/coinbase.d.ts +2 -2
- package/dist/providers/hyperliquid.d.cts +2 -2
- package/dist/providers/hyperliquid.d.ts +2 -2
- package/dist/{statusline-DqzBqy42.d.cts → statusline-DOPiT6I6.d.cts} +5 -3
- package/dist/{statusline-CGkB2EOo.d.ts → statusline-zdF4eZLr.d.ts} +5 -3
- package/dist/ui.cjs +201 -4
- package/dist/ui.d.cts +89 -2
- package/dist/ui.d.ts +89 -2
- package/dist/ui.js +3 -3
- package/dist/vela.global.js +709 -144
- package/dist/vela.global.min.js +93 -44
- package/dist/widget.cjs +798 -188
- package/dist/widget.d.cts +6 -6
- package/dist/widget.d.ts +6 -6
- package/dist/widget.js +7 -7
- package/dist/workspace.cjs +798 -188
- package/dist/workspace.d.cts +16 -6
- package/dist/workspace.d.ts +16 -6
- package/dist/workspace.js +6 -6
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, tzButtonLabel, TIMEZONES, normalizeTimezone, tzMenuLabel, Vela, TypedEventBus, MultiProviderFeed, registerBuiltinChartTypes, resolveTheme, buildToolbar, createCustomMark, createAttributionMark, DrawingToolbar, applyAttributionMarkTheme, sharedBarStore, timeframeToMs } from './chunk-
|
|
2
|
-
import { chartType, resolveTopbarComposition, topbarActionOverride, TOPBAR_BUILTIN_IDS, widgetActions, SidePanel, sidePanels, DEFAULT_PANEL_ORDER, symbolRanking, resolveEngines, legendActionsProviderFor, statePersistenceHandlers, topbarHas, rendererDefaults, widgetAttachments, getDrawingType } from './chunk-
|
|
3
|
-
import { Tooltip, KeymapManager, isEditableTarget, Drawer } from './chunk-
|
|
4
|
-
import { Menu, Dialog, applyPlotOverlayTokens, ensureUIHost } from './chunk-
|
|
5
|
-
import { registerIcon, svg16, injectStyles, iconEl, iconMarkup,
|
|
1
|
+
import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, tzButtonLabel, TIMEZONES, normalizeTimezone, tzMenuLabel, LEGEND_AT_TOP_ATTR, Vela, TypedEventBus, MultiProviderFeed, registerBuiltinChartTypes, resolveTheme, buildToolbar, createCustomMark, createAttributionMark, DrawingToolbar, applyAttributionMarkTheme, sharedBarStore, timeframeToMs } from './chunk-6WDDVMBJ.js';
|
|
2
|
+
import { chartType, resolveTopbarComposition, topbarActionOverride, TOPBAR_BUILTIN_IDS, widgetActions, SidePanel, sidePanels, DEFAULT_PANEL_ORDER, symbolRanking, resolveEngines, legendActionsProviderFor, legendCalloutsProviderFor, statePersistenceHandlers, topbarHas, rendererDefaults, widgetAttachments, getDrawingType } from './chunk-EQCHJZOT.js';
|
|
3
|
+
import { Tooltip, KeymapManager, isEditableTarget, Drawer } from './chunk-62SVGONC.js';
|
|
4
|
+
import { Menu, Dialog, CalloutBubble, applyPlotOverlayTokens, ensureUIHost } from './chunk-FCVIG7JG.js';
|
|
5
|
+
import { registerIcon, svg16, injectStyles, iconEl, iconMarkup, SESSION_OFF, SESSION_POST, SESSION_PRE, categoricalColor } from './chunk-WFSZBX3R.js';
|
|
6
6
|
import { baseOf } from './chunk-W4EJWLEO.js';
|
|
7
7
|
|
|
8
8
|
// src/widget/timeframe.ts
|
|
@@ -654,7 +654,7 @@ var Topbar = class {
|
|
|
654
654
|
this.leftActionsHost.className = "vela-widget-actions-left";
|
|
655
655
|
this.panelsHost = doc.createElement("span");
|
|
656
656
|
this.panelsHost.className = "vela-widget-panels";
|
|
657
|
-
const tool = (cls,
|
|
657
|
+
const tool = (cls, icon, tip, onClick) => this.toolButton(cls, icon, tip, onClick, this.tooltips);
|
|
658
658
|
if (vis("undo-redo")) {
|
|
659
659
|
this.undoBtn = tool("vela-widget-undo", "undo", "Undo", opts.onUndoClick);
|
|
660
660
|
this.redoBtn = tool("vela-widget-redo", "redo", "Redo", opts.onRedoClick);
|
|
@@ -852,8 +852,8 @@ var Topbar = class {
|
|
|
852
852
|
}
|
|
853
853
|
renderStyleButton(doc) {
|
|
854
854
|
this.styleButton.replaceChildren();
|
|
855
|
-
const
|
|
856
|
-
if (
|
|
855
|
+
const icon = priceStyleIcon(this.priceStyle);
|
|
856
|
+
if (icon) this.styleButton.appendChild(iconEl(icon, doc));
|
|
857
857
|
else this.styleButton.appendChild(doc.createTextNode(priceStyleLabel(this.priceStyle)));
|
|
858
858
|
this.styleButton.setAttribute("aria-label", `Chart style \u2014 ${priceStyleLabel(this.priceStyle)}`);
|
|
859
859
|
}
|
|
@@ -945,11 +945,11 @@ var Topbar = class {
|
|
|
945
945
|
this.el.remove();
|
|
946
946
|
}
|
|
947
947
|
/** One icon-only tool button with its kit tooltip, parked in `sink` for disposal. */
|
|
948
|
-
toolButton(cls,
|
|
948
|
+
toolButton(cls, icon, tip, onClick, sink) {
|
|
949
949
|
const doc = this.el.ownerDocument;
|
|
950
950
|
const b = doc.createElement("button");
|
|
951
951
|
b.className = `vela-widget-tool ${cls}`;
|
|
952
|
-
b.appendChild(iconEl(
|
|
952
|
+
b.appendChild(iconEl(icon, doc));
|
|
953
953
|
b.setAttribute("aria-label", tip);
|
|
954
954
|
sink.push(new Tooltip(b, { content: tip, triggerId: `vela-tool-${cls}`, host: this.host }));
|
|
955
955
|
if (onClick) b.addEventListener("click", onClick);
|
|
@@ -1629,13 +1629,13 @@ var MenuBuilder = class {
|
|
|
1629
1629
|
this.actions = /* @__PURE__ */ new Map();
|
|
1630
1630
|
this.seq = 0;
|
|
1631
1631
|
}
|
|
1632
|
-
entry(label,
|
|
1632
|
+
entry(label, icon, run, separatorBefore = false) {
|
|
1633
1633
|
const id = this.next();
|
|
1634
1634
|
this.actions.set(id, run);
|
|
1635
|
-
return { id, label, icon
|
|
1635
|
+
return { id, label, icon, separatorBefore };
|
|
1636
1636
|
}
|
|
1637
|
-
submenu(label,
|
|
1638
|
-
return { id: this.next(), label, icon
|
|
1637
|
+
submenu(label, icon, submenu, separatorBefore = false) {
|
|
1638
|
+
return { id: this.next(), label, icon, submenu, separatorBefore };
|
|
1639
1639
|
}
|
|
1640
1640
|
next() {
|
|
1641
1641
|
this.seq += 1;
|
|
@@ -1872,8 +1872,8 @@ var ObjectTree = class extends SidePanel {
|
|
|
1872
1872
|
const acts = doc.createElement("span");
|
|
1873
1873
|
acts.className = "vela-ot-acts";
|
|
1874
1874
|
head.appendChild(acts);
|
|
1875
|
-
const op = (
|
|
1876
|
-
acts.appendChild(this.btn({ icon
|
|
1875
|
+
const op = (icon, title, run) => {
|
|
1876
|
+
acts.appendChild(this.btn({ icon, title, run }));
|
|
1877
1877
|
};
|
|
1878
1878
|
if (pane.kind !== "price") {
|
|
1879
1879
|
if (pane.order > 1) op("arrow-up", "Move pane up", () => chart.panes.move(pane.id, "up"));
|
|
@@ -1888,8 +1888,8 @@ var ObjectTree = class extends SidePanel {
|
|
|
1888
1888
|
const { chart } = pass;
|
|
1889
1889
|
if (row.kind === "price") {
|
|
1890
1890
|
const base = this.symbolName.replace(/[-_/]?(USDT|USDC|USD1|USDS|BUSD|USD|EUR|PERP)$/i, "") || this.symbolName;
|
|
1891
|
-
const
|
|
1892
|
-
const el2 = this.row(
|
|
1891
|
+
const icon = tickerIconEl(doc, base || "P", this.symbolName || "Price", "vela-ot-avatar", this.symbolRaw ? this.iconFor?.(this.symbolRaw) : void 0);
|
|
1892
|
+
const el2 = this.row(icon, row.label, row.visible, [
|
|
1893
1893
|
{
|
|
1894
1894
|
icon: row.visible ? "eye" : "eye-off",
|
|
1895
1895
|
title: row.visible ? "Hide" : "Show",
|
|
@@ -2008,16 +2008,16 @@ var ObjectTree = class extends SidePanel {
|
|
|
2008
2008
|
const doc = this.el.ownerDocument;
|
|
2009
2009
|
const { chart } = pass;
|
|
2010
2010
|
const markup = drawingMeta(d.type).icon;
|
|
2011
|
-
let
|
|
2011
|
+
let icon;
|
|
2012
2012
|
if (markup) {
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2013
|
+
icon = doc.createElement("span");
|
|
2014
|
+
icon.className = "vela-icon";
|
|
2015
|
+
icon.setAttribute("aria-hidden", "true");
|
|
2016
|
+
icon.innerHTML = markup;
|
|
2017
2017
|
} else {
|
|
2018
|
-
|
|
2018
|
+
icon = iconEl("pen", doc);
|
|
2019
2019
|
}
|
|
2020
|
-
const el = this.row(
|
|
2020
|
+
const el = this.row(icon, drawingLabel(d), d.visible, [
|
|
2021
2021
|
{
|
|
2022
2022
|
icon: d.locked ? "lock" : "unlock",
|
|
2023
2023
|
title: d.locked ? "Unlock" : "Lock",
|
|
@@ -2083,7 +2083,7 @@ var ObjectTree = class extends SidePanel {
|
|
|
2083
2083
|
}
|
|
2084
2084
|
}
|
|
2085
2085
|
/** The shared row shell: icon, name, optional tag, then the action buttons. */
|
|
2086
|
-
row(
|
|
2086
|
+
row(icon, label, visible, actions, tag) {
|
|
2087
2087
|
const doc = this.el.ownerDocument;
|
|
2088
2088
|
const el = doc.createElement("div");
|
|
2089
2089
|
el.className = "vela-ot-row";
|
|
@@ -2092,7 +2092,7 @@ var ObjectTree = class extends SidePanel {
|
|
|
2092
2092
|
name.className = "vela-ot-name";
|
|
2093
2093
|
name.textContent = label;
|
|
2094
2094
|
name.title = label;
|
|
2095
|
-
el.append(
|
|
2095
|
+
el.append(icon, name);
|
|
2096
2096
|
if (tag) {
|
|
2097
2097
|
const t = doc.createElement("span");
|
|
2098
2098
|
t.className = "vela-ot-tag";
|
|
@@ -3940,45 +3940,24 @@ var CSS10 = `
|
|
|
3940
3940
|
}
|
|
3941
3941
|
.vela-statusline .vela-sl-symbol { font-weight: 600; font-size: var(--vela-font-size-lg); }
|
|
3942
3942
|
.vela-statusline .vela-sl-meta { color: var(--vela-fg-muted); font-size: var(--vela-font-size-md); font-weight: 600; }
|
|
3943
|
-
/* Market status badge \u2014 icon-only 16px circle, label on hover
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
place-items: center;
|
|
3947
|
-
width: 16px;
|
|
3948
|
-
height: 16px;
|
|
3949
|
-
border-radius: 50%;
|
|
3950
|
-
flex: none;
|
|
3951
|
-
align-self: center;
|
|
3952
|
-
line-height: 0;
|
|
3953
|
-
cursor: default;
|
|
3954
|
-
}
|
|
3955
|
-
.vela-statusline .vela-sl-market svg {
|
|
3956
|
-
width: 12px;
|
|
3957
|
-
height: 12px;
|
|
3958
|
-
display: block;
|
|
3959
|
-
}
|
|
3960
|
-
/* Open wears the theme's up color; the other sessions are meaning constants from the
|
|
3961
|
-
* palette (amber pre, sky post, gray closed/holiday). Same ink at 20% for the circle. */
|
|
3962
|
-
.vela-statusline .vela-sl-market[data-status='open'] {
|
|
3963
|
-
background: color-mix(in srgb, var(--vela-up) 20%, transparent);
|
|
3964
|
-
color: var(--vela-up);
|
|
3965
|
-
}
|
|
3966
|
-
.vela-statusline .vela-sl-market[data-status='pre'] { background: color-mix(in srgb, ${SESSION_PRE} 20%, transparent); color: ${SESSION_PRE}; }
|
|
3967
|
-
.vela-statusline .vela-sl-market[data-status='post'] { background: color-mix(in srgb, ${SESSION_POST} 20%, transparent); color: ${SESSION_POST}; }
|
|
3968
|
-
.vela-statusline .vela-sl-market[data-status='closed'],
|
|
3969
|
-
.vela-statusline .vela-sl-market[data-status='holiday'] { background: color-mix(in srgb, ${SESSION_OFF} 20%, transparent); color: ${SESSION_OFF}; }
|
|
3943
|
+
/* Market status badge \u2014 a kit callout bubble (icon-only 16px circle, label on hover
|
|
3944
|
+
* via the kit tooltip); the session tint is applied per status in setMarketStatus. */
|
|
3945
|
+
.vela-statusline .vela-sl-market { align-self: center; }
|
|
3970
3946
|
.vela-statusline .vela-sl-ohlc { display: flex; gap: var(--vela-space-1); color: var(--vela-fg-muted); }
|
|
3971
3947
|
.vela-statusline .vela-sl-ohlc b { color: var(--vela-fg); font-weight: 500; }
|
|
3972
3948
|
/* The change value wears the SAME ink as the OHLC values (set inline per render) \u2014
|
|
3973
3949
|
* these are the pre-ink fallbacks only. */
|
|
3974
3950
|
.vela-statusline .vela-sl-change[data-dir='up'] { color: var(--vela-up); }
|
|
3975
3951
|
.vela-statusline .vela-sl-change[data-dir='down'] { color: var(--vela-down); }
|
|
3976
|
-
/* Stack the
|
|
3977
|
-
* The renderer
|
|
3978
|
-
*
|
|
3979
|
-
*
|
|
3980
|
-
*
|
|
3981
|
-
|
|
3952
|
+
/* Stack the TOP pane's legend below the status line (lower study panes stay put).
|
|
3953
|
+
* The renderer marks whichever legend sits at the plot's top edge \u2014 the price pane
|
|
3954
|
+
* normally, or a maximized study pane filling the plot \u2014 so the legend never merges
|
|
3955
|
+
* with the status line whichever pane owns the top. The renderer sets the legend's
|
|
3956
|
+
* inline top \u2014 shift with a transform, don't fight it. Scoped to hosts that actually
|
|
3957
|
+
* CARRY a status line (the marker class set by the Statusline constructor) \u2014 the
|
|
3958
|
+
* stylesheet is document-global, so a bare attribute selector here would shift every
|
|
3959
|
+
* chart on the page, including statusline-less ones. */
|
|
3960
|
+
.vela-has-statusline [${LEGEND_AT_TOP_ATTR}] { transform: translateY(26px); }
|
|
3982
3961
|
/* Mobile: two-line chip \u2014 logo / symbol / meta / market status on one aligned row, the
|
|
3983
3962
|
* bar change on the next. Full O/H/L/C stays hidden (too dense on a phone-width plot).
|
|
3984
3963
|
* GRID, not a wrapping flexbox: an absolutely positioned wrapping flex container sizes
|
|
@@ -4014,7 +3993,7 @@ var CSS10 = `
|
|
|
4014
3993
|
font-size: var(--vela-font-size-sm);
|
|
4015
3994
|
line-height: 1.2;
|
|
4016
3995
|
}
|
|
4017
|
-
[data-layout='mobile'] .vela-has-statusline [
|
|
3996
|
+
[data-layout='mobile'] .vela-has-statusline [${LEGEND_AT_TOP_ATTR}] { transform: translateY(40px); }
|
|
4018
3997
|
/* FIT mode (multi-chart cells \u2014 see setFitMode): the line never wraps; segments that
|
|
4019
3998
|
* don't fit are HIDDEN by fit() (change first, then meta, then the market badge), so
|
|
4020
3999
|
* overflow:hidden only guards the transient between a resize and the next measure.
|
|
@@ -4031,7 +4010,7 @@ var CSS10 = `
|
|
|
4031
4010
|
padding-left: 0;
|
|
4032
4011
|
}
|
|
4033
4012
|
/* One row again \u2014 the mobile two-line shift doesn't apply in fit mode. */
|
|
4034
|
-
[data-layout='mobile'] .vela-sl-fit-host.vela-has-statusline [
|
|
4013
|
+
[data-layout='mobile'] .vela-sl-fit-host.vela-has-statusline [${LEGEND_AT_TOP_ATTR}] { transform: translateY(26px); }
|
|
4035
4014
|
`;
|
|
4036
4015
|
function baseOfTicker(ticker) {
|
|
4037
4016
|
return ticker.replace(/[-_/]?(USDT|USDC|USD1|USDS|BUSD|USD|EUR|PERP)$/i, "") || ticker;
|
|
@@ -4043,6 +4022,13 @@ var MARKET_LABELS = {
|
|
|
4043
4022
|
closed: "Market Closed",
|
|
4044
4023
|
holiday: "Market Holiday"
|
|
4045
4024
|
};
|
|
4025
|
+
var MARKET_INKS = {
|
|
4026
|
+
open: "var(--vela-up)",
|
|
4027
|
+
pre: SESSION_PRE,
|
|
4028
|
+
post: SESSION_POST,
|
|
4029
|
+
closed: SESSION_OFF,
|
|
4030
|
+
holiday: SESSION_OFF
|
|
4031
|
+
};
|
|
4046
4032
|
function statuslineInkOf(renderer, priceStyle) {
|
|
4047
4033
|
const cfg = renderer.getConfig();
|
|
4048
4034
|
const c = (v) => typeof v === "string" ? v : null;
|
|
@@ -4101,8 +4087,15 @@ var Statusline = class {
|
|
|
4101
4087
|
this.symbolEl.textContent = ticker;
|
|
4102
4088
|
this.metaEl = doc.createElement("span");
|
|
4103
4089
|
this.metaEl.className = "vela-sl-meta";
|
|
4104
|
-
this.
|
|
4105
|
-
|
|
4090
|
+
this.marketBubble = new CalloutBubble({
|
|
4091
|
+
icon: "market-open",
|
|
4092
|
+
background: `color-mix(in srgb, ${MARKET_INKS.open} 20%, transparent)`,
|
|
4093
|
+
color: MARKET_INKS.open,
|
|
4094
|
+
label: MARKET_LABELS.open,
|
|
4095
|
+
host
|
|
4096
|
+
});
|
|
4097
|
+
this.marketEl = this.marketBubble.el;
|
|
4098
|
+
this.marketEl.classList.add("vela-sl-market");
|
|
4106
4099
|
this.ohlcEl = doc.createElement("span");
|
|
4107
4100
|
this.ohlcEl.className = "vela-sl-ohlc";
|
|
4108
4101
|
this.changeEl = doc.createElement("span");
|
|
@@ -4190,8 +4183,13 @@ var Statusline = class {
|
|
|
4190
4183
|
* hover label. Callers with no session model leave the constructor's 'open'. */
|
|
4191
4184
|
setMarketStatus(status) {
|
|
4192
4185
|
this.marketEl.dataset.status = status;
|
|
4193
|
-
|
|
4194
|
-
this.
|
|
4186
|
+
const ink = MARKET_INKS[status];
|
|
4187
|
+
this.marketBubble.set({
|
|
4188
|
+
icon: `market-${status}`,
|
|
4189
|
+
background: `color-mix(in srgb, ${ink} 20%, transparent)`,
|
|
4190
|
+
color: ink,
|
|
4191
|
+
label: MARKET_LABELS[status]
|
|
4192
|
+
});
|
|
4195
4193
|
this.marketTip.setContent(MARKET_LABELS[status]);
|
|
4196
4194
|
}
|
|
4197
4195
|
setPartVisible(part, visible) {
|
|
@@ -4224,6 +4222,7 @@ var Statusline = class {
|
|
|
4224
4222
|
this.fitRO?.disconnect();
|
|
4225
4223
|
this.fitRO = null;
|
|
4226
4224
|
this.marketTip.destroy();
|
|
4225
|
+
this.marketBubble.destroy();
|
|
4227
4226
|
this.host.classList.remove("vela-has-statusline", "vela-sl-fit-host");
|
|
4228
4227
|
this.el.remove();
|
|
4229
4228
|
}
|
|
@@ -4760,6 +4759,8 @@ var SessionShadingTracker = class {
|
|
|
4760
4759
|
this.spec = null;
|
|
4761
4760
|
this.ready = false;
|
|
4762
4761
|
this.session = "regular";
|
|
4762
|
+
/** Whether one bar is shorter than a civil day — only then do pre/post bars exist. */
|
|
4763
|
+
this.intraday = false;
|
|
4763
4764
|
this.covered = null;
|
|
4764
4765
|
/** The newest range seen — viewport moves during metadata resolution (a load's fit
|
|
4765
4766
|
* animation) must not be lost, so the resolution always expands the LATEST range. */
|
|
@@ -4772,6 +4773,8 @@ var SessionShadingTracker = class {
|
|
|
4772
4773
|
this.spec = null;
|
|
4773
4774
|
this.covered = null;
|
|
4774
4775
|
this.session = opts.session;
|
|
4776
|
+
const tfMs = timeframeMs(opts.timeframe);
|
|
4777
|
+
this.intraday = Number.isFinite(tfMs) && tfMs < DAY_MS;
|
|
4775
4778
|
this.lastRange = opts.range;
|
|
4776
4779
|
void data.symbolInfo(symbol).catch(() => void 0).then((si) => {
|
|
4777
4780
|
if (my !== this.epoch) return;
|
|
@@ -4799,7 +4802,7 @@ var SessionShadingTracker = class {
|
|
|
4799
4802
|
if (force) this.onZones(null);
|
|
4800
4803
|
return;
|
|
4801
4804
|
}
|
|
4802
|
-
if (this.session !== "extended") {
|
|
4805
|
+
if (this.session !== "extended" || !this.intraday) {
|
|
4803
4806
|
if (force) this.onZones({ pre: [], post: [] });
|
|
4804
4807
|
return;
|
|
4805
4808
|
}
|
|
@@ -5002,6 +5005,7 @@ var ChartCell = class {
|
|
|
5002
5005
|
this.inner.renderer.set("attribution", false);
|
|
5003
5006
|
this.inner.renderer.set("dialogHost", deps.dialogHost);
|
|
5004
5007
|
this.inner.renderer.setLegendActions(legendActionsProviderFor(this.inner, () => deps.context()));
|
|
5008
|
+
this.inner.renderer.setLegendCallouts(legendCalloutsProviderFor(this.inner, () => deps.context()));
|
|
5005
5009
|
if (this.inner.renderer.supports("historyChords")) this.inner.renderer.set("historyChords", false);
|
|
5006
5010
|
this.history.onChart(this.inner);
|
|
5007
5011
|
this.inner.renderer.onConfigChanged(() => {
|
|
@@ -5118,20 +5122,30 @@ var ChartCell = class {
|
|
|
5118
5122
|
this.refreshNativeCatalog();
|
|
5119
5123
|
this.pushSettingsSections();
|
|
5120
5124
|
this.offMarket = this.inner.on("market:changed", ({ symbol: symbol2, timeframe }) => {
|
|
5121
|
-
this.
|
|
5122
|
-
this.state.provider = parseSymbol(symbol2).provider ?? void 0;
|
|
5123
|
-
this.state.timeframe = timeframe;
|
|
5124
|
-
this.state.session = normalizeSession(this.inner?.market.session);
|
|
5125
|
-
this.watermark?.update(symbol2, timeframe);
|
|
5126
|
-
this.statusline?.setSymbol(symbol2);
|
|
5127
|
-
this.statusline?.setMeta(timeframe, this.inner?.data.displayPrefix(symbol2) ?? this.state.provider ?? "");
|
|
5128
|
-
if (this.inner) this.statusline?.onChart(this.inner);
|
|
5125
|
+
this.projectMarket(symbol2, timeframe);
|
|
5129
5126
|
this.refreshNativeCatalog();
|
|
5130
5127
|
this.refreshSessionAvailable();
|
|
5131
5128
|
if (this.inner) this.marketStatus?.track(this.inner.data, symbol2);
|
|
5132
5129
|
this.deps.onMarketChanged(this.id);
|
|
5133
5130
|
});
|
|
5134
5131
|
}
|
|
5132
|
+
/**
|
|
5133
|
+
* Project a market identity into the cell state and its display overlays (watermark,
|
|
5134
|
+
* statusline), WITHOUT the data-dependent bookkeeping. Runs twice per user pick: once
|
|
5135
|
+
* optimistically from the cell setters — the labels reflect the pick immediately, not
|
|
5136
|
+
* after the bars load — and again from `market:changed` (the committed pass, and the
|
|
5137
|
+
* only pass for host `chart.setMarket` calls). Idempotent, so the double run converges.
|
|
5138
|
+
*/
|
|
5139
|
+
projectMarket(symbol, timeframe) {
|
|
5140
|
+
this.state.symbol = symbol;
|
|
5141
|
+
this.state.provider = parseSymbol(symbol).provider ?? void 0;
|
|
5142
|
+
this.state.timeframe = timeframe;
|
|
5143
|
+
this.state.session = normalizeSession(this.inner?.market.session);
|
|
5144
|
+
this.watermark?.update(symbol, timeframe);
|
|
5145
|
+
this.statusline?.setSymbol(symbol);
|
|
5146
|
+
this.statusline?.setMeta(timeframe, this.inner?.data.displayPrefix(symbol) ?? this.state.provider ?? "");
|
|
5147
|
+
if (this.inner) this.statusline?.onChart(this.inner);
|
|
5148
|
+
}
|
|
5135
5149
|
/**
|
|
5136
5150
|
* Does this cell's market HAVE sessions (RTH/ETH meaningful)? Derived from the
|
|
5137
5151
|
* symbol's own metadata (`syminfo.session !== '24x7'`), asynchronously — the
|
|
@@ -5177,7 +5191,7 @@ var ChartCell = class {
|
|
|
5177
5191
|
const requestedSpan = Math.max(this.state.bars ?? 1e3, this.rangeBars) * timeframeMs(this.state.timeframe ?? "60");
|
|
5178
5192
|
const fallbackSpan = Number.isFinite(requestedSpan) ? Math.max(3 * 864e5, requestedSpan) : 3 * 864e5;
|
|
5179
5193
|
const range = chart.getVisibleRange() ?? { from: now - fallbackSpan, to: now };
|
|
5180
|
-
this.sessionShading.track(chart.data, symbol, { session: this.session, range });
|
|
5194
|
+
this.sessionShading.track(chart.data, symbol, { session: this.session, timeframe: this.timeframe, range });
|
|
5181
5195
|
}
|
|
5182
5196
|
/** The session-shade colors live in the renderer CONFIG (persisted with it, edited
|
|
5183
5197
|
* live by the dialog swatch) — the cell only proxies them into its settings rows. */
|
|
@@ -5366,17 +5380,23 @@ var ChartCell = class {
|
|
|
5366
5380
|
get indicatorCount() {
|
|
5367
5381
|
return this.instances.length + this.nativeCatalog.filter((n) => n.present).length;
|
|
5368
5382
|
}
|
|
5369
|
-
/** Switch this cell's market in place (the chart instance survives).
|
|
5383
|
+
/** Switch this cell's market in place (the chart instance survives). The projection
|
|
5384
|
+
* is OPTIMISTIC — labels and chrome show the pick before the bars load; it follows
|
|
5385
|
+
* the setMarket call so the statusline reads the already-blanked chart. */
|
|
5370
5386
|
setSymbol(symbol) {
|
|
5371
5387
|
if (!this.inner || symbol === this.symbol) return;
|
|
5372
5388
|
this.unresolvedToasted = null;
|
|
5373
5389
|
void this.inner.setMarket({ symbol });
|
|
5390
|
+
this.projectMarket(symbol, this.timeframe);
|
|
5391
|
+
this.deps.onMarketChanged(this.id);
|
|
5374
5392
|
}
|
|
5375
5393
|
setTimeframe(timeframe) {
|
|
5376
5394
|
if (!this.inner || timeframe === this.timeframe) return;
|
|
5377
5395
|
this.activeRangeId = null;
|
|
5378
5396
|
this.rangeBars = 0;
|
|
5379
5397
|
void this.inner.setMarket({ timeframe, bars: this.state.bars });
|
|
5398
|
+
this.projectMarket(this.symbol, timeframe);
|
|
5399
|
+
this.deps.onMarketChanged(this.id);
|
|
5380
5400
|
}
|
|
5381
5401
|
/** Applied live (renderer feature) — no reload. */
|
|
5382
5402
|
setPriceStyle(style) {
|
|
@@ -6239,11 +6259,11 @@ var MobileBar = class {
|
|
|
6239
6259
|
injectStyles(STYLE_ID13, CSS13, doc);
|
|
6240
6260
|
this.el = doc.createElement("div");
|
|
6241
6261
|
this.el.className = "vela-mobilebar";
|
|
6242
|
-
const item = (cls, label, onClick,
|
|
6262
|
+
const item = (cls, label, onClick, icon) => {
|
|
6243
6263
|
const b = doc.createElement("button");
|
|
6244
6264
|
b.className = `vela-mb-item ${cls}`;
|
|
6245
6265
|
b.setAttribute("aria-label", label);
|
|
6246
|
-
if (
|
|
6266
|
+
if (icon) b.appendChild(iconEl(icon, doc));
|
|
6247
6267
|
b.addEventListener("click", onClick);
|
|
6248
6268
|
return b;
|
|
6249
6269
|
};
|
|
@@ -6789,11 +6809,11 @@ var MoreDrawer = class {
|
|
|
6789
6809
|
renderMain(doc) {
|
|
6790
6810
|
const actions = doc.createElement("div");
|
|
6791
6811
|
actions.className = "vela-md-actions";
|
|
6792
|
-
const action = (
|
|
6812
|
+
const action = (icon, label, enabled, run) => {
|
|
6793
6813
|
const b = doc.createElement("button");
|
|
6794
6814
|
b.className = "vela-md-action";
|
|
6795
6815
|
b.disabled = !enabled;
|
|
6796
|
-
b.appendChild(iconEl(
|
|
6816
|
+
b.appendChild(iconEl(icon, doc));
|
|
6797
6817
|
b.appendChild(doc.createTextNode(label));
|
|
6798
6818
|
b.addEventListener("click", () => {
|
|
6799
6819
|
run();
|
|
@@ -7218,11 +7238,11 @@ var DrawingPill = class {
|
|
|
7218
7238
|
this.el.hidden = true;
|
|
7219
7239
|
this.toolGlyph = doc.createElement("span");
|
|
7220
7240
|
this.toolGlyph.className = "vela-drawpill-tool";
|
|
7221
|
-
const btn = (
|
|
7241
|
+
const btn = (icon, label, onClick) => {
|
|
7222
7242
|
const b = doc.createElement("button");
|
|
7223
7243
|
b.className = "vela-drawpill-btn";
|
|
7224
7244
|
b.setAttribute("aria-label", label);
|
|
7225
|
-
b.appendChild(iconEl(
|
|
7245
|
+
b.appendChild(iconEl(icon, doc));
|
|
7226
7246
|
b.addEventListener("click", onClick);
|
|
7227
7247
|
return b;
|
|
7228
7248
|
};
|
|
@@ -7778,7 +7798,10 @@ var VelaWorkspace = class {
|
|
|
7778
7798
|
this.topbar.renderActions();
|
|
7779
7799
|
this.mobileBar?.renderActions();
|
|
7780
7800
|
this.dock.refresh();
|
|
7781
|
-
for (const cell of this.cells())
|
|
7801
|
+
for (const cell of this.cells()) {
|
|
7802
|
+
cell.chart.renderer.setLegendActions(legendActionsProviderFor(cell.chart, () => this.context()));
|
|
7803
|
+
cell.chart.renderer.setLegendCallouts(legendCalloutsProviderFor(cell.chart, () => this.context()));
|
|
7804
|
+
}
|
|
7782
7805
|
}
|
|
7783
7806
|
// ── state surface (the SDK's read/restore of the whole grid's config + content) ──
|
|
7784
7807
|
/**
|
|
@@ -98,11 +98,11 @@ registerIcon(
|
|
|
98
98
|
);
|
|
99
99
|
registerIcon(
|
|
100
100
|
"market-pre",
|
|
101
|
-
svg24('<path d="M12 2v8"/><path d="m4.93 10.93 1.41 1.41"/><path d="M2 18h2"/><path d="M20 18h2"/><path d="m19.07 10.93-1.41 1.41"/><path d="M22 22H2"/><path d="
|
|
101
|
+
svg24('<path d="M12 2v8"/><path d="m4.93 10.93 1.41 1.41"/><path d="M2 18h2"/><path d="M20 18h2"/><path d="m19.07 10.93-1.41 1.41"/><path d="M22 22H2"/><path d="m8 6 4-4 4 4"/><path d="M16 18a4 4 0 0 0-8 0"/>')
|
|
102
102
|
);
|
|
103
103
|
registerIcon(
|
|
104
104
|
"market-post",
|
|
105
|
-
svg24('<path d="M12 10V2"/><path d="m4.93 10.93 1.41 1.41"/><path d="M2 18h2"/><path d="M20 18h2"/><path d="m19.07 10.93-1.41 1.41"/><path d="M22 22H2"/><path d="m16
|
|
105
|
+
svg24('<path d="M12 10V2"/><path d="m4.93 10.93 1.41 1.41"/><path d="M2 18h2"/><path d="M20 18h2"/><path d="m19.07 10.93-1.41 1.41"/><path d="M22 22H2"/><path d="m16 14-4 4-4-4"/><path d="M16 6a4 4 0 0 0-8 0"/>')
|
|
106
106
|
);
|
|
107
107
|
registerIcon("market-closed", svg24('<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>'));
|
|
108
108
|
registerIcon(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-
|
|
1
|
+
import { u as Millis, af as InputSchema, ad as IndicatorMeta, P as PriceStyle, O as OHLCV, m as InputValue, k as IndicatorModel, j as MoveTarget, ar as PaneAxis, aE as SeriesSpec, ab as Fill, B as Background, aw as PriceLine, a1 as DrawingLine, Z as DrawingBox, a0 as DrawingLabel, a5 as DrawingPolyline, a2 as DrawingLinefill, a7 as DrawingTable, g as IndicatorStatus, a as VisibleRange, c as VelaTheme, S as SerializedDrawing, w as DrawingTypeKey, v as SnapMode, a3 as DrawingMode, I as IChartRenderer, R as RendererCapabilities, o as LegendActionView, p as LegendCalloutView, U as Unsubscribe, C as CrosshairEvent, A as AxisLongPressEvent, s as DataWindowReadout, n as SymbolPickerFn, aS as PaneInfo, aa as DrawingsOption, D as Drawing, b as VelaOptions, y as AddIndicatorOptions, aq as MarketSwitch, ap as MarketSnapshot, V as VisibleRangePreset, T as ThemeName } from './options-FM0peknS.cjs';
|
|
2
|
+
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-8Z95Q-RJ.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A strategy's broker state at ONE bar — the flat summary a host reads while a script
|
|
@@ -92,6 +92,14 @@ interface PreparedScript {
|
|
|
92
92
|
/** The language that produced this (the engine's `language`). */
|
|
93
93
|
language: string;
|
|
94
94
|
inputs: InputSchema[];
|
|
95
|
+
/**
|
|
96
|
+
* Declaration-property schema (a strategy's `initial_capital`, an indicator's
|
|
97
|
+
* `precision`, …) — the settings dialog renders these on a "Properties" tab.
|
|
98
|
+
* `defval` is the EFFECTIVE default: the value the script declares, else the
|
|
99
|
+
* engine's configured default, else the language's own. Absent ≡ the language
|
|
100
|
+
* has no declaration properties (`capabilities.props` false).
|
|
101
|
+
*/
|
|
102
|
+
props?: InputSchema[];
|
|
95
103
|
meta: IndicatorMeta;
|
|
96
104
|
/**
|
|
97
105
|
* Whether the script references a viewport built-in (e.g. Pine
|
|
@@ -109,6 +117,9 @@ interface EngineCapabilities {
|
|
|
109
117
|
visibleRange: boolean;
|
|
110
118
|
/** Exposes an inputs schema (drives the renderer's settings dialog). */
|
|
111
119
|
inputs: boolean;
|
|
120
|
+
/** Exposes a declaration-props schema (`PreparedScript.props`) and honors prop
|
|
121
|
+
* overrides on `execute`/`update`. Absent ≡ false. */
|
|
122
|
+
props?: boolean;
|
|
112
123
|
}
|
|
113
124
|
/** Market context an execution needs. Vela owns the bars; this is the metadata. */
|
|
114
125
|
interface ExecutionMarket {
|
|
@@ -145,6 +156,9 @@ interface ExecutionRequest {
|
|
|
145
156
|
*/
|
|
146
157
|
fetchSeries?: FetchSeries;
|
|
147
158
|
inputs?: Record<string, InputValue>;
|
|
159
|
+
/** Declaration-prop overrides, keyed like `PreparedScript.props`. Only meaningful
|
|
160
|
+
* when `capabilities.props`; other engines ignore it. */
|
|
161
|
+
props?: Record<string, InputValue>;
|
|
148
162
|
visibleRange?: VisibleBarRange;
|
|
149
163
|
mode: 'static' | 'live';
|
|
150
164
|
/**
|
|
@@ -221,8 +235,10 @@ interface ExecutionSession {
|
|
|
221
235
|
getContext?(select?: ContextSelect): Promise<EngineContextSnapshot | null>;
|
|
222
236
|
/** Tear down (stops any streaming / incremental re-execution). */
|
|
223
237
|
stop(): void;
|
|
224
|
-
/** Re-run / re-stream with merged input overrides.
|
|
225
|
-
|
|
238
|
+
/** Re-run / re-stream with merged input overrides. `props` (when given) merges
|
|
239
|
+
* declaration-prop overrides the same way — a props-capable engine re-runs with
|
|
240
|
+
* both applied; others may ignore the second argument. */
|
|
241
|
+
update(inputs: Record<string, InputValue>, props?: Record<string, InputValue>): void;
|
|
226
242
|
/** Update the viewport window (re-runs viewport-dependent scripts; no-op otherwise). */
|
|
227
243
|
setVisibleRange(range: VisibleBarRange): void;
|
|
228
244
|
/** Signal that Vela's bars changed. No reason = live tick; see {@link BarsChangeReason}. */
|
|
@@ -272,10 +288,18 @@ interface IndicatorHandle {
|
|
|
272
288
|
readonly source?: string;
|
|
273
289
|
/** Inputs parsed from the Pine source (populated once the script is prepared). */
|
|
274
290
|
readonly inputs: readonly InputSchema[];
|
|
291
|
+
/** Declaration-props schema (a strategy's `initial_capital`, an indicator's
|
|
292
|
+
* `precision`, …; populated once the script is prepared). Empty when the
|
|
293
|
+
* engine exposes none. */
|
|
294
|
+
readonly props: readonly InputSchema[];
|
|
275
295
|
/** Whether the indicator is currently shown (vs hidden). Hidden indicators stop computing. */
|
|
276
296
|
readonly visible: boolean;
|
|
277
297
|
setInput(key: string, value: InputValue): void;
|
|
278
298
|
setInputs(values: Record<string, InputValue>): void;
|
|
299
|
+
/** Override one declaration prop and re-run (a prop change replays the whole script). */
|
|
300
|
+
setProp(key: string, value: InputValue): void;
|
|
301
|
+
/** Override several declaration props at once and re-run. */
|
|
302
|
+
setProps(values: Record<string, InputValue>): void;
|
|
279
303
|
/**
|
|
280
304
|
* Hide or show the indicator. Hiding **suspends** it — its visuals are dropped (the legend
|
|
281
305
|
* row stays, marked hidden) and its computation stops (the engine session is torn down), so a
|
|
@@ -459,8 +483,8 @@ interface NativeIndicatorDescriptor {
|
|
|
459
483
|
/** Full display name (picker, settings header, handle title). */
|
|
460
484
|
readonly title: string;
|
|
461
485
|
/**
|
|
462
|
-
* Compact name for the on-chart legend chip
|
|
463
|
-
*
|
|
486
|
+
* Compact name for the on-chart legend chip and the settings-dialog header.
|
|
487
|
+
* Absent ⇒ {@link title}. The picker keeps the full title either way.
|
|
464
488
|
*/
|
|
465
489
|
readonly shortTitle?: string;
|
|
466
490
|
readonly paneHint: 'price' | 'new';
|
|
@@ -800,6 +824,8 @@ interface IndicatorSummary {
|
|
|
800
824
|
barColors: number;
|
|
801
825
|
trades: number;
|
|
802
826
|
inputs: number;
|
|
827
|
+
/** Elements flagged `force_overlay` (routed to the price pane), across every kind. */
|
|
828
|
+
forcedOverlay: number;
|
|
803
829
|
}
|
|
804
830
|
/** A snapshot of everything the Vela core has generated for the mounted indicators. */
|
|
805
831
|
interface SceneInspection {
|
|
@@ -819,6 +845,7 @@ interface SceneInspection {
|
|
|
819
845
|
tables: number;
|
|
820
846
|
barColors: number;
|
|
821
847
|
trades: number;
|
|
848
|
+
forcedOverlay: number;
|
|
822
849
|
};
|
|
823
850
|
}
|
|
824
851
|
|
|
@@ -853,6 +880,13 @@ declare class RendererControl {
|
|
|
853
880
|
* degradation as the sync ghost crosshair.
|
|
854
881
|
*/
|
|
855
882
|
setLegendActions(provider: ((indicatorId: string) => LegendActionView[]) | null): void;
|
|
883
|
+
/**
|
|
884
|
+
* Wire the legend rows' HOST-CONTRIBUTED callout bubbles (the shells route the
|
|
885
|
+
* plugin registry through this; see `registerLegendCallout`). Silent on a renderer
|
|
886
|
+
* without the seam — contributed callouts simply never show there, same graceful
|
|
887
|
+
* degradation as {@link setLegendActions}.
|
|
888
|
+
*/
|
|
889
|
+
setLegendCallouts(provider: ((indicatorId: string) => LegendCalloutView[]) | null): void;
|
|
856
890
|
/**
|
|
857
891
|
* Replace the indicator legend's fold toggle with a host action (or restore it with
|
|
858
892
|
* `null`) — multi-chart shells point the chip at their indicator overview instead of
|
|
@@ -1648,6 +1682,64 @@ declare function registerLegendAction(desc: LegendActionDescriptor): () => void;
|
|
|
1648
1682
|
declare function unregisterLegendAction(id: string): void;
|
|
1649
1683
|
/** Every registered legend action, `order`-sorted (registration order breaks ties). */
|
|
1650
1684
|
declare function legendActions(): LegendActionDescriptor[];
|
|
1685
|
+
/** One block of a legend callout's deployed panel, descriptor-side: plain text, or a
|
|
1686
|
+
* button whose `run` receives the shell's {@link WidgetContext} and the row's
|
|
1687
|
+
* indicator — the same signature as a legend action's `run`. */
|
|
1688
|
+
type LegendCalloutItem = {
|
|
1689
|
+
type: 'text';
|
|
1690
|
+
text: string;
|
|
1691
|
+
} | {
|
|
1692
|
+
type: 'button';
|
|
1693
|
+
label: string;
|
|
1694
|
+
/** Emphasized (selection-colored) button — the panel's main action. */
|
|
1695
|
+
primary?: boolean;
|
|
1696
|
+
/** Close the panel after `run` (default true). */
|
|
1697
|
+
close?: boolean;
|
|
1698
|
+
run(ctx: WidgetContext, indicator: LegendIndicatorInfo): void;
|
|
1699
|
+
};
|
|
1700
|
+
/** The panel a clickable callout deploys: an optional heading over ordered blocks. */
|
|
1701
|
+
interface LegendCalloutContent {
|
|
1702
|
+
title?: string;
|
|
1703
|
+
items: LegendCalloutItem[];
|
|
1704
|
+
}
|
|
1705
|
+
/** A callout's resolved presentation for one row — what {@link LegendCalloutDescriptor.callout} returns. */
|
|
1706
|
+
interface LegendCalloutSpec {
|
|
1707
|
+
/** Icon id from the `vela/ui` icon registry (register yours with `registerIcon`). */
|
|
1708
|
+
icon: string;
|
|
1709
|
+
/** Bubble fill — any CSS color (`color-mix` token washes match the built-in badges). */
|
|
1710
|
+
background: string;
|
|
1711
|
+
/** Icon ink (default: the legend row's text color). */
|
|
1712
|
+
color?: string;
|
|
1713
|
+
/** Hover text; also the bubble's accessible name. */
|
|
1714
|
+
tooltip: string;
|
|
1715
|
+
/** Deployed panel — presence makes the bubble clickable. */
|
|
1716
|
+
content?: LegendCalloutContent;
|
|
1717
|
+
}
|
|
1718
|
+
/**
|
|
1719
|
+
* A contributed LEGEND CALLOUT: a small tinted bubble with a centered icon, always
|
|
1720
|
+
* visible right of the indicator's legend title (trailing the whole row while its
|
|
1721
|
+
* hover controls are out). When the spec carries `content`, clicking the bubble
|
|
1722
|
+
* deploys that panel — below it, flipping above near the bottom screen edge.
|
|
1723
|
+
*
|
|
1724
|
+
* Unlike a legend action's static icon, a callout's whole presentation is resolved
|
|
1725
|
+
* per row through `callout` — return `null` to show none (the per-indicator gate),
|
|
1726
|
+
* or a spec whose icon/tint/panel follow your own state (a market-status bubble
|
|
1727
|
+
* changes dress as sessions roll). Late state changes re-project through the shells'
|
|
1728
|
+
* `refreshActions()`, like every contribution.
|
|
1729
|
+
*/
|
|
1730
|
+
interface LegendCalloutDescriptor {
|
|
1731
|
+
/** Stable id — re-registering an id replaces it. */
|
|
1732
|
+
id: string;
|
|
1733
|
+
/** Sort key within the contributed group (ascending; default 0). */
|
|
1734
|
+
order?: number;
|
|
1735
|
+
/** Resolve the row's bubble — `null`/`undefined` shows none. */
|
|
1736
|
+
callout(indicator: LegendIndicatorInfo): LegendCalloutSpec | null | undefined;
|
|
1737
|
+
}
|
|
1738
|
+
/** Register (or replace) a legend callout. Returns an unregister disposer. */
|
|
1739
|
+
declare function registerLegendCallout(desc: LegendCalloutDescriptor): () => void;
|
|
1740
|
+
declare function unregisterLegendCallout(id: string): void;
|
|
1741
|
+
/** Every registered legend callout, `order`-sorted (registration order breaks ties). */
|
|
1742
|
+
declare function legendCallouts(): LegendCalloutDescriptor[];
|
|
1651
1743
|
/**
|
|
1652
1744
|
* The surface a `scope: 'cell'` persistence handler works against — bound to ONE cell
|
|
1653
1745
|
* (never the active one by proxy), because serialize/restore run per cell, including
|
|
@@ -1742,4 +1834,4 @@ declare function unregisterDefaultEngine(language: string): void;
|
|
|
1742
1834
|
* language. The shell layers (widget, workspace cell) register exactly this result. */
|
|
1743
1835
|
declare function resolveEngines(overrides?: Record<string, EngineFactory>): Record<string, EngineFactory>;
|
|
1744
1836
|
|
|
1745
|
-
export {
|
|
1837
|
+
export { TypedEventBus as $, type RunIndicatorResult as A, type BarsChangeReason as B, type CellStateContext as C, type DrawingsDocument as D, type ExternalIndicatorEntry as E, type FetchSeries as F, type SceneInspection as G, type ScriptRunCause as H, type IndicatorHandle as I, type ScriptRunResult as J, type SidePanelButton as K, type LegendActionDescriptor as L, type SidePanelDescriptor as M, type NativeIndicator as N, OVERRIDABLE_TOPBAR_IDS as O, type ParsedSymbol as P, type SidePanelHandle as Q, type Resolved as R, type ScriptingEngine as S, type SidePanelHeader as T, type StatePersistenceHandler as U, Vela as V, type WidgetContext as W, type StrategyFill as X, type StrategyState as Y, type StrategyTrade as Z, type SymbolRankingHook as _, type ScriptRun as a, type VelaDeps as a0, type VelaEventMap as a1, type VisibleBarRange as a2, type WidgetActionDescriptor as a3, type WidgetActionTarget as a4, type WidgetAttachment as a5, getNativeIndicator as a6, legendActions as a7, legendCallouts as a8, nativeIndicatorDescriptors as a9, nativeIndicatorTypes as aa, registerDefaultEngine as ab, registerLegendAction as ac, registerLegendCallout as ad, registerNativeIndicator as ae, registerSidePanel as af, registerStatePersistence as ag, registerSymbolRanking as ah, registerWidgetAction as ai, registerWidgetAttachment as aj, resolveEngines as ak, sidePanels as al, statePersistenceHandlers as am, symbolRanking as an, topbarActionOverride as ao, unregisterDefaultEngine as ap, unregisterLegendAction as aq, unregisterLegendCallout as ar, unregisterNativeIndicator as as, unregisterSidePanel as at, unregisterStatePersistence as au, unregisterWidgetAction as av, unregisterWidgetAttachment as aw, widgetActions as ax, widgetAttachments as ay, DEFAULT_PANEL_ORDER as az, type ContextSelect as b, DataControl as c, DrawingsControl as d, type EngineAlert as e, type EngineCapabilities as f, type EngineContextSnapshot as g, type EngineFactory as h, type EngineWarning as i, type ExecutionHandlers as j, type ExecutionMarket as k, type ExecutionRequest as l, type ExecutionSession as m, type IndicatorEventMap as n, type IndicatorSummary as o, type LegendCalloutContent as p, type LegendCalloutDescriptor as q, type LegendCalloutItem as r, type LegendCalloutSpec as s, type LegendIndicatorInfo as t, type NativeIndicatorContext as u, type NativeIndicatorDescriptor as v, type NativeIndicatorInfo as w, type NativeIndicatorOutput as x, type PreparedScript as y, RendererControl as z };
|