@luxalgo/vela 0.6.6 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/{DataProvider-JJq7M2it.d.ts → DataProvider-BSLlBpB9.d.ts} +10 -0
  2. package/dist/{DataProvider-DDUYw2qP.d.cts → DataProvider-BsQM2WNH.d.cts} +10 -0
  3. package/dist/{bottombar-COnL2Sk4.d.ts → bottombar-Br4rzx_R.d.ts} +52 -6
  4. package/dist/{bottombar-DeDXbF_K.d.cts → bottombar-Div5zibZ.d.cts} +52 -6
  5. package/dist/{chunk-JQFO2WMU.js → chunk-6WFKTAT4.js} +37 -1
  6. package/dist/{chunk-OEUGUXL7.js → chunk-L3I2CCYO.js} +49 -1
  7. package/dist/chunk-W4EJWLEO.js +12 -0
  8. package/dist/{chunk-TMXK2SJR.js → chunk-WVP4XV5A.js} +221 -65
  9. package/dist/{contributions-DNMqrAuw.d.cts → contributions-Hv4_cOJo.d.cts} +46 -3
  10. package/dist/{contributions-BqCIsbaP.d.ts → contributions-Z12BrWCy.d.ts} +46 -3
  11. package/dist/index.cjs +64 -0
  12. package/dist/index.d.cts +8 -4
  13. package/dist/index.d.ts +8 -4
  14. package/dist/index.js +2 -2
  15. package/dist/{plugin-WnvNNJOp.d.ts → plugin-9koBjc5H.d.ts} +2 -2
  16. package/dist/{plugin-CN8U2__Q.d.cts → plugin-BXhDHTYn.d.cts} +2 -2
  17. package/dist/plugin.cjs +28 -0
  18. package/dist/plugin.d.cts +3 -3
  19. package/dist/plugin.d.ts +3 -3
  20. package/dist/plugin.js +1 -1
  21. package/dist/providers/binance.cjs +16 -0
  22. package/dist/providers/binance.d.cts +4 -1
  23. package/dist/providers/binance.d.ts +4 -1
  24. package/dist/providers/binance.js +7 -0
  25. package/dist/providers/coinbase.cjs +16 -0
  26. package/dist/providers/coinbase.d.cts +4 -1
  27. package/dist/providers/coinbase.d.ts +4 -1
  28. package/dist/providers/coinbase.js +7 -0
  29. package/dist/providers/hyperliquid.cjs +16 -0
  30. package/dist/providers/hyperliquid.d.cts +4 -1
  31. package/dist/providers/hyperliquid.d.ts +4 -1
  32. package/dist/providers/hyperliquid.js +7 -0
  33. package/dist/vela.global.js +90 -0
  34. package/dist/vela.global.min.js +42 -42
  35. package/dist/widget.cjs +319 -63
  36. package/dist/widget.d.cts +52 -10
  37. package/dist/widget.d.ts +52 -10
  38. package/dist/widget.js +5 -4
  39. package/dist/workspace.cjs +265 -65
  40. package/dist/workspace.d.cts +13 -4
  41. package/dist/workspace.d.ts +13 -4
  42. package/dist/workspace.js +4 -3
  43. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { O as OHLCV, U as Unsubscribe } from '../options-BaVTMXaO.cjs';
2
- import { D as DataProvider, P as ProviderInfo, B as BarRange, S as SymbolInfo, a as SymbolDescriptor } from '../DataProvider-DDUYw2qP.cjs';
2
+ import { D as DataProvider, P as ProviderInfo, B as BarRange, S as SymbolInfo, a as SymbolDescriptor } from '../DataProvider-BsQM2WNH.cjs';
3
3
 
