@luxalgo/vela 0.8.0 → 0.8.1

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/widget.cjs CHANGED
@@ -3617,14 +3617,49 @@ function buildColorPicker(color, theme, onChange, options = {}) {
3617
3617
  const knob = document.createElement("div");
3618
3618
  knob.style.cssText = "position:absolute;top:50%;width:15px;height:15px;border-radius:50%;background:var(--vela-selected-bg);box-shadow:0 1px 3px rgba(0,0,0,0.55);transform:translate(-50%,-50%);pointer-events:none;";
3619
3619
  track.appendChild(knob);
3620
- const pctBox = document.createElement("div");
3621
- pctBox.style.cssText = `min-width:42px;text-align:center;font:var(--vela-font-size-md) ${theme.fontFamily};color:var(--vela-fg);border:1px solid var(--vela-border);border-radius:5px;padding:3px 4px;`;
3620
+ const pctBox = document.createElement("input");
3621
+ pctBox.type = "text";
3622
+ pctBox.inputMode = "numeric";
3623
+ pctBox.title = "Opacity (%)";
3624
+ pctBox.style.cssText = `width:46px;box-sizing:border-box;text-align:center;font:var(--vela-font-size-md) ${theme.fontFamily};color:var(--vela-fg);background:transparent;border:1px solid var(--vela-border);border-radius:5px;padding:3px 4px;outline:none;`;
3625
+ pctBox.addEventListener("focus", () => {
3626
+ pctBox.style.borderColor = "var(--vela-border-strong)";
3627
+ pctBox.select();
3628
+ });
3622
3629
  opRow.append(track, pctBox);
3623
3630
  const paintOpacity = () => {
3624
3631
  track.style.background = `linear-gradient(to right, ${curHex}00, ${curHex}ff), ${CHECKER}`;
3625
3632
  knob.style.left = `${curAlpha * 100}%`;
3626
- pctBox.textContent = `${Math.round(curAlpha * 100)}%`;
3633
+ pctBox.value = `${Math.round(curAlpha * 100)}%`;
3627
3634
  };
3635
+ const commitTyped = () => {
3636
+ pctBox.style.borderColor = "var(--vela-border)";
3637
+ const n = parseFloat(pctBox.value.replace("%", ""));
3638
+ if (Number.isFinite(n)) {
3639
+ const next = Math.max(0, Math.min(100, n)) / 100;
3640
+ if (Math.round(next * 100) !== Math.round(curAlpha * 100)) {
3641
+ curAlpha = next;
3642
+ paintOpacity();
3643
+ emit();
3644
+ return;
3645
+ }
3646
+ }
3647
+ paintOpacity();
3648
+ };
3649
+ pctBox.addEventListener("change", commitTyped);
3650
+ pctBox.addEventListener("blur", () => {
3651
+ pctBox.style.borderColor = "var(--vela-border)";
3652
+ paintOpacity();
3653
+ });
3654
+ pctBox.addEventListener("keydown", (e) => {
3655
+ if (e.key === "Escape") return;
3656
+ e.stopPropagation();
3657
+ if (e.key === "Enter") {
3658
+ e.preventDefault();
3659
+ commitTyped();
3660
+ pctBox.blur();
3661
+ }
3662
+ });
3628
3663
  let dragging = false;
3629
3664
  const onDrag = (clientX) => {
3630
3665
  const r = track.getBoundingClientRect();
@@ -15211,7 +15246,12 @@ var TimeframeQuick = class {
15211
15246
  content: (body) => body.append(this.input, this.hint),
15212
15247
  onOpenChange: (open2) => opts.onOpenChange?.(open2)
15213
15248
  });
15214
- this.input.addEventListener("input", () => this.renderHint());
15249
+ this.input.addEventListener("input", () => {
15250
+ const { selectionStart, selectionEnd } = this.input;
15251
+ this.input.value = this.input.value.toUpperCase();
15252
+ this.input.setSelectionRange(selectionStart, selectionEnd);
15253
+ this.renderHint();
15254
+ });
15215
15255
  this.input.addEventListener("keydown", (e) => {
15216
15256
  if (e.key !== "Enter") return;
15217
15257
  const parsed = parseTimeframe(this.input.value);
@@ -15223,7 +15263,7 @@ var TimeframeQuick = class {
15223
15263
  }
15224
15264
  open(seed = "") {
15225
15265
  this.dialog.show();
15226
- this.input.value = seed;
15266
+ this.input.value = seed.toUpperCase();
15227
15267
  this.renderHint();
15228
15268
  setTimeout(() => {
15229
15269
  this.input.focus();
@@ -15241,7 +15281,7 @@ var TimeframeQuick = class {
15241
15281
  this.open(text);
15242
15282
  return;
15243
15283
  }
15244
- this.input.value += text;
15284
+ this.input.value += text.toUpperCase();
15245
15285
  this.renderHint();
15246
15286
  }
15247
15287
  close() {
@@ -15254,7 +15294,7 @@ var TimeframeQuick = class {
15254
15294
  const raw = this.input.value.trim();
15255
15295
  const parsed = parseTimeframe(raw);
15256
15296
  if (!raw) {
15257
- this.hint.textContent = "e.g. 15, 4h, D, 3M";
15297
+ this.hint.textContent = "e.g. 15, 4H, D, 3M";
15258
15298
  delete this.hint.dataset.invalid;
15259
15299
  } else if (parsed.valid) {
15260
15300
  this.hint.textContent = parsed.label ?? "";
@@ -15357,7 +15397,7 @@ var ShortcutsHelp = class {
15357
15397
  addRow("Delete the drawing under the cursor", ["Middle-click"]);
15358
15398
  const s = doc.createElement("div");
15359
15399
  s.className = "vela-sh-static";
15360
- s.textContent = "Typing a letter opens the symbol search; typing a digit opens the timeframe entry.";
15400
+ s.textContent = "Typing a letter or 0 opens the symbol search; typing a digit from 1 to 9 opens the timeframe entry.";
15361
15401
  this.list.appendChild(s);
15362
15402
  }
15363
15403
  };
@@ -18379,23 +18419,21 @@ function arrowHitHtml(svg) {
18379
18419
  return `<span class="vela-dtb-hit vela-dtb-hit--arrow">${iconSpan(svg, 11)}</span>`;
18380
18420
  }
18381
18421
 
18382
- // src/renderers/native/chrome/luxalgo-logos.ts
18383
- var LUXALGO_SYMBOL_SVG = '<svg viewBox="0 0 45 40" aria-hidden="true"><g fill="currentColor"><path d="m40.25 38 4.58-7.998L28.802 2l-16.03 28 9.16-.001 6.87-12z"/><path d="M34.525 32.002 9.33 31.997 27.655 0h-9.158L.18 31.993 4.759 40h34.347z"/></g></svg>';
18384
- var LUXALGO_WORDMARK_SVG = '<svg viewBox="0 0 964 252" aria-hidden="true"><path fill="currentColor" fill-rule="evenodd" d="M 614 94.500 L 614 189 633.500 189 L 653 189 653 94.500 L 653 0 633.500 0 L 614 0 614 94.500 M 0 97.500 L 0 189 63.023 189 L 126.045 189 125.773 170.750 L 125.500 152.500 84.250 152.239 L 43 151.978 43 78.989 L 43 6 21.500 6 L 0 6 0 97.500 M 450.387 96.451 C 421.871 146.253, 398.306 186.994, 398.020 186.987 C 397.423 186.972, 362 124.724, 362 123.691 C 362 123.316, 370.100 108.818, 380 91.472 C 389.900 74.127, 398 59.500, 398 58.968 C 398 58.380, 391.007 58, 380.210 58 L 362.420 58 348.060 83.138 C 334.400 107.052, 333.637 108.160, 332.399 105.888 C 331.682 104.575, 325.287 93.375, 318.187 81 L 305.277 58.500 287.139 58.227 C 277.162 58.078, 269 58.186, 269 58.469 C 269 58.751, 277.154 73.274, 287.120 90.741 C 297.086 108.209, 305.261 122.983, 305.287 123.574 C 305.312 124.164, 297.318 138.789, 287.522 156.074 C 277.725 173.358, 269.524 187.838, 269.296 188.250 C 269.068 188.662, 276.977 189, 286.870 189 L 304.859 189 319.163 163.959 C 331.321 142.674, 333.647 139.165, 334.670 140.563 C 335.331 141.468, 341.864 152.737, 349.186 165.606 L 362.500 189.003 402.442 188.752 L 442.384 188.500 472.080 136.695 C 488.413 108.203, 501.939 84.729, 502.138 84.531 C 502.337 84.333, 516 107.757, 532.500 136.583 L 562.500 188.994 584.750 188.997 C 596.987 188.999, 607 188.854, 607 188.675 C 607 188.319, 503.014 6.686, 502.532 6.201 C 502.369 6.037, 478.904 46.649, 450.387 96.451 M 717.500 55.017 C 697.175 57.389, 680.641 68.752, 672.036 86.264 C 665.866 98.818, 663.840 108.024, 663.840 123.500 C 663.840 133.409, 664.328 138.355, 665.892 144.300 C 672.076 167.810, 689.191 184.757, 711.529 189.489 C 730.549 193.518, 747.264 189.540, 761.282 177.648 C 764.944 174.542, 768.178 172, 768.470 172 C 769.345 172, 769.030 185.018, 767.979 192.285 C 765.618 208.613, 755.148 218.672, 738.473 220.632 C 732.586 221.324, 723.136 219.599, 717.709 216.843 C 712.693 214.295, 706.636 207.946, 703.972 202.443 C 702.789 199.999, 701.749 198, 701.661 198.001 C 700.201 198.007, 665.596 205.071, 665.230 205.437 C 664.326 206.341, 669.156 218.313, 672.607 223.721 C 682.146 238.672, 700.008 248.257, 723.500 251.033 C 758.132 255.124, 788.930 241.875, 800.287 218 C 806.923 204.047, 807 203.001, 807 126.542 L 807 58 788.500 58 L 770 58 770 66.500 C 770 71.175, 769.641 75, 769.203 75 C 768.765 75, 766.627 73.142, 764.453 70.872 C 752.805 58.708, 735.614 52.903, 717.500 55.017 M 878.500 55.031 C 850.107 59.412, 830.755 75.064, 822.285 100.500 C 819.905 107.644, 819.614 110.051, 819.565 123 C 819.501 139.581, 820.786 145.825, 826.763 158 C 832.104 168.880, 842.842 179.424, 854.077 184.822 C 867.651 191.343, 873.132 192.462, 891.500 192.462 C 909.868 192.462, 915.349 191.343, 928.923 184.822 C 944.653 177.265, 956.667 162.306, 961.710 144 C 963.074 139.048, 963.481 134.047, 963.418 123 C 963.346 110.140, 963.038 107.595, 960.694 100.500 C 953.325 78.193, 936.695 62.854, 913.500 56.969 C 904.262 54.625, 887.240 53.682, 878.500 55.031 M 134.015 102.750 C 134.027 139.250, 134.310 148.689, 135.549 153.947 C 141.139 177.663, 159.815 193, 183.105 193 C 196.453 193, 210.163 186.171, 217.936 175.650 C 219.826 173.093, 221.738 171, 222.186 171 C 222.634 171, 223 175.050, 223 180 L 223 189 242.507 189 L 262.014 189 261.757 123.750 L 261.500 58.500 242.500 58.500 L 223.500 58.500 223 99.500 C 222.513 139.406, 222.441 140.610, 220.289 144.634 C 209.729 164.377, 183.014 164.880, 174.299 145.500 C 172.677 141.895, 172.469 137.382, 172.190 99.750 L 171.880 58 152.940 58 L 134 58 134.015 102.750 M 729.932 87.998 C 719.311 89.821, 710.155 97.164, 705.141 107.880 C 702.851 112.772, 702.510 114.798, 702.505 123.521 C 702.500 132.834, 702.732 134.014, 705.787 140.218 C 709.761 148.290, 715.989 154.097, 723.853 157.063 C 731.409 159.912, 744.359 159.466, 750.795 156.136 C 767.289 147.601, 774.103 127.713, 767.019 108.780 C 761.433 93.851, 746.051 85.232, 729.932 87.998 M 883.972 88.348 C 865.749 92.310, 854.873 109.966, 858.119 130.316 C 860.933 147.963, 872.346 158.830, 889.084 159.799 C 900.714 160.472, 906.867 158.234, 914.650 150.497 C 919.856 145.323, 921.123 143.340, 922.900 137.587 C 925.412 129.456, 925.655 118.570, 923.489 111.275 C 918.479 94.405, 901.478 84.541, 883.972 88.348"/></svg>';
18422
+ // src/renderers/native/chrome/vela-logos.ts
18423
+ var VELA_MARK_SVG = '<svg viewBox="0 -142 161.66 148" aria-hidden="true"><g fill="currentColor"><path d="M0 -140L32.91 -140L77.52 -62.73L61.06 -34.24Z"/><path d="M161.66 -140L128.75 -140L84.14 -62.73L100.59 -34.24Z"/><path d="M80.83 -52.04L95.85 -26.02L80.83 0L65.81 -26.02Z"/></g></svg>';
18424
+ var VELA_LETTERS_SVG = '<svg viewBox="161.66 -142 310.57 148" aria-hidden="true"><g fill="currentColor"><path d="M226.3 1.17Q200.81 1.17 186.12 -12.99Q171.42 -27.15 171.42 -51.17Q171.42 -75.2 185.87 -89.6Q200.33 -104 224.25 -104Q247.4 -104 261.7 -90.58Q276.01 -77.15 276.3 -54.59Q276.3 -49.9 275.42 -45.02H200.81V-43.55Q201.2 -32.62 207.75 -26.42Q214.29 -20.21 225.03 -20.21Q233.72 -20.21 239.34 -23.93Q244.95 -27.64 246.81 -34.77H274.64Q272.1 -19.14 259.16 -8.98Q246.22 1.17 226.3 1.17ZM201.5 -63.38H247.88Q246.42 -72.75 240.27 -77.88Q234.12 -83.01 224.45 -83.01Q215.17 -83.01 208.92 -77.73Q202.67 -72.46 201.5 -63.38ZM287.54 0V-140.04H315.76V0ZM429.34 -23.83H432.56V0H418.11Q407.76 0 403.36 -4.44Q398.97 -8.89 399.16 -16.8Q387.83 1.17 365.57 1.17Q348.48 1.17 337.88 -6.74Q327.29 -14.65 327.29 -29Q327.29 -45.41 339.45 -54.3Q351.6 -63.18 374.55 -63.18H394.96V-68.16Q394.96 -75.2 390.08 -79.3Q385.2 -83.4 376.51 -83.4Q368.3 -83.4 363.03 -79.98Q357.76 -76.56 356.88 -70.8H329.73Q331.19 -85.84 344.08 -94.92Q356.97 -104 377.29 -104Q399.06 -104 410.88 -94.43Q422.7 -84.86 422.7 -66.6V-30.18Q422.7 -26.37 424.26 -25.1Q425.82 -23.83 429.34 -23.83ZM394.96 -42.38V-44.43H374.36Q365.47 -44.43 360.59 -40.92Q355.7 -37.4 355.7 -30.96Q355.7 -25.59 359.81 -22.41Q363.91 -19.24 370.94 -19.24Q381.97 -19.24 388.37 -25.54Q394.77 -31.84 394.96 -42.38Z"/><path fill-opacity="0.55" d="M437.44 -124.28H441.96V-113.41H445.34V-124.28H449.87V-127.4H437.44ZM451.43 -113.41H454.7V-123.29L458.97 -113.41H461.62L465.99 -123.29V-113.41H469.21V-127.4H464.53L460.42 -117.68L456.16 -127.4H451.43Z"/></g></svg>';
18385
18425
 
18386
18426
  // src/renderers/native/chrome/AttributionMark.ts
18387
- var ATTRIBUTION_URL = "https://luxalgo.com/vela";
18427
+ var ATTRIBUTION_URL = "https://velacharts.dev/?utm_source=vela&utm_medium=attribution";
18388
18428
  var STYLE_ID20 = "vela-attribution-styles";
18389
18429
  var CSS20 = `
18390
18430
  .vela-attribution {
18391
18431
  text-decoration: none;
18392
18432
  display: flex;
18393
18433
  align-items: center;
18394
- /* Gutter, wordmark size and offset below are the brand lockup's own ratios,
18395
- measured off the official horizontal logo: gutter 0.157, wordmark height
18396
- 0.966, and wordmark 0.109 LOWER than the symbol \u2014 box-centering the two
18397
- reads wrong because the symbol's ink hangs low and the wordmark descends. */
18398
- gap: 4px;
18434
+ /* No gutter: the V is the wordmark's first letter, and the letters' viewBox starts
18435
+ where the V's ends, so the kit's own letter spacing comes with them. */
18436
+ gap: 0;
18399
18437
  }
18400
18438
  .vela-attribution .vela-attr-symbol {
18401
18439
  flex: none;
@@ -18403,7 +18441,7 @@ var CSS20 = `
18403
18441
  line-height: 0;
18404
18442
  }
18405
18443
  .vela-attribution .vela-attr-symbol svg {
18406
- height: 28px;
18444
+ height: 24px;
18407
18445
  width: auto;
18408
18446
  display: block;
18409
18447
  filter: drop-shadow(0 1px 2px var(--vela-attr-shadow, rgba(0,0,0,0.45)));
@@ -18414,15 +18452,13 @@ var CSS20 = `
18414
18452
  opacity: 0;
18415
18453
  display: flex;
18416
18454
  align-items: center;
18417
- /* Offset here, not on the image: the clip box must not crop the descender. */
18418
- position: relative;
18419
- top: 3px;
18455
+ /* Same height and baseline as the V (one viewBox height), so no vertical offset. */
18420
18456
  transform: translateX(-8px);
18421
18457
  transition: max-width 0.3s ease, opacity 0.25s ease, transform 0.3s ease;
18422
18458
  flex: none;
18423
18459
  }
18424
18460
  .vela-attribution .vela-attr-wordmark svg {
18425
- height: 27px;
18461
+ height: 24px;
18426
18462
  width: auto;
18427
18463
  display: block;
18428
18464
  filter: drop-shadow(0 1px 2px var(--vela-attr-shadow, rgba(0,0,0,0.45)));
@@ -18437,14 +18473,11 @@ var CSS20 = `
18437
18473
  (data-layout): the workspace's single grid-wide mark lives OUTSIDE any renderer
18438
18474
  container, so only the shell attribute reaches it. */
18439
18475
  [data-vela-layout='mobile'] .vela-attribution .vela-attr-symbol svg,
18440
- [data-layout='mobile'] .vela-attribution .vela-attr-symbol svg { height: 22px; }
18476
+ [data-layout='mobile'] .vela-attribution .vela-attr-symbol svg { height: 20px; }
18441
18477
  [data-vela-layout='mobile'] .vela-attribution .vela-attr-wordmark,
18442
- [data-layout='mobile'] .vela-attribution .vela-attr-wordmark {
18443
- top: 2px;
18444
- transform: translateX(-6px);
18445
- }
18478
+ [data-layout='mobile'] .vela-attribution .vela-attr-wordmark { transform: translateX(-6px); }
18446
18479
  [data-vela-layout='mobile'] .vela-attribution .vela-attr-wordmark svg,
18447
- [data-layout='mobile'] .vela-attribution .vela-attr-wordmark svg { height: 21px; }
18480
+ [data-layout='mobile'] .vela-attribution .vela-attr-wordmark svg { height: 20px; }
18448
18481
  [data-vela-layout='mobile'] .vela-attribution:hover .vela-attr-wordmark,
18449
18482
  [data-layout='mobile'] .vela-attribution:hover .vela-attr-wordmark { transform: translateX(0); }
18450
18483
  `;
@@ -18501,10 +18534,10 @@ function createAttributionMark(doc, background) {
18501
18534
  const symbol = doc.createElement("span");
18502
18535
  symbol.className = "vela-attr-symbol";
18503
18536
  symbol.setAttribute("aria-hidden", "true");
18504
- symbol.innerHTML = LUXALGO_SYMBOL_SVG;
18537
+ symbol.innerHTML = VELA_MARK_SVG;
18505
18538
  const wordmark = doc.createElement("span");
18506
18539
  wordmark.className = "vela-attr-wordmark";
18507
- wordmark.innerHTML = LUXALGO_WORDMARK_SVG;
18540
+ wordmark.innerHTML = VELA_LETTERS_SVG;
18508
18541
  a.append(symbol, wordmark);
18509
18542
  return a;
18510
18543
  }
@@ -25948,6 +25981,12 @@ var InputController = class {
25948
25981
  this.lastTapT = 0;
25949
25982
  this.lastTapX = 0;
25950
25983
  this.lastTapY = 0;
25984
+ // Whether the last two primary presses were claimed by the drawings layer. A double-click
25985
+ // is the last press plus the one before it; a tool-driven click pair must never fall through
25986
+ // to the pane maximize toggle, even when the tool disarmed itself between the two clicks
25987
+ // (a finished placement leaves plain cursor mode for the second click).
25988
+ this.lastPressDrawing = false;
25989
+ this.prevPressDrawing = false;
25951
25990
  this.onTouchContextMenu = (e) => {
25952
25991
  if (this.touches.size === 0) return;
25953
25992
  if (!(e.target instanceof Node) || !this.el?.contains(e.target)) return;
@@ -26002,19 +26041,24 @@ var InputController = class {
26002
26041
  this.moved = false;
26003
26042
  this.startX = x;
26004
26043
  this.startY = y;
26044
+ this.prevPressDrawing = this.lastPressDrawing;
26045
+ this.lastPressDrawing = false;
26005
26046
  if (this.deps.drawingsClaim?.(x, y)) {
26006
26047
  this.region = "drawing";
26048
+ this.lastPressDrawing = true;
26007
26049
  this.deps.drawingsPointerDown?.(x, y, this.snapMode(e), e.shiftKey, e.ctrlKey || e.metaKey);
26008
26050
  this.capture(e.pointerId);
26009
26051
  return;
26010
26052
  }
26011
26053
  if (e.shiftKey && this.regionAt(x, y) === "data" && this.deps.drawingsMeasureStart?.(x, y, this.snapMode(e))) {
26012
26054
  this.region = "drawing";
26055
+ this.lastPressDrawing = true;
26013
26056
  this.capture(e.pointerId);
26014
26057
  return;
26015
26058
  }
26016
26059
  if ((e.ctrlKey || e.metaKey) && this.regionAt(x, y) === "data" && this.deps.drawingsMarqueeStart?.(x, y)) {
26017
26060
  this.region = "drawing";
26061
+ this.lastPressDrawing = true;
26018
26062
  this.capture(e.pointerId);
26019
26063
  return;
26020
26064
  }
@@ -26336,6 +26380,7 @@ var InputController = class {
26336
26380
  if (region === "price") this.deps.resetPriceScale(x, y);
26337
26381
  else if (region === "separator") this.deps.resetPaneSize(y);
26338
26382
  else if (region === "time") this.deps.resetView();
26383
+ else if (this.lastPressDrawing || this.prevPressDrawing) return;
26339
26384
  else this.deps.dataDblClick(x, y);
26340
26385
  }
26341
26386
  };
@@ -28501,6 +28546,7 @@ function timeTicks(fromMs, toMs, target = 8, offsetMs = 0) {
28501
28546
  const step = pickStep(span / Math.max(1, target));
28502
28547
  const zFrom = fromMs + offsetMs;
28503
28548
  const zTo = toMs + offsetMs;
28549
+ if (step >= MONTH) return calendarTicks(zFrom, zTo, step >= YEAR ? 12 : step >= 3 * MONTH ? 3 : 1, offsetMs);
28504
28550
  const first = Math.ceil(zFrom / step) * step;
28505
28551
  const out = [];
28506
28552
  for (let zt = first; zt <= zTo; zt += step) {
@@ -28531,6 +28577,18 @@ function timeTicks(fromMs, toMs, target = 8, offsetMs = 0) {
28531
28577
  }
28532
28578
  return out;
28533
28579
  }
28580
+ function calendarTicks(zFrom, zTo, months, offsetMs) {
28581
+ const d0 = new Date(zFrom);
28582
+ let idx = d0.getUTCFullYear() * 12 + d0.getUTCMonth();
28583
+ if (Date.UTC(Math.floor(idx / 12), idx % 12, 1) < zFrom) idx += 1;
28584
+ idx = Math.ceil(idx / months) * months;
28585
+ const out = [];
28586
+ for (let zt = Date.UTC(Math.floor(idx / 12), idx % 12, 1); zt <= zTo; idx += months, zt = Date.UTC(Math.floor(idx / 12), idx % 12, 1)) {
28587
+ const label = months === 12 ? String(Math.floor(idx / 12)) : MONTHS[idx % 12];
28588
+ out.push({ time: zt - offsetMs, label, major: true });
28589
+ }
28590
+ return out;
28591
+ }
28534
28592
 
28535
28593
  // src/renderers/native/chrome/countdown.ts
28536
28594
  function countdownText(barOpen, barMs, now2) {
@@ -46770,7 +46828,7 @@ var ChartCell = class {
46770
46828
  * then the manifest in the host's own order. */
46771
46829
  libraryRows() {
46772
46830
  return [
46773
- ...this.supportedNatives().map((n) => ({ name: n.title, category: "Vela", native: true, nativeType: n.type, beta: n.beta })),
46831
+ ...this.supportedNatives().map((n) => ({ name: n.title, category: "Built-in", native: true, nativeType: n.type, beta: n.beta })),
46774
46832
  ...this.manifest.map((e) => ({ name: e.name, language: e.language, category: e.category }))
46775
46833
  ];
46776
46834
  }
@@ -47770,11 +47828,11 @@ function resolveTyping(key, open2) {
47770
47828
  if (open2.dialogs > 0) {
47771
47829
  if (key.length !== 1) return null;
47772
47830
  if (open2.symbolSearch) return { target: "symbol", text: key.toUpperCase() };
47773
- if (open2.timeframeEntry) return { target: "timeframe", text: key };
47831
+ if (open2.timeframeEntry) return { target: "timeframe", text: key.toUpperCase() };
47774
47832
  return null;
47775
47833
  }
47776
- if (/^[a-zA-Z]$/.test(key)) return { target: "symbol", text: key.toUpperCase() };
47777
- if (/^[0-9]$/.test(key)) return { target: "timeframe", text: key };
47834
+ if (/^[a-zA-Z0]$/.test(key)) return { target: "symbol", text: key.toUpperCase() };
47835
+ if (/^[1-9]$/.test(key)) return { target: "timeframe", text: key };
47778
47836
  return null;
47779
47837
  }
47780
47838
  var VelaWorkspace = class {
@@ -49512,7 +49570,7 @@ var VelaWorkspace = class {
49512
49570
  }
49513
49571
  });
49514
49572
  }
49515
- /** Bare-typing router: letters → symbol search (seeded), digits → timeframe entry. */
49573
+ /** Bare-typing router: letters and `0` → symbol search (seeded), digits 1–9 → timeframe entry. */
49516
49574
  routeTyping(ev) {
49517
49575
  if (this.destroyed) return;
49518
49576
  if (ev.ctrlKey || ev.metaKey || ev.altKey) return;
package/dist/widget.js CHANGED
@@ -1,9 +1,9 @@
1
- import { VelaWorkspace } from './chunk-E3GU6AUI.js';
2
- export { Bottombar, ChartContextMenu, DataWindow, IndicatorPicker, ObjectTree, PanelDock, RANGE_PRESETS, ShortcutsHelp, Statusline, SymbolPicker, TimeframeQuick, Topbar, Watermark, dataWindowSections, decimalsFor, decodeState, encodeState, filterSymbols, fmtChange, fmtPrice, localStorageAdapter, parseTimeframe, priceStyleLabel, resolveIndicators, sanitizeState, timeframeLabel, timeframeMs } from './chunk-E3GU6AUI.js';
3
- export { TIMEZONES, normalizeTimezone, tzButtonLabel, tzMenuLabel, tzOffset } from './chunk-QBPUT5SU.js';
1
+ import { VelaWorkspace } from './chunk-DBDXKZUF.js';
2
+ export { Bottombar, ChartContextMenu, DataWindow, IndicatorPicker, ObjectTree, PanelDock, RANGE_PRESETS, ShortcutsHelp, Statusline, SymbolPicker, TimeframeQuick, Topbar, Watermark, dataWindowSections, decimalsFor, decodeState, encodeState, filterSymbols, fmtChange, fmtPrice, localStorageAdapter, parseTimeframe, priceStyleLabel, resolveIndicators, sanitizeState, timeframeLabel, timeframeMs } from './chunk-DBDXKZUF.js';
3
+ export { TIMEZONES, normalizeTimezone, tzButtonLabel, tzMenuLabel, tzOffset } from './chunk-ATGTCWHJ.js';
4
4
  export { DEFAULT_PANEL_MAX_WIDTH, DEFAULT_PANEL_MIN_WIDTH, DEFAULT_PANEL_ORDER, DEFAULT_PANEL_WIDTH, OVERRIDABLE_TOPBAR_IDS, SidePanel, TOPBAR_BUILTIN_IDS, TOPBAR_DEFAULT_LEFT, TOPBAR_DEFAULT_RIGHT, clampPanelWidth, pinnedTopbarActionIds, registerSidePanel, registerStatePersistence, registerSymbolRanking, registerWidgetAction, registerWidgetAttachment, resolveTopbarComposition, sidePanels, statePersistenceHandlers, symbolRanking, topbarActionOverride, topbarHas, unregisterSidePanel, unregisterStatePersistence, unregisterWidgetAction, unregisterWidgetAttachment, widgetActions, widgetAttachments } from './chunk-EZ5FWVLA.js';
5
- import './chunk-KA77UTRF.js';
6
- import './chunk-2IAETM2I.js';
5
+ import './chunk-LMBYEGUR.js';
6
+ import './chunk-NELQJCGK.js';
7
7
  import './chunk-BZQM2XO7.js';
8
8
  import './chunk-W4EJWLEO.js';
9
9