@luxalgo/vela 0.6.10 → 0.6.11
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-CWmp31dA.d.ts → DataProvider-BBf-jc6W.d.ts} +1 -1
- package/dist/{DataProvider-l_eLMly_.d.cts → DataProvider-p0TEyhlX.d.cts} +1 -1
- package/dist/{chunk-FFOP37FQ.js → chunk-73PEA4MU.js} +131 -33
- package/dist/{chunk-NMTQXNT4.js → chunk-IO3NYSQV.js} +65 -22
- package/dist/{chunk-4KZVZ7QQ.js → chunk-MTLJKZDZ.js} +9 -1
- package/dist/{contributions-BCz6Dr6a.d.ts → contributions-Bbe2R-mQ.d.ts} +16 -2
- package/dist/{contributions-D9vTzm5p.d.cts → contributions-CO01zWve.d.cts} +16 -2
- package/dist/index.cjs +139 -32
- package/dist/index.d.cts +12 -6
- package/dist/index.d.ts +12 -6
- package/dist/index.js +3 -3
- package/dist/{options-DSqHsQyN.d.cts → options-yp7sA96q.d.cts} +8 -1
- package/dist/{options-DSqHsQyN.d.ts → options-yp7sA96q.d.ts} +8 -1
- package/dist/{plugin-Bt8hLR8Z.d.cts → plugin-CkkH8QnX.d.cts} +3 -3
- package/dist/{plugin-CH7pfMrE.d.ts → plugin-DwxjM3Ni.d.ts} +3 -3
- package/dist/plugin.cjs +9 -0
- 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-5K7y4Ya2.d.ts → statusline-CHPDuKNp.d.ts} +13 -5
- package/dist/{statusline-TYLQmoeh.d.cts → statusline-DTHZUFqK.d.cts} +13 -5
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/vela.global.js +139 -32
- package/dist/vela.global.min.js +43 -43
- package/dist/widget.cjs +201 -52
- package/dist/widget.d.cts +6 -6
- package/dist/widget.d.ts +6 -6
- package/dist/widget.js +4 -4
- package/dist/workspace.cjs +201 -52
- package/dist/workspace.d.cts +20 -11
- package/dist/workspace.d.ts +20 -11
- package/dist/workspace.js +3 -3
- package/package.json +1 -1
- /package/dist/{chunk-AOGZBKUE.js → chunk-H26BEHF4.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deserializeDrawing, chartTypes, rendererLayers, foldBaseModulation, registerChartType, rendererDefaults, getDrawingType, settingsRowVisible, normalizeSettingsRow, TextLabel, Callout, resetDrawingSettings, registerNativeIndicator, chartType, getNativeIndicator, nativeIndicatorDescriptors, drawingTypes, settingsRowValueKeys, formatDuration, RegressionChannel, FixedRangeVolumeProfile, SegmentDrawing, ArrowMark, GlyphStamp, RadialFib, FibSpiral, DedekindTessellation, MachFigure, GannSquare, FibRatios, MeasureBox, PositionTool, AnchoredVwap, PatternDrawing, Comment, PriceNote, Signpost, Note, PriceLabel, GANN_SQUARE_ARCS, lineSegmentIntersection, DEFAULT_DRAWING_COLOR, GLYPH_OPTIONS, STAMP_SIZE_OPTIONS, LINE_STYLE_OPTIONS, DEDEKIND_CURVATURE_OPTIONS, MACH_NUMBER_OPTIONS, MACH_WAVE_COUNT_OPTIONS, TEXT_SIZE_OPTIONS, createDrawing, inputVisible, tickerModifierIds, CalloutBase, DIRECTION_OPTIONS } from './chunk-
|
|
1
|
+
import { deserializeDrawing, chartTypes, rendererLayers, foldBaseModulation, registerChartType, rendererDefaults, getDrawingType, settingsRowVisible, normalizeSettingsRow, TextLabel, Callout, resetDrawingSettings, registerNativeIndicator, chartType, getNativeIndicator, nativeIndicatorDescriptors, drawingTypes, settingsRowValueKeys, formatDuration, RegressionChannel, FixedRangeVolumeProfile, SegmentDrawing, ArrowMark, GlyphStamp, RadialFib, FibSpiral, DedekindTessellation, MachFigure, GannSquare, FibRatios, MeasureBox, PositionTool, AnchoredVwap, PatternDrawing, Comment, PriceNote, Signpost, Note, PriceLabel, GANN_SQUARE_ARCS, lineSegmentIntersection, DEFAULT_DRAWING_COLOR, GLYPH_OPTIONS, STAMP_SIZE_OPTIONS, LINE_STYLE_OPTIONS, DEDEKIND_CURVATURE_OPTIONS, MACH_NUMBER_OPTIONS, MACH_WAVE_COUNT_OPTIONS, TEXT_SIZE_OPTIONS, createDrawing, inputVisible, tickerModifierIds, CalloutBase, DIRECTION_OPTIONS } from './chunk-MTLJKZDZ.js';
|
|
2
2
|
import { themeTokens, Dialog, closeOpenPopovers, closeWidthPopover, fieldSection, buildFieldControl, fieldSeparator, fieldGrid, fieldRow, blendOver, splitColor, CalloutBubble, Menu, TextArea, Popover, NumberInput, buildColorPicker, isPopoverOpen, eventDismissedPopover, toggleSelectList, openPopoverTrigger, fieldGridColumns, FIELD_GAP_PX, STATIC_TOKENS } from './chunk-MHY7MVXH.js';
|
|
3
3
|
import { icon, iconAt, withAlpha, WARNING, ACCENT, NEUTRAL, BEARISH, BULLISH, isDarkColor, SERIES_LINE, SLATE, CROSSHAIR, TRADE_EXIT, TRADE_SHORT, TRADE_LONG, overlayScrollbarCss, SLATE_DEEP, VALID, INVALID, FIELD_FOCUS_CSS, FIELD_FOCUS_RING, svg24, svg24Solid } from './chunk-KG4YT3TI.js';
|
|
4
4
|
|
|
@@ -6859,6 +6859,7 @@ var DOUBLE_TAP_MS = 350;
|
|
|
6859
6859
|
var DOUBLE_TAP_SLOP = 30;
|
|
6860
6860
|
var TIME_SCALE_K = 4e-3;
|
|
6861
6861
|
var WHEEL_ZOOM_K = 4e-3;
|
|
6862
|
+
var WHEEL_PRICE_DRAG_PX = 0.25;
|
|
6862
6863
|
function wheelZoomAnchor(coords, cursorX, rightEdge) {
|
|
6863
6864
|
if (rightEdge) return { logical: coords.rightEdgeLogical, x: coords.width };
|
|
6864
6865
|
return { logical: coords.xToLogical(cursorX), x: cursorX };
|
|
@@ -6989,7 +6990,7 @@ var InputController = class {
|
|
|
6989
6990
|
this.capture(e.pointerId);
|
|
6990
6991
|
return;
|
|
6991
6992
|
}
|
|
6992
|
-
if (e.shiftKey && this.regionAt(x, y) === "data" && this.deps.drawingsMeasureStart?.(x, y)) {
|
|
6993
|
+
if (e.shiftKey && this.regionAt(x, y) === "data" && this.deps.drawingsMeasureStart?.(x, y, this.snapMode(e))) {
|
|
6993
6994
|
this.region = "drawing";
|
|
6994
6995
|
this.capture(e.pointerId);
|
|
6995
6996
|
return;
|
|
@@ -7103,7 +7104,7 @@ var InputController = class {
|
|
|
7103
7104
|
const wasTouch = e.pointerType === "touch";
|
|
7104
7105
|
const tapRelease = this.dragging && !this.moved && (!wasTouch || Math.hypot(x - this.startX, y - this.startY) <= TOUCH_TAP_SLOP);
|
|
7105
7106
|
if (this.dragging && this.region === "drawing") {
|
|
7106
|
-
this.deps.drawingsPointerUp?.(x, y);
|
|
7107
|
+
this.deps.drawingsPointerUp?.(x, y, this.snapMode(e));
|
|
7107
7108
|
} else if (tapRelease && this.region === "data") {
|
|
7108
7109
|
this.deps.onClick(x, y);
|
|
7109
7110
|
} else if (this.dragging && this.region === "data") {
|
|
@@ -7124,7 +7125,7 @@ var InputController = class {
|
|
|
7124
7125
|
if (e.pointerType === "touch") this.touches.delete(e.pointerId);
|
|
7125
7126
|
this.cancelLongPress();
|
|
7126
7127
|
if (!this.dragging) return;
|
|
7127
|
-
if (this.region === "drawing" && !Number.isNaN(this.cursorX)) this.deps.drawingsPointerUp?.(this.cursorX, this.cursorY);
|
|
7128
|
+
if (this.region === "drawing" && !Number.isNaN(this.cursorX)) this.deps.drawingsPointerUp?.(this.cursorX, this.cursorY, this.snapMode(e));
|
|
7128
7129
|
if (this.region === "crosshair" || e.pointerType === "touch") this.deps.onPointerMove(null, null);
|
|
7129
7130
|
this.endGesture(e);
|
|
7130
7131
|
};
|
|
@@ -7140,6 +7141,12 @@ var InputController = class {
|
|
|
7140
7141
|
this.onWheel = (e) => {
|
|
7141
7142
|
e.preventDefault();
|
|
7142
7143
|
this.deps.drawingsClearTransient?.();
|
|
7144
|
+
const { x, y } = this.local(e);
|
|
7145
|
+
if (this.regionAt(x, y) === "price" && e.deltaY !== 0) {
|
|
7146
|
+
this.deps.beginPriceScale(x, y);
|
|
7147
|
+
this.deps.priceScaleBy(e.deltaY * WHEEL_PRICE_DRAG_PX);
|
|
7148
|
+
return;
|
|
7149
|
+
}
|
|
7143
7150
|
const coords = this.deps.getCoords();
|
|
7144
7151
|
const vp = coords.getViewport();
|
|
7145
7152
|
const pan = wheelPanDelta(e.deltaX, e.deltaY, e.shiftKey);
|
|
@@ -7147,9 +7154,8 @@ var InputController = class {
|
|
|
7147
7154
|
this.deps.apply({ barSpacing: vp.barSpacing, rightOffset: wheelPanRightOffset(vp.rightOffset, pan, coords.pxPerBar()) });
|
|
7148
7155
|
return;
|
|
7149
7156
|
}
|
|
7150
|
-
const cursorX = this.local(e).x;
|
|
7151
7157
|
const rightEdge = this.rightEdgeZoom && !(e.ctrlKey || e.metaKey);
|
|
7152
|
-
const anchor = wheelZoomAnchor(coords,
|
|
7158
|
+
const anchor = wheelZoomAnchor(coords, x, rightEdge);
|
|
7153
7159
|
const target = clampBarSpacing(vp.barSpacing * Math.exp(-e.deltaY * WHEEL_ZOOM_K));
|
|
7154
7160
|
this.deps.zoomTo(target, anchor.logical, anchor.x);
|
|
7155
7161
|
};
|
|
@@ -8631,6 +8637,15 @@ function drawingSetEmpty(s) {
|
|
|
8631
8637
|
function fontSizePx(size) {
|
|
8632
8638
|
return size === "auto" ? 12 : namedFontSize(size);
|
|
8633
8639
|
}
|
|
8640
|
+
function lineCoversWindow(a, b, extend, lo, hi) {
|
|
8641
|
+
const minX = Math.min(a, b);
|
|
8642
|
+
const maxX = Math.max(a, b);
|
|
8643
|
+
if (a === b) return a >= lo && a <= hi;
|
|
8644
|
+
if (extend === "both") return true;
|
|
8645
|
+
if (extend === "left") return maxX >= lo;
|
|
8646
|
+
if (extend === "right") return minX <= hi;
|
|
8647
|
+
return maxX >= lo && minX <= hi;
|
|
8648
|
+
}
|
|
8634
8649
|
var DrawingSceneRenderer = class {
|
|
8635
8650
|
constructor(deps, set = EMPTY_DRAWING_SET) {
|
|
8636
8651
|
this.deps = deps;
|
|
@@ -8695,7 +8710,7 @@ var DrawingSceneRenderer = class {
|
|
|
8695
8710
|
};
|
|
8696
8711
|
for (const ln of this.set.lines) {
|
|
8697
8712
|
if (ln.invisible) continue;
|
|
8698
|
-
if (!
|
|
8713
|
+
if (!lineCoversWindow(this.logicalOf(ln.xloc, ln.x1), this.logicalOf(ln.xloc, ln.x2), ln.extend, lo, hi)) continue;
|
|
8699
8714
|
fold(ln.y1);
|
|
8700
8715
|
fold(ln.y2);
|
|
8701
8716
|
}
|
|
@@ -12545,6 +12560,22 @@ var DrawingInteraction = class {
|
|
|
12545
12560
|
this.snapAt = changed ? { point: snapped, paneId } : null;
|
|
12546
12561
|
return snapped;
|
|
12547
12562
|
}
|
|
12563
|
+
/**
|
|
12564
|
+
* Resolve a cursor pixel through the magnet and return the snapped pixel — the same
|
|
12565
|
+
* conversion drawing placement uses. Updates the snap-ring marker. The measure
|
|
12566
|
+
* ruler goes through this so its endpoints follow weak/strong/Ctrl magnet too.
|
|
12567
|
+
*/
|
|
12568
|
+
snapCursor(x, y, mode) {
|
|
12569
|
+
const proj = this.deps.projector();
|
|
12570
|
+
const paneId = proj.paneIdAtY(y) ?? "price";
|
|
12571
|
+
const point = this.resolve(x, y, paneId, mode);
|
|
12572
|
+
const sy = proj.yOf(point.price, paneId);
|
|
12573
|
+
return { x: proj.xOf(point.time), y: sy ?? y };
|
|
12574
|
+
}
|
|
12575
|
+
/** Drop the snap-ring marker (a transient mode ended without going through `up`). */
|
|
12576
|
+
clearSnapMarker() {
|
|
12577
|
+
this.snapAt = null;
|
|
12578
|
+
}
|
|
12548
12579
|
/** Resolve a pixel to a data point with the segment angle locked to 45° steps around
|
|
12549
12580
|
* `pivot` (Shift held on a line tool). Works in PIXEL space — the user reasons about
|
|
12550
12581
|
* the angle they see, not about time/price units. The magnet is bypassed: snapping
|
|
@@ -13950,30 +13981,39 @@ var MeasureOverlay = class {
|
|
|
13950
13981
|
isFinished() {
|
|
13951
13982
|
return this.state === "finished";
|
|
13952
13983
|
}
|
|
13953
|
-
/** A press: begin the measurement, or finish it on the second click.
|
|
13954
|
-
|
|
13984
|
+
/** A press: begin the measurement, or finish it on the second click.
|
|
13985
|
+
* `x,y` are the raw cursor (drag-slop vs click-move-click). `gx,gy` are the
|
|
13986
|
+
* graphic endpoints — magnet-snapped when the magnet is on, else the same as `x,y`. */
|
|
13987
|
+
down(x, y, gx = x, gy = y) {
|
|
13955
13988
|
if (this.state === "measuring") {
|
|
13956
|
-
this.end = { x, y };
|
|
13989
|
+
this.end = { x: gx, y: gy };
|
|
13957
13990
|
this.state = "finished";
|
|
13958
13991
|
return;
|
|
13959
13992
|
}
|
|
13960
|
-
this.start = { x, y };
|
|
13961
|
-
this.end = { x, y };
|
|
13993
|
+
this.start = { x: gx, y: gy };
|
|
13994
|
+
this.end = { x: gx, y: gy };
|
|
13962
13995
|
this.pressX = x;
|
|
13963
13996
|
this.pressY = y;
|
|
13964
13997
|
this.state = "measuring";
|
|
13965
13998
|
}
|
|
13999
|
+
/** Size the in-progress ruler. `x,y` are the graphic (magnet-snapped) cursor. */
|
|
13966
14000
|
move(x, y) {
|
|
13967
14001
|
if (this.state === "measuring") this.end = { x, y };
|
|
13968
14002
|
}
|
|
13969
14003
|
/** A release: finish if the press was actually dragged (press-drag-release), else wait
|
|
13970
|
-
* for the second click (click-move-click).
|
|
13971
|
-
|
|
14004
|
+
* for the second click (click-move-click). `x,y` are the raw cursor (slop); `gx,gy`
|
|
14005
|
+
* are the graphic end (magnet-snapped when the magnet is on). */
|
|
14006
|
+
up(x, y, gx = x, gy = y) {
|
|
13972
14007
|
if (this.state === "measuring" && Math.hypot(x - this.pressX, y - this.pressY) > DRAG_SLOP3) {
|
|
13973
|
-
this.end = { x, y };
|
|
14008
|
+
this.end = { x: gx, y: gy };
|
|
13974
14009
|
this.state = "finished";
|
|
13975
14010
|
}
|
|
13976
14011
|
}
|
|
14012
|
+
/** Current graphic endpoints in media pixels, or null when idle. */
|
|
14013
|
+
points() {
|
|
14014
|
+
if (!this.start || !this.end) return null;
|
|
14015
|
+
return { start: this.start, end: this.end };
|
|
14016
|
+
}
|
|
13977
14017
|
clear() {
|
|
13978
14018
|
this.state = "idle";
|
|
13979
14019
|
this.start = null;
|
|
@@ -14350,11 +14390,13 @@ var UserDrawingController = class {
|
|
|
14350
14390
|
}
|
|
14351
14391
|
/** Shift+press on the empty plot: arm the measure ruler AND start it at (x, y) in one
|
|
14352
14392
|
* gesture — the equivalent of clicking the toolbar's Measure button, then pressing.
|
|
14353
|
-
*
|
|
14354
|
-
|
|
14393
|
+
* `snap` is the effective magnet (sticky mode, or Ctrl/Cmd-forced strong). Returns
|
|
14394
|
+
* false when a mode/tool is already active (the normal press path owns it). */
|
|
14395
|
+
beginMeasureAt(x, y, snap = "off") {
|
|
14355
14396
|
if (this.measureMode || this.eraserMode || this.activeTool != null) return false;
|
|
14356
14397
|
this.withModeIntent(() => this.toggleMeasure());
|
|
14357
|
-
this.
|
|
14398
|
+
const g = this.interaction.snapCursor(x, y, snap);
|
|
14399
|
+
this.measure.down(x, y, g.x, g.y);
|
|
14358
14400
|
this.render();
|
|
14359
14401
|
return true;
|
|
14360
14402
|
}
|
|
@@ -14376,7 +14418,8 @@ var UserDrawingController = class {
|
|
|
14376
14418
|
return;
|
|
14377
14419
|
}
|
|
14378
14420
|
if (this.measureMode) {
|
|
14379
|
-
this.
|
|
14421
|
+
const g = this.interaction.snapCursor(x, y, snap);
|
|
14422
|
+
this.measure.down(x, y, g.x, g.y);
|
|
14380
14423
|
if (this.measure.isFinished()) this.withModeIntent(() => this.exitMeasure(false));
|
|
14381
14424
|
this.render();
|
|
14382
14425
|
return;
|
|
@@ -14389,7 +14432,8 @@ var UserDrawingController = class {
|
|
|
14389
14432
|
return;
|
|
14390
14433
|
}
|
|
14391
14434
|
if (this.measureMode) {
|
|
14392
|
-
this.
|
|
14435
|
+
const g = this.interaction.snapCursor(x, y, snap);
|
|
14436
|
+
this.measure.move(g.x, g.y);
|
|
14393
14437
|
this.render();
|
|
14394
14438
|
return;
|
|
14395
14439
|
}
|
|
@@ -14407,13 +14451,14 @@ var UserDrawingController = class {
|
|
|
14407
14451
|
this.render();
|
|
14408
14452
|
}
|
|
14409
14453
|
}
|
|
14410
|
-
pointerUp(x, y) {
|
|
14454
|
+
pointerUp(x, y, snap = "off") {
|
|
14411
14455
|
if (this.eraserMode) {
|
|
14412
14456
|
this.erasing = false;
|
|
14413
14457
|
return;
|
|
14414
14458
|
}
|
|
14415
14459
|
if (this.measureMode) {
|
|
14416
|
-
this.
|
|
14460
|
+
const g = this.interaction.snapCursor(x, y, snap);
|
|
14461
|
+
this.measure.up(x, y, g.x, g.y);
|
|
14417
14462
|
if (this.measure.isFinished()) this.withModeIntent(() => this.exitMeasure(false));
|
|
14418
14463
|
this.render();
|
|
14419
14464
|
return;
|
|
@@ -14458,6 +14503,7 @@ var UserDrawingController = class {
|
|
|
14458
14503
|
/** Leave ruler mode. `clearGraphic` keeps a just-finished measurement on screen (false). */
|
|
14459
14504
|
exitMeasure(clearGraphic = true) {
|
|
14460
14505
|
this.measureMode = false;
|
|
14506
|
+
this.interaction.clearSnapMarker();
|
|
14461
14507
|
if (clearGraphic) this.measure.clear();
|
|
14462
14508
|
this.toolbar.setMeasureActive(false);
|
|
14463
14509
|
this.render();
|
|
@@ -14598,15 +14644,28 @@ var UserDrawingController = class {
|
|
|
14598
14644
|
if (this.eraserMode) return "pointer";
|
|
14599
14645
|
return this.interaction.cursorAt(x, y);
|
|
14600
14646
|
}
|
|
14601
|
-
/** Right-click
|
|
14602
|
-
*
|
|
14603
|
-
*
|
|
14604
|
-
*
|
|
14647
|
+
/** Right-click: an explicit escape back to the pointer. Cancels an in-progress
|
|
14648
|
+
* placement or measurement, and also plain-disarms an armed-but-idle drawing
|
|
14649
|
+
* tool or the eraser — so a right-click ALWAYS reverts to the pointer, even in
|
|
14650
|
+
* stay-in-drawing-mode (where Escape would leave a drawing tool armed).
|
|
14651
|
+
* Persistent toggles (magnet, stay-mode, favorites) are untouched. Returns
|
|
14652
|
+
* whether the press was consumed; false lets the host's context menu open
|
|
14653
|
+
* normally. */
|
|
14605
14654
|
cancelPlacement() {
|
|
14606
|
-
if (
|
|
14607
|
-
|
|
14608
|
-
|
|
14609
|
-
|
|
14655
|
+
if (this.measureMode || this.eraserMode) {
|
|
14656
|
+
this.withModeIntent(() => this.measureMode ? this.exitMeasure() : this.exitEraser());
|
|
14657
|
+
return true;
|
|
14658
|
+
}
|
|
14659
|
+
if (this.interaction.isPlacing()) {
|
|
14660
|
+
this.interaction.cancel();
|
|
14661
|
+
if (this.activeTool != null) this.emit({ kind: "arm", type: null });
|
|
14662
|
+
return true;
|
|
14663
|
+
}
|
|
14664
|
+
if (this.activeTool != null) {
|
|
14665
|
+
this.emit({ kind: "arm", type: null });
|
|
14666
|
+
return true;
|
|
14667
|
+
}
|
|
14668
|
+
return false;
|
|
14610
14669
|
}
|
|
14611
14670
|
/** Double-click over a drawing → suppress the chart's view reset (single-click already
|
|
14612
14671
|
* opens settings). Returns true only when a drawing is under the cursor. */
|
|
@@ -14632,6 +14691,10 @@ var UserDrawingController = class {
|
|
|
14632
14691
|
return true;
|
|
14633
14692
|
}
|
|
14634
14693
|
if (this.interaction.cancel()) return true;
|
|
14694
|
+
if (this.measureMode) {
|
|
14695
|
+
this.withModeIntent(() => this.exitMeasure());
|
|
14696
|
+
return true;
|
|
14697
|
+
}
|
|
14635
14698
|
if (this.selectedIds.size) {
|
|
14636
14699
|
this.clearSelection();
|
|
14637
14700
|
return true;
|
|
@@ -17164,13 +17227,13 @@ var NativeRenderer = class {
|
|
|
17164
17227
|
resetView: () => this.resetView(),
|
|
17165
17228
|
// User drawings claim a gesture before pan when armed / over a drawing.
|
|
17166
17229
|
drawingsClaim: (x, y) => this.userDrawings?.claim(x, y) ?? false,
|
|
17167
|
-
drawingsMeasureStart: (x, y) => this.userDrawings?.beginMeasureAt(x, y) ?? false,
|
|
17230
|
+
drawingsMeasureStart: (x, y, snap) => this.userDrawings?.beginMeasureAt(x, y, snap) ?? false,
|
|
17168
17231
|
drawingsDeleteAt: (x, y) => this.userDrawings?.deleteAt(x, y) ?? false,
|
|
17169
17232
|
drawingsCancelPlacement: () => this.userDrawings?.cancelPlacement() ?? false,
|
|
17170
17233
|
drawingsSnapMode: () => this.snapMode,
|
|
17171
17234
|
drawingsPointerDown: (x, y, snap, shift) => this.userDrawings?.pointerDown(x, y, snap, shift),
|
|
17172
17235
|
drawingsPointerMove: (x, y, snap, shift) => this.userDrawings?.pointerMove(x, y, snap, shift),
|
|
17173
|
-
drawingsPointerUp: (x, y) => this.userDrawings?.pointerUp(x, y),
|
|
17236
|
+
drawingsPointerUp: (x, y, snap) => this.userDrawings?.pointerUp(x, y, snap),
|
|
17174
17237
|
drawingsCursor: (x, y) => this.userDrawings?.cursorAt(x, y) ?? null,
|
|
17175
17238
|
drawingsDblClick: (x, y) => this.userDrawings?.dblClick(x, y) ?? false,
|
|
17176
17239
|
drawingsClearTransient: () => this.userDrawings?.clearTransient()
|
|
@@ -17485,7 +17548,8 @@ var NativeRenderer = class {
|
|
|
17485
17548
|
}
|
|
17486
17549
|
const skipFit = opts?.preserveView === true && this.didInitialFit;
|
|
17487
17550
|
if (this.coords.width > 0 && !skipFit) {
|
|
17488
|
-
this.
|
|
17551
|
+
if (this.didInitialFit) this.reframeKeepZoom();
|
|
17552
|
+
else this.fitContent();
|
|
17489
17553
|
this.didInitialFit = true;
|
|
17490
17554
|
}
|
|
17491
17555
|
if (!this.introPlayed && this.bars.length > 0) {
|
|
@@ -18133,6 +18197,7 @@ var NativeRenderer = class {
|
|
|
18133
18197
|
this.scaleDragHeight = res.height;
|
|
18134
18198
|
this.scaleDragStart = { ...res.holder.scale };
|
|
18135
18199
|
res.holder.manualScale = { ...res.holder.scale };
|
|
18200
|
+
this.axisScaleButtons?.reposition();
|
|
18136
18201
|
this.scheduler.invalidate(4 /* Full */);
|
|
18137
18202
|
}
|
|
18138
18203
|
/** Rescale the grabbed scale around its center by the total drag (down ⇒ zoom out). */
|
|
@@ -18164,6 +18229,7 @@ var NativeRenderer = class {
|
|
|
18164
18229
|
const res = this.resolveScaleHolder(x, y);
|
|
18165
18230
|
if (!res) return;
|
|
18166
18231
|
res.holder.manualScale = null;
|
|
18232
|
+
this.axisScaleButtons?.reposition();
|
|
18167
18233
|
this.scheduler.invalidate(4 /* Full */);
|
|
18168
18234
|
}
|
|
18169
18235
|
/**
|
|
@@ -18801,6 +18867,20 @@ var NativeRenderer = class {
|
|
|
18801
18867
|
this.coords.setViewport(v);
|
|
18802
18868
|
this.targetBarSpacing = v.barSpacing;
|
|
18803
18869
|
}
|
|
18870
|
+
/** Re-frame after a series replacement (a symbol/timeframe switch): keep the user's
|
|
18871
|
+
* zoom (bar spacing), re-anchor the newest bars at the default right offset.
|
|
18872
|
+
* `clampViewport`'s fit-all-bars floor deliberately does NOT apply — a progressive
|
|
18873
|
+
* head may still be backfilling toward the previous depth, and raising the spacing
|
|
18874
|
+
* to its temporary bar count would lose the zoom this exists to keep. */
|
|
18875
|
+
reframeKeepZoom() {
|
|
18876
|
+
this.animator?.stop();
|
|
18877
|
+
this.panVelocity = 0;
|
|
18878
|
+
for (const pane of this.scene.panes.values()) pane.manualScale = null;
|
|
18879
|
+
for (const sl of this.scene.indicatorScales.values()) sl.manualScale = null;
|
|
18880
|
+
const v = { barSpacing: clampBarSpacing(this.coords.getViewport().barSpacing), rightOffset: defaultViewport().rightOffset };
|
|
18881
|
+
this.coords.setViewport(v);
|
|
18882
|
+
this.targetBarSpacing = v.barSpacing;
|
|
18883
|
+
}
|
|
18804
18884
|
paneBoundsFor(paneId) {
|
|
18805
18885
|
const p = this.scene.panes.get(paneId);
|
|
18806
18886
|
return { top: p?.bounds.top ?? 0, height: p?.bounds.height ?? 0, rightAxis: this.rightAxisW };
|
|
@@ -19367,6 +19447,12 @@ var IndicatorHandleImpl = class {
|
|
|
19367
19447
|
get visible() {
|
|
19368
19448
|
return this.visibleState;
|
|
19369
19449
|
}
|
|
19450
|
+
inputValues() {
|
|
19451
|
+
return this.controller.inputValuesOf(this.id);
|
|
19452
|
+
}
|
|
19453
|
+
propValues() {
|
|
19454
|
+
return this.controller.propValuesOf(this.id);
|
|
19455
|
+
}
|
|
19370
19456
|
setInput(key, value) {
|
|
19371
19457
|
this.controller.applyInputs(this.id, { [key]: value });
|
|
19372
19458
|
}
|
|
@@ -19506,6 +19592,7 @@ var RUN_EMIT_THROTTLE_MS = 1e3;
|
|
|
19506
19592
|
var PREVIEW_BARS = 300;
|
|
19507
19593
|
var SINGLE_LOAD_BARS = 5e3;
|
|
19508
19594
|
var CHUNK_BARS = 1e4;
|
|
19595
|
+
var FIRST_PAINT_BARS = 100;
|
|
19509
19596
|
var GAP_FACTOR = 1.5;
|
|
19510
19597
|
var HEAL_COOLDOWN_MS = 5e3;
|
|
19511
19598
|
var EngineOrchestrator = class _EngineOrchestrator {
|
|
@@ -19775,6 +19862,7 @@ var EngineOrchestrator = class _EngineOrchestrator {
|
|
|
19775
19862
|
let painted = false;
|
|
19776
19863
|
const paint = (bars, final) => {
|
|
19777
19864
|
if (this.generation !== gen || !final && bars.length === 0) return;
|
|
19865
|
+
if (!painted && !final && bars.length < Math.min(requested, FIRST_PAINT_BARS)) return;
|
|
19778
19866
|
this.setBarSeries(bars, painted ? { preserveView: true } : void 0);
|
|
19779
19867
|
if (!painted && bars.length > 0) {
|
|
19780
19868
|
painted = true;
|
|
@@ -20405,6 +20493,15 @@ var EngineOrchestrator = class _EngineOrchestrator {
|
|
|
20405
20493
|
record.pendingCause = "inputs";
|
|
20406
20494
|
if (record.session) record.session.update(record.inputValues);
|
|
20407
20495
|
else if (record.native && !record.hidden) record.native.instance.setInputs(record.inputValues);
|
|
20496
|
+
this.events.emit("indicator:inputs", { id });
|
|
20497
|
+
}
|
|
20498
|
+
/** IndicatorController: the CURRENT stored input values (defaults merged with edits). */
|
|
20499
|
+
inputValuesOf(id) {
|
|
20500
|
+
return { ...this.registry.get(id)?.inputValues };
|
|
20501
|
+
}
|
|
20502
|
+
/** IndicatorController: the CURRENT declaration-prop overrides. */
|
|
20503
|
+
propValuesOf(id) {
|
|
20504
|
+
return { ...this.registry.get(id)?.propValues };
|
|
20408
20505
|
}
|
|
20409
20506
|
/** IndicatorController: re-run an indicator with merged declaration-prop overrides.
|
|
20410
20507
|
* Same lifecycle as {@link applyInputs} — a prop change replays the whole script.
|
|
@@ -20418,6 +20515,7 @@ var EngineOrchestrator = class _EngineOrchestrator {
|
|
|
20418
20515
|
if (!record.hidden) this.setLoading(record, true);
|
|
20419
20516
|
record.pendingCause = "inputs";
|
|
20420
20517
|
record.session.update(record.inputValues, record.propValues);
|
|
20518
|
+
this.events.emit("indicator:inputs", { id });
|
|
20421
20519
|
}
|
|
20422
20520
|
/** IndicatorController: tear down an indicator and (if now empty) its pane. */
|
|
20423
20521
|
/** Live handles of every indicator on the chart (script + native), insertion order. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, tzButtonLabel, TIMEZONES, normalizeTimezone, tzMenuLabel, isGroupRow, defaultMemberOf, groupKeyOf, groupMembers, LEGEND_AT_TOP_ATTR, 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, legendCalloutsProviderFor, statePersistenceHandlers, topbarHas, rendererDefaults, widgetAttachments, getDrawingType } from './chunk-
|
|
1
|
+
import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, tzButtonLabel, TIMEZONES, normalizeTimezone, tzMenuLabel, isGroupRow, defaultMemberOf, groupKeyOf, groupMembers, LEGEND_AT_TOP_ATTR, Vela, TypedEventBus, MultiProviderFeed, registerBuiltinChartTypes, resolveTheme, buildToolbar, createCustomMark, createAttributionMark, DrawingToolbar, applyAttributionMarkTheme, sharedBarStore, timeframeToMs } from './chunk-73PEA4MU.js';
|
|
2
|
+
import { chartType, resolveTopbarComposition, topbarActionOverride, TOPBAR_BUILTIN_IDS, widgetActions, SidePanel, sidePanels, DEFAULT_PANEL_ORDER, symbolRanking, resolveEngines, legendActionsProviderFor, legendCalloutsProviderFor, statePersistenceHandlers, topbarHas, rendererDefaults, widgetAttachments, getDrawingType, inputDeltas } from './chunk-MTLJKZDZ.js';
|
|
3
3
|
import { Tooltip, KeymapManager, isEditableTarget, Drawer } from './chunk-G77Y7LK2.js';
|
|
4
4
|
import { Menu, Dialog, CalloutBubble, applyPlotOverlayTokens, ensureUIHost } from './chunk-MHY7MVXH.js';
|
|
5
5
|
import { registerIcon, svg16, injectStyles, iconEl, iconMarkup, SESSION_OFF, SESSION_POST, SESSION_PRE, icon, categoricalColor } from './chunk-KG4YT3TI.js';
|
|
@@ -3757,11 +3757,12 @@ async function resolveIndicators(config, fetchImpl = fetch) {
|
|
|
3757
3757
|
}
|
|
3758
3758
|
return out;
|
|
3759
3759
|
}
|
|
3760
|
+
var ledgerEntryName = (e) => typeof e === "string" ? e : e.name;
|
|
3760
3761
|
function indicatorLedger(i) {
|
|
3761
3762
|
const natives = [...i.present];
|
|
3762
3763
|
if (i.volumePending && !natives.includes("volume")) natives.push("volume");
|
|
3763
3764
|
return {
|
|
3764
|
-
manifest: i.manifestSettled ? [...i.
|
|
3765
|
+
manifest: i.manifestSettled ? [...i.instanceEntries] : [...i.pendingManifest ?? i.instanceEntries],
|
|
3765
3766
|
natives
|
|
3766
3767
|
};
|
|
3767
3768
|
}
|
|
@@ -3843,7 +3844,17 @@ function sanitizeCell(raw) {
|
|
|
3843
3844
|
if (c.drawings != null && typeof c.drawings === "object") out.drawings = c.drawings;
|
|
3844
3845
|
const ind = c.indicators;
|
|
3845
3846
|
if (ind != null && typeof ind === "object") {
|
|
3846
|
-
const manifest = Array.isArray(ind.manifest) ? ind.manifest.
|
|
3847
|
+
const manifest = Array.isArray(ind.manifest) ? ind.manifest.flatMap((n) => {
|
|
3848
|
+
if (typeof n === "string") return [n];
|
|
3849
|
+
if (n != null && typeof n === "object" && typeof n.name === "string") {
|
|
3850
|
+
const e = n;
|
|
3851
|
+
const bag = (v) => v != null && typeof v === "object" && !Array.isArray(v) ? v : void 0;
|
|
3852
|
+
const inputs = bag(e.inputs);
|
|
3853
|
+
const props = bag(e.props);
|
|
3854
|
+
return [inputs || props ? { name: e.name, ...inputs ? { inputs } : {}, ...props ? { props } : {} } : e.name];
|
|
3855
|
+
}
|
|
3856
|
+
return [];
|
|
3857
|
+
}) : [];
|
|
3847
3858
|
const natives = Array.isArray(ind.natives) ? ind.natives.filter((n) => typeof n === "string") : [];
|
|
3848
3859
|
out.indicators = { manifest, natives };
|
|
3849
3860
|
}
|
|
@@ -4969,6 +4980,7 @@ var TIME_AXIS_H2 = 22;
|
|
|
4969
4980
|
var CONTROLS_BOTTOM_PX = TIME_AXIS_H2 + 12;
|
|
4970
4981
|
var CLUSTER_H = 24;
|
|
4971
4982
|
var CLUSTER_PILL = "rgba(0,0,0,0.65)";
|
|
4983
|
+
var CLUSTER_LEFT_CSS = "calc((100% + var(--vela-toolbar-gutter, 0px) - var(--vela-scale-gutter, 0px)) / 2)";
|
|
4972
4984
|
var STYLE_ID12 = "vela-cell-controls";
|
|
4973
4985
|
var CSS12 = `
|
|
4974
4986
|
.vela-cc-btn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;border-radius:var(--vela-radius-sm);background:transparent;line-height:0;font-size:12px;color:var(--vela-fg-muted);cursor:pointer;}
|
|
@@ -4978,8 +4990,11 @@ var CSS12 = `
|
|
|
4978
4990
|
.vela-cc-grip{cursor:grab;touch-action:none;}
|
|
4979
4991
|
.vela-cc-grip:active{cursor:grabbing;}
|
|
4980
4992
|
`;
|
|
4981
|
-
function
|
|
4982
|
-
|
|
4993
|
+
function plotCenterX(width, toolbarGutter = 0, scaleGutter = 0) {
|
|
4994
|
+
return (width + toolbarGutter - scaleGutter) / 2;
|
|
4995
|
+
}
|
|
4996
|
+
function nearBottomCenter(x, y, width, height, proximityPx = CELL_CONTROLS_PROXIMITY_PX, gutters = {}) {
|
|
4997
|
+
const cx = plotCenterX(width, gutters.toolbar ?? 0, gutters.scale ?? 0);
|
|
4983
4998
|
const cy = height - CONTROLS_BOTTOM_PX - CLUSTER_H / 2;
|
|
4984
4999
|
return Math.hypot(x - cx, y - cy) <= proximityPx;
|
|
4985
5000
|
}
|
|
@@ -4998,7 +5013,7 @@ var CellControls = class {
|
|
|
4998
5013
|
if (this.suspended) return;
|
|
4999
5014
|
if (this.dragging) return;
|
|
5000
5015
|
const rect = this.host.getBoundingClientRect();
|
|
5001
|
-
this.setNear(nearBottomCenter(e.clientX - rect.left, e.clientY - rect.top, rect.width, rect.height));
|
|
5016
|
+
this.setNear(nearBottomCenter(e.clientX - rect.left, e.clientY - rect.top, rect.width, rect.height, CELL_CONTROLS_PROXIMITY_PX, this.hostGutters()));
|
|
5002
5017
|
};
|
|
5003
5018
|
this.onHostLeave = () => {
|
|
5004
5019
|
if (this.dragging) return;
|
|
@@ -5009,7 +5024,7 @@ var CellControls = class {
|
|
|
5009
5024
|
this.root = host.ownerDocument.createElement("div");
|
|
5010
5025
|
Object.assign(this.root.style, {
|
|
5011
5026
|
position: "absolute",
|
|
5012
|
-
left:
|
|
5027
|
+
left: CLUSTER_LEFT_CSS,
|
|
5013
5028
|
bottom: `${CONTROLS_BOTTOM_PX}px`,
|
|
5014
5029
|
transform: "translateX(-50%)",
|
|
5015
5030
|
zIndex: "6",
|
|
@@ -5109,6 +5124,16 @@ var CellControls = class {
|
|
|
5109
5124
|
this.suspended = on;
|
|
5110
5125
|
if (on) this.setNear(false);
|
|
5111
5126
|
}
|
|
5127
|
+
/** Live renderer gutters on the cell host (0 when unpublished — a test stub). */
|
|
5128
|
+
hostGutters() {
|
|
5129
|
+
const view = this.host.ownerDocument.defaultView;
|
|
5130
|
+
if (!view) return { toolbar: 0, scale: 0 };
|
|
5131
|
+
const cs = view.getComputedStyle(this.host);
|
|
5132
|
+
return {
|
|
5133
|
+
toolbar: Number.parseFloat(cs.getPropertyValue("--vela-toolbar-gutter")) || 0,
|
|
5134
|
+
scale: Number.parseFloat(cs.getPropertyValue("--vela-scale-gutter")) || 0
|
|
5135
|
+
};
|
|
5136
|
+
}
|
|
5112
5137
|
setNear(near) {
|
|
5113
5138
|
if (near === this.near) return;
|
|
5114
5139
|
this.near = near;
|
|
@@ -5223,6 +5248,12 @@ function cellDrawings(opt) {
|
|
|
5223
5248
|
if (opt === true || opt == null) return { toolbar: false };
|
|
5224
5249
|
return { ...opt, toolbar: false };
|
|
5225
5250
|
}
|
|
5251
|
+
function instanceDeltas(handle) {
|
|
5252
|
+
if (!handle) return void 0;
|
|
5253
|
+
const inputs = inputDeltas(handle.inputs, handle.inputValues());
|
|
5254
|
+
const props = inputDeltas(handle.props, handle.propValues());
|
|
5255
|
+
return inputs || props ? { ...inputs ? { inputs } : {}, ...props ? { props } : {} } : void 0;
|
|
5256
|
+
}
|
|
5226
5257
|
var ChartCell = class {
|
|
5227
5258
|
constructor(id, gridHost, seed, deps) {
|
|
5228
5259
|
this.id = id;
|
|
@@ -5398,6 +5429,7 @@ var ChartCell = class {
|
|
|
5398
5429
|
this.syncPresentNatives();
|
|
5399
5430
|
this.refreshNativeCatalog();
|
|
5400
5431
|
});
|
|
5432
|
+
this.inner.on("indicator:inputs", () => this.deps.onStateDirty());
|
|
5401
5433
|
this.inner.on("indicator:removed", ({ id: id2 }) => {
|
|
5402
5434
|
if (this.destroyed) return;
|
|
5403
5435
|
const idx = this.instances.findIndex((it) => it.handle?.id === id2);
|
|
@@ -5406,7 +5438,7 @@ var ChartCell = class {
|
|
|
5406
5438
|
this.instances.splice(idx, 1);
|
|
5407
5439
|
this.history.push({
|
|
5408
5440
|
undo: () => {
|
|
5409
|
-
snapshot.handle = this.addToChart(snapshot.entry);
|
|
5441
|
+
snapshot.handle = this.addToChart(snapshot.entry, snapshot.values);
|
|
5410
5442
|
this.instances.push(snapshot);
|
|
5411
5443
|
this.deps.onIndicatorsChanged(this.id);
|
|
5412
5444
|
},
|
|
@@ -5795,9 +5827,9 @@ var ChartCell = class {
|
|
|
5795
5827
|
this.manifest = list;
|
|
5796
5828
|
if (this.pendingManifestNames) {
|
|
5797
5829
|
if (list.length === 0) return;
|
|
5798
|
-
for (const
|
|
5799
|
-
const entry = list.find((e) => e.name ===
|
|
5800
|
-
if (entry) this.addManifestInstance(entry, { record: false });
|
|
5830
|
+
for (const led of this.pendingManifestNames) {
|
|
5831
|
+
const entry = list.find((e) => e.name === ledgerEntryName(led));
|
|
5832
|
+
if (entry) this.addManifestInstance(entry, { record: false, ...typeof led === "object" ? { inputs: led.inputs, props: led.props } : {} });
|
|
5801
5833
|
}
|
|
5802
5834
|
this.pendingManifestNames = null;
|
|
5803
5835
|
return;
|
|
@@ -5827,9 +5859,9 @@ var ChartCell = class {
|
|
|
5827
5859
|
}
|
|
5828
5860
|
for (const it of [...this.instances]) this.dropInstance(it);
|
|
5829
5861
|
if (this.manifest.length > 0) {
|
|
5830
|
-
for (const
|
|
5831
|
-
const entry = this.manifest.find((e) => e.name ===
|
|
5832
|
-
if (entry) this.addManifestInstance(entry, { record: false });
|
|
5862
|
+
for (const item of led.manifest) {
|
|
5863
|
+
const entry = this.manifest.find((e) => e.name === ledgerEntryName(item));
|
|
5864
|
+
if (entry) this.addManifestInstance(entry, { record: false, ...typeof item === "object" ? { inputs: item.inputs, props: item.props } : {} });
|
|
5833
5865
|
}
|
|
5834
5866
|
this.pendingManifestNames = null;
|
|
5835
5867
|
} else if (!this.deps.manifestSettled()) {
|
|
@@ -5878,12 +5910,13 @@ var ChartCell = class {
|
|
|
5878
5910
|
* a persistence handler's `restore` runs silently, a user-driven call records.
|
|
5879
5911
|
*/
|
|
5880
5912
|
addExternalIndicator(entry) {
|
|
5881
|
-
this.addManifestInstance({ ...entry, enabled: true }, { external: true });
|
|
5913
|
+
this.addManifestInstance({ ...entry, enabled: true }, { external: true, ...entry.inputs ? { inputs: entry.inputs } : {}, ...entry.props ? { props: entry.props } : {} });
|
|
5882
5914
|
}
|
|
5883
5915
|
/** Add ONE instance of a manifest entry (repeatable — duplicates are legitimate). */
|
|
5884
5916
|
addManifestInstance(entry, opts = {}) {
|
|
5885
5917
|
if (this.destroyed) return;
|
|
5886
|
-
const
|
|
5918
|
+
const values = opts.inputs || opts.props ? { inputs: opts.inputs, props: opts.props } : void 0;
|
|
5919
|
+
const it = { entry, handle: this.addToChart(entry, values), ...opts.external ? { external: true } : {}, ...values ? { values } : {} };
|
|
5887
5920
|
this.instances.push(it);
|
|
5888
5921
|
this.deps.onIndicatorsChanged(this.id);
|
|
5889
5922
|
if (opts.record === false) return;
|
|
@@ -5891,7 +5924,7 @@ var ChartCell = class {
|
|
|
5891
5924
|
this.history.push({
|
|
5892
5925
|
undo: () => this.dropInstance(snapshot),
|
|
5893
5926
|
redo: () => {
|
|
5894
|
-
snapshot.handle = this.addToChart(snapshot.entry);
|
|
5927
|
+
snapshot.handle = this.addToChart(snapshot.entry, snapshot.values);
|
|
5895
5928
|
this.instances.push(snapshot);
|
|
5896
5929
|
this.deps.onIndicatorsChanged(this.id);
|
|
5897
5930
|
}
|
|
@@ -5904,7 +5937,7 @@ var ChartCell = class {
|
|
|
5904
5937
|
const snapshot = it;
|
|
5905
5938
|
this.history.push({
|
|
5906
5939
|
undo: () => {
|
|
5907
|
-
snapshot.handle = this.addToChart(snapshot.entry);
|
|
5940
|
+
snapshot.handle = this.addToChart(snapshot.entry, snapshot.values);
|
|
5908
5941
|
this.instances.push(snapshot);
|
|
5909
5942
|
this.deps.onIndicatorsChanged(this.id);
|
|
5910
5943
|
},
|
|
@@ -5914,6 +5947,9 @@ var ChartCell = class {
|
|
|
5914
5947
|
dropInstance(it) {
|
|
5915
5948
|
const idx = this.instances.indexOf(it);
|
|
5916
5949
|
if (idx >= 0) this.instances.splice(idx, 1);
|
|
5950
|
+
const captured = instanceDeltas(it.handle);
|
|
5951
|
+
if (captured) it.values = captured;
|
|
5952
|
+
else delete it.values;
|
|
5917
5953
|
try {
|
|
5918
5954
|
it.handle?.remove();
|
|
5919
5955
|
} catch {
|
|
@@ -5956,9 +5992,13 @@ var ChartCell = class {
|
|
|
5956
5992
|
this.deps.onIndicatorsChanged(this.id);
|
|
5957
5993
|
});
|
|
5958
5994
|
}
|
|
5959
|
-
addToChart(entry) {
|
|
5995
|
+
addToChart(entry, values) {
|
|
5960
5996
|
try {
|
|
5961
|
-
return this.inner?.addIndicator(entry.script,
|
|
5997
|
+
return this.inner?.addIndicator(entry.script, {
|
|
5998
|
+
...entry.language !== void 0 ? { language: entry.language } : {},
|
|
5999
|
+
...values?.inputs ? { inputs: values.inputs } : {},
|
|
6000
|
+
...values?.props ? { props: values.props } : {}
|
|
6001
|
+
}) ?? null;
|
|
5962
6002
|
} catch (err) {
|
|
5963
6003
|
console.warn(`[vela] indicator "${entry.name}" failed to add:`, err);
|
|
5964
6004
|
return null;
|
|
@@ -6072,7 +6112,10 @@ var ChartCell = class {
|
|
|
6072
6112
|
// manifest — their plugin persists them via the `ext` seam instead.
|
|
6073
6113
|
indicators: indicatorLedger({
|
|
6074
6114
|
present: this.inner ? this.inner.presentNativeIndicators() : [],
|
|
6075
|
-
|
|
6115
|
+
instanceEntries: this.instances.filter((it) => !it.external).map((it) => {
|
|
6116
|
+
const d = it.handle ? instanceDeltas(it.handle) : it.values;
|
|
6117
|
+
return d ? { name: it.entry.name, ...d } : it.entry.name;
|
|
6118
|
+
}),
|
|
6076
6119
|
pendingManifest: this.pendingManifestNames,
|
|
6077
6120
|
manifestSettled: this.deps.manifestSettled(),
|
|
6078
6121
|
volumePending: this.volumeMayBePending && this.volumeIntent
|
|
@@ -5734,6 +5734,14 @@ function inputVisible(when, values) {
|
|
|
5734
5734
|
const conds = Array.isArray(when) ? when : [when];
|
|
5735
5735
|
return conds.every((c) => c.anyOf ? c.anyOf.some((x) => x === values[c.key]) : values[c.key] === c.equals);
|
|
5736
5736
|
}
|
|
5737
|
+
function inputDeltas(schema, values) {
|
|
5738
|
+
const out = {};
|
|
5739
|
+
for (const s of schema) {
|
|
5740
|
+
const v = values[s.key];
|
|
5741
|
+
if (v !== void 0 && JSON.stringify(v) !== JSON.stringify(s.defval)) out[s.key] = v;
|
|
5742
|
+
}
|
|
5743
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
5744
|
+
}
|
|
5737
5745
|
|
|
5738
5746
|
// src/renderers/native/layers.ts
|
|
5739
5747
|
function foldBaseModulation(acc, next) {
|
|
@@ -6160,4 +6168,4 @@ var SidePanel = class {
|
|
|
6160
6168
|
}
|
|
6161
6169
|
};
|
|
6162
6170
|
|
|
6163
|
-
export { AnchoredVwap, ArrowMark, Callout, CalloutBase, Comment, DEDEKIND_CURVATURE_OPTIONS, DEFAULT_DRAWING_COLOR, DEFAULT_PANEL_MAX_WIDTH, DEFAULT_PANEL_MIN_WIDTH, DEFAULT_PANEL_ORDER, DEFAULT_PANEL_WIDTH, DIRECTION_OPTIONS, DedekindTessellation, Drawing, FibRatios, FibSpiral, FixedRangeVolumeProfile, GANN_SQUARE_ARCS, GLYPH_OPTIONS, GannSquare, GlyphStamp, LINE_STYLE_OPTIONS, MACH_NUMBER_OPTIONS, MACH_WAVE_COUNT_OPTIONS, MachFigure, MeasureBox, Note, OVERRIDABLE_TOPBAR_IDS, PatternDrawing, PositionTool, PriceLabel, PriceNote, RadialFib, RegressionChannel, STAMP_SIZE_OPTIONS, SegmentDrawing, SidePanel, Signpost, TEXT_SIZE_OPTIONS, TOPBAR_BUILTIN_IDS, TOPBAR_DEFAULT_LEFT, TOPBAR_DEFAULT_RIGHT, TextLabel, chartType, chartTypes, clampPanelWidth, createDrawing, deserializeDrawing, drawingTypes, foldBaseModulation, formatDuration, getDrawingType, getNativeIndicator, inputVisible, legendActions, legendActionsProviderFor, legendCallouts, legendCalloutsProviderFor, lineSegmentIntersection, nativeIndicatorDescriptors, nativeIndicatorTypes, normalizeSettingsRow, pinnedTopbarActionIds, registerChartType, registerDefaultEngine, registerDrawingType, registerLegendAction, registerLegendCallout, registerNativeIndicator, registerRendererDefaults, registerRendererLayer, registerSidePanel, registerStatePersistence, registerSymbolRanking, registerWidgetAction, registerWidgetAttachment, rendererDefaults, rendererLayers, resetDrawingSettings, resolveEngines, resolveTopbarComposition, settingsRowValueKeys, settingsRowVisible, sidePanels, statePersistenceHandlers, symbolRanking, tickerModifierIds, topbarActionOverride, topbarHas, unregisterChartType, unregisterDefaultEngine, unregisterLegendAction, unregisterLegendCallout, unregisterNativeIndicator, unregisterRendererDefaults, unregisterRendererLayer, unregisterSidePanel, unregisterStatePersistence, unregisterWidgetAction, unregisterWidgetAttachment, widgetActions, widgetAttachments };
|
|
6171
|
+
export { AnchoredVwap, ArrowMark, Callout, CalloutBase, Comment, DEDEKIND_CURVATURE_OPTIONS, DEFAULT_DRAWING_COLOR, DEFAULT_PANEL_MAX_WIDTH, DEFAULT_PANEL_MIN_WIDTH, DEFAULT_PANEL_ORDER, DEFAULT_PANEL_WIDTH, DIRECTION_OPTIONS, DedekindTessellation, Drawing, FibRatios, FibSpiral, FixedRangeVolumeProfile, GANN_SQUARE_ARCS, GLYPH_OPTIONS, GannSquare, GlyphStamp, LINE_STYLE_OPTIONS, MACH_NUMBER_OPTIONS, MACH_WAVE_COUNT_OPTIONS, MachFigure, MeasureBox, Note, OVERRIDABLE_TOPBAR_IDS, PatternDrawing, PositionTool, PriceLabel, PriceNote, RadialFib, RegressionChannel, STAMP_SIZE_OPTIONS, SegmentDrawing, SidePanel, Signpost, TEXT_SIZE_OPTIONS, TOPBAR_BUILTIN_IDS, TOPBAR_DEFAULT_LEFT, TOPBAR_DEFAULT_RIGHT, TextLabel, chartType, chartTypes, clampPanelWidth, createDrawing, deserializeDrawing, drawingTypes, foldBaseModulation, formatDuration, getDrawingType, getNativeIndicator, inputDeltas, inputVisible, legendActions, legendActionsProviderFor, legendCallouts, legendCalloutsProviderFor, lineSegmentIntersection, nativeIndicatorDescriptors, nativeIndicatorTypes, normalizeSettingsRow, pinnedTopbarActionIds, registerChartType, registerDefaultEngine, registerDrawingType, registerLegendAction, registerLegendCallout, registerNativeIndicator, registerRendererDefaults, registerRendererLayer, registerSidePanel, registerStatePersistence, registerSymbolRanking, registerWidgetAction, registerWidgetAttachment, rendererDefaults, rendererLayers, resetDrawingSettings, resolveEngines, resolveTopbarComposition, settingsRowValueKeys, settingsRowVisible, sidePanels, statePersistenceHandlers, symbolRanking, tickerModifierIds, topbarActionOverride, topbarHas, unregisterChartType, unregisterDefaultEngine, unregisterLegendAction, unregisterLegendCallout, unregisterNativeIndicator, unregisterRendererDefaults, unregisterRendererLayer, unregisterSidePanel, unregisterStatePersistence, unregisterWidgetAction, unregisterWidgetAttachment, widgetActions, widgetAttachments };
|