4
4
  /**
5
5
  * Binance market-data provider, built from scratch on the public REST + WebSocket
@@ -23,6 +23,9 @@ declare class BinanceProvider implements DataProvider {
23
23
  getBars(ticker: string, timeframe: string, range: BarRange): Promise<OHLCV[]>;
24
24
  getSymbolInfo(ticker: string): Promise<SymbolInfo | undefined>;
25
25
  listSymbols(): Promise<SymbolDescriptor[]>;
26
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
27
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
28
+ resolveSymbolIcon(symbol: SymbolDescriptor): string | undefined;
26
29
  subscribe(ticker: string, timeframe: string, onBar: (bar: OHLCV) => void): Unsubscribe;
27
30
  /**
28
31
  * Open a Binance kline WebSocket (single-stream URL form — the stream is in the
@@ -1,5 +1,5 @@
1
1
  import { O as OHLCV, U as Unsubscribe } from '../options-BaVTMXaO.js';
2
- import { D as DataProvider, P as ProviderInfo, B as BarRange, S as SymbolInfo, a as SymbolDescriptor } from '../DataProvider-JJq7M2it.js';
2
+ import { D as DataProvider, P as ProviderInfo, B as BarRange, S as SymbolInfo, a as SymbolDescriptor } from '../DataProvider-BSLlBpB9.js';
3
3
 
4
4
  /**
5
5
  * Binance market-data provider, built from scratch on the public REST + WebSocket
@@ -23,6 +23,9 @@ declare class BinanceProvider implements DataProvider {
23
23
  getBars(ticker: string, timeframe: string, range: BarRange): Promise<OHLCV[]>;
24
24
  getSymbolInfo(ticker: string): Promise<SymbolInfo | undefined>;
25
25
  listSymbols(): Promise<SymbolDescriptor[]>;
26
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
27
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
28
+ resolveSymbolIcon(symbol: SymbolDescriptor): string | undefined;
26
29
  subscribe(ticker: string, timeframe: string, onBar: (bar: OHLCV) => void): Unsubscribe;
27
30
  /**
28
31
  * Open a Binance kline WebSocket (single-stream URL form — the stream is in the
@@ -1,3 +1,5 @@
1
+ import { ledgerCryptoIconUrl, baseOf } from '../chunk-W4EJWLEO.js';
2
+
1
3
  // src/data/providers/binance/BinanceProvider.ts
2
4
  var SPOT_BASE = "https://api.binance.com/api/v3";
3
5
  var SPOT_BASE_US = "https://api.binance.us/api/v3";
@@ -184,6 +186,11 @@ var BinanceProvider = class {
184
186
  }
185
187
  return this.symbolsPromise;
186
188
  }
189
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
190
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
191
+ resolveSymbolIcon(symbol) {
192
+ return ledgerCryptoIconUrl(baseOf(symbol));
193
+ }
187
194
  subscribe(ticker, timeframe, onBar) {
188
195
  const { apiSymbol, isFutures } = parseTicker(ticker);
189
196
  const interval = TF_TO_INTERVAL[normalizeTf(timeframe)];
@@ -1,5 +1,16 @@
1
1
  'use strict';
2
2
 
3
+ // src/data/symbol-base.ts
4
+ function baseOf(d) {
5
+ const fromDesc = d.description?.split("/")[0]?.trim();
6
+ if (fromDesc) return fromDesc.replace(/\s+Perpetual$/i, "");
7
+ return d.ticker.replace(/[-_/]?(USDT|USDC|USD1|USDS|BUSD|USD|EUR|PERP)$/i, "") || d.ticker;
8
+ }
9
+ function ledgerCryptoIconUrl(base) {
10
+ const key = base.trim().toUpperCase();
11
+ return key ? `https://crypto-icons.ledger.com/${encodeURIComponent(key)}.png` : void 0;
12
+ }
13
+
3
14
  // src/data/providers/coinbase/RequestGate.ts
4
15
  var REAL_CLOCK = {
5
16
  now: () => Date.now(),
@@ -234,6 +245,11 @@ var CoinbaseProvider = class {
234
245
  }
235
246
  return this.symbolsPromise;
236
247
  }
248
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
249
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
250
+ resolveSymbolIcon(symbol) {
251
+ return ledgerCryptoIconUrl(baseOf(symbol));
252
+ }
237
253
  subscribe(ticker, timeframe, onBar) {
238
254
  const gran = TF_TO_GRAN[normalizeTf(timeframe)];
239
255
  if (gran && typeof WebSocket !== "undefined") return this.streamTicker(ticker, timeframe, gran, onBar);
@@ -1,5 +1,5 @@
1
1
  import { O as OHLCV, U as Unsubscribe } from '../options-BaVTMXaO.cjs';
2
- import { D as DataProvider, P as ProviderInfo, B as BarRange, S as SymbolInfo, a as SymbolDescriptor } from '../DataProvider-DDUYw2qP.cjs';
2
+ import { D as DataProvider, P as ProviderInfo, B as BarRange, S as SymbolInfo, a as SymbolDescriptor } from '../DataProvider-BsQM2WNH.cjs';
3
3
 
4
4
  /**
5
5
  * Coinbase market-data provider, built from scratch on the public Exchange REST + WebSocket APIs
@@ -24,6 +24,9 @@ declare class CoinbaseProvider implements DataProvider {
24
24
  getBars(ticker: string, timeframe: string, range: BarRange): Promise<OHLCV[]>;
25
25
  getSymbolInfo(ticker: string): Promise<SymbolInfo | undefined>;
26
26
  listSymbols(): Promise<SymbolDescriptor[]>;
27
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
28
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
29
+ resolveSymbolIcon(symbol: SymbolDescriptor): string | undefined;
27
30
  subscribe(ticker: string, timeframe: string, onBar: (bar: OHLCV) => void): Unsubscribe;
28
31
  private fetchProducts;
29
32
  /**
@@ -1,5 +1,5 @@
1
1
  import { O as OHLCV, U as Unsubscribe } from '../options-BaVTMXaO.js';
2
- import { D as DataProvider, P as ProviderInfo, B as BarRange, S as SymbolInfo, a as SymbolDescriptor } from '../DataProvider-JJq7M2it.js';
2
+ import { D as DataProvider, P as ProviderInfo, B as BarRange, S as SymbolInfo, a as SymbolDescriptor } from '../DataProvider-BSLlBpB9.js';
3
3
 
4
4
  /**
5
5
  * Coinbase market-data provider, built from scratch on the public Exchange REST + WebSocket APIs
@@ -24,6 +24,9 @@ declare class CoinbaseProvider implements DataProvider {
24
24
  getBars(ticker: string, timeframe: string, range: BarRange): Promise<OHLCV[]>;
25
25
  getSymbolInfo(ticker: string): Promise<SymbolInfo | undefined>;
26
26
  listSymbols(): Promise<SymbolDescriptor[]>;
27
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
28
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
29
+ resolveSymbolIcon(symbol: SymbolDescriptor): string | undefined;
27
30
  subscribe(ticker: string, timeframe: string, onBar: (bar: OHLCV) => void): Unsubscribe;
28
31
  private fetchProducts;
29
32
  /**
@@ -1,3 +1,5 @@
1
+ import { ledgerCryptoIconUrl, baseOf } from '../chunk-W4EJWLEO.js';
2
+
1
3
  // src/data/providers/coinbase/RequestGate.ts
2
4
  var REAL_CLOCK = {
3
5
  now: () => Date.now(),
@@ -232,6 +234,11 @@ var CoinbaseProvider = class {
232
234
  }
233
235
  return this.symbolsPromise;
234
236
  }
237
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
238
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
239
+ resolveSymbolIcon(symbol) {
240
+ return ledgerCryptoIconUrl(baseOf(symbol));
241
+ }
235
242
  subscribe(ticker, timeframe, onBar) {
236
243
  const gran = TF_TO_GRAN[normalizeTf(timeframe)];
237
244
  if (gran && typeof WebSocket !== "undefined") return this.streamTicker(ticker, timeframe, gran, onBar);
@@ -1,5 +1,16 @@
1
1
  'use strict';
2
2
 
3
+ // src/data/symbol-base.ts
4
+ function baseOf(d) {
5
+ const fromDesc = d.description?.split("/")[0]?.trim();
6
+ if (fromDesc) return fromDesc.replace(/\s+Perpetual$/i, "");
7
+ return d.ticker.replace(/[-_/]?(USDT|USDC|USD1|USDS|BUSD|USD|EUR|PERP)$/i, "") || d.ticker;
8
+ }
9
+ function ledgerCryptoIconUrl(base) {
10
+ const key = base.trim().toUpperCase();
11
+ return key ? `https://crypto-icons.ledger.com/${encodeURIComponent(key)}.png` : void 0;
12
+ }
13
+
3
14
  // src/data/providers/hyperliquid/HyperliquidProvider.ts
4
15
  var INFO_URL = "https://api.hyperliquid.xyz/info";
5
16
  var WS_URL = "wss://api.hyperliquid.xyz/ws";
@@ -172,6 +183,11 @@ var HyperliquidProvider = class {
172
183
  }
173
184
  return this.symbolsPromise;
174
185
  }
186
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
187
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
188
+ resolveSymbolIcon(symbol) {
189
+ return ledgerCryptoIconUrl(baseOf(symbol));
190
+ }
175
191
  subscribe(ticker, timeframe, onBar) {
176
192
  const coin = parseCoin(ticker);
177
193
  const interval = TF_TO_INTERVAL[normalizeTf(timeframe)];
@@ -1,5 +1,5 @@
1
1
  import { O as OHLCV, U as Unsubscribe } from '../options-BaVTMXaO.cjs';
2
- import { D as DataProvider, P as ProviderInfo, B as BarRange, S as SymbolInfo, a as SymbolDescriptor } from '../DataProvider-DDUYw2qP.cjs';
2
+ import { D as DataProvider, P as ProviderInfo, B as BarRange, S as SymbolInfo, a as SymbolDescriptor } from '../DataProvider-BsQM2WNH.cjs';
3
3
 
4
4
  /**
5
5
  * Hyperliquid market-data provider, built from scratch on the public info API — no
@@ -26,6 +26,9 @@ declare class HyperliquidProvider implements DataProvider {
26
26
  getBars(ticker: string, timeframe: string, range: BarRange): Promise<OHLCV[]>;
27
27
  getSymbolInfo(ticker: string): Promise<SymbolInfo | undefined>;
28
28
  listSymbols(): Promise<SymbolDescriptor[]>;
29
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
30
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
31
+ resolveSymbolIcon(symbol: SymbolDescriptor): string | undefined;
29
32
  subscribe(ticker: string, timeframe: string, onBar: (bar: OHLCV) => void): Unsubscribe;
30
33
  private listPerps;
31
34
  private listSpot;
@@ -1,5 +1,5 @@
1
1
  import { O as OHLCV, U as Unsubscribe } from '../options-BaVTMXaO.js';
2
- import { D as DataProvider, P as ProviderInfo, B as BarRange, S as SymbolInfo, a as SymbolDescriptor } from '../DataProvider-JJq7M2it.js';
2
+ import { D as DataProvider, P as ProviderInfo, B as BarRange, S as SymbolInfo, a as SymbolDescriptor } from '../DataProvider-BSLlBpB9.js';
3
3
 
4
4
  /**
5
5
  * Hyperliquid market-data provider, built from scratch on the public info API — no
@@ -26,6 +26,9 @@ declare class HyperliquidProvider implements DataProvider {
26
26
  getBars(ticker: string, timeframe: string, range: BarRange): Promise<OHLCV[]>;
27
27
  getSymbolInfo(ticker: string): Promise<SymbolInfo | undefined>;
28
28
  listSymbols(): Promise<SymbolDescriptor[]>;
29
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
30
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
31
+ resolveSymbolIcon(symbol: SymbolDescriptor): string | undefined;
29
32
  subscribe(ticker: string, timeframe: string, onBar: (bar: OHLCV) => void): Unsubscribe;
30
33
  private listPerps;
31
34
  private listSpot;
@@ -1,3 +1,5 @@
1
+ import { ledgerCryptoIconUrl, baseOf } from '../chunk-W4EJWLEO.js';
2
+
1
3
  // src/data/providers/hyperliquid/HyperliquidProvider.ts
2
4
  var INFO_URL = "https://api.hyperliquid.xyz/info";
3
5
  var WS_URL = "wss://api.hyperliquid.xyz/ws";
@@ -170,6 +172,11 @@ var HyperliquidProvider = class {
170
172
  }
171
173
  return this.symbolsPromise;
172
174
  }
175
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
176
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
177
+ resolveSymbolIcon(symbol) {
178
+ return ledgerCryptoIconUrl(baseOf(symbol));
179
+ }
173
180
  subscribe(ticker, timeframe, onBar) {
174
181
  const coin = parseCoin(ticker);
175
182
  const interval = TF_TO_INTERVAL[normalizeTf(timeframe)];
@@ -7067,6 +7067,28 @@ var Vela = (function (exports) {
7067
7067
  const d = this.entries.get(resolved.provider)?.byTicker?.get(normTicker(resolved.ticker));
7068
7068
  return `${d?.prefix ?? resolved.provider}:${d?.ticker ?? resolved.ticker}`;
7069
7069
  }
7070
+ /** The icon URL for a DESCRIPTOR — routed to its OWNING provider's resolver (the
7071
+ * provider owns the knowledge of where its asset class's icons live). A missing
7072
+ * provider, an absent resolver, or a resolver that throws all mean "no icon" —
7073
+ * the shells' initials badge takes over, never an error. */
7074
+ symbolIconOf(d) {
7075
+ const name = d.provider ? normName(d.provider) : [...this.entries.keys()][0];
7076
+ const entry = name !== void 0 ? this.entries.get(name) : void 0;
7077
+ try {
7078
+ return entry?.provider.resolveSymbolIcon?.(d) ?? void 0;
7079
+ } catch {
7080
+ return void 0;
7081
+ }
7082
+ }
7083
+ /** The icon URL for a raw SYMBOL string (the statusline/object-tree path): resolve
7084
+ * to the owning provider, find its descriptor, route to the resolver. Before the
7085
+ * index settles (or for a lenient sole-provider resolution) a minimal synthetic
7086
+ * descriptor is offered — crypto resolvers can answer from the ticker alone. */
7087
+ symbolIcon(resolved) {
7088
+ if (!resolved) return void 0;
7089
+ const d = this.entries.get(resolved.provider)?.byTicker?.get(normTicker(resolved.ticker));
7090
+ return this.symbolIconOf({ ...d ?? { ticker: resolved.ticker }, provider: d?.provider ?? resolved.provider });
7091
+ }
7070
7092
  /** Indexed symbols for one provider (or all, concatenated) — for autocomplete. */
7071
7093
  symbolsOf(rawName) {
7072
7094
  if (rawName != null) return this.entries.get(normName(rawName))?.descriptors ?? [];
@@ -9287,6 +9309,14 @@ var Vela = (function (exports) {
9287
9309
  providerInstance(name) {
9288
9310
  return this.registry.get(name);
9289
9311
  }
9312
+ /** The icon URL for a DESCRIPTOR — its owning provider's `resolveSymbolIcon` (picker rows). */
9313
+ symbolIconOf(d) {
9314
+ return this.registry.symbolIconOf(d);
9315
+ }
9316
+ /** The icon URL for a raw SYMBOL string — resolve, then route (statusline, object tree). */
9317
+ symbolIcon(raw) {
9318
+ return this.registry.symbolIcon(this.resolveSymbol(raw));
9319
+ }
9290
9320
  symbols(name) {
9291
9321
  return this.registry.symbolsOf(name);
9292
9322
  }
@@ -9513,6 +9543,12 @@ var Vela = (function (exports) {
9513
9543
  symbols(provider) {
9514
9544
  return this.registry?.symbols(provider) ?? [];
9515
9545
  }
9546
+ /** The icon URL for `symbol` — its owning provider's `resolveSymbolIcon`, routed
9547
+ * through resolution. Undefined while unresolvable, when the provider declares no
9548
+ * resolver, or on a custom `deps.dataFeed` — the shells then show initials. */
9549
+ symbolIcon(symbol) {
9550
+ return this.registry?.symbolIcon(symbol);
9551
+ }
9516
9552
  /** Per-symbol metadata (Pine `syminfo.*`), resolved through the owning provider. */
9517
9553
  symbolInfo(symbol) {
9518
9554
  return this.registry?.symbolInfoFor(symbol) ?? Promise.resolve(void 0);
@@ -37004,6 +37040,9 @@ ${overlayScrollbarCss(".vela-sd-pane")}
37004
37040
  return element;
37005
37041
  }
37006
37042
 
37043
+ // src/widget/topbar-composition.ts
37044
+ var TOPBAR_BUILTIN_IDS = ["symbol", "timeframes", "style", "layout", "indicators", "actions", "undo-redo", "alerts", "panels", "screenshot"];
37045
+
37007
37046
  // src/widget/contributions.ts
37008
37047
  var registry4 = /* @__PURE__ */ new Map();
37009
37048
  var attachments = /* @__PURE__ */ new Map();
@@ -37033,7 +37072,18 @@ ${overlayScrollbarCss(".vela-sd-pane")}
37033
37072
  function sidePanels() {
37034
37073
  return [...panels.values()].sort((a, b) => (a.order ?? DEFAULT_PANEL_ORDER) - (b.order ?? DEFAULT_PANEL_ORDER));
37035
37074
  }
37075
+ var OVERRIDABLE_TOPBAR_IDS = ["indicators", "screenshot"];
37076
+ var overridableSet = new Set(OVERRIDABLE_TOPBAR_IDS);
37077
+ var builtinTopbarSet = new Set(TOPBAR_BUILTIN_IDS);
37078
+ function topbarActionOverride(id) {
37079
+ if (!overridableSet.has(id)) return void 0;
37080
+ return registry4.get(id);
37081
+ }
37036
37082
  function registerWidgetAction(desc) {
37083
+ if (builtinTopbarSet.has(desc.id) && !overridableSet.has(desc.id)) {
37084
+ console.warn(`[vela] widget action "${desc.id}": this built-in topbar slot is a stateful control and cannot be overridden \u2014 ignored. Overridable slots: ${OVERRIDABLE_TOPBAR_IDS.join(", ")}.`);
37085
+ return () => void 0;
37086
+ }
37037
37087
  registry4.set(desc.id, desc);
37038
37088
  return () => {
37039
37089
  if (registry4.get(desc.id) === desc) registry4.delete(desc.id);
@@ -37073,6 +37123,16 @@ ${overlayScrollbarCss(".vela-sd-pane")}
37073
37123
  function statePersistenceHandlers(scope) {
37074
37124
  return [...stateHandlers.values()].filter((h) => h.scope === scope);
37075
37125
  }
37126
+ var symbolRankingHook;
37127
+ function registerSymbolRanking(hook) {
37128
+ symbolRankingHook = hook;
37129
+ return () => {
37130
+ if (symbolRankingHook === hook) symbolRankingHook = void 0;
37131
+ };
37132
+ }
37133
+ function symbolRanking() {
37134
+ return symbolRankingHook;
37135
+ }
37076
37136
  var defaultEngines = /* @__PURE__ */ new Map();
37077
37137
  function registerDefaultEngine(language, make) {
37078
37138
  defaultEngines.set(language, make);
@@ -37104,6 +37164,17 @@ ${overlayScrollbarCss(".vela-sd-pane")}
37104
37164
  return `${parts3.instanceId}:${parts3.kind}:${normTitle}#${parts3.ordinal}`;
37105
37165
  }
37106
37166
 
37167
+ // src/data/symbol-base.ts
37168
+ function baseOf(d) {
37169
+ const fromDesc = d.description?.split("/")[0]?.trim();
37170
+ if (fromDesc) return fromDesc.replace(/\s+Perpetual$/i, "");
37171
+ return d.ticker.replace(/[-_/]?(USDT|USDC|USD1|USDS|BUSD|USD|EUR|PERP)$/i, "") || d.ticker;
37172
+ }
37173
+ function ledgerCryptoIconUrl(base) {
37174
+ const key = base.trim().toUpperCase();
37175
+ return key ? `https://crypto-icons.ledger.com/${encodeURIComponent(key)}.png` : void 0;
37176
+ }
37177
+
37107
37178
  // src/data/providers/binance/BinanceProvider.ts
37108
37179
  var SPOT_BASE = "https://api.binance.com/api/v3";
37109
37180
  var SPOT_BASE_US = "https://api.binance.us/api/v3";
@@ -37290,6 +37361,11 @@ ${overlayScrollbarCss(".vela-sd-pane")}
37290
37361
  }
37291
37362
  return this.symbolsPromise;
37292
37363
  }
37364
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
37365
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
37366
+ resolveSymbolIcon(symbol) {
37367
+ return ledgerCryptoIconUrl(baseOf(symbol));
37368
+ }
37293
37369
  subscribe(ticker, timeframe, onBar) {
37294
37370
  const { apiSymbol, isFutures } = parseTicker(ticker);
37295
37371
  const interval = TF_TO_INTERVAL[normalizeTf(timeframe)];
@@ -37663,6 +37739,11 @@ ${overlayScrollbarCss(".vela-sd-pane")}
37663
37739
  }
37664
37740
  return this.symbolsPromise;
37665
37741
  }
37742
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
37743
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
37744
+ resolveSymbolIcon(symbol) {
37745
+ return ledgerCryptoIconUrl(baseOf(symbol));
37746
+ }
37666
37747
  subscribe(ticker, timeframe, onBar) {
37667
37748
  const coin = parseCoin(ticker);
37668
37749
  const interval = TF_TO_INTERVAL2[normalizeTf2(timeframe)];
@@ -38083,6 +38164,11 @@ ${overlayScrollbarCss(".vela-sd-pane")}
38083
38164
  }
38084
38165
  return this.symbolsPromise;
38085
38166
  }
38167
+ /** Predefined icon source for a crypto venue: the Ledger crypto-icon CDN, keyed by
38168
+ * the BASE asset (the description's first segment, else the de-suffixed ticker). */
38169
+ resolveSymbolIcon(symbol) {
38170
+ return ledgerCryptoIconUrl(baseOf(symbol));
38171
+ }
38086
38172
  subscribe(ticker, timeframe, onBar) {
38087
38173
  const gran = TF_TO_GRAN[normalizeTf3(timeframe)];
38088
38174
  if (gran && typeof WebSocket !== "undefined") return this.streamTicker(ticker, timeframe, gran, onBar);
@@ -38336,6 +38422,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
38336
38422
  exports.MultiProviderFeed = MultiProviderFeed;
38337
38423
  exports.NEUTRAL = NEUTRAL;
38338
38424
  exports.NativeRenderer = NativeRenderer;
38425
+ exports.OVERRIDABLE_TOPBAR_IDS = OVERRIDABLE_TOPBAR_IDS;
38339
38426
  exports.RendererControl = RendererControl;
38340
38427
  exports.SERIES_LINE = SERIES_LINE;
38341
38428
  exports.SESSION_OFF = SESSION_OFF;
@@ -38379,6 +38466,7 @@ ${overlayScrollbarCss(".vela-sd-pane")}
38379
38466
  exports.registerRendererLayer = registerRendererLayer;
38380
38467
  exports.registerSidePanel = registerSidePanel;
38381
38468
  exports.registerStatePersistence = registerStatePersistence;
38469
+ exports.registerSymbolRanking = registerSymbolRanking;
38382
38470
  exports.registerWidgetAction = registerWidgetAction;
38383
38471
  exports.registerWidgetAttachment = registerWidgetAttachment;
38384
38472
  exports.rendererDefaults = rendererDefaults;
@@ -38391,8 +38479,10 @@ ${overlayScrollbarCss(".vela-sd-pane")}
38391
38479
  exports.splitColor = splitColor;
38392
38480
  exports.stableSeriesId = stableSeriesId;
38393
38481
  exports.statePersistenceHandlers = statePersistenceHandlers;
38482
+ exports.symbolRanking = symbolRanking;
38394
38483
  exports.tickerModifierIds = tickerModifierIds;
38395
38484
  exports.timeframeToMs = timeframeToMs;
38485
+ exports.topbarActionOverride = topbarActionOverride;
38396
38486
  exports.unregisterChartType = unregisterChartType;
38397
38487
  exports.unregisterDefaultEngine = unregisterDefaultEngine;
38398
38488
  exports.unregisterLegendAction = unregisterLegendAction;