oakscriptjs 0.5.0 → 0.6.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.
Files changed (78) hide show
  1. package/README.md +42 -8
  2. package/dist/array/index.d.ts +7 -7
  3. package/dist/array/index.d.ts.map +1 -1
  4. package/dist/box/index.d.ts +11 -3
  5. package/dist/box/index.d.ts.map +1 -1
  6. package/dist/color/index.d.ts +15 -15
  7. package/dist/color/index.d.ts.map +1 -1
  8. package/dist/compare/index.d.ts +8 -0
  9. package/dist/compare/index.d.ts.map +1 -0
  10. package/dist/drawing/registry.d.ts +19 -0
  11. package/dist/drawing/registry.d.ts.map +1 -0
  12. package/dist/index.cjs +1740 -608
  13. package/dist/index.d.ts +9 -5
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.mjs +1740 -608
  16. package/dist/input.d.ts +7 -1
  17. package/dist/input.d.ts.map +1 -1
  18. package/dist/label/index.d.ts +12 -4
  19. package/dist/label/index.d.ts.map +1 -1
  20. package/dist/line/index.d.ts +11 -3
  21. package/dist/line/index.d.ts.map +1 -1
  22. package/dist/linefill/index.d.ts +3 -1
  23. package/dist/linefill/index.d.ts.map +1 -1
  24. package/dist/map/index.d.ts +14 -0
  25. package/dist/map/index.d.ts.map +1 -0
  26. package/dist/polyline/index.d.ts +1 -0
  27. package/dist/polyline/index.d.ts.map +1 -1
  28. package/dist/runtime/adapters/SimpleInputAdapter.d.ts.map +1 -1
  29. package/dist/runtime/index.cjs +40 -1
  30. package/dist/runtime/index.d.ts +1 -1
  31. package/dist/runtime/index.d.ts.map +1 -1
  32. package/dist/runtime/index.mjs +40 -1
  33. package/dist/runtime/inputs.d.ts +3 -0
  34. package/dist/runtime/inputs.d.ts.map +1 -1
  35. package/dist/runtime/series.d.ts.map +1 -1
  36. package/dist/runtime/types.d.ts +1 -1
  37. package/dist/runtime/types.d.ts.map +1 -1
  38. package/dist/script/index.cjs +3097 -635
  39. package/dist/script/index.d.ts +293 -27
  40. package/dist/script/index.d.ts.map +1 -1
  41. package/dist/script/index.mjs +3097 -635
  42. package/dist/security/resample.d.ts +13 -0
  43. package/dist/security/resample.d.ts.map +1 -0
  44. package/dist/session/bars.d.ts +34 -0
  45. package/dist/session/bars.d.ts.map +1 -0
  46. package/dist/session/calendar.d.ts +31 -0
  47. package/dist/session/calendar.d.ts.map +1 -0
  48. package/dist/str/dateformat.d.ts +2 -0
  49. package/dist/str/dateformat.d.ts.map +1 -0
  50. package/dist/str/index.d.ts +1 -1
  51. package/dist/str/index.d.ts.map +1 -1
  52. package/dist/str/messageformat.d.ts +2 -0
  53. package/dist/str/messageformat.d.ts.map +1 -0
  54. package/dist/str/numberformat.d.ts +3 -0
  55. package/dist/str/numberformat.d.ts.map +1 -0
  56. package/dist/ta/index.d.ts +14 -5
  57. package/dist/ta/index.d.ts.map +1 -1
  58. package/dist/ta-series.d.ts +23 -5
  59. package/dist/ta-series.d.ts.map +1 -1
  60. package/dist/text/index.d.ts +4 -0
  61. package/dist/text/index.d.ts.map +1 -0
  62. package/dist/time/datestring.d.ts +2 -0
  63. package/dist/time/datestring.d.ts.map +1 -0
  64. package/dist/time/index.d.ts +11 -0
  65. package/dist/time/index.d.ts.map +1 -1
  66. package/dist/time/session.d.ts +2 -0
  67. package/dist/time/session.d.ts.map +1 -0
  68. package/dist/time/timezone.d.ts +13 -0
  69. package/dist/time/timezone.d.ts.map +1 -0
  70. package/dist/timeframe/index.d.ts +17 -0
  71. package/dist/timeframe/index.d.ts.map +1 -0
  72. package/dist/types/index.d.ts +7 -0
  73. package/dist/types/index.d.ts.map +1 -1
  74. package/dist/types/metadata.d.ts +1 -1
  75. package/dist/types/metadata.d.ts.map +1 -1
  76. package/dist/utils/index.d.ts +1 -0
  77. package/dist/utils/index.d.ts.map +1 -1
  78. package/package.json +1 -1
@@ -3,9 +3,9 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
6
+ var __export = (target, all7) => {
7
+ for (var name in all7)
8
+ __defProp(target, name, { get: all7[name], enumerable: true });
9
9
  };
10
10
  var __copyProps = (to, from, except, desc) => {
11
11
  if (from && typeof from === "object" || typeof from === "function") {
@@ -24,21 +24,35 @@ __export(index_exports, {
24
24
  Series: () => Series,
25
25
  alertcondition: () => alertcondition,
26
26
  barcolor: () => barcolor,
27
+ barmerge: () => barmerge,
27
28
  bgcolor: () => bgcolor,
29
+ box: () => box,
30
+ chart: () => chart,
28
31
  close: () => close,
29
32
  color: () => color,
33
+ compare: () => compare_exports,
34
+ dayofmonth: () => dayofmonth2,
35
+ dayofweek: () => dayofweek2,
30
36
  eachBar: () => eachBar,
31
37
  executeScript: () => executeScript,
32
38
  fill: () => fill,
39
+ fixnan: () => fixnan2,
33
40
  high: () => high,
34
41
  hl2: () => hl2,
35
42
  hlc3: () => hlc3,
36
43
  hlcc4: () => hlcc4,
37
44
  hline: () => hline,
45
+ hour: () => hour2,
46
+ inSession: () => inSession3,
38
47
  indicator: () => indicator,
39
48
  input: () => input,
49
+ label: () => label,
50
+ line: () => line,
51
+ linefill: () => linefill,
40
52
  low: () => low,
41
53
  math: () => math_exports,
54
+ minute: () => minute2,
55
+ month: () => month2,
42
56
  na: () => isNA,
43
57
  nz: () => nz,
44
58
  ohlc4: () => ohlc4,
@@ -46,12 +60,59 @@ __export(index_exports, {
46
60
  plot: () => plot,
47
61
  plotchar: () => plotchar,
48
62
  plotshape: () => plotshape,
63
+ polyline: () => polyline,
64
+ request: () => request,
65
+ second: () => second2,
49
66
  seriesOf: () => seriesOf,
67
+ session: () => session,
68
+ str: () => str,
69
+ syminfo: () => syminfo,
50
70
  ta: () => ta2,
51
- volume: () => volume
71
+ text: () => text,
72
+ ticker: () => ticker,
73
+ time: () => time,
74
+ time_close: () => time_close,
75
+ time_tradingday: () => time_tradingday,
76
+ timeframe: () => timeframe,
77
+ timestamp: () => timestamp2,
78
+ volume: () => volume,
79
+ weekofyear: () => weekofyear2,
80
+ year: () => year2
52
81
  });
53
82
  module.exports = __toCommonJS(index_exports);
54
83
 
84
+ // src/compare/index.ts
85
+ var compare_exports = {};
86
+ __export(compare_exports, {
87
+ EPSILON: () => EPSILON,
88
+ eq: () => eq,
89
+ ge: () => ge,
90
+ gt: () => gt,
91
+ le: () => le,
92
+ lt: () => lt,
93
+ ne: () => ne
94
+ });
95
+ var EPSILON = 1e-10;
96
+ var valid = (a, b2) => !Number.isNaN(a) && !Number.isNaN(b2);
97
+ function eq(a, b2) {
98
+ return valid(a, b2) && Math.abs(a - b2) <= EPSILON;
99
+ }
100
+ function ne(a, b2) {
101
+ return valid(a, b2) && Math.abs(a - b2) > EPSILON;
102
+ }
103
+ function lt(a, b2) {
104
+ return valid(a, b2) && b2 - a > EPSILON;
105
+ }
106
+ function le(a, b2) {
107
+ return valid(a, b2) && a - b2 <= EPSILON;
108
+ }
109
+ function gt(a, b2) {
110
+ return valid(a, b2) && a - b2 > EPSILON;
111
+ }
112
+ function ge(a, b2) {
113
+ return valid(a, b2) && b2 - a <= EPSILON;
114
+ }
115
+
55
116
  // src/runtime/series.ts
56
117
  var BarData = class _BarData {
57
118
  _bars;
@@ -194,8 +255,8 @@ var Series = class _Series {
194
255
  * @param field - Field to extract ('open', 'high', 'low', 'close', 'volume')
195
256
  * @returns Series with extracted field values
196
257
  */
197
- static fromBars(bars2, field) {
198
- return new _Series(bars2, (bar) => bar[field] ?? NaN);
258
+ static fromBars(bars2, field2) {
259
+ return new _Series(bars2, (bar) => bar[field2] ?? NaN);
199
260
  }
200
261
  /**
201
262
  * Create a constant series (same value for all bars)
@@ -300,7 +361,7 @@ var Series = class _Series {
300
361
  });
301
362
  }
302
363
  // ============================================
303
- // Comparison Operations
364
+ // Comparison Operations (PineScript operators: tolerance 1e-10, false with na; see src/compare)
304
365
  // ============================================
305
366
  /**
306
367
  * Greater than comparison
@@ -311,7 +372,7 @@ var Series = class _Series {
311
372
  return new _Series(this.dataSource, (bar, i, data) => {
312
373
  const a = this.extractor(bar, i, data);
313
374
  const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
314
- return a > b2 ? 1 : 0;
375
+ return gt(a, b2) ? 1 : 0;
315
376
  });
316
377
  }
317
378
  /**
@@ -323,7 +384,7 @@ var Series = class _Series {
323
384
  return new _Series(this.dataSource, (bar, i, data) => {
324
385
  const a = this.extractor(bar, i, data);
325
386
  const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
326
- return a >= b2 ? 1 : 0;
387
+ return ge(a, b2) ? 1 : 0;
327
388
  });
328
389
  }
329
390
  /**
@@ -335,7 +396,7 @@ var Series = class _Series {
335
396
  return new _Series(this.dataSource, (bar, i, data) => {
336
397
  const a = this.extractor(bar, i, data);
337
398
  const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
338
- return a < b2 ? 1 : 0;
399
+ return lt(a, b2) ? 1 : 0;
339
400
  });
340
401
  }
341
402
  /**
@@ -347,7 +408,7 @@ var Series = class _Series {
347
408
  return new _Series(this.dataSource, (bar, i, data) => {
348
409
  const a = this.extractor(bar, i, data);
349
410
  const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
350
- return a <= b2 ? 1 : 0;
411
+ return le(a, b2) ? 1 : 0;
351
412
  });
352
413
  }
353
414
  /**
@@ -359,7 +420,7 @@ var Series = class _Series {
359
420
  return new _Series(this.dataSource, (bar, i, data) => {
360
421
  const a = this.extractor(bar, i, data);
361
422
  const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
362
- return a === b2 ? 1 : 0;
423
+ return eq(a, b2) ? 1 : 0;
363
424
  });
364
425
  }
365
426
  /**
@@ -371,7 +432,7 @@ var Series = class _Series {
371
432
  return new _Series(this.dataSource, (bar, i, data) => {
372
433
  const a = this.extractor(bar, i, data);
373
434
  const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
374
- return a !== b2 ? 1 : 0;
435
+ return ne(a, b2) ? 1 : 0;
375
436
  });
376
437
  }
377
438
  // ============================================
@@ -569,6 +630,7 @@ var Series = class _Series {
569
630
  // src/ta-series.ts
570
631
  var ta_series_exports = {};
571
632
  __export(ta_series_exports, {
633
+ accdist: () => accdist2,
572
634
  alma: () => alma2,
573
635
  atr: () => atr2,
574
636
  barssince: () => barssince2,
@@ -591,6 +653,7 @@ __export(ta_series_exports, {
591
653
  highestbars: () => highestbars2,
592
654
  hma: () => hma2,
593
655
  ichimoku: () => ichimoku2,
656
+ iii: () => iii2,
594
657
  kc: () => kc2,
595
658
  kcw: () => kcw2,
596
659
  linreg: () => linreg2,
@@ -603,11 +666,15 @@ __export(ta_series_exports, {
603
666
  min: () => min2,
604
667
  mode: () => mode2,
605
668
  mom: () => mom2,
669
+ nvi: () => nvi2,
670
+ obv: () => obv2,
606
671
  percentile_linear_interpolation: () => percentile_linear_interpolation2,
607
672
  percentile_nearest_rank: () => percentile_nearest_rank2,
608
673
  percentrank: () => percentrank2,
609
674
  pivothigh: () => pivothigh2,
610
675
  pivotlow: () => pivotlow2,
676
+ pvi: () => pvi2,
677
+ pvt: () => pvt2,
611
678
  range: () => range2,
612
679
  rci: () => rci2,
613
680
  rising: () => rising2,
@@ -626,16 +693,19 @@ __export(ta_series_exports, {
626
693
  valuewhen: () => valuewhen2,
627
694
  variance: () => variance2,
628
695
  vwap: () => vwap2,
696
+ vwapBands: () => vwapBands,
629
697
  vwma: () => vwma2,
698
+ wad: () => wad2,
630
699
  wma: () => wma2,
631
700
  wpr: () => wpr2,
701
+ wvad: () => wvad2,
632
702
  zigzag: () => zigzag2
633
703
  });
634
704
 
635
705
  // src/ta/index.ts
636
- function sma(source, length) {
706
+ function sma(source, length2) {
637
707
  const result = [];
638
- const len = Math.floor(length);
708
+ const len = Math.floor(length2);
639
709
  for (let i = 0; i < source.length; i++) {
640
710
  if (i < len - 1) {
641
711
  result.push(NaN);
@@ -649,9 +719,9 @@ function sma(source, length) {
649
719
  }
650
720
  return result;
651
721
  }
652
- function ema(source, length) {
722
+ function ema(source, length2) {
653
723
  const result = [];
654
- const len = Math.floor(length);
724
+ const len = Math.floor(length2);
655
725
  const multiplier = 2 / (len + 1);
656
726
  let firstValidIndex = -1;
657
727
  let validCount = 0;
@@ -684,16 +754,16 @@ function ema(source, length) {
684
754
  }
685
755
  return result;
686
756
  }
687
- function rsi(source, length) {
757
+ function rsi(source, length2) {
688
758
  const result = [];
689
759
  const changes = [];
690
760
  for (let i = 1; i < source.length; i++) {
691
761
  changes.push(source[i] - source[i - 1]);
692
762
  }
693
- const gains = changes.map((c) => c > 0 ? c : 0);
694
- const losses = changes.map((c) => c < 0 ? -c : 0);
695
- const avgGains = rma(gains, length);
696
- const avgLosses = rma(losses, length);
763
+ const gains = changes.map((c) => Number.isNaN(c) ? NaN : c > 0 ? c : 0);
764
+ const losses = changes.map((c) => Number.isNaN(c) ? NaN : c < 0 ? -c : 0);
765
+ const avgGains = rma(gains, length2);
766
+ const avgLosses = rma(losses, length2);
697
767
  result.push(NaN);
698
768
  for (let i = 0; i < avgGains.length; i++) {
699
769
  if (avgLosses[i] === 0) {
@@ -719,34 +789,53 @@ function macd(source, fastLength, slowLength, signalLength) {
719
789
  }
720
790
  return [macdLine, signalLine, histogram];
721
791
  }
722
- function bb(series, length, mult) {
723
- const basis = sma(series, length);
724
- const dev3 = stdev(series, length);
725
- const upper = [];
726
- const lower = [];
792
+ function bb(series, length2, mult) {
793
+ const basis = sma(series, length2);
794
+ const dev3 = stdev(series, length2);
795
+ const upper2 = [];
796
+ const lower2 = [];
727
797
  for (let i = 0; i < series.length; i++) {
728
- upper.push(basis[i] + mult * dev3[i]);
729
- lower.push(basis[i] - mult * dev3[i]);
730
- }
731
- return [basis, upper, lower];
798
+ upper2.push(basis[i] + mult * dev3[i]);
799
+ lower2.push(basis[i] - mult * dev3[i]);
800
+ }
801
+ return [basis, upper2, lower2];
802
+ }
803
+ function stdev(source, length2, biased = true) {
804
+ const len = Math.floor(length2);
805
+ return source.map((_, i) => {
806
+ const values = lastValues(source, i, len);
807
+ if (!values) return NaN;
808
+ const mean = values.reduce((a, b2) => a + b2, 0) / len;
809
+ const squares = values.reduce((a, b2) => a + (b2 - mean) * (b2 - mean), 0);
810
+ return Math.sqrt(squares / (biased ? len : len - 1));
811
+ });
732
812
  }
733
- function stdev(source, length) {
734
- const result = [];
735
- const len = Math.floor(length);
736
- const avg2 = sma(source, len);
737
- for (let i = 0; i < source.length; i++) {
738
- if (i < len - 1) {
739
- result.push(NaN);
740
- } else {
741
- let sumSquares = 0;
742
- for (let j = 0; j < len; j++) {
743
- const diff = source[i - j] - avg2[i];
744
- sumSquares += diff * diff;
745
- }
746
- result.push(Math.sqrt(sumSquares / len));
747
- }
748
- }
749
- return result;
813
+ function lastValues(source, i, length2) {
814
+ const values = [];
815
+ for (let j = i; j >= 0 && values.length < length2; j--) {
816
+ const x = source[j];
817
+ if (!Number.isNaN(x)) values.push(x);
818
+ }
819
+ return values.length === length2 ? values : null;
820
+ }
821
+ function windowUntilNa(source, i, length2) {
822
+ const values = [];
823
+ for (let j = 0; j < length2 && i - j >= 0; j++) {
824
+ const x = source[i - j];
825
+ if (Number.isNaN(x)) break;
826
+ values.push([x, -j]);
827
+ }
828
+ return values;
829
+ }
830
+ function extremeOffset(source, length2, isHigher) {
831
+ return source.map((_, i) => {
832
+ if (i < length2 - 1) return NaN;
833
+ const w = windowUntilNa(source, i, length2);
834
+ if (w.length === 0) return 0;
835
+ let best = w[0];
836
+ for (const item of w) if (isHigher(item[0], best[0])) best = item;
837
+ return best[1];
838
+ });
750
839
  }
751
840
  function crossover(series1, series2) {
752
841
  const result = [];
@@ -770,13 +859,13 @@ function crossunder(series1, series2) {
770
859
  }
771
860
  return result;
772
861
  }
773
- function change(source, length = 1) {
862
+ function change(source, length2 = 1) {
774
863
  const result = [];
775
864
  for (let i = 0; i < source.length; i++) {
776
- if (i < length) {
865
+ if (i < length2) {
777
866
  result.push(NaN);
778
867
  } else {
779
- result.push(source[i] - source[i - length]);
868
+ result.push(source[i] - source[i - length2]);
780
869
  }
781
870
  }
782
871
  return result;
@@ -811,14 +900,14 @@ function tr(handle_na = false, high2, low2, close2) {
811
900
  }
812
901
  return result;
813
902
  }
814
- function atr(length, high2, low2, close2) {
903
+ function atr(length2, high2, low2, close2) {
815
904
  if (!high2 || !low2 || !close2) {
816
905
  throw new Error(
817
906
  "ta.atr() requires high, low, and close series. Either pass them explicitly or use createContext({ chart: { high, low, close } }) for implicit data."
818
907
  );
819
908
  }
820
909
  const trueRange = tr(false, high2, low2, close2);
821
- return rma(trueRange, length);
910
+ return rma(trueRange, length2);
822
911
  }
823
912
  function supertrend(factor, atrPeriod, high2, low2, close2, wicks = false) {
824
913
  if (!high2 || !low2 || !close2) {
@@ -870,9 +959,9 @@ function supertrend(factor, atrPeriod, high2, low2, close2, wicks = false) {
870
959
  }
871
960
  return [supertrendValues, directions];
872
961
  }
873
- function rma(source, length) {
962
+ function rma(source, length2) {
874
963
  const result = [];
875
- const len = Math.floor(length);
964
+ const len = Math.floor(length2);
876
965
  const alpha = 1 / len;
877
966
  let firstValidIndex = -1;
878
967
  let validCount = 0;
@@ -899,15 +988,17 @@ function rma(source, length) {
899
988
  const val = source[i];
900
989
  if (val !== void 0 && !isNaN(val)) {
901
990
  rmaValue = alpha * val + (1 - alpha) * rmaValue;
991
+ result.push(rmaValue);
992
+ } else {
993
+ result.push(NaN);
902
994
  }
903
- result.push(rmaValue);
904
995
  }
905
996
  }
906
997
  return result;
907
998
  }
908
- function wma(source, length) {
999
+ function wma(source, length2) {
909
1000
  const result = [];
910
- const len = Math.floor(length);
1001
+ const len = Math.floor(length2);
911
1002
  for (let i = 0; i < source.length; i++) {
912
1003
  if (i < len - 1) {
913
1004
  result.push(NaN);
@@ -924,48 +1015,27 @@ function wma(source, length) {
924
1015
  }
925
1016
  return result;
926
1017
  }
927
- function highest(source, length) {
928
- const result = [];
929
- for (let i = 0; i < source.length; i++) {
930
- if (i < length - 1) {
931
- result.push(NaN);
932
- } else {
933
- let max4 = -Infinity;
934
- for (let j = 0; j < length; j++) {
935
- if (!isNaN(source[i - j])) {
936
- max4 = Math.max(max4, source[i - j]);
937
- }
938
- }
939
- result.push(max4 === -Infinity ? NaN : max4);
940
- }
941
- }
942
- return result;
1018
+ function highest(source, length2) {
1019
+ return source.map((_, i) => {
1020
+ if (i < length2 - 1) return NaN;
1021
+ const w = windowUntilNa(source, i, length2);
1022
+ return w.length ? Math.max(...w.map((x) => x[0])) : NaN;
1023
+ });
943
1024
  }
944
- function lowest(source, length) {
945
- const result = [];
946
- for (let i = 0; i < source.length; i++) {
947
- if (i < length - 1) {
948
- result.push(NaN);
949
- } else {
950
- let min4 = Infinity;
951
- for (let j = 0; j < length; j++) {
952
- if (!isNaN(source[i - j])) {
953
- min4 = Math.min(min4, source[i - j]);
954
- }
955
- }
956
- result.push(min4 === Infinity ? NaN : min4);
957
- }
958
- }
959
- return result;
1025
+ function lowest(source, length2) {
1026
+ return source.map((_, i) => {
1027
+ if (i < length2 - 1) return NaN;
1028
+ const w = windowUntilNa(source, i, length2);
1029
+ return w.length ? Math.min(...w.map((x) => x[0])) : NaN;
1030
+ });
960
1031
  }
961
1032
  function cum(source) {
962
- const result = [];
963
1033
  let sum2 = 0;
964
- for (let i = 0; i < source.length; i++) {
965
- sum2 += source[i];
966
- result.push(sum2);
967
- }
968
- return result;
1034
+ return source.map((v) => {
1035
+ if (Number.isNaN(v)) return NaN;
1036
+ sum2 += v;
1037
+ return sum2;
1038
+ });
969
1039
  }
970
1040
  function cross(source1, source2) {
971
1041
  const result = [];
@@ -980,14 +1050,14 @@ function cross(source1, source2) {
980
1050
  }
981
1051
  return result;
982
1052
  }
983
- function rising(source, length) {
1053
+ function rising(source, length2) {
984
1054
  const result = [];
985
1055
  for (let i = 0; i < source.length; i++) {
986
- if (i < length) {
1056
+ if (i < length2) {
987
1057
  result.push(false);
988
1058
  } else {
989
1059
  let isRising = true;
990
- for (let j = 1; j <= length; j++) {
1060
+ for (let j = 1; j <= length2; j++) {
991
1061
  if (source[i - j + 1] <= source[i - j]) {
992
1062
  isRising = false;
993
1063
  break;
@@ -998,14 +1068,14 @@ function rising(source, length) {
998
1068
  }
999
1069
  return result;
1000
1070
  }
1001
- function falling(source, length) {
1071
+ function falling(source, length2) {
1002
1072
  const result = [];
1003
1073
  for (let i = 0; i < source.length; i++) {
1004
- if (i < length) {
1074
+ if (i < length2) {
1005
1075
  result.push(false);
1006
1076
  } else {
1007
1077
  let isFalling = true;
1008
- for (let j = 1; j <= length; j++) {
1078
+ for (let j = 1; j <= length2; j++) {
1009
1079
  if (source[i - j + 1] >= source[i - j]) {
1010
1080
  isFalling = false;
1011
1081
  break;
@@ -1016,13 +1086,13 @@ function falling(source, length) {
1016
1086
  }
1017
1087
  return result;
1018
1088
  }
1019
- function roc(source, length) {
1089
+ function roc(source, length2) {
1020
1090
  const result = [];
1021
1091
  for (let i = 0; i < source.length; i++) {
1022
- if (i < length) {
1092
+ if (i < length2) {
1023
1093
  result.push(NaN);
1024
1094
  } else {
1025
- const oldValue = source[i - length];
1095
+ const oldValue = source[i - length2];
1026
1096
  if (oldValue === 0 || isNaN(oldValue) || isNaN(source[i])) {
1027
1097
  result.push(NaN);
1028
1098
  } else {
@@ -1033,49 +1103,49 @@ function roc(source, length) {
1033
1103
  }
1034
1104
  return result;
1035
1105
  }
1036
- function mom(source, length) {
1106
+ function mom(source, length2) {
1037
1107
  const result = [];
1038
1108
  for (let i = 0; i < source.length; i++) {
1039
- if (i < length) {
1109
+ if (i < length2) {
1040
1110
  result.push(NaN);
1041
1111
  } else {
1042
- if (isNaN(source[i]) || isNaN(source[i - length])) {
1112
+ if (isNaN(source[i]) || isNaN(source[i - length2])) {
1043
1113
  result.push(NaN);
1044
1114
  } else {
1045
- result.push(source[i] - source[i - length]);
1115
+ result.push(source[i] - source[i - length2]);
1046
1116
  }
1047
1117
  }
1048
1118
  }
1049
1119
  return result;
1050
1120
  }
1051
- function dev(source, length) {
1121
+ function dev(source, length2) {
1052
1122
  const result = [];
1053
- const meanValues = sma(source, length);
1123
+ const meanValues = sma(source, length2);
1054
1124
  for (let i = 0; i < source.length; i++) {
1055
- if (i < length - 1 || isNaN(meanValues[i])) {
1125
+ if (i < length2 - 1 || isNaN(meanValues[i])) {
1056
1126
  result.push(NaN);
1057
1127
  } else {
1058
1128
  let sum2 = 0;
1059
- for (let j = 0; j < length; j++) {
1129
+ for (let j = 0; j < length2; j++) {
1060
1130
  if (!isNaN(source[i - j])) {
1061
1131
  sum2 += Math.abs(source[i - j] - meanValues[i]);
1062
1132
  }
1063
1133
  }
1064
- result.push(sum2 / length);
1134
+ result.push(sum2 / length2);
1065
1135
  }
1066
1136
  }
1067
1137
  return result;
1068
1138
  }
1069
- function variance(source, length, biased = true) {
1139
+ function variance(source, length2, biased = true) {
1070
1140
  const result = [];
1071
- const meanValues = sma(source, length);
1141
+ const meanValues = sma(source, length2);
1072
1142
  for (let i = 0; i < source.length; i++) {
1073
- if (i < length - 1 || isNaN(meanValues[i])) {
1143
+ if (i < length2 - 1 || isNaN(meanValues[i])) {
1074
1144
  result.push(NaN);
1075
1145
  } else {
1076
1146
  let sumSquares = 0;
1077
1147
  let count = 0;
1078
- for (let j = 0; j < length; j++) {
1148
+ for (let j = 0; j < length2; j++) {
1079
1149
  if (!isNaN(source[i - j])) {
1080
1150
  const diff = source[i - j] - meanValues[i];
1081
1151
  sumSquares += diff * diff;
@@ -1088,14 +1158,14 @@ function variance(source, length, biased = true) {
1088
1158
  }
1089
1159
  return result;
1090
1160
  }
1091
- function median(source, length) {
1161
+ function median(source, length2) {
1092
1162
  const result = [];
1093
1163
  for (let i = 0; i < source.length; i++) {
1094
- if (i < length - 1) {
1164
+ if (i < length2 - 1) {
1095
1165
  result.push(NaN);
1096
1166
  } else {
1097
1167
  const values = [];
1098
- for (let j = 0; j < length; j++) {
1168
+ for (let j = 0; j < length2; j++) {
1099
1169
  if (!isNaN(source[i - j])) {
1100
1170
  values.push(source[i - j]);
1101
1171
  }
@@ -1131,7 +1201,7 @@ function swma(source) {
1131
1201
  }
1132
1202
  return result;
1133
1203
  }
1134
- function vwma(source, length, volume2) {
1204
+ function vwma(source, length2, volume2) {
1135
1205
  if (!volume2) {
1136
1206
  throw new Error(
1137
1207
  "ta.vwma() requires volume series. Either pass it explicitly or use createContext({ chart: { ..., volume } }) for implicit data."
@@ -1141,8 +1211,8 @@ function vwma(source, length, volume2) {
1141
1211
  for (let i = 0; i < source.length; i++) {
1142
1212
  sourceTimesVolume.push(source[i] * volume2[i]);
1143
1213
  }
1144
- const numerator = sma(sourceTimesVolume, length);
1145
- const denominator = sma(volume2, length);
1214
+ const numerator = sma(sourceTimesVolume, length2);
1215
+ const denominator = sma(volume2, length2);
1146
1216
  const result = [];
1147
1217
  for (let i = 0; i < source.length; i++) {
1148
1218
  if (denominator[i] === 0 || isNaN(denominator[i])) {
@@ -1153,9 +1223,9 @@ function vwma(source, length, volume2) {
1153
1223
  }
1154
1224
  return result;
1155
1225
  }
1156
- function linreg(source, length, offset = 0) {
1226
+ function linreg(source, length2, offset = 0) {
1157
1227
  const result = [];
1158
- const len = Math.floor(length);
1228
+ const len = Math.floor(length2);
1159
1229
  for (let i = 0; i < source.length; i++) {
1160
1230
  if (i < len - 1) {
1161
1231
  result.push(NaN);
@@ -1191,14 +1261,14 @@ function linreg(source, length, offset = 0) {
1191
1261
  }
1192
1262
  return result;
1193
1263
  }
1194
- function correlation(source1, source2, length) {
1264
+ function correlation(source1, source2, length2) {
1195
1265
  const result = [];
1196
1266
  for (let i = 0; i < source1.length; i++) {
1197
- if (i < length - 1) {
1267
+ if (i < length2 - 1) {
1198
1268
  result.push(NaN);
1199
1269
  } else {
1200
1270
  const pairs = [];
1201
- for (let j = 0; j < length; j++) {
1271
+ for (let j = 0; j < length2; j++) {
1202
1272
  if (!isNaN(source1[i - j]) && !isNaN(source2[i - j])) {
1203
1273
  pairs.push([source1[i - j], source2[i - j]]);
1204
1274
  }
@@ -1235,10 +1305,10 @@ function correlation(source1, source2, length) {
1235
1305
  }
1236
1306
  return result;
1237
1307
  }
1238
- function percentrank(source, length) {
1308
+ function percentrank(source, length2) {
1239
1309
  const result = [];
1240
1310
  for (let i = 0; i < source.length; i++) {
1241
- if (i < length) {
1311
+ if (i < length2) {
1242
1312
  result.push(NaN);
1243
1313
  } else {
1244
1314
  if (isNaN(source[i])) {
@@ -1246,7 +1316,7 @@ function percentrank(source, length) {
1246
1316
  continue;
1247
1317
  }
1248
1318
  let hasNaN = false;
1249
- for (let j = 1; j <= length; j++) {
1319
+ for (let j = 1; j <= length2; j++) {
1250
1320
  if (isNaN(source[i - j])) {
1251
1321
  hasNaN = true;
1252
1322
  break;
@@ -1257,21 +1327,21 @@ function percentrank(source, length) {
1257
1327
  } else {
1258
1328
  const currentValue = source[i];
1259
1329
  let countLessOrEqual = 0;
1260
- for (let j = 1; j <= length; j++) {
1330
+ for (let j = 1; j <= length2; j++) {
1261
1331
  if (source[i - j] <= currentValue) {
1262
1332
  countLessOrEqual++;
1263
1333
  }
1264
1334
  }
1265
- result.push(countLessOrEqual / length * 100);
1335
+ result.push(countLessOrEqual / length2 * 100);
1266
1336
  }
1267
1337
  }
1268
1338
  }
1269
1339
  return result;
1270
1340
  }
1271
- function cci(source, length) {
1341
+ function cci(source, length2) {
1272
1342
  const result = [];
1273
- const smaValues = sma(source, length);
1274
- const devValues = dev(source, length);
1343
+ const smaValues = sma(source, length2);
1344
+ const devValues = dev(source, length2);
1275
1345
  for (let i = 0; i < source.length; i++) {
1276
1346
  if (isNaN(smaValues[i]) || isNaN(devValues[i]) || devValues[i] === 0) {
1277
1347
  result.push(NaN);
@@ -1282,10 +1352,10 @@ function cci(source, length) {
1282
1352
  }
1283
1353
  return result;
1284
1354
  }
1285
- function stoch(source, high2, low2, length) {
1355
+ function stoch(source, high2, low2, length2) {
1286
1356
  const result = [];
1287
- const lowestValues = lowest(low2, length);
1288
- const highestValues = highest(high2, length);
1357
+ const lowestValues = lowest(low2, length2);
1358
+ const highestValues = highest(high2, length2);
1289
1359
  for (let i = 0; i < source.length; i++) {
1290
1360
  if (isNaN(lowestValues[i]) || isNaN(highestValues[i])) {
1291
1361
  result.push(NaN);
@@ -1301,7 +1371,7 @@ function stoch(source, high2, low2, length) {
1301
1371
  }
1302
1372
  return result;
1303
1373
  }
1304
- function mfi(source, length, volume2) {
1374
+ function mfi(source, length2, volume2) {
1305
1375
  if (!volume2) {
1306
1376
  throw new Error(
1307
1377
  "ta.mfi() requires volume series. Either pass it explicitly or use createContext({ chart: { ..., volume } }) for implicit data."
@@ -1330,12 +1400,12 @@ function mfi(source, length, volume2) {
1330
1400
  }
1331
1401
  }
1332
1402
  for (let i = 0; i < source.length; i++) {
1333
- if (i < length) {
1403
+ if (i < length2) {
1334
1404
  result.push(NaN);
1335
1405
  } else {
1336
1406
  let posSum = 0;
1337
1407
  let negSum = 0;
1338
- for (let j = 0; j < length; j++) {
1408
+ for (let j = 0; j < length2; j++) {
1339
1409
  posSum += positiveFlow[i - j];
1340
1410
  negSum += negativeFlow[i - j];
1341
1411
  }
@@ -1350,11 +1420,11 @@ function mfi(source, length, volume2) {
1350
1420
  }
1351
1421
  return result;
1352
1422
  }
1353
- function hma(source, length) {
1354
- const halfLength = Math.floor(length / 2);
1355
- const sqrtLength = Math.floor(Math.sqrt(length));
1423
+ function hma(source, length2) {
1424
+ const halfLength = Math.floor(length2 / 2);
1425
+ const sqrtLength = Math.floor(Math.sqrt(length2));
1356
1426
  const wmaHalf = wma(source, halfLength);
1357
- const wmaFull = wma(source, length);
1427
+ const wmaFull = wma(source, length2);
1358
1428
  const diff = [];
1359
1429
  for (let i = 0; i < source.length; i++) {
1360
1430
  diff.push(2 * wmaHalf[i] - wmaFull[i]);
@@ -1438,89 +1508,44 @@ function sar(start, inc, max4, high2, low2, close2) {
1438
1508
  }
1439
1509
  return result;
1440
1510
  }
1511
+ function pivot(source, leftbars, rightbars, isHigh) {
1512
+ const beatsLeft = isHigh ? (x, v) => x > v : (x, v) => x < v;
1513
+ const beatsRight = isHigh ? (x, v) => x >= v : (x, v) => x <= v;
1514
+ return source.map((_, i) => {
1515
+ const center = i - rightbars;
1516
+ if (center - leftbars < 0) return NaN;
1517
+ const v = source[center];
1518
+ if (Number.isNaN(v)) return NaN;
1519
+ for (let j = 1; j <= leftbars; j++) {
1520
+ const x = source[center - j];
1521
+ if (Number.isNaN(x)) break;
1522
+ if (beatsLeft(x, v)) return NaN;
1523
+ }
1524
+ for (let j = 1; j <= rightbars; j++) {
1525
+ const x = source[center + j];
1526
+ if (Number.isNaN(x)) break;
1527
+ if (beatsRight(x, v)) return NaN;
1528
+ }
1529
+ return v;
1530
+ });
1531
+ }
1441
1532
  function pivothigh(sourceOrLeftbars, leftbarsOrRightbars, rightbars, high2) {
1442
- let source;
1443
- let leftbars;
1444
- let right;
1445
1533
  if (rightbars === void 0) {
1446
1534
  if (!high2) {
1447
1535
  throw new Error("ta.pivothigh() requires high series when using two-parameter version.");
1448
1536
  }
1449
- source = high2;
1450
- leftbars = sourceOrLeftbars;
1451
- right = leftbarsOrRightbars;
1452
- } else {
1453
- source = sourceOrLeftbars;
1454
- leftbars = leftbarsOrRightbars;
1455
- right = rightbars;
1456
- }
1457
- const result = [];
1458
- for (let i = 0; i < source.length; i++) {
1459
- if (i < leftbars || i + right >= source.length) {
1460
- result.push(NaN);
1461
- continue;
1462
- }
1463
- const centerValue = source[i];
1464
- let isPivot = true;
1465
- for (let j = 1; j <= leftbars; j++) {
1466
- if (source[i - j] >= centerValue) {
1467
- isPivot = false;
1468
- break;
1469
- }
1470
- }
1471
- if (isPivot) {
1472
- for (let j = 1; j <= right; j++) {
1473
- if (source[i + j] >= centerValue) {
1474
- isPivot = false;
1475
- break;
1476
- }
1477
- }
1478
- }
1479
- result.push(isPivot ? centerValue : NaN);
1537
+ return pivot(high2, sourceOrLeftbars, leftbarsOrRightbars, true);
1480
1538
  }
1481
- return result;
1539
+ return pivot(sourceOrLeftbars, leftbarsOrRightbars, rightbars, true);
1482
1540
  }
1483
1541
  function pivotlow(sourceOrLeftbars, leftbarsOrRightbars, rightbars, low2) {
1484
- let source;
1485
- let leftbars;
1486
- let right;
1487
1542
  if (rightbars === void 0) {
1488
1543
  if (!low2) {
1489
1544
  throw new Error("ta.pivotlow() requires low series when using two-parameter version.");
1490
1545
  }
1491
- source = low2;
1492
- leftbars = sourceOrLeftbars;
1493
- right = leftbarsOrRightbars;
1494
- } else {
1495
- source = sourceOrLeftbars;
1496
- leftbars = leftbarsOrRightbars;
1497
- right = rightbars;
1498
- }
1499
- const result = [];
1500
- for (let i = 0; i < source.length; i++) {
1501
- if (i < leftbars || i + right >= source.length) {
1502
- result.push(NaN);
1503
- continue;
1504
- }
1505
- const centerValue = source[i];
1506
- let isPivot = true;
1507
- for (let j = 1; j <= leftbars; j++) {
1508
- if (source[i - j] <= centerValue) {
1509
- isPivot = false;
1510
- break;
1511
- }
1512
- }
1513
- if (isPivot) {
1514
- for (let j = 1; j <= right; j++) {
1515
- if (source[i + j] <= centerValue) {
1516
- isPivot = false;
1517
- break;
1518
- }
1519
- }
1520
- }
1521
- result.push(isPivot ? centerValue : NaN);
1546
+ return pivot(low2, sourceOrLeftbars, leftbarsOrRightbars, false);
1522
1547
  }
1523
- return result;
1548
+ return pivot(sourceOrLeftbars, leftbarsOrRightbars, rightbars, false);
1524
1549
  }
1525
1550
  function barssince(condition) {
1526
1551
  const result = [];
@@ -1625,16 +1650,16 @@ function tsi(source, shortLength, longLength) {
1625
1650
  }
1626
1651
  return result;
1627
1652
  }
1628
- function cmo(source, length) {
1653
+ function cmo(source, length2) {
1629
1654
  const result = [];
1630
1655
  for (let i = 0; i < source.length; i++) {
1631
- if (i < length) {
1656
+ if (i < length2) {
1632
1657
  result.push(NaN);
1633
1658
  continue;
1634
1659
  }
1635
1660
  let sumGains = 0;
1636
1661
  let sumLosses = 0;
1637
- for (let j = 0; j < length; j++) {
1662
+ for (let j = 0; j < length2; j++) {
1638
1663
  const change3 = source[i - j] - source[i - j - 1];
1639
1664
  if (change3 > 0) {
1640
1665
  sumGains += change3;
@@ -1652,8 +1677,8 @@ function cmo(source, length) {
1652
1677
  }
1653
1678
  return result;
1654
1679
  }
1655
- function kc(source, length, mult, useTrueRange = true, high2, low2, close2) {
1656
- const middle = ema(source, length);
1680
+ function kc(source, length2, mult, useTrueRange = true, high2, low2, close2) {
1681
+ const middle = ema(source, length2);
1657
1682
  let range3;
1658
1683
  if (useTrueRange) {
1659
1684
  if (!high2 || !low2 || !close2) {
@@ -1669,38 +1694,38 @@ function kc(source, length, mult, useTrueRange = true, high2, low2, close2) {
1669
1694
  range3.push(high2[i] - low2[i]);
1670
1695
  }
1671
1696
  }
1672
- const rangeEma = ema(range3, length);
1673
- const upper = [];
1674
- const lower = [];
1697
+ const rangeEma = ema(range3, length2);
1698
+ const upper2 = [];
1699
+ const lower2 = [];
1675
1700
  for (let i = 0; i < middle.length; i++) {
1676
- upper.push(middle[i] + rangeEma[i] * mult);
1677
- lower.push(middle[i] - rangeEma[i] * mult);
1701
+ upper2.push(middle[i] + rangeEma[i] * mult);
1702
+ lower2.push(middle[i] - rangeEma[i] * mult);
1678
1703
  }
1679
- return [middle, upper, lower];
1704
+ return [middle, upper2, lower2];
1680
1705
  }
1681
- function bbw(source, length, mult) {
1682
- const [basis, upper, lower] = bb(source, length, mult);
1706
+ function bbw(source, length2, mult) {
1707
+ const [basis, upper2, lower2] = bb(source, length2, mult);
1683
1708
  const result = [];
1684
1709
  for (let i = 0; i < source.length; i++) {
1685
1710
  if (basis[i] === 0) {
1686
1711
  result.push(NaN);
1687
1712
  } else {
1688
- const width = (upper[i] - lower[i]) / basis[i] * 100;
1713
+ const width = (upper2[i] - lower2[i]) / basis[i] * 100;
1689
1714
  result.push(width);
1690
1715
  }
1691
1716
  }
1692
1717
  return result;
1693
1718
  }
1694
- function wpr(high2, low2, close2, length = 14) {
1719
+ function wpr(high2, low2, close2, length2 = 14) {
1695
1720
  const result = [];
1696
1721
  for (let i = 0; i < close2.length; i++) {
1697
- if (i < length - 1) {
1722
+ if (i < length2 - 1) {
1698
1723
  result.push(NaN);
1699
1724
  continue;
1700
1725
  }
1701
- let highestHigh = high2[i - length + 1];
1702
- let lowestLow = low2[i - length + 1];
1703
- for (let j = i - length + 2; j <= i; j++) {
1726
+ let highestHigh = high2[i - length2 + 1];
1727
+ let lowestLow = low2[i - length2 + 1];
1728
+ for (let j = i - length2 + 2; j <= i; j++) {
1704
1729
  if (high2[j] > highestHigh) highestHigh = high2[j];
1705
1730
  if (low2[j] < lowestLow) lowestLow = low2[j];
1706
1731
  }
@@ -1714,181 +1739,138 @@ function wpr(high2, low2, close2, length = 14) {
1714
1739
  }
1715
1740
  return result;
1716
1741
  }
1717
- function vwap(source, volume2) {
1742
+ function vwap(source, volume2, anchor, stdev_mult) {
1718
1743
  if (source.length !== volume2.length) {
1719
1744
  throw new Error("ta.vwap: source and volume must have the same length");
1720
1745
  }
1721
- const result = [];
1722
- let cumulativePV = 0;
1723
- let cumulativeVolume = 0;
1746
+ const mid = [];
1747
+ const upper2 = [];
1748
+ const lower2 = [];
1749
+ let sumPV = 0;
1750
+ let sumV = 0;
1751
+ let sumPPV = 0;
1724
1752
  for (let i = 0; i < source.length; i++) {
1725
- if (isNaN(source[i]) || isNaN(volume2[i])) {
1726
- result.push(NaN);
1727
- continue;
1753
+ if (anchor && anchor[i]) {
1754
+ sumPV = 0;
1755
+ sumV = 0;
1756
+ sumPPV = 0;
1728
1757
  }
1729
- cumulativePV += source[i] * volume2[i];
1730
- cumulativeVolume += volume2[i];
1731
- if (cumulativeVolume === 0) {
1732
- result.push(NaN);
1733
- } else {
1734
- result.push(cumulativePV / cumulativeVolume);
1758
+ const s = source[i];
1759
+ const v = volume2[i];
1760
+ if (!Number.isNaN(s) && !Number.isNaN(v)) {
1761
+ sumPV += s * v;
1762
+ sumV += v;
1763
+ sumPPV += s * s * v;
1764
+ }
1765
+ const m = sumV === 0 ? NaN : sumPV / sumV;
1766
+ mid.push(m);
1767
+ if (stdev_mult !== void 0) {
1768
+ const sd = Math.sqrt(Math.max(0, sumPPV / sumV - m * m));
1769
+ upper2.push(m + stdev_mult * sd);
1770
+ lower2.push(m - stdev_mult * sd);
1735
1771
  }
1736
1772
  }
1737
- return result;
1773
+ return stdev_mult === void 0 ? mid : [mid, upper2, lower2];
1738
1774
  }
1739
- function alma(source, length = 9, offset = 0.85, sigma = 6, floor2 = false) {
1775
+ function alma(source, length2 = 9, offset = 0.85, sigma = 6, floor2 = false) {
1740
1776
  const result = [];
1741
- const m = floor2 ? Math.floor(offset * (length - 1)) : offset * (length - 1);
1742
- const s = length / sigma;
1777
+ const m = floor2 ? Math.floor(offset * (length2 - 1)) : offset * (length2 - 1);
1778
+ const s = length2 / sigma;
1743
1779
  const weights = [];
1744
1780
  let weightSum = 0;
1745
- for (let i = 0; i < length; i++) {
1781
+ for (let i = 0; i < length2; i++) {
1746
1782
  const weight = Math.exp(-1 * Math.pow(i - m, 2) / (2 * Math.pow(s, 2)));
1747
1783
  weights.push(weight);
1748
1784
  weightSum += weight;
1749
1785
  }
1750
- for (let i = 0; i < length; i++) {
1786
+ for (let i = 0; i < length2; i++) {
1751
1787
  weights[i] /= weightSum;
1752
1788
  }
1753
1789
  for (let i = 0; i < source.length; i++) {
1754
- if (i < length - 1) {
1790
+ if (i < length2 - 1) {
1755
1791
  result.push(NaN);
1756
1792
  continue;
1757
1793
  }
1758
1794
  let almaValue = 0;
1759
- for (let j = 0; j < length; j++) {
1760
- almaValue += source[i - length + 1 + j] * weights[j];
1795
+ for (let j = 0; j < length2; j++) {
1796
+ almaValue += source[i - length2 + 1 + j] * weights[j];
1761
1797
  }
1762
1798
  result.push(almaValue);
1763
1799
  }
1764
1800
  return result;
1765
1801
  }
1766
- function kcw(source, length = 20, mult = 2, useTrueRange = true, high2, low2, close2) {
1767
- const [basis, upper, lower] = kc(source, length, mult, useTrueRange, high2, low2, close2);
1802
+ function kcw(source, length2 = 20, mult = 2, useTrueRange = true, high2, low2, close2) {
1803
+ const [basis, upper2, lower2] = kc(source, length2, mult, useTrueRange, high2, low2, close2);
1768
1804
  const result = [];
1769
1805
  for (let i = 0; i < source.length; i++) {
1770
1806
  if (isNaN(basis[i]) || basis[i] === 0) {
1771
1807
  result.push(NaN);
1772
1808
  } else {
1773
- const width = (upper[i] - lower[i]) / basis[i] * 100;
1809
+ const width = (upper2[i] - lower2[i]) / basis[i] * 100;
1774
1810
  result.push(width);
1775
1811
  }
1776
1812
  }
1777
1813
  return result;
1778
1814
  }
1779
- function range(high2, low2) {
1780
- if (high2.length !== low2.length) {
1781
- throw new Error("ta.range: high and low must have the same length");
1782
- }
1783
- const result = [];
1784
- for (let i = 0; i < high2.length; i++) {
1785
- if (isNaN(high2[i]) || isNaN(low2[i])) {
1786
- result.push(NaN);
1787
- } else {
1788
- result.push(high2[i] - low2[i]);
1789
- }
1790
- }
1791
- return result;
1815
+ function range(source, length2) {
1816
+ return source.map((_, i) => {
1817
+ const values = lastValues(source, i, length2);
1818
+ return values ? Math.max(...values) - Math.min(...values) : NaN;
1819
+ });
1792
1820
  }
1793
- function highestbars(source, length) {
1794
- const result = [];
1795
- for (let i = 0; i < source.length; i++) {
1796
- if (i < length - 1) {
1797
- result.push(NaN);
1798
- continue;
1799
- }
1800
- let highestValue = source[i - length + 1];
1801
- let highestOffset = length - 1;
1802
- for (let j = i - length + 2; j <= i; j++) {
1803
- if (source[j] > highestValue) {
1804
- highestValue = source[j];
1805
- highestOffset = i - j;
1806
- }
1807
- }
1808
- result.push(highestOffset);
1809
- }
1810
- return result;
1821
+ function highestbars(source, length2) {
1822
+ return extremeOffset(source, length2, (a, b2) => a >= b2);
1811
1823
  }
1812
- function lowestbars(source, length) {
1813
- const result = [];
1814
- for (let i = 0; i < source.length; i++) {
1815
- if (i < length - 1) {
1816
- result.push(NaN);
1817
- continue;
1818
- }
1819
- let lowestValue = source[i - length + 1];
1820
- let lowestOffset = length - 1;
1821
- for (let j = i - length + 2; j <= i; j++) {
1822
- if (source[j] < lowestValue) {
1823
- lowestValue = source[j];
1824
- lowestOffset = i - j;
1825
- }
1826
- }
1827
- result.push(lowestOffset);
1828
- }
1829
- return result;
1824
+ function lowestbars(source, length2) {
1825
+ return extremeOffset(source, length2, (a, b2) => a <= b2);
1830
1826
  }
1831
- function max(source1, source2) {
1832
- if (source1.length !== source2.length) {
1833
- throw new Error("ta.max: source1 and source2 must have the same length");
1834
- }
1835
- const result = [];
1836
- for (let i = 0; i < source1.length; i++) {
1837
- if (isNaN(source1[i]) || isNaN(source2[i])) {
1838
- result.push(NaN);
1839
- } else {
1840
- result.push(Math.max(source1[i], source2[i]));
1841
- }
1842
- }
1843
- return result;
1827
+ function max(source) {
1828
+ let best = NaN;
1829
+ return source.map((x) => {
1830
+ if (!Number.isNaN(x) && !(x <= best)) best = x;
1831
+ return best;
1832
+ });
1844
1833
  }
1845
- function min(source1, source2) {
1846
- if (source1.length !== source2.length) {
1847
- throw new Error("ta.min: source1 and source2 must have the same length");
1848
- }
1849
- const result = [];
1850
- for (let i = 0; i < source1.length; i++) {
1851
- if (isNaN(source1[i]) || isNaN(source2[i])) {
1852
- result.push(NaN);
1853
- } else {
1854
- result.push(Math.min(source1[i], source2[i]));
1855
- }
1856
- }
1857
- return result;
1834
+ function min(source) {
1835
+ let best = NaN;
1836
+ return source.map((x) => {
1837
+ if (!Number.isNaN(x) && !(x >= best)) best = x;
1838
+ return best;
1839
+ });
1858
1840
  }
1859
- function cog(source, length = 10) {
1841
+ function cog(source, length2 = 10) {
1860
1842
  const result = [];
1861
1843
  for (let i = 0; i < source.length; i++) {
1862
- if (i < length - 1) {
1844
+ if (i < length2 - 1) {
1863
1845
  result.push(NaN);
1864
1846
  continue;
1865
1847
  }
1866
1848
  let numerator = 0;
1867
1849
  let denominator = 0;
1868
- for (let j = 0; j < length; j++) {
1850
+ for (let j = 0; j < length2; j++) {
1869
1851
  const weight = j + 1;
1870
- const price = source[i - length + 1 + j];
1852
+ const price = source[i - length2 + 1 + j];
1871
1853
  numerator += weight * price;
1872
1854
  denominator += price;
1873
1855
  }
1874
1856
  if (denominator === 0) {
1875
1857
  result.push(NaN);
1876
1858
  } else {
1877
- const cog3 = -1 * (numerator / denominator) + (length + 1) / 2;
1859
+ const cog3 = -1 * (numerator / denominator) + (length2 + 1) / 2;
1878
1860
  result.push(cog3);
1879
1861
  }
1880
1862
  }
1881
1863
  return result;
1882
1864
  }
1883
- function mode(source, length) {
1865
+ function mode(source, length2) {
1884
1866
  const result = [];
1885
1867
  for (let i = 0; i < source.length; i++) {
1886
- if (i < length - 1) {
1868
+ if (i < length2 - 1) {
1887
1869
  result.push(NaN);
1888
1870
  continue;
1889
1871
  }
1890
1872
  const values = [];
1891
- for (let j = 0; j < length; j++) {
1873
+ for (let j = 0; j < length2; j++) {
1892
1874
  const value = source[i - j];
1893
1875
  if (!isNaN(value)) {
1894
1876
  values.push(value);
@@ -1918,15 +1900,15 @@ function mode(source, length) {
1918
1900
  }
1919
1901
  return result;
1920
1902
  }
1921
- function percentile_linear_interpolation(source, length, percentage) {
1903
+ function percentile_linear_interpolation(source, length2, percentage) {
1922
1904
  const result = [];
1923
1905
  for (let i = 0; i < source.length; i++) {
1924
- if (i < length - 1) {
1906
+ if (i < length2 - 1) {
1925
1907
  result.push(NaN);
1926
1908
  continue;
1927
1909
  }
1928
1910
  const values = [];
1929
- for (let j = 0; j < length; j++) {
1911
+ for (let j = 0; j < length2; j++) {
1930
1912
  const value = source[i - j];
1931
1913
  values.push(value);
1932
1914
  }
@@ -1948,15 +1930,15 @@ function percentile_linear_interpolation(source, length, percentage) {
1948
1930
  }
1949
1931
  return result;
1950
1932
  }
1951
- function percentile_nearest_rank(source, length, percentage) {
1933
+ function percentile_nearest_rank(source, length2, percentage) {
1952
1934
  const result = [];
1953
1935
  for (let i = 0; i < source.length; i++) {
1954
- if (i < length - 1) {
1936
+ if (i < length2 - 1) {
1955
1937
  result.push(NaN);
1956
1938
  continue;
1957
1939
  }
1958
1940
  const values = [];
1959
- for (let j = 0; j < length; j++) {
1941
+ for (let j = 0; j < length2; j++) {
1960
1942
  const value = source[i - j];
1961
1943
  if (!isNaN(value)) {
1962
1944
  values.push(value);
@@ -1977,16 +1959,16 @@ function percentile_nearest_rank(source, length, percentage) {
1977
1959
  }
1978
1960
  return result;
1979
1961
  }
1980
- function rci(source, length) {
1962
+ function rci(source, length2) {
1981
1963
  const result = [];
1982
1964
  for (let i = 0; i < source.length; i++) {
1983
- if (i < length - 1) {
1965
+ if (i < length2 - 1) {
1984
1966
  result.push(NaN);
1985
1967
  continue;
1986
1968
  }
1987
1969
  const values = [];
1988
- for (let j = 0; j < length; j++) {
1989
- values.push(source[i - length + 1 + j]);
1970
+ for (let j = 0; j < length2; j++) {
1971
+ values.push(source[i - length2 + 1 + j]);
1990
1972
  }
1991
1973
  if (values.some((v) => isNaN(v))) {
1992
1974
  result.push(NaN);
@@ -1994,7 +1976,7 @@ function rci(source, length) {
1994
1976
  }
1995
1977
  const indexed = values.map((value, index) => ({ value, index }));
1996
1978
  const sorted = [...indexed].sort((a, b2) => a.value - b2.value);
1997
- const ranks = new Array(length).fill(0);
1979
+ const ranks = new Array(length2).fill(0);
1998
1980
  let currentRank = 1;
1999
1981
  for (let j = 0; j < sorted.length; j++) {
2000
1982
  let tieCount = 1;
@@ -2009,12 +1991,12 @@ function rci(source, length) {
2009
1991
  currentRank += tieCount;
2010
1992
  }
2011
1993
  let sumSquaredDiff = 0;
2012
- for (let j = 0; j < length; j++) {
1994
+ for (let j = 0; j < length2; j++) {
2013
1995
  const timeRank = j + 1;
2014
1996
  const diff = ranks[j] - timeRank;
2015
1997
  sumSquaredDiff += diff * diff;
2016
1998
  }
2017
- const n = length;
1999
+ const n = length2;
2018
2000
  const base = (n * n * n - n) / 12;
2019
2001
  let tieCorrection = 0;
2020
2002
  for (let j = 0; j < sorted.length; ) {
@@ -2040,11 +2022,11 @@ function rci(source, length) {
2040
2022
  return result;
2041
2023
  }
2042
2024
  function ichimoku(conversionPeriods, basePeriods, laggingSpan2Periods, displacement, high2, low2, close2) {
2043
- const length = high2.length;
2025
+ const length2 = high2.length;
2044
2026
  const highestConversion = highest(high2, conversionPeriods);
2045
2027
  const lowestConversion = lowest(low2, conversionPeriods);
2046
2028
  const tenkanSen = [];
2047
- for (let i = 0; i < length; i++) {
2029
+ for (let i = 0; i < length2; i++) {
2048
2030
  if (isNaN(highestConversion[i]) || isNaN(lowestConversion[i])) {
2049
2031
  tenkanSen.push(NaN);
2050
2032
  } else {
@@ -2054,7 +2036,7 @@ function ichimoku(conversionPeriods, basePeriods, laggingSpan2Periods, displacem
2054
2036
  const highestBase = highest(high2, basePeriods);
2055
2037
  const lowestBase = lowest(low2, basePeriods);
2056
2038
  const kijunSen = [];
2057
- for (let i = 0; i < length; i++) {
2039
+ for (let i = 0; i < length2; i++) {
2058
2040
  if (isNaN(highestBase[i]) || isNaN(lowestBase[i])) {
2059
2041
  kijunSen.push(NaN);
2060
2042
  } else {
@@ -2062,7 +2044,7 @@ function ichimoku(conversionPeriods, basePeriods, laggingSpan2Periods, displacem
2062
2044
  }
2063
2045
  }
2064
2046
  const senkouSpanA = [];
2065
- for (let i = 0; i < length; i++) {
2047
+ for (let i = 0; i < length2; i++) {
2066
2048
  const sourceIndex = i - displacement;
2067
2049
  if (sourceIndex < 0 || isNaN(tenkanSen[sourceIndex]) || isNaN(kijunSen[sourceIndex])) {
2068
2050
  senkouSpanA.push(NaN);
@@ -2073,7 +2055,7 @@ function ichimoku(conversionPeriods, basePeriods, laggingSpan2Periods, displacem
2073
2055
  const highestLagging = highest(high2, laggingSpan2Periods);
2074
2056
  const lowestLagging = lowest(low2, laggingSpan2Periods);
2075
2057
  const senkouSpanB = [];
2076
- for (let i = 0; i < length; i++) {
2058
+ for (let i = 0; i < length2; i++) {
2077
2059
  const sourceIndex = i - displacement;
2078
2060
  if (sourceIndex < 0 || isNaN(highestLagging[sourceIndex]) || isNaN(lowestLagging[sourceIndex])) {
2079
2061
  senkouSpanB.push(NaN);
@@ -2082,9 +2064,9 @@ function ichimoku(conversionPeriods, basePeriods, laggingSpan2Periods, displacem
2082
2064
  }
2083
2065
  }
2084
2066
  const chikouSpan = [];
2085
- for (let i = 0; i < length; i++) {
2067
+ for (let i = 0; i < length2; i++) {
2086
2068
  const sourceIndex = i + displacement;
2087
- if (sourceIndex >= length || isNaN(close2[sourceIndex])) {
2069
+ if (sourceIndex >= length2 || isNaN(close2[sourceIndex])) {
2088
2070
  chikouSpan.push(NaN);
2089
2071
  } else {
2090
2072
  chikouSpan.push(close2[sourceIndex]);
@@ -2106,13 +2088,13 @@ function zigzag(deviation = 5, depth = 10, backstep = 3, source, high2, low2) {
2106
2088
  "ta.zigzag() requires either source series or high/low series. Either pass them explicitly or use createContext({ chart: { high, low, close } }) for implicit data."
2107
2089
  );
2108
2090
  }
2109
- const length = highSource.length;
2110
- if (lowSource.length !== length) {
2091
+ const length2 = highSource.length;
2092
+ if (lowSource.length !== length2) {
2111
2093
  throw new Error("ta.zigzag: high and low must have the same length");
2112
2094
  }
2113
- const zigzagValues = new Array(length).fill(NaN);
2114
- const directions = new Array(length).fill(0);
2115
- const isPivot = new Array(length).fill(false);
2095
+ const zigzagValues = new Array(length2).fill(NaN);
2096
+ const directions = new Array(length2).fill(0);
2097
+ const isPivot = new Array(length2).fill(false);
2116
2098
  const getDeviation = (price1, price2) => {
2117
2099
  if (Math.abs(price1) < 1e-10 || isNaN(price1) || isNaN(price2)) return 0;
2118
2100
  return Math.abs((price2 - price1) / price1) * 100;
@@ -2126,7 +2108,7 @@ function zigzag(deviation = 5, depth = 10, backstep = 3, source, high2, low2) {
2126
2108
  let initialLowest = Infinity;
2127
2109
  let initialHighIndex = -1;
2128
2110
  let initialLowIndex = -1;
2129
- for (let i = 0; i < Math.min(depth, length); i++) {
2111
+ for (let i = 0; i < Math.min(depth, length2); i++) {
2130
2112
  if (!isNaN(highSource[i]) && highSource[i] > initialHighest) {
2131
2113
  initialHighest = highSource[i];
2132
2114
  initialHighIndex = i;
@@ -2149,7 +2131,7 @@ function zigzag(deviation = 5, depth = 10, backstep = 3, source, high2, low2) {
2149
2131
  } else {
2150
2132
  startIndex = depth;
2151
2133
  }
2152
- for (let i = Math.max(startIndex, depth); i < length; i++) {
2134
+ for (let i = Math.max(startIndex, depth); i < length2; i++) {
2153
2135
  const currentHigh = highSource[i];
2154
2136
  const currentLow = lowSource[i];
2155
2137
  if (isNaN(currentHigh) || isNaN(currentLow)) {
@@ -2227,53 +2209,116 @@ function zigzag(deviation = 5, depth = 10, backstep = 3, source, high2, low2) {
2227
2209
  if (potentialPivot) {
2228
2210
  confirmedPivots.push(potentialPivot);
2229
2211
  }
2230
- for (const pivot of confirmedPivots) {
2231
- zigzagValues[pivot.index] = pivot.price;
2232
- isPivot[pivot.index] = true;
2212
+ for (const pivot2 of confirmedPivots) {
2213
+ zigzagValues[pivot2.index] = pivot2.price;
2214
+ isPivot[pivot2.index] = true;
2233
2215
  }
2234
2216
  let currentDir = 0;
2235
2217
  let pivotIdx = 0;
2236
2218
  const numConfirmed = lastPotentialWasAdded ? confirmedPivots.length - 1 : confirmedPivots.length;
2237
- for (let i = 0; i < length; i++) {
2219
+ for (let i = 0; i < length2; i++) {
2238
2220
  while (pivotIdx < numConfirmed && confirmedPivots[pivotIdx].index <= i) {
2239
- const pivot = confirmedPivots[pivotIdx];
2240
- currentDir = pivot.type === "low" ? 1 : -1;
2221
+ const pivot2 = confirmedPivots[pivotIdx];
2222
+ currentDir = pivot2.type === "low" ? 1 : -1;
2241
2223
  pivotIdx++;
2242
2224
  }
2243
2225
  directions[i] = currentDir;
2244
2226
  }
2245
2227
  return [zigzagValues, directions, isPivot];
2246
2228
  }
2229
+ function obv(close2, volume2) {
2230
+ return cum(close2.map((c, i) => i === 0 ? NaN : Math.sign(c - close2[i - 1]) * volume2[i]));
2231
+ }
2232
+ function pvt(close2, volume2) {
2233
+ return cum(
2234
+ close2.map((c, i) => i === 0 ? NaN : (c - close2[i - 1]) / close2[i - 1] * volume2[i])
2235
+ );
2236
+ }
2237
+ function accdist(high2, low2, close2, volume2) {
2238
+ return cum(
2239
+ close2.map((c, i) => {
2240
+ const h = high2[i];
2241
+ const l = low2[i];
2242
+ return h === l ? 0 : (2 * c - l - h) / (h - l) * volume2[i];
2243
+ })
2244
+ );
2245
+ }
2246
+ function iii(high2, low2, close2, volume2) {
2247
+ return close2.map((c, i) => {
2248
+ const range3 = high2[i] - low2[i];
2249
+ return range3 === 0 ? NaN : (2 * c - high2[i] - low2[i]) / range3 * volume2[i];
2250
+ });
2251
+ }
2252
+ function wvad(open2, high2, low2, close2, volume2) {
2253
+ return close2.map((c, i) => {
2254
+ const range3 = high2[i] - low2[i];
2255
+ return range3 === 0 ? NaN : (c - open2[i]) / range3 * volume2[i];
2256
+ });
2257
+ }
2258
+ function wad(high2, low2, close2) {
2259
+ return cum(
2260
+ close2.map((c, i) => {
2261
+ const prev = i === 0 ? NaN : close2[i - 1];
2262
+ const mom3 = c - prev;
2263
+ if (mom3 > 0) return c - Math.min(low2[i], prev);
2264
+ if (mom3 < 0) return c - Math.max(high2[i], prev);
2265
+ return 0;
2266
+ })
2267
+ );
2268
+ }
2269
+ function volumeIndex(close2, volume2, use) {
2270
+ const result = [];
2271
+ let prevIndex = NaN;
2272
+ for (let i = 0; i < close2.length; i++) {
2273
+ const prev = !prevIndex ? 1 : prevIndex;
2274
+ const c = close2[i];
2275
+ const prevC = i === 0 ? NaN : close2[i - 1];
2276
+ let value = prev;
2277
+ if (c && prevC) {
2278
+ const prevV = i === 0 || Number.isNaN(volume2[i - 1]) ? 0 : volume2[i - 1];
2279
+ if (use(volume2[i], prevV)) value = prev + (c - prevC) / prevC * prev;
2280
+ }
2281
+ result.push(value);
2282
+ prevIndex = value;
2283
+ }
2284
+ return result;
2285
+ }
2286
+ function nvi(close2, volume2) {
2287
+ return volumeIndex(close2, volume2, (v, prevV) => v < prevV);
2288
+ }
2289
+ function pvi(close2, volume2) {
2290
+ return volumeIndex(close2, volume2, (v, prevV) => v > prevV);
2291
+ }
2247
2292
 
2248
2293
  // src/ta-series.ts
2249
- function sma2(source, length) {
2294
+ function sma2(source, length2) {
2250
2295
  const bars2 = source.bars;
2251
2296
  const sourceValues = source.toArray();
2252
- const result = sma(sourceValues, length);
2297
+ const result = sma(sourceValues, length2);
2253
2298
  return Series.fromArray(bars2, result);
2254
2299
  }
2255
- function ema2(source, length) {
2300
+ function ema2(source, length2) {
2256
2301
  const bars2 = source.bars;
2257
2302
  const sourceValues = source.toArray();
2258
- const result = ema(sourceValues, length);
2303
+ const result = ema(sourceValues, length2);
2259
2304
  return Series.fromArray(bars2, result);
2260
2305
  }
2261
- function wma2(source, length) {
2306
+ function wma2(source, length2) {
2262
2307
  const bars2 = source.bars;
2263
2308
  const sourceValues = source.toArray();
2264
- const result = wma(sourceValues, length);
2309
+ const result = wma(sourceValues, length2);
2265
2310
  return Series.fromArray(bars2, result);
2266
2311
  }
2267
- function rma2(source, length) {
2312
+ function rma2(source, length2) {
2268
2313
  const bars2 = source.bars;
2269
2314
  const sourceValues = source.toArray();
2270
- const result = rma(sourceValues, length);
2315
+ const result = rma(sourceValues, length2);
2271
2316
  return Series.fromArray(bars2, result);
2272
2317
  }
2273
- function rsi2(source, length) {
2318
+ function rsi2(source, length2) {
2274
2319
  const bars2 = source.bars;
2275
2320
  const sourceValues = source.toArray();
2276
- const result = rsi(sourceValues, length);
2321
+ const result = rsi(sourceValues, length2);
2277
2322
  return Series.fromArray(bars2, result);
2278
2323
  }
2279
2324
  function macd2(source, fastLength, slowLength, signalLength) {
@@ -2285,26 +2330,24 @@ function macd2(source, fastLength, slowLength, signalLength) {
2285
2330
  const histSeries = Series.fromArray(bars2, histVals);
2286
2331
  return [macdSeries, signalSeries, histSeries];
2287
2332
  }
2288
- function bb2(source, length, mult) {
2333
+ function bb2(source, length2, mult) {
2289
2334
  const bars2 = source.bars;
2290
2335
  const sourceValues = source.toArray();
2291
- const [upperVals, basisVals, lowerVals] = bb(sourceValues, length, mult);
2336
+ const [upperVals, basisVals, lowerVals] = bb(sourceValues, length2, mult);
2292
2337
  const upperSeries = Series.fromArray(bars2, upperVals);
2293
2338
  const basisSeries = Series.fromArray(bars2, basisVals);
2294
2339
  const lowerSeries = Series.fromArray(bars2, lowerVals);
2295
2340
  return [upperSeries, basisSeries, lowerSeries];
2296
2341
  }
2297
- function stdev2(source, length) {
2342
+ function stdev2(source, length2, biased = true) {
2298
2343
  const bars2 = source.bars;
2299
- const sourceValues = source.toArray();
2300
- const result = stdev(sourceValues, length);
2301
- return Series.fromArray(bars2, result);
2344
+ return Series.fromArray(bars2, stdev(source.toArray(), length2, biased));
2302
2345
  }
2303
- function atr2(bars2, length) {
2346
+ function atr2(bars2, length2) {
2304
2347
  const high2 = bars2.map((b2) => b2.high);
2305
2348
  const low2 = bars2.map((b2) => b2.low);
2306
2349
  const close2 = bars2.map((b2) => b2.close);
2307
- const result = atr(length, high2, low2, close2);
2350
+ const result = atr(length2, high2, low2, close2);
2308
2351
  return Series.fromArray(bars2, result);
2309
2352
  }
2310
2353
  function tr2(bars2, handle_na = false) {
@@ -2314,12 +2357,46 @@ function tr2(bars2, handle_na = false) {
2314
2357
  const result = tr(handle_na, high2, low2, close2);
2315
2358
  return Series.fromArray(bars2, result);
2316
2359
  }
2317
- function stoch2(source, high2, low2, length) {
2360
+ var col = (bars2, f) => bars2.map((b2) => b2[f] ?? NaN);
2361
+ function obv2(bars2) {
2362
+ return Series.fromArray(bars2, obv(col(bars2, "close"), col(bars2, "volume")));
2363
+ }
2364
+ function pvt2(bars2) {
2365
+ return Series.fromArray(bars2, pvt(col(bars2, "close"), col(bars2, "volume")));
2366
+ }
2367
+ function accdist2(bars2) {
2368
+ return Series.fromArray(
2369
+ bars2,
2370
+ accdist(col(bars2, "high"), col(bars2, "low"), col(bars2, "close"), col(bars2, "volume"))
2371
+ );
2372
+ }
2373
+ function nvi2(bars2) {
2374
+ return Series.fromArray(bars2, nvi(col(bars2, "close"), col(bars2, "volume")));
2375
+ }
2376
+ function pvi2(bars2) {
2377
+ return Series.fromArray(bars2, pvi(col(bars2, "close"), col(bars2, "volume")));
2378
+ }
2379
+ function iii2(bars2) {
2380
+ return Series.fromArray(
2381
+ bars2,
2382
+ iii(col(bars2, "high"), col(bars2, "low"), col(bars2, "close"), col(bars2, "volume"))
2383
+ );
2384
+ }
2385
+ function wad2(bars2) {
2386
+ return Series.fromArray(bars2, wad(col(bars2, "high"), col(bars2, "low"), col(bars2, "close")));
2387
+ }
2388
+ function wvad2(bars2) {
2389
+ return Series.fromArray(
2390
+ bars2,
2391
+ wvad(col(bars2, "open"), col(bars2, "high"), col(bars2, "low"), col(bars2, "close"), col(bars2, "volume"))
2392
+ );
2393
+ }
2394
+ function stoch2(source, high2, low2, length2) {
2318
2395
  const bars2 = source.bars;
2319
2396
  const sourceValues = source.toArray();
2320
2397
  const highValues = high2.toArray();
2321
2398
  const lowValues = low2.toArray();
2322
- const result = stoch(sourceValues, highValues, lowValues, length);
2399
+ const result = stoch(sourceValues, highValues, lowValues, length2);
2323
2400
  return Series.fromArray(bars2, result);
2324
2401
  }
2325
2402
  function crossover2(source1, source2) {
@@ -2346,47 +2423,47 @@ function cross2(source1, source2) {
2346
2423
  const numResult = result.map((b2) => b2 ? 1 : 0);
2347
2424
  return Series.fromArray(bars2, numResult);
2348
2425
  }
2349
- function change2(source, length = 1) {
2426
+ function change2(source, length2 = 1) {
2350
2427
  const bars2 = source.bars;
2351
2428
  const sourceValues = source.toArray();
2352
- const result = change(sourceValues, length);
2429
+ const result = change(sourceValues, length2);
2353
2430
  return Series.fromArray(bars2, result);
2354
2431
  }
2355
- function mom2(source, length) {
2432
+ function mom2(source, length2) {
2356
2433
  const bars2 = source.bars;
2357
2434
  const sourceValues = source.toArray();
2358
- const result = mom(sourceValues, length);
2435
+ const result = mom(sourceValues, length2);
2359
2436
  return Series.fromArray(bars2, result);
2360
2437
  }
2361
- function roc2(source, length) {
2438
+ function roc2(source, length2) {
2362
2439
  const bars2 = source.bars;
2363
2440
  const sourceValues = source.toArray();
2364
- const result = roc(sourceValues, length);
2441
+ const result = roc(sourceValues, length2);
2365
2442
  return Series.fromArray(bars2, result);
2366
2443
  }
2367
- function highest2(source, length) {
2444
+ function highest2(source, length2) {
2368
2445
  const bars2 = source.bars;
2369
2446
  const sourceValues = source.toArray();
2370
- const result = highest(sourceValues, length);
2447
+ const result = highest(sourceValues, length2);
2371
2448
  return Series.fromArray(bars2, result);
2372
2449
  }
2373
- function lowest2(source, length) {
2450
+ function lowest2(source, length2) {
2374
2451
  const bars2 = source.bars;
2375
2452
  const sourceValues = source.toArray();
2376
- const result = lowest(sourceValues, length);
2453
+ const result = lowest(sourceValues, length2);
2377
2454
  return Series.fromArray(bars2, result);
2378
2455
  }
2379
- function rising2(source, length) {
2456
+ function rising2(source, length2) {
2380
2457
  const bars2 = source.bars;
2381
2458
  const sourceValues = source.toArray();
2382
- const result = rising(sourceValues, length);
2459
+ const result = rising(sourceValues, length2);
2383
2460
  const numResult = result.map((b2) => b2 ? 1 : 0);
2384
2461
  return Series.fromArray(bars2, numResult);
2385
2462
  }
2386
- function falling2(source, length) {
2463
+ function falling2(source, length2) {
2387
2464
  const bars2 = source.bars;
2388
2465
  const sourceValues = source.toArray();
2389
- const result = falling(sourceValues, length);
2466
+ const result = falling(sourceValues, length2);
2390
2467
  const numResult = result.map((b2) => b2 ? 1 : 0);
2391
2468
  return Series.fromArray(bars2, numResult);
2392
2469
  }
@@ -2405,12 +2482,14 @@ function supertrend2(bars2, factor, atrLength) {
2405
2482
  const dirSeries = Series.fromArray(bars2, dirVals);
2406
2483
  return [trendSeries, dirSeries];
2407
2484
  }
2408
- function vwap2(source, volume2) {
2485
+ function vwap2(source, volume2, anchor) {
2409
2486
  const bars2 = source.bars;
2410
- const sourceValues = source.toArray();
2411
- const volumeValues = volume2.toArray();
2412
- const result = vwap(sourceValues, volumeValues);
2413
- return Series.fromArray(bars2, result);
2487
+ return Series.fromArray(bars2, vwap(source.toArray(), volume2.toArray(), anchor?.toArray()));
2488
+ }
2489
+ function vwapBands(source, volume2, anchor, stdev_mult) {
2490
+ const bars2 = source.bars;
2491
+ const [m, u, l] = vwap(source.toArray(), volume2.toArray(), anchor?.toArray(), stdev_mult);
2492
+ return [Series.fromArray(bars2, m), Series.fromArray(bars2, u), Series.fromArray(bars2, l)];
2414
2493
  }
2415
2494
  function ichimoku2(bars2, conversionPeriods, basePeriods, laggingSpan2Periods, displacement) {
2416
2495
  const high2 = bars2.map((b2) => b2.high);
@@ -2433,23 +2512,23 @@ function ichimoku2(bars2, conversionPeriods, basePeriods, laggingSpan2Periods, d
2433
2512
  Series.fromArray(bars2, chikou)
2434
2513
  ];
2435
2514
  }
2436
- function vwma2(source, length, volume2) {
2515
+ function vwma2(source, length2, volume2) {
2437
2516
  const bars2 = source.bars;
2438
2517
  const sourceValues = source.toArray();
2439
2518
  const volumeValues = volume2.toArray();
2440
- const result = vwma(sourceValues, length, volumeValues);
2519
+ const result = vwma(sourceValues, length2, volumeValues);
2441
2520
  return Series.fromArray(bars2, result);
2442
2521
  }
2443
- function linreg2(source, length, offset = 0) {
2522
+ function linreg2(source, length2, offset = 0) {
2444
2523
  const bars2 = source.bars;
2445
2524
  const sourceValues = source.toArray();
2446
- const result = linreg(sourceValues, length, offset);
2525
+ const result = linreg(sourceValues, length2, offset);
2447
2526
  return Series.fromArray(bars2, result);
2448
2527
  }
2449
- function alma2(source, length = 9, offset = 0.85, sigma = 6, floor2 = false) {
2528
+ function alma2(source, length2 = 9, offset = 0.85, sigma = 6, floor2 = false) {
2450
2529
  const bars2 = source.bars;
2451
2530
  const sourceValues = source.toArray();
2452
- const result = alma(sourceValues, length, offset, sigma, floor2);
2531
+ const result = alma(sourceValues, length2, offset, sigma, floor2);
2453
2532
  return Series.fromArray(bars2, result);
2454
2533
  }
2455
2534
  function zigzag2(bars2, deviation = 5, depth = 10, backstep = 3) {
@@ -2469,10 +2548,10 @@ function zigzag2(bars2, deviation = 5, depth = 10, backstep = 3) {
2469
2548
  Series.fromArray(bars2, pivotVals.map((b2) => b2 ? 1 : 0))
2470
2549
  ];
2471
2550
  }
2472
- function cci2(source, length) {
2551
+ function cci2(source, length2) {
2473
2552
  const bars2 = source.bars;
2474
2553
  const sourceValues = source.toArray();
2475
- const result = cci(sourceValues, length);
2554
+ const result = cci(sourceValues, length2);
2476
2555
  return Series.fromArray(bars2, result);
2477
2556
  }
2478
2557
  function sar2(bars2, start = 0.02, inc = 0.02, max4 = 0.2) {
@@ -2482,19 +2561,19 @@ function sar2(bars2, start = 0.02, inc = 0.02, max4 = 0.2) {
2482
2561
  const result = sar(start, inc, max4, high2, low2, close2);
2483
2562
  return Series.fromArray(bars2, result);
2484
2563
  }
2485
- function dev2(source, length) {
2564
+ function dev2(source, length2) {
2486
2565
  const bars2 = source.bars;
2487
- const result = dev(source.toArray(), length);
2566
+ const result = dev(source.toArray(), length2);
2488
2567
  return Series.fromArray(bars2, result);
2489
2568
  }
2490
- function variance2(source, length, biased = true) {
2569
+ function variance2(source, length2, biased = true) {
2491
2570
  const bars2 = source.bars;
2492
- const result = variance(source.toArray(), length, biased);
2571
+ const result = variance(source.toArray(), length2, biased);
2493
2572
  return Series.fromArray(bars2, result);
2494
2573
  }
2495
- function median2(source, length) {
2574
+ function median2(source, length2) {
2496
2575
  const bars2 = source.bars;
2497
- const result = median(source.toArray(), length);
2576
+ const result = median(source.toArray(), length2);
2498
2577
  return Series.fromArray(bars2, result);
2499
2578
  }
2500
2579
  function swma2(source) {
@@ -2502,24 +2581,24 @@ function swma2(source) {
2502
2581
  const result = swma(source.toArray());
2503
2582
  return Series.fromArray(bars2, result);
2504
2583
  }
2505
- function correlation2(source1, source2, length) {
2584
+ function correlation2(source1, source2, length2) {
2506
2585
  const bars2 = source1.bars;
2507
- const result = correlation(source1.toArray(), source2.toArray(), length);
2586
+ const result = correlation(source1.toArray(), source2.toArray(), length2);
2508
2587
  return Series.fromArray(bars2, result);
2509
2588
  }
2510
- function percentrank2(source, length) {
2589
+ function percentrank2(source, length2) {
2511
2590
  const bars2 = source.bars;
2512
- const result = percentrank(source.toArray(), length);
2591
+ const result = percentrank(source.toArray(), length2);
2513
2592
  return Series.fromArray(bars2, result);
2514
2593
  }
2515
- function mfi2(source, length, volume2) {
2594
+ function mfi2(source, length2, volume2) {
2516
2595
  const bars2 = source.bars;
2517
- const result = mfi(source.toArray(), length, volume2.toArray());
2596
+ const result = mfi(source.toArray(), length2, volume2.toArray());
2518
2597
  return Series.fromArray(bars2, result);
2519
2598
  }
2520
- function hma2(source, length) {
2599
+ function hma2(source, length2) {
2521
2600
  const bars2 = source.bars;
2522
- const result = hma(source.toArray(), length);
2601
+ const result = hma(source.toArray(), length2);
2523
2602
  return Series.fromArray(bars2, result);
2524
2603
  }
2525
2604
  function pivothigh2(source, leftbars, rightbars) {
@@ -2560,89 +2639,86 @@ function tsi2(source, shortLength, longLength) {
2560
2639
  const result = tsi(source.toArray(), shortLength, longLength);
2561
2640
  return Series.fromArray(bars2, result);
2562
2641
  }
2563
- function cmo2(source, length) {
2642
+ function cmo2(source, length2) {
2564
2643
  const bars2 = source.bars;
2565
- const result = cmo(source.toArray(), length);
2644
+ const result = cmo(source.toArray(), length2);
2566
2645
  return Series.fromArray(bars2, result);
2567
2646
  }
2568
- function kc2(bars2, source, length, mult, useTrueRange = true) {
2647
+ function kc2(bars2, source, length2, mult, useTrueRange = true) {
2569
2648
  const high2 = bars2.map((b2) => b2.high);
2570
2649
  const low2 = bars2.map((b2) => b2.low);
2571
2650
  const close2 = bars2.map((b2) => b2.close);
2572
- const [middle, upper, lower] = kc(source.toArray(), length, mult, useTrueRange, high2, low2, close2);
2651
+ const [middle, upper2, lower2] = kc(source.toArray(), length2, mult, useTrueRange, high2, low2, close2);
2573
2652
  return [
2574
2653
  Series.fromArray(bars2, middle),
2575
- Series.fromArray(bars2, upper),
2576
- Series.fromArray(bars2, lower)
2654
+ Series.fromArray(bars2, upper2),
2655
+ Series.fromArray(bars2, lower2)
2577
2656
  ];
2578
2657
  }
2579
- function bbw2(source, length, mult) {
2658
+ function bbw2(source, length2, mult) {
2580
2659
  const bars2 = source.bars;
2581
- const result = bbw(source.toArray(), length, mult);
2660
+ const result = bbw(source.toArray(), length2, mult);
2582
2661
  return Series.fromArray(bars2, result);
2583
2662
  }
2584
- function wpr2(bars2, length = 14) {
2663
+ function wpr2(bars2, length2 = 14) {
2585
2664
  const high2 = bars2.map((b2) => b2.high);
2586
2665
  const low2 = bars2.map((b2) => b2.low);
2587
2666
  const close2 = bars2.map((b2) => b2.close);
2588
- const result = wpr(high2, low2, close2, length);
2667
+ const result = wpr(high2, low2, close2, length2);
2589
2668
  return Series.fromArray(bars2, result);
2590
2669
  }
2591
- function kcw2(bars2, source, length = 20, mult = 2, useTrueRange = true) {
2670
+ function kcw2(bars2, source, length2 = 20, mult = 2, useTrueRange = true) {
2592
2671
  const high2 = bars2.map((b2) => b2.high);
2593
2672
  const low2 = bars2.map((b2) => b2.low);
2594
2673
  const close2 = bars2.map((b2) => b2.close);
2595
- const result = kcw(source.toArray(), length, mult, useTrueRange, high2, low2, close2);
2674
+ const result = kcw(source.toArray(), length2, mult, useTrueRange, high2, low2, close2);
2596
2675
  return Series.fromArray(bars2, result);
2597
2676
  }
2598
- function range2(high2, low2) {
2599
- const bars2 = high2.bars;
2600
- const result = range(high2.toArray(), low2.toArray());
2601
- return Series.fromArray(bars2, result);
2677
+ function range2(source, length2) {
2678
+ const bars2 = source.bars;
2679
+ return Series.fromArray(bars2, range(source.toArray(), length2));
2602
2680
  }
2603
- function highestbars2(source, length) {
2681
+ function highestbars2(source, length2) {
2604
2682
  const bars2 = source.bars;
2605
- const result = highestbars(source.toArray(), length);
2683
+ const result = highestbars(source.toArray(), length2);
2606
2684
  return Series.fromArray(bars2, result);
2607
2685
  }
2608
- function lowestbars2(source, length) {
2686
+ function lowestbars2(source, length2) {
2609
2687
  const bars2 = source.bars;
2610
- const result = lowestbars(source.toArray(), length);
2688
+ const result = lowestbars(source.toArray(), length2);
2611
2689
  return Series.fromArray(bars2, result);
2612
2690
  }
2613
- function max2(source1, source2) {
2614
- const bars2 = source1.bars;
2615
- const result = max(source1.toArray(), source2.toArray());
2616
- return Series.fromArray(bars2, result);
2691
+ function max2(source) {
2692
+ const bars2 = source.bars;
2693
+ return Series.fromArray(bars2, max(source.toArray()));
2617
2694
  }
2618
- function min2(source1, source2) {
2619
- const bars2 = source1.bars;
2620
- const result = min(source1.toArray(), source2.toArray());
2621
- return Series.fromArray(bars2, result);
2695
+ function min2(source) {
2696
+ const bars2 = source.bars;
2697
+ return Series.fromArray(bars2, min(source.toArray()));
2622
2698
  }
2623
- function cog2(source, length = 10) {
2699
+ function cog2(source, length2 = 10) {
2624
2700
  const bars2 = source.bars;
2625
- const result = cog(source.toArray(), length);
2701
+ const result = cog(source.toArray(), length2);
2626
2702
  return Series.fromArray(bars2, result);
2627
2703
  }
2628
- function mode2(source, length) {
2704
+ function mode2(source, length2) {
2629
2705
  const bars2 = source.bars;
2630
- const result = mode(source.toArray(), length);
2706
+ const result = mode(source.toArray(), length2);
2631
2707
  return Series.fromArray(bars2, result);
2632
2708
  }
2633
- function percentile_linear_interpolation2(source, length, percentage) {
2709
+ function percentile_linear_interpolation2(source, length2, percentage) {
2634
2710
  const bars2 = source.bars;
2635
- const result = percentile_linear_interpolation(source.toArray(), length, percentage);
2711
+ const result = percentile_linear_interpolation(source.toArray(), length2, percentage);
2636
2712
  return Series.fromArray(bars2, result);
2637
2713
  }
2638
- function percentile_nearest_rank2(source, length, percentage) {
2714
+ function percentile_nearest_rank2(source, length2, percentage) {
2639
2715
  const bars2 = source.bars;
2640
- const result = percentile_nearest_rank(source.toArray(), length, percentage);
2716
+ const result = percentile_nearest_rank(source.toArray(), length2, percentage);
2641
2717
  return Series.fromArray(bars2, result);
2642
2718
  }
2643
- function rci2(source, length) {
2719
+ function rci2(source, length2) {
2644
2720
  const bars2 = source.bars;
2645
- const result = rci(source.toArray(), length);
2721
+ const result = rci(source.toArray(), length2);
2646
2722
  return Series.fromArray(bars2, result);
2647
2723
  }
2648
2724
  var ta = {
@@ -2701,6 +2777,15 @@ var ta = {
2701
2777
  lowestbars: lowestbars2,
2702
2778
  max: max2,
2703
2779
  min: min2,
2780
+ vwapBands,
2781
+ obv: obv2,
2782
+ pvt: pvt2,
2783
+ accdist: accdist2,
2784
+ nvi: nvi2,
2785
+ pvi: pvi2,
2786
+ iii: iii2,
2787
+ wad: wad2,
2788
+ wvad: wvad2,
2704
2789
  cog: cog2,
2705
2790
  mode: mode2,
2706
2791
  percentile_linear_interpolation: percentile_linear_interpolation2,
@@ -2773,52 +2858,59 @@ function t(clr) {
2773
2858
  }
2774
2859
  function parseColor(clr) {
2775
2860
  if (typeof clr === "string") {
2776
- const match = clr.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
2777
- if (match) {
2861
+ const hex = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(clr.trim());
2862
+ if (hex) {
2863
+ let digits = hex[1];
2864
+ if (digits.length <= 4) digits = [...digits].map((c) => c + c).join("");
2865
+ const byte = (k) => parseInt(digits.slice(k, k + 2), 16);
2866
+ return { r: byte(0), g: byte(2), b: byte(4), t: digits.length === 8 ? (1 - byte(6) / 255) * 100 : 0 };
2867
+ }
2868
+ const match2 = clr.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
2869
+ if (match2) {
2778
2870
  return {
2779
- r: parseInt(match[1]),
2780
- g: parseInt(match[2]),
2781
- b: parseInt(match[3]),
2782
- t: match[4] ? (1 - parseFloat(match[4])) * 100 : 0
2871
+ r: parseInt(match2[1]),
2872
+ g: parseInt(match2[2]),
2873
+ b: parseInt(match2[3]),
2874
+ t: match2[4] ? (1 - parseFloat(match2[4])) * 100 : 0
2783
2875
  };
2784
2876
  }
2785
2877
  }
2786
2878
  return { r: 0, g: 0, b: 0, t: 0 };
2787
2879
  }
2788
- var aqua = "#00FFFF";
2789
- var black = "#000000";
2790
- var blue = "#0000FF";
2791
- var fuchsia = "#FF00FF";
2792
- var gray = "#808080";
2793
- var green = "#00FF00";
2794
- var lime = "#00FF00";
2795
- var maroon = "#800000";
2796
- var navy = "#000080";
2880
+ var aqua = "#00BCD4";
2881
+ var black = "#363A45";
2882
+ var blue = "#2962FF";
2883
+ var fuchsia = "#E040FB";
2884
+ var gray = "#787B86";
2885
+ var green = "#4CAF50";
2886
+ var lime = "#00E676";
2887
+ var maroon = "#880E4F";
2888
+ var navy = "#311B92";
2797
2889
  var olive = "#808000";
2798
- var orange = "#FFA500";
2799
- var purple = "#800080";
2800
- var red = "#FF0000";
2801
- var silver = "#C0C0C0";
2802
- var teal = "#008080";
2890
+ var orange = "#FF9800";
2891
+ var purple = "#9C27B0";
2892
+ var red = "#F23645";
2893
+ var silver = "#B2B5BE";
2894
+ var teal = "#089981";
2803
2895
  var white = "#FFFFFF";
2804
- var yellow = "#FFFF00";
2896
+ var yellow = "#FDD835";
2805
2897
  function from_gradient(value, bottom_value, top_value, bottom_color, top_color) {
2806
- const parseColor2 = (col) => {
2807
- if (typeof col === "string") {
2808
- if (col.startsWith("#")) {
2809
- const hex = col.slice(1);
2898
+ const parseColor2 = (col2) => {
2899
+ if (typeof col2 === "string") {
2900
+ if (col2.startsWith("#")) {
2901
+ const hex = col2.slice(1);
2810
2902
  const r4 = parseInt(hex.slice(0, 2), 16);
2811
2903
  const g4 = parseInt(hex.slice(2, 4), 16);
2812
2904
  const b4 = parseInt(hex.slice(4, 6), 16);
2813
2905
  return [r4, g4, b4, 1];
2814
2906
  }
2815
- const match = col.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
2816
- if (match) {
2907
+ const match2 = col2.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
2908
+ if (match2) {
2817
2909
  return [
2818
- parseInt(match[1]),
2819
- parseInt(match[2]),
2820
- parseInt(match[3]),
2821
- match[4] ? parseFloat(match[4]) : 1
2910
+ parseInt(match2[1]),
2911
+ parseInt(match2[2]),
2912
+ parseInt(match2[3]),
2913
+ match2[4] ? parseFloat(match2[4]) : 1
2822
2914
  ];
2823
2915
  }
2824
2916
  }
@@ -2844,81 +2936,2065 @@ function from_gradient(value, bottom_value, top_value, bottom_color, top_color)
2844
2936
  return `rgba(${r3}, ${g3}, ${b3}, ${a})`;
2845
2937
  }
2846
2938
 
2939
+ // src/drawing/registry.ts
2940
+ var DEFAULT_MAX_COUNT = 50;
2941
+ var SLACK = 5;
2942
+ var live = { line: [], label: [], box: [], polyline: [], linefill: [] };
2943
+ var limits = {
2944
+ line: DEFAULT_MAX_COUNT,
2945
+ label: DEFAULT_MAX_COUNT,
2946
+ box: DEFAULT_MAX_COUNT,
2947
+ polyline: DEFAULT_MAX_COUNT
2948
+ };
2949
+ var deleted = /* @__PURE__ */ new WeakSet();
2950
+ var COORDINATES = {
2951
+ line: ["x1", "y1", "x2", "y2"],
2952
+ label: ["x", "y"],
2953
+ box: ["left", "top", "right", "bottom"],
2954
+ polyline: [],
2955
+ linefill: []
2956
+ };
2957
+ function markDeleted(kind, obj, explicit) {
2958
+ deleted.add(obj);
2959
+ for (const field2 of COORDINATES[kind]) obj[field2] = NaN;
2960
+ if (kind === "line" && explicit) {
2961
+ for (const fill2 of live.linefill.filter((f) => f.line1 === obj || f.line2 === obj)) remove("linefill", fill2);
2962
+ }
2963
+ }
2964
+ function register(kind, obj) {
2965
+ const list = live[kind];
2966
+ list.push(obj);
2967
+ const max4 = limits[kind === "linefill" ? "line" : kind];
2968
+ if (list.length > max4 + SLACK) {
2969
+ for (const old of list.splice(0, list.length - max4)) markDeleted(kind, old, false);
2970
+ }
2971
+ return obj;
2972
+ }
2973
+ function remove(kind, obj) {
2974
+ const list = live[kind];
2975
+ const index = list.indexOf(obj);
2976
+ if (index !== -1) list.splice(index, 1);
2977
+ if (!deleted.has(obj)) markDeleted(kind, obj, true);
2978
+ }
2979
+ function isDeleted(obj) {
2980
+ return typeof obj === "object" && obj !== null && deleted.has(obj);
2981
+ }
2982
+ function all(kind) {
2983
+ return [...live[kind]];
2984
+ }
2985
+ function resetDrawings(newLimits = {}) {
2986
+ for (const kind of Object.keys(live)) live[kind].length = 0;
2987
+ limits = {
2988
+ line: newLimits.line ?? DEFAULT_MAX_COUNT,
2989
+ label: newLimits.label ?? DEFAULT_MAX_COUNT,
2990
+ box: newLimits.box ?? DEFAULT_MAX_COUNT,
2991
+ polyline: newLimits.polyline ?? DEFAULT_MAX_COUNT
2992
+ };
2993
+ }
2994
+ function setDrawingLimits(newLimits) {
2995
+ limits = { ...limits, ...Object.fromEntries(Object.entries(newLimits).filter(([, v]) => v !== void 0)) };
2996
+ }
2997
+
2847
2998
  // src/utils/index.ts
2848
2999
  function isNA(value) {
2849
- return value === null || value === void 0 || Number.isNaN(value);
3000
+ return value === null || value === void 0 || Number.isNaN(value) || isDeleted(value);
2850
3001
  }
2851
3002
  function nz(value, defaultValue = 0) {
2852
3003
  return isNA(value) ? defaultValue : value;
2853
3004
  }
3005
+ function fixnan(source) {
3006
+ let last;
3007
+ let seen = false;
3008
+ return source.map((v) => {
3009
+ if (!isNA(v)) {
3010
+ last = v;
3011
+ seen = true;
3012
+ return v;
3013
+ }
3014
+ return seen ? last : v;
3015
+ });
3016
+ }
2854
3017
 
2855
- // src/math/index.ts
2856
- var math_exports = {};
2857
- __export(math_exports, {
2858
- abs: () => abs,
2859
- acos: () => acos,
2860
- asin: () => asin,
2861
- atan: () => atan,
2862
- avg: () => avg,
2863
- ceil: () => ceil,
2864
- cos: () => cos,
2865
- e: () => e,
2866
- exp: () => exp,
2867
- floor: () => floor,
2868
- log: () => log,
2869
- log10: () => log10,
2870
- max: () => max3,
2871
- min: () => min3,
2872
- phi: () => phi,
2873
- pi: () => pi,
2874
- pow: () => pow,
2875
- random: () => random,
2876
- round: () => round,
2877
- round_to_mintick: () => round_to_mintick,
2878
- rphi: () => rphi,
2879
- sign: () => sign,
2880
- sin: () => sin,
2881
- sqrt: () => sqrt,
2882
- sum: () => sum,
2883
- tan: () => tan,
2884
- todegrees: () => todegrees,
2885
- toradians: () => toradians
3018
+ // src/line/index.ts
3019
+ var line_exports = {};
3020
+ __export(line_exports, {
3021
+ all: () => all2,
3022
+ copy: () => copy,
3023
+ delete: () => delete_line,
3024
+ delete_line: () => delete_line,
3025
+ get_price: () => get_price,
3026
+ get_x1: () => get_x1,
3027
+ get_x2: () => get_x2,
3028
+ get_y1: () => get_y1,
3029
+ get_y2: () => get_y2,
3030
+ new: () => new_line,
3031
+ new_line: () => new_line,
3032
+ set_color: () => set_color,
3033
+ set_extend: () => set_extend,
3034
+ set_first_point: () => set_first_point,
3035
+ set_second_point: () => set_second_point,
3036
+ set_style: () => set_style,
3037
+ set_width: () => set_width,
3038
+ set_x1: () => set_x1,
3039
+ set_x2: () => set_x2,
3040
+ set_xloc: () => set_xloc,
3041
+ set_xy1: () => set_xy1,
3042
+ set_xy2: () => set_xy2,
3043
+ set_y1: () => set_y1,
3044
+ set_y2: () => set_y2
2886
3045
  });
2887
- function abs(value) {
2888
- if (value instanceof Series) {
2889
- const bars2 = value.bars;
2890
- const valueArray = value.toArray();
2891
- const length = bars2.length;
2892
- const result = [];
2893
- for (let i = 0; i < length; i++) {
2894
- const v = valueArray[i] ?? NaN;
2895
- result.push(Math.abs(v));
2896
- }
2897
- return Series.fromArray(bars2, result);
2898
- }
2899
- return Math.abs(value);
3046
+ function new_line(...args) {
3047
+ let x1, y1, x2, y2, rest;
3048
+ if (typeof args[0] === "object" && args[0] !== null) {
3049
+ const [p1, p2, ...others] = args;
3050
+ const xloc2 = others[0] ?? "bar_index";
3051
+ [x1, y1, x2, y2, rest] = [pointX(p1, xloc2), p1.price, pointX(p2, xloc2), p2.price, others];
3052
+ } else {
3053
+ [x1, y1, x2, y2] = args;
3054
+ rest = args.slice(4);
3055
+ }
3056
+ const [xloc, extend, lineColor, style, width, force_overlay] = rest;
3057
+ return register("line", {
3058
+ x1,
3059
+ y1,
3060
+ x2,
3061
+ y2,
3062
+ xloc: xloc ?? "bar_index",
3063
+ extend: extend ?? "none",
3064
+ color: lineColor,
3065
+ style: style || "solid",
3066
+ width: width || 1,
3067
+ force_overlay: force_overlay ?? false
3068
+ });
2900
3069
  }
2901
- function ceil(value) {
2902
- if (value instanceof Series) {
2903
- const bars2 = value.bars;
2904
- const valueArray = value.toArray();
2905
- const length = bars2.length;
2906
- const result = [];
2907
- for (let i = 0; i < length; i++) {
2908
- const v = valueArray[i] ?? NaN;
2909
- result.push(Math.ceil(v));
3070
+ function get_price(id, x) {
3071
+ const { x1, y1, x2, y2, extend, xloc } = id;
3072
+ if (xloc === "bar_time") {
3073
+ throw new Error("line.get_price() only works with xloc.bar_index lines, not xloc.bar_time");
3074
+ }
3075
+ if (x2 === x1) {
3076
+ return NaN;
3077
+ }
3078
+ const slope = (y2 - y1) / (x2 - x1);
3079
+ const price = y1 + slope * (x - x1);
3080
+ if (extend === "none") {
3081
+ if (x < Math.min(x1, x2) || x > Math.max(x1, x2)) {
3082
+ return NaN;
3083
+ }
3084
+ } else if (extend === "left") {
3085
+ if (x > Math.max(x1, x2)) {
3086
+ return NaN;
3087
+ }
3088
+ } else if (extend === "right") {
3089
+ if (x < Math.min(x1, x2)) {
3090
+ return NaN;
2910
3091
  }
2911
- return Series.fromArray(bars2, result);
2912
3092
  }
2913
- return Math.ceil(value);
3093
+ return price;
2914
3094
  }
2915
- function floor(value) {
2916
- if (value instanceof Series) {
3095
+ function get_x1(id) {
3096
+ return id.x1;
3097
+ }
3098
+ function get_x2(id) {
3099
+ return id.x2;
3100
+ }
3101
+ function get_y1(id) {
3102
+ return id.y1;
3103
+ }
3104
+ function get_y2(id) {
3105
+ return id.y2;
3106
+ }
3107
+ function copy(id) {
3108
+ return register("line", { ...id });
3109
+ }
3110
+ function set_x1(id, x) {
3111
+ if (isDeleted(id)) return id;
3112
+ id.x1 = x;
3113
+ return id;
3114
+ }
3115
+ function set_x2(id, x) {
3116
+ if (isDeleted(id)) return id;
3117
+ id.x2 = x;
3118
+ return id;
3119
+ }
3120
+ function set_y1(id, y) {
3121
+ if (isDeleted(id)) return id;
3122
+ id.y1 = y;
3123
+ return id;
3124
+ }
3125
+ function set_y2(id, y) {
3126
+ if (isDeleted(id)) return id;
3127
+ id.y2 = y;
3128
+ return id;
3129
+ }
3130
+ function set_xy1(id, x, y) {
3131
+ if (isDeleted(id)) return id;
3132
+ id.x1 = x;
3133
+ id.y1 = y;
3134
+ return id;
3135
+ }
3136
+ function set_xy2(id, x, y) {
3137
+ if (isDeleted(id)) return id;
3138
+ id.x2 = x;
3139
+ id.y2 = y;
3140
+ return id;
3141
+ }
3142
+ function set_xloc(id, x1, x2, xloc) {
3143
+ if (isDeleted(id)) return id;
3144
+ id.x1 = x1;
3145
+ id.x2 = x2;
3146
+ id.xloc = xloc;
3147
+ return id;
3148
+ }
3149
+ function set_extend(id, extend) {
3150
+ if (isDeleted(id)) return id;
3151
+ id.extend = extend;
3152
+ return id;
3153
+ }
3154
+ function set_color(id, lineColor) {
3155
+ if (isDeleted(id)) return id;
3156
+ id.color = lineColor;
3157
+ return id;
3158
+ }
3159
+ function set_style(id, style) {
3160
+ if (isDeleted(id)) return id;
3161
+ id.style = style;
3162
+ return id;
3163
+ }
3164
+ function set_width(id, width) {
3165
+ if (isDeleted(id)) return id;
3166
+ id.width = width;
3167
+ return id;
3168
+ }
3169
+ function delete_line(id) {
3170
+ remove("line", id);
3171
+ }
3172
+ function pointX(point, xloc) {
3173
+ const x = xloc === "bar_time" ? point.time : point.index;
3174
+ return x ?? NaN;
3175
+ }
3176
+ function all2() {
3177
+ return all("line");
3178
+ }
3179
+ function set_first_point(id, point) {
3180
+ if (isDeleted(id)) return id;
3181
+ id.x1 = pointX(point, id.xloc);
3182
+ id.y1 = point.price;
3183
+ return id;
3184
+ }
3185
+ function set_second_point(id, point) {
3186
+ if (isDeleted(id)) return id;
3187
+ id.x2 = pointX(point, id.xloc);
3188
+ id.y2 = point.price;
3189
+ return id;
3190
+ }
3191
+
3192
+ // src/label/index.ts
3193
+ var label_exports = {};
3194
+ __export(label_exports, {
3195
+ all: () => all3,
3196
+ copy: () => copy2,
3197
+ delete: () => delete_label,
3198
+ delete_label: () => delete_label,
3199
+ get_text: () => get_text,
3200
+ get_x: () => get_x,
3201
+ get_y: () => get_y,
3202
+ new: () => new_label,
3203
+ new_label: () => new_label,
3204
+ set_color: () => set_color2,
3205
+ set_point: () => set_point,
3206
+ set_size: () => set_size,
3207
+ set_style: () => set_style2,
3208
+ set_text: () => set_text,
3209
+ set_text_font_family: () => set_text_font_family,
3210
+ set_text_formatting: () => set_text_formatting,
3211
+ set_textalign: () => set_textalign,
3212
+ set_textcolor: () => set_textcolor,
3213
+ set_tooltip: () => set_tooltip,
3214
+ set_x: () => set_x,
3215
+ set_xloc: () => set_xloc2,
3216
+ set_xy: () => set_xy,
3217
+ set_y: () => set_y,
3218
+ set_yloc: () => set_yloc
3219
+ });
3220
+ function new_label(...args) {
3221
+ let x, y, rest;
3222
+ if (typeof args[0] === "object" && args[0] !== null) {
3223
+ const point = args[0];
3224
+ rest = args.slice(1);
3225
+ x = pointX2(point, rest[1] ?? "bar_index");
3226
+ y = point.price;
3227
+ } else {
3228
+ [x, y] = args;
3229
+ rest = args.slice(2);
3230
+ }
3231
+ const [
3232
+ text2,
3233
+ xloc,
3234
+ yloc,
3235
+ labelColor,
3236
+ style,
3237
+ textcolor,
3238
+ size,
3239
+ textalign,
3240
+ tooltip,
3241
+ text_font_family,
3242
+ force_overlay,
3243
+ text_formatting
3244
+ ] = rest;
3245
+ return register("label", {
3246
+ x,
3247
+ y,
3248
+ xloc: xloc ?? "bar_index",
3249
+ yloc: yloc ?? "price",
3250
+ text: text2,
3251
+ tooltip,
3252
+ color: labelColor,
3253
+ style,
3254
+ textcolor,
3255
+ size,
3256
+ textalign,
3257
+ text_font_family,
3258
+ force_overlay: force_overlay ?? false,
3259
+ text_formatting
3260
+ });
3261
+ }
3262
+ function get_x(id) {
3263
+ return id.x;
3264
+ }
3265
+ function get_y(id) {
3266
+ return id.y;
3267
+ }
3268
+ function get_text(id) {
3269
+ return id.text;
3270
+ }
3271
+ function copy2(id) {
3272
+ return register("label", { ...id });
3273
+ }
3274
+ function set_x(id, x) {
3275
+ if (isDeleted(id)) return id;
3276
+ id.x = x;
3277
+ return id;
3278
+ }
3279
+ function set_y(id, y) {
3280
+ if (isDeleted(id)) return id;
3281
+ id.y = y;
3282
+ return id;
3283
+ }
3284
+ function set_xy(id, x, y) {
3285
+ if (isDeleted(id)) return id;
3286
+ id.x = x;
3287
+ id.y = y;
3288
+ return id;
3289
+ }
3290
+ function set_xloc2(id, x, xloc) {
3291
+ if (isDeleted(id)) return id;
3292
+ id.x = x;
3293
+ id.xloc = xloc;
3294
+ return id;
3295
+ }
3296
+ function set_yloc(id, yloc) {
3297
+ if (isDeleted(id)) return id;
3298
+ id.yloc = yloc;
3299
+ return id;
3300
+ }
3301
+ function set_text(id, text2) {
3302
+ if (isDeleted(id)) return id;
3303
+ id.text = text2;
3304
+ return id;
3305
+ }
3306
+ function set_tooltip(id, tooltip) {
3307
+ if (isDeleted(id)) return id;
3308
+ id.tooltip = tooltip;
3309
+ return id;
3310
+ }
3311
+ function set_color2(id, labelColor) {
3312
+ if (isDeleted(id)) return id;
3313
+ id.color = labelColor;
3314
+ return id;
3315
+ }
3316
+ function set_textcolor(id, textColor) {
3317
+ if (isDeleted(id)) return id;
3318
+ id.textcolor = textColor;
3319
+ return id;
3320
+ }
3321
+ function set_style2(id, style) {
3322
+ if (isDeleted(id)) return id;
3323
+ id.style = style;
3324
+ return id;
3325
+ }
3326
+ function set_size(id, size) {
3327
+ if (isDeleted(id)) return id;
3328
+ id.size = size;
3329
+ return id;
3330
+ }
3331
+ function set_textalign(id, align) {
3332
+ if (isDeleted(id)) return id;
3333
+ id.textalign = align;
3334
+ return id;
3335
+ }
3336
+ function set_text_font_family(id, font) {
3337
+ if (isDeleted(id)) return id;
3338
+ id.text_font_family = font;
3339
+ return id;
3340
+ }
3341
+ function delete_label(id) {
3342
+ remove("label", id);
3343
+ }
3344
+ function pointX2(point, xloc) {
3345
+ const x = xloc === "bar_time" ? point.time : point.index;
3346
+ return x ?? NaN;
3347
+ }
3348
+ function all3() {
3349
+ return all("label");
3350
+ }
3351
+ function set_point(id, point) {
3352
+ if (isDeleted(id)) return id;
3353
+ id.x = pointX2(point, id.xloc);
3354
+ id.y = point.price;
3355
+ return id;
3356
+ }
3357
+ function set_text_formatting(id, formatting) {
3358
+ if (isDeleted(id)) return id;
3359
+ id.text_formatting = formatting;
3360
+ return id;
3361
+ }
3362
+
3363
+ // src/box/index.ts
3364
+ var box_exports = {};
3365
+ __export(box_exports, {
3366
+ all: () => all4,
3367
+ copy: () => copy3,
3368
+ delete: () => delete_box,
3369
+ delete_box: () => delete_box,
3370
+ get_bottom: () => get_bottom,
3371
+ get_left: () => get_left,
3372
+ get_right: () => get_right,
3373
+ get_top: () => get_top,
3374
+ new: () => new_box,
3375
+ new_box: () => new_box,
3376
+ set_bgcolor: () => set_bgcolor,
3377
+ set_border_color: () => set_border_color,
3378
+ set_border_style: () => set_border_style,
3379
+ set_border_width: () => set_border_width,
3380
+ set_bottom: () => set_bottom,
3381
+ set_bottom_right_point: () => set_bottom_right_point,
3382
+ set_extend: () => set_extend2,
3383
+ set_left: () => set_left,
3384
+ set_lefttop: () => set_lefttop,
3385
+ set_right: () => set_right,
3386
+ set_rightbottom: () => set_rightbottom,
3387
+ set_text: () => set_text2,
3388
+ set_text_color: () => set_text_color,
3389
+ set_text_font_family: () => set_text_font_family2,
3390
+ set_text_formatting: () => set_text_formatting2,
3391
+ set_text_halign: () => set_text_halign,
3392
+ set_text_size: () => set_text_size,
3393
+ set_text_valign: () => set_text_valign,
3394
+ set_text_wrap: () => set_text_wrap,
3395
+ set_top: () => set_top,
3396
+ set_top_left_point: () => set_top_left_point,
3397
+ set_xloc: () => set_xloc3
3398
+ });
3399
+ function new_box(...args) {
3400
+ let left, top, right, bottom, rest;
3401
+ if (typeof args[0] === "object" && args[0] !== null) {
3402
+ const [tl, br, ...others] = args;
3403
+ const xloc2 = others[4] ?? "bar_index";
3404
+ [left, top, right, bottom, rest] = [pointX3(tl, xloc2), tl.price, pointX3(br, xloc2), br.price, others];
3405
+ } else {
3406
+ [left, top, right, bottom] = args;
3407
+ rest = args.slice(4);
3408
+ }
3409
+ const [
3410
+ border_color,
3411
+ border_width,
3412
+ border_style,
3413
+ extend,
3414
+ xloc,
3415
+ bgcolor2,
3416
+ text2,
3417
+ text_size,
3418
+ text_color,
3419
+ text_halign,
3420
+ text_valign,
3421
+ text_wrap,
3422
+ text_font_family,
3423
+ force_overlay,
3424
+ text_formatting
3425
+ ] = rest;
3426
+ return register("box", {
3427
+ left,
3428
+ top,
3429
+ right,
3430
+ bottom,
3431
+ xloc: xloc ?? "bar_index",
3432
+ extend: extend ?? "none",
3433
+ border_color,
3434
+ border_width: border_width || 1,
3435
+ border_style: border_style || "solid",
3436
+ bgcolor: bgcolor2,
3437
+ text: text2,
3438
+ text_size,
3439
+ text_color,
3440
+ text_halign,
3441
+ text_valign,
3442
+ text_wrap,
3443
+ text_font_family,
3444
+ force_overlay: force_overlay ?? false,
3445
+ text_formatting
3446
+ });
3447
+ }
3448
+ function get_left(id) {
3449
+ return id.left;
3450
+ }
3451
+ function get_right(id) {
3452
+ return id.right;
3453
+ }
3454
+ function get_top(id) {
3455
+ return id.top;
3456
+ }
3457
+ function get_bottom(id) {
3458
+ return id.bottom;
3459
+ }
3460
+ function copy3(id) {
3461
+ return register("box", { ...id });
3462
+ }
3463
+ function set_left(id, left) {
3464
+ if (isDeleted(id)) return id;
3465
+ id.left = left;
3466
+ return id;
3467
+ }
3468
+ function set_right(id, right) {
3469
+ if (isDeleted(id)) return id;
3470
+ id.right = right;
3471
+ return id;
3472
+ }
3473
+ function set_top(id, top) {
3474
+ if (isDeleted(id)) return id;
3475
+ id.top = top;
3476
+ return id;
3477
+ }
3478
+ function set_bottom(id, bottom) {
3479
+ if (isDeleted(id)) return id;
3480
+ id.bottom = bottom;
3481
+ return id;
3482
+ }
3483
+ function set_lefttop(id, left, top) {
3484
+ if (isDeleted(id)) return id;
3485
+ id.left = left;
3486
+ id.top = top;
3487
+ return id;
3488
+ }
3489
+ function set_rightbottom(id, right, bottom) {
3490
+ if (isDeleted(id)) return id;
3491
+ id.right = right;
3492
+ id.bottom = bottom;
3493
+ return id;
3494
+ }
3495
+ function set_xloc3(id, left, right, xloc) {
3496
+ if (isDeleted(id)) return id;
3497
+ id.left = left;
3498
+ id.right = right;
3499
+ id.xloc = xloc;
3500
+ return id;
3501
+ }
3502
+ function set_extend2(id, extend) {
3503
+ if (isDeleted(id)) return id;
3504
+ id.extend = extend;
3505
+ return id;
3506
+ }
3507
+ function set_border_color(id, borderColor) {
3508
+ if (isDeleted(id)) return id;
3509
+ id.border_color = borderColor;
3510
+ return id;
3511
+ }
3512
+ function set_border_width(id, width) {
3513
+ if (isDeleted(id)) return id;
3514
+ id.border_width = width;
3515
+ return id;
3516
+ }
3517
+ function set_border_style(id, style) {
3518
+ if (isDeleted(id)) return id;
3519
+ id.border_style = style;
3520
+ return id;
3521
+ }
3522
+ function set_bgcolor(id, bgColor) {
3523
+ if (isDeleted(id)) return id;
3524
+ id.bgcolor = bgColor;
3525
+ return id;
3526
+ }
3527
+ function set_text2(id, text2) {
3528
+ if (isDeleted(id)) return id;
3529
+ id.text = text2;
3530
+ return id;
3531
+ }
3532
+ function set_text_color(id, textColor) {
3533
+ if (isDeleted(id)) return id;
3534
+ id.text_color = textColor;
3535
+ return id;
3536
+ }
3537
+ function set_text_size(id, size) {
3538
+ if (isDeleted(id)) return id;
3539
+ id.text_size = size;
3540
+ return id;
3541
+ }
3542
+ function set_text_halign(id, align) {
3543
+ if (isDeleted(id)) return id;
3544
+ id.text_halign = align;
3545
+ return id;
3546
+ }
3547
+ function set_text_valign(id, align) {
3548
+ if (isDeleted(id)) return id;
3549
+ id.text_valign = align;
3550
+ return id;
3551
+ }
3552
+ function set_text_wrap(id, wrap) {
3553
+ if (isDeleted(id)) return id;
3554
+ id.text_wrap = wrap;
3555
+ return id;
3556
+ }
3557
+ function set_text_font_family2(id, font) {
3558
+ if (isDeleted(id)) return id;
3559
+ id.text_font_family = font;
3560
+ return id;
3561
+ }
3562
+ function delete_box(id) {
3563
+ remove("box", id);
3564
+ }
3565
+ function pointX3(point, xloc) {
3566
+ const x = xloc === "bar_time" ? point.time : point.index;
3567
+ return x ?? NaN;
3568
+ }
3569
+ function all4() {
3570
+ return all("box");
3571
+ }
3572
+ function set_top_left_point(id, point) {
3573
+ if (isDeleted(id)) return id;
3574
+ id.left = pointX3(point, id.xloc);
3575
+ id.top = point.price;
3576
+ return id;
3577
+ }
3578
+ function set_bottom_right_point(id, point) {
3579
+ if (isDeleted(id)) return id;
3580
+ id.right = pointX3(point, id.xloc);
3581
+ id.bottom = point.price;
3582
+ return id;
3583
+ }
3584
+ function set_text_formatting2(id, formatting) {
3585
+ if (isDeleted(id)) return id;
3586
+ id.text_formatting = formatting;
3587
+ return id;
3588
+ }
3589
+
3590
+ // src/linefill/index.ts
3591
+ var linefill_exports = {};
3592
+ __export(linefill_exports, {
3593
+ all: () => all5,
3594
+ delete: () => delete_linefill,
3595
+ delete_linefill: () => delete_linefill,
3596
+ get_line1: () => get_line1,
3597
+ get_line2: () => get_line2,
3598
+ new: () => new_linefill,
3599
+ new_linefill: () => new_linefill,
3600
+ set_color: () => set_color3
3601
+ });
3602
+ function new_linefill(line1, line2, fillColor) {
3603
+ return register("linefill", {
3604
+ line1,
3605
+ line2,
3606
+ color: fillColor
3607
+ });
3608
+ }
3609
+ function get_line1(id) {
3610
+ return id.line1;
3611
+ }
3612
+ function get_line2(id) {
3613
+ return id.line2;
3614
+ }
3615
+ function set_color3(id, fillColor) {
3616
+ if (isDeleted(id)) return id;
3617
+ id.color = fillColor;
3618
+ return id;
3619
+ }
3620
+ function delete_linefill(id) {
3621
+ remove("linefill", id);
3622
+ }
3623
+ function all5() {
3624
+ return all("linefill");
3625
+ }
3626
+
3627
+ // src/polyline/index.ts
3628
+ var polyline_exports = {};
3629
+ __export(polyline_exports, {
3630
+ all: () => all6,
3631
+ clear_all: () => clear_all,
3632
+ delete: () => delete_polyline,
3633
+ delete_polyline: () => delete_polyline,
3634
+ get_all: () => get_all,
3635
+ new: () => new_polyline,
3636
+ new_polyline: () => new_polyline,
3637
+ reset_id_counter: () => reset_id_counter
3638
+ });
3639
+ var polylineIdCounter = 0;
3640
+ function generateId() {
3641
+ return `polyline_${++polylineIdCounter}`;
3642
+ }
3643
+ function new_polyline(points, curved = false, closed = false, xloc = "bar_index", line_color = "#2196F3", fill_color = null, line_style = "solid", line_width = 1, force_overlay = false) {
3644
+ if (curved) {
3645
+ console.warn(
3646
+ "polyline.new(): curved polylines are not yet supported. Using straight-line connections."
3647
+ );
3648
+ }
3649
+ if (line_width < 1) {
3650
+ console.warn("polyline.new(): line_width must be at least 1. Using 1.");
3651
+ line_width = 1;
3652
+ }
3653
+ const polyline2 = {
3654
+ id: generateId(),
3655
+ points: [...points],
3656
+ // Create a copy of the points array
3657
+ curved,
3658
+ closed,
3659
+ xloc,
3660
+ line_color,
3661
+ fill_color,
3662
+ line_style,
3663
+ line_width,
3664
+ force_overlay
3665
+ };
3666
+ return register("polyline", polyline2);
3667
+ }
3668
+ function delete_polyline(id) {
3669
+ remove("polyline", id);
3670
+ }
3671
+ function get_all() {
3672
+ return all("polyline");
3673
+ }
3674
+ function all6() {
3675
+ return all("polyline");
3676
+ }
3677
+ function clear_all() {
3678
+ for (const p of all("polyline")) remove("polyline", p);
3679
+ }
3680
+ function reset_id_counter() {
3681
+ polylineIdCounter = 0;
3682
+ }
3683
+
3684
+ // src/chartpoint/index.ts
3685
+ var chartpoint_exports = {};
3686
+ __export(chartpoint_exports, {
3687
+ copy: () => copy4,
3688
+ from_index: () => from_index,
3689
+ from_time: () => from_time,
3690
+ new: () => new_point,
3691
+ new_point: () => new_point
3692
+ });
3693
+ function new_point(time2, index, price) {
3694
+ return {
3695
+ time: time2,
3696
+ index,
3697
+ price
3698
+ };
3699
+ }
3700
+ function from_time(time2, price) {
3701
+ return {
3702
+ time: time2,
3703
+ index: null,
3704
+ price
3705
+ };
3706
+ }
3707
+ function from_index(index, price) {
3708
+ return {
3709
+ time: null,
3710
+ index,
3711
+ price
3712
+ };
3713
+ }
3714
+ function copy4(point) {
3715
+ return {
3716
+ time: point.time,
3717
+ index: point.index,
3718
+ price: point.price
3719
+ };
3720
+ }
3721
+
3722
+ // src/text/index.ts
3723
+ var text_exports = {};
3724
+ __export(text_exports, {
3725
+ format_bold: () => format_bold,
3726
+ format_italic: () => format_italic,
3727
+ format_none: () => format_none
3728
+ });
3729
+ var format_none = 0;
3730
+ var format_bold = 1;
3731
+ var format_italic = 2;
3732
+
3733
+ // src/timeframe/index.ts
3734
+ var timeframe_exports = {};
3735
+ __export(timeframe_exports, {
3736
+ from_seconds: () => from_seconds,
3737
+ in_seconds: () => in_seconds,
3738
+ info: () => info
3739
+ });
3740
+ var SECONDS_PER_MINUTE = 60;
3741
+ var SECONDS_PER_DAY = 86400;
3742
+ var SECONDS_PER_WEEK = 604800;
3743
+ var SECONDS_PER_MONTH = 2628003;
3744
+ var SECONDS_365_DAYS = 365 * SECONDS_PER_DAY;
3745
+ var UNIT_SECONDS = {
3746
+ S: 1,
3747
+ "": SECONDS_PER_MINUTE,
3748
+ D: SECONDS_PER_DAY,
3749
+ W: SECONDS_PER_WEEK,
3750
+ M: SECONDS_PER_MONTH
3751
+ };
3752
+ var SECOND_TIMEFRAMES = [1, 5, 10, 15, 30];
3753
+ function in_seconds(timeframe2) {
3754
+ const text2 = timeframe2.trim();
3755
+ if (text2 === "") {
3756
+ throw new RangeError("timeframe.in_seconds() needs a timeframe: the chart timeframe is not known here");
3757
+ }
3758
+ const before = /^(\d*)([SDWMT]?)$/.exec(text2);
3759
+ const after = before ? null : /^([SDWMT])(\d+)$/.exec(text2);
3760
+ if (!before && !after) throw new RangeError(`Invalid timeframe "${timeframe2}"`);
3761
+ const [digits, unit] = before ? [before[1], before[2]] : [after[2], after[1]];
3762
+ if (unit === "T") return NaN;
3763
+ const multiplier = digits === "" ? 1 : Number(digits);
3764
+ return multiplier * UNIT_SECONDS[unit];
3765
+ }
3766
+ function from_seconds(seconds) {
3767
+ if (Number.isNaN(seconds)) throw new RangeError("timeframe.from_seconds() needs a number of seconds");
3768
+ if (seconds >= SECONDS_365_DAYS) return "12M";
3769
+ if (seconds > 0) {
3770
+ if (seconds % SECONDS_PER_MONTH === 0) return `${seconds / SECONDS_PER_MONTH}M`;
3771
+ if (seconds % SECONDS_PER_WEEK === 0) return `${seconds / SECONDS_PER_WEEK}W`;
3772
+ if (seconds % SECONDS_PER_DAY === 0) return `${seconds / SECONDS_PER_DAY}D`;
3773
+ if (seconds % SECONDS_PER_MINUTE === 0 && seconds < SECONDS_PER_DAY) return `${seconds / SECONDS_PER_MINUTE}`;
3774
+ }
3775
+ const second3 = SECOND_TIMEFRAMES.find((m) => seconds <= m);
3776
+ if (second3 !== void 0) return `${second3}S`;
3777
+ if (seconds < SECONDS_PER_DAY) return `${Math.ceil(seconds / SECONDS_PER_MINUTE)}`;
3778
+ return `${Math.ceil(seconds / SECONDS_PER_DAY)}D`;
3779
+ }
3780
+ function info(timeframe2) {
3781
+ const text2 = timeframe2.trim();
3782
+ const m = /^(\d*)([SDWMT]?)$/.exec(text2);
3783
+ if (!m || text2 === "") throw new RangeError(`Invalid timeframe "${timeframe2}"`);
3784
+ const unit = m[2];
3785
+ const multiplier = m[1] === "" ? 1 : Number(m[1]);
3786
+ return {
3787
+ period: unit === "" ? String(multiplier) : `${multiplier}${unit}`,
3788
+ multiplier,
3789
+ isintraday: unit === "" || unit === "S" || unit === "T",
3790
+ isdaily: unit === "D",
3791
+ isweekly: unit === "W",
3792
+ ismonthly: unit === "M",
3793
+ isminutes: unit === "",
3794
+ isseconds: unit === "S",
3795
+ isticks: unit === "T",
3796
+ isdwm: unit === "D" || unit === "W" || unit === "M"
3797
+ };
3798
+ }
3799
+
3800
+ // src/time/timezone.ts
3801
+ var MS_PER_SECOND = 1e3;
3802
+ var MS_PER_DAY = 864e5;
3803
+ var MAX_OFFSET_SECONDS = 18 * 3600;
3804
+ var OFFSET_NOTATION = /^(?:UTC|GMT)(?:([+-])(\d{1,2})(?::?(\d{2})(?::?(\d{2}))?)?)?$/;
3805
+ var REJECTED_NAMES = /* @__PURE__ */ new Set(["EST", "MST", "HST"]);
3806
+ var canonicalNames;
3807
+ function hasTimeZoneCase(name) {
3808
+ if (name.split("/").some((segment) => !/^[A-Z]/.test(segment))) return false;
3809
+ canonicalNames ??= new Map(Intl.supportedValuesOf("timeZone").map((n) => [n.toLowerCase(), n]));
3810
+ const canonical = canonicalNames.get(name.toLowerCase());
3811
+ return canonical === void 0 || canonical === name;
3812
+ }
3813
+ var zones = /* @__PURE__ */ new Map();
3814
+ function resolveZone(timezone) {
3815
+ let zone = zones.get(timezone);
3816
+ if (zone) return zone;
3817
+ const invalid = () => new RangeError(
3818
+ `Invalid time zone "${timezone}": use UTC/GMT offset notation ("UTC-5", "GMT+0530") or an IANA name ("America/New_York")`
3819
+ );
3820
+ const m = OFFSET_NOTATION.exec(timezone);
3821
+ if (m) {
3822
+ const [, sign2, h = "0", mi = "0", s] = m;
3823
+ const minutes = Number(mi);
3824
+ const seconds = s === void 0 ? 0 : Number(s);
3825
+ if (minutes > 59 || seconds > 59 || s !== void 0 && h.length !== 2) throw invalid();
3826
+ const offsetSeconds = Number(h) * 3600 + minutes * 60 + seconds;
3827
+ if (offsetSeconds > MAX_OFFSET_SECONDS) throw invalid();
3828
+ zone = { kind: "fixed", offsetMs: (sign2 === "-" ? -offsetSeconds : offsetSeconds) * MS_PER_SECOND };
3829
+ } else {
3830
+ if (REJECTED_NAMES.has(timezone) || !hasTimeZoneCase(timezone)) throw invalid();
3831
+ let format2;
3832
+ try {
3833
+ format2 = new Intl.DateTimeFormat("en-US", {
3834
+ timeZone: timezone,
3835
+ hourCycle: "h23",
3836
+ year: "numeric",
3837
+ month: "numeric",
3838
+ day: "numeric",
3839
+ hour: "numeric",
3840
+ minute: "numeric",
3841
+ second: "numeric"
3842
+ });
3843
+ } catch {
3844
+ throw invalid();
3845
+ }
3846
+ zone = { kind: "iana", format: format2 };
3847
+ }
3848
+ zones.set(timezone, zone);
3849
+ return zone;
3850
+ }
3851
+ function offsetAt(zone, time2) {
3852
+ if (zone.kind === "fixed") return zone.offsetMs;
3853
+ const wholeSecond = Math.floor(time2 / 1e3) * 1e3;
3854
+ const f = {};
3855
+ for (const part of zone.format.formatToParts(wholeSecond)) {
3856
+ if (part.type !== "literal") f[part.type] = Number(part.value);
3857
+ }
3858
+ const local = Date.UTC(f.year, f.month - 1, f.day, f.hour, f.minute, f.second);
3859
+ return local - wholeSecond;
3860
+ }
3861
+ function zoneOffset(time2, timezone) {
3862
+ return offsetAt(resolveZone(timezone), time2);
3863
+ }
3864
+ function zonedFields(time2, timezone) {
3865
+ const local = new Date(time2 + offsetAt(resolveZone(timezone), time2));
3866
+ return {
3867
+ year: local.getUTCFullYear(),
3868
+ month: local.getUTCMonth() + 1,
3869
+ day: local.getUTCDate(),
3870
+ hour: local.getUTCHours(),
3871
+ minute: local.getUTCMinutes(),
3872
+ second: local.getUTCSeconds(),
3873
+ dayOfWeek: local.getUTCDay() + 1
3874
+ };
3875
+ }
3876
+ function zonedToUnix(timezone, year3, month3, day, hour3 = 0, minute3 = 0, second3 = 0) {
3877
+ const zone = resolveZone(timezone);
3878
+ const local = Date.UTC(year3, month3 - 1, day, hour3, minute3, second3);
3879
+ if (zone.kind === "fixed") return local - zone.offsetMs;
3880
+ const before = offsetAt(zone, local - MS_PER_DAY);
3881
+ const after = offsetAt(zone, local + MS_PER_DAY);
3882
+ const candidates = [local - before, local - after].filter((t2) => local - offsetAt(zone, t2) === t2);
3883
+ if (candidates.length) return Math.max(...candidates);
3884
+ return local - before;
3885
+ }
3886
+
3887
+ // src/time/datestring.ts
3888
+ var MONTHS = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
3889
+ var FULL_MONTHS = [
3890
+ "january",
3891
+ "february",
3892
+ "march",
3893
+ "april",
3894
+ "may",
3895
+ "june",
3896
+ "july",
3897
+ "august",
3898
+ "september",
3899
+ "october",
3900
+ "november",
3901
+ "december"
3902
+ ];
3903
+ var ZONE_NAMES = {
3904
+ ut: 0,
3905
+ utc: 0,
3906
+ gmt: 0,
3907
+ est: -5,
3908
+ edt: -4,
3909
+ cst: -6,
3910
+ cdt: -5,
3911
+ mst: -7,
3912
+ mdt: -6,
3913
+ pst: -8,
3914
+ pdt: -7
3915
+ };
3916
+ var TIME = String.raw`(\d{1,2}):(\d{2})(?::(\d{2})(?:\.(\d{1,3})\d*)?)?`;
3917
+ var ZONE = String.raw`(ut|utc|gmt|[ecmp][sd]t|(?:utc|gmt)?\s*[+-]\d{1,2}(?::?\d{2})?)`;
3918
+ var NUMERIC_ZONE = String.raw`([+-]\d{2}(?::?\d{2})?)`;
3919
+ var DATE = String.raw`(\d{4})([-/])(\d{1,2})\2(\d{1,2})`;
3920
+ var WEEKDAY = String.raw`(?:[a-z]{3,9},?\s+)?`;
3921
+ var ISO_T = new RegExp(String.raw`^${DATE}t${TIME}\s*${NUMERIC_ZONE}?$`, "i");
3922
+ var ISO = new RegExp(String.raw`^${DATE}(?:\s+${TIME})?\s*${ZONE}?$`, "i");
3923
+ var DAY_FIRST = new RegExp(String.raw`^${WEEKDAY}(\d{1,2})(?:\s+|-)([a-z]+)\.?,?(?:\s+|-)(\d{4})(?:,?\s+${TIME})?\s*${ZONE}?$`, "i");
3924
+ var MONTH_FIRST = new RegExp(String.raw`^${WEEKDAY}([a-z]+)\.?\s+(\d{1,2}),?\s+(\d{4})(?:,?\s+${TIME})?\s*${ZONE}?$`, "i");
3925
+ function monthNumber(name) {
3926
+ const lower2 = name.toLowerCase();
3927
+ const i = FULL_MONTHS.findIndex((full, k) => lower2.startsWith(MONTHS[k]) && full.startsWith(lower2));
3928
+ return i + 1;
3929
+ }
3930
+ function zoneMinutes(zone) {
3931
+ if (!zone) return 0;
3932
+ const lower2 = zone.toLowerCase().replace(/\s+/g, "");
3933
+ const named = ZONE_NAMES[lower2];
3934
+ if (named !== void 0) return named * 60;
3935
+ const m = /^(?:utc|gmt)?([+-])(\d{1,2})(?::?(\d{2}))?$/.exec(lower2);
3936
+ if (!m) return NaN;
3937
+ const minutes = Number(m[2]) * 60 + (m[3] ? Number(m[3]) : 0);
3938
+ return m[1] === "-" ? -minutes : minutes;
3939
+ }
3940
+ function parseDateString(dateString) {
3941
+ const text2 = dateString.trim();
3942
+ let year3, month3, day;
3943
+ let rest;
3944
+ let m;
3945
+ if (m = ISO_T.exec(text2) ?? ISO.exec(text2)) {
3946
+ [year3, month3, day] = [m[1], Number(m[3]), m[4]];
3947
+ rest = m.slice(5);
3948
+ } else if (m = DAY_FIRST.exec(text2)) {
3949
+ [day, month3, year3] = [m[1], monthNumber(m[2]), m[3]];
3950
+ rest = m.slice(4);
3951
+ } else if (m = MONTH_FIRST.exec(text2)) {
3952
+ [month3, day, year3] = [monthNumber(m[1]), m[2], m[3]];
3953
+ rest = m.slice(4);
3954
+ } else {
3955
+ throw new SyntaxError(`Invalid date string "${dateString}": use RFC 2822 or ISO 8601 ("20 Feb 2020", "2020-02-20T14:48:00")`);
3956
+ }
3957
+ const [hour3 = "0", minute3 = "0", second3 = "0", millis = "0", zone] = rest;
3958
+ const d = Number(day);
3959
+ const h = Number(hour3);
3960
+ const mi = Number(minute3);
3961
+ const s = Number(second3);
3962
+ const offset = zoneMinutes(zone);
3963
+ const endOfDay = h === 24 && mi === 0 && s === 0 && Number(millis) === 0;
3964
+ if (month3 < 1 || month3 > 12 || d < 1 || d > 31 || h > 23 && !endOfDay || mi > 59 || s > 59 || Number.isNaN(offset)) {
3965
+ throw new SyntaxError(`Invalid date string "${dateString}": a field is out of range`);
3966
+ }
3967
+ const ms = Number(millis.padEnd(3, "0"));
3968
+ return Date.UTC(Number(year3), month3 - 1, d, h, mi, s, ms) - offset * 6e4;
3969
+ }
3970
+
3971
+ // src/time/session.ts
3972
+ var PERIOD = /^(\d{2})(\d{2})-(\d{2})(\d{2})$/;
3973
+ var sessions = /* @__PURE__ */ new Map();
3974
+ function parseSession(session2) {
3975
+ let parsed = sessions.get(session2);
3976
+ if (parsed) return parsed;
3977
+ const invalid = () => new SyntaxError(`Invalid session "${session2}": expected "HHmm-HHmm[,HHmm-HHmm...][:days]"`);
3978
+ const text2 = session2.trim() === "24x7" ? "0000-0000" : session2.replace(/\s+/g, "");
3979
+ const [periodText = "", dayText, extra] = text2.split(":");
3980
+ if (extra !== void 0 || periodText === "") throw invalid();
3981
+ const periods = periodText.split(",").map((p) => {
3982
+ const m = PERIOD.exec(p);
3983
+ if (!m) throw invalid();
3984
+ const [h1, m1, h2, m2] = [m[1], m[2], m[3], m[4]].map(Number);
3985
+ if (h1 > 23 || h2 > 23 || m1 > 59 || m2 > 59) throw invalid();
3986
+ return { start: h1 * 60 + m1, end: h2 * 60 + m2 };
3987
+ });
3988
+ const dayDigits = dayText ?? (periods.length > 1 ? "23456" : "1234567");
3989
+ if (!/^[1-7]+$/.test(dayDigits)) throw invalid();
3990
+ const days = new Array(8).fill(false);
3991
+ for (const d of dayDigits) days[Number(d)] = true;
3992
+ parsed = { periods, days };
3993
+ sessions.set(session2, parsed);
3994
+ return parsed;
3995
+ }
3996
+ function inSession(time2, session2, timezone) {
3997
+ if (Number.isNaN(time2)) return false;
3998
+ const { periods, days } = parseSession(session2);
3999
+ const f = zonedFields(time2, timezone);
4000
+ const minute3 = f.hour * 60 + f.minute;
4001
+ const nextDay = f.dayOfWeek % 7 + 1;
4002
+ for (const { start, end } of periods) {
4003
+ if (start < end || start === 0 && end === 0) {
4004
+ if (minute3 >= start && (minute3 < end || end === 0) && days[f.dayOfWeek]) return true;
4005
+ } else {
4006
+ if (minute3 >= start && days[nextDay]) return true;
4007
+ if (minute3 < end && days[f.dayOfWeek]) return true;
4008
+ }
4009
+ }
4010
+ return false;
4011
+ }
4012
+
4013
+ // src/time/index.ts
4014
+ function timestamp(first, ...rest) {
4015
+ if (typeof first === "string") {
4016
+ if (rest.length === 0) return parseDateString(first);
4017
+ const [year3, month4, day2, hour4, minute4, second4] = rest;
4018
+ return zonedToUnix(first, year3, month4, day2, hour4 ?? 0, minute4 ?? 0, second4 ?? 0);
4019
+ }
4020
+ const [month3, day, hour3, minute3, second3] = rest;
4021
+ return new Date(first, month3 - 1, day, hour3 || 0, minute3 || 0, second3 || 0).getTime();
4022
+ }
4023
+ function field(time2, timezone, pick) {
4024
+ return Number.isNaN(time2) ? NaN : pick(zonedFields(time2, timezone));
4025
+ }
4026
+ function year(time2, timezone) {
4027
+ return field(time2, timezone, (f) => f.year);
4028
+ }
4029
+ function month(time2, timezone) {
4030
+ return field(time2, timezone, (f) => f.month);
4031
+ }
4032
+ function dayofmonth(time2, timezone) {
4033
+ return field(time2, timezone, (f) => f.day);
4034
+ }
4035
+ function dayofweek(time2, timezone) {
4036
+ return field(time2, timezone, (f) => f.dayOfWeek);
4037
+ }
4038
+ function weekofyear(time2, timezone) {
4039
+ return field(time2, timezone, (f) => {
4040
+ const date = Date.UTC(f.year, f.month - 1, f.day);
4041
+ const mondayBased = (f.dayOfWeek + 5) % 7;
4042
+ const thursday = new Date(date + (3 - mondayBased) * 864e5);
4043
+ const yearStart = Date.UTC(thursday.getUTCFullYear(), 0, 1);
4044
+ return 1 + Math.floor((thursday.getTime() - yearStart) / (7 * 864e5));
4045
+ });
4046
+ }
4047
+ function hour(time2, timezone) {
4048
+ return field(time2, timezone, (f) => f.hour);
4049
+ }
4050
+ function minute(time2, timezone) {
4051
+ return field(time2, timezone, (f) => f.minute);
4052
+ }
4053
+ function second(time2, timezone) {
4054
+ return field(time2, timezone, (f) => f.second);
4055
+ }
4056
+ function inSession2(time2, session2, timezone) {
4057
+ return inSession(time2, session2, timezone);
4058
+ }
4059
+
4060
+ // src/str/index.ts
4061
+ var str_exports = {};
4062
+ __export(str_exports, {
4063
+ charAt: () => charAt,
4064
+ concat: () => concat,
4065
+ contains: () => contains,
4066
+ endswith: () => endswith,
4067
+ format: () => format,
4068
+ format_time: () => format_time,
4069
+ length: () => length,
4070
+ lower: () => lower,
4071
+ match: () => match,
4072
+ pos: () => pos,
4073
+ repeat: () => repeat,
4074
+ replace: () => replace,
4075
+ replace_all: () => replace_all,
4076
+ split: () => split,
4077
+ startswith: () => startswith,
4078
+ substring: () => substring,
4079
+ tonumber: () => tonumber,
4080
+ tostring: () => tostring,
4081
+ trim: () => trim,
4082
+ trimLeft: () => trimLeft,
4083
+ trimRight: () => trimRight,
4084
+ upper: () => upper
4085
+ });
4086
+
4087
+ // src/str/numberformat.ts
4088
+ var patterns = /* @__PURE__ */ new Map();
4089
+ function parsePattern(pattern) {
4090
+ const cached = patterns.get(pattern);
4091
+ if (cached) return cached;
4092
+ let prefix = "";
4093
+ let suffix = "";
4094
+ let number2 = "";
4095
+ let percent = false;
4096
+ let phase = "prefix";
4097
+ for (let i = 0; i < pattern.length; i++) {
4098
+ const ch = pattern[i];
4099
+ let literal;
4100
+ if (ch === "'") {
4101
+ const end = pattern.indexOf("'", i + 1);
4102
+ if (end === i + 1) {
4103
+ literal = "'";
4104
+ i = end;
4105
+ } else {
4106
+ literal = pattern.slice(i + 1, end === -1 ? void 0 : end);
4107
+ i = end === -1 ? pattern.length : end;
4108
+ }
4109
+ } else if (phase !== "suffix" && ("#0,.".includes(ch) || phase === "number" && ch === "E")) {
4110
+ phase = "number";
4111
+ number2 += ch;
4112
+ continue;
4113
+ } else {
4114
+ if (ch === "%") percent = true;
4115
+ literal = ch;
4116
+ }
4117
+ if (phase === "number") phase = "suffix";
4118
+ if (phase === "prefix") prefix += literal;
4119
+ else suffix += literal;
4120
+ }
4121
+ const [mantissa = "", exp2] = number2.split("E");
4122
+ const [intPart = "", fracPart = ""] = mantissa.split(".");
4123
+ const lastComma = intPart.lastIndexOf(",");
4124
+ const parsed = {
4125
+ prefix,
4126
+ suffix,
4127
+ // as in Java, a pattern with a decimal point and no '0' at all ("#.##") shows one integer digit
4128
+ minInt: !mantissa.includes("0") && mantissa.includes(".") ? 1 : [...intPart].filter((c) => c === "0").length,
4129
+ minFrac: [...fracPart].filter((c) => c === "0").length,
4130
+ maxFrac: [...fracPart].filter((c) => c === "0" || c === "#").length,
4131
+ grouping: lastComma === -1 ? 0 : intPart.length - lastComma - 1,
4132
+ percent,
4133
+ exponent: exp2 === void 0 ? null : exp2.length,
4134
+ hasDigits: /[0#]/.test(mantissa)
4135
+ };
4136
+ patterns.set(pattern, parsed);
4137
+ return parsed;
4138
+ }
4139
+ function shortestDigits(x) {
4140
+ const m = /^(\d+)(?:\.(\d+))?(?:e([+-]\d+))?$/.exec(String(Math.abs(x)));
4141
+ const all7 = m[1] + (m[2] ?? "");
4142
+ let intLen = m[1].length + Number(m[3] ?? 0);
4143
+ const lead = all7.length - all7.replace(/^0+/, "").length;
4144
+ intLen -= lead;
4145
+ const digits = all7.slice(lead).replace(/0+$/, "");
4146
+ return { digits, intLen: digits ? intLen : 0 };
4147
+ }
4148
+ function exactDigits(x) {
4149
+ const abs2 = Math.abs(x);
4150
+ if (abs2 === 0) return { digits: "", intLen: 0 };
4151
+ const view = new DataView(new ArrayBuffer(8));
4152
+ view.setFloat64(0, abs2);
4153
+ const bits = view.getBigUint64(0);
4154
+ const expBits = Number(bits >> 52n & 0x7ffn);
4155
+ let mant = bits & 0xfffffffffffffn;
4156
+ const e2 = expBits === 0 ? -1074 : expBits - 1075;
4157
+ if (expBits !== 0) mant |= 1n << 52n;
4158
+ let str2;
4159
+ let fracDigits;
4160
+ if (e2 >= 0) {
4161
+ str2 = (mant << BigInt(e2)).toString();
4162
+ fracDigits = 0;
4163
+ } else {
4164
+ str2 = (mant * 5n ** BigInt(-e2)).toString();
4165
+ fracDigits = -e2;
4166
+ }
4167
+ const intLen = str2.length - fracDigits;
4168
+ const lead = str2.length - str2.replace(/^0+/, "").length;
4169
+ const digits = str2.slice(lead).replace(/0+$/, "");
4170
+ return { digits, intLen: intLen - lead };
4171
+ }
4172
+ function roundDigits(d, frac, mode3) {
4173
+ const keep = d.intLen + frac;
4174
+ if (keep >= d.digits.length) return d;
4175
+ if (keep < 0) return { digits: "", intLen: 0 };
4176
+ const first = d.digits.charCodeAt(keep) - 48;
4177
+ let up;
4178
+ if (mode3 === "halfUpShortest") up = first >= 5;
4179
+ else if (first !== 5) up = first > 5;
4180
+ else if (d.digits.length > keep + 1) up = true;
4181
+ else up = keep > 0 && (d.digits.charCodeAt(keep - 1) - 48) % 2 === 1;
4182
+ let kept = d.digits.slice(0, keep);
4183
+ let intLen = d.intLen;
4184
+ if (up) {
4185
+ const n = (BigInt(kept || "0") + 1n).toString();
4186
+ if (n.length > kept.length) intLen += 1;
4187
+ kept = n;
4188
+ }
4189
+ kept = kept.replace(/0+$/, "");
4190
+ return { digits: kept, intLen: kept ? intLen : 0 };
4191
+ }
4192
+ function group(int, size) {
4193
+ if (!size || int.length <= size) return int;
4194
+ const parts = [];
4195
+ for (let end = int.length; end > 0; end -= size) parts.unshift(int.slice(Math.max(0, end - size), end));
4196
+ return parts.join(",");
4197
+ }
4198
+ function layout(d, p) {
4199
+ let int = d.intLen > 0 ? d.digits.slice(0, d.intLen).padEnd(d.intLen, "0") : "";
4200
+ int = int.replace(/^0+/, "").padStart(p.minInt, "0");
4201
+ let frac = d.intLen < 0 ? "0".repeat(-d.intLen) + d.digits : d.digits.slice(Math.max(0, d.intLen));
4202
+ frac = frac.slice(0, p.maxFrac).replace(/0+$/, "").padEnd(p.minFrac, "0");
4203
+ if (!int && !frac) int = "0";
4204
+ return group(int, p.grouping) + (frac ? "." + frac : "");
4205
+ }
4206
+ function formatNumber(value, pattern, mode3) {
4207
+ if (Number.isNaN(value)) return "NaN";
4208
+ const p = parsePattern(pattern);
4209
+ if (!Number.isFinite(value)) return (value < 0 ? "-" : "") + p.prefix + "\u221E" + p.suffix;
4210
+ const x = p.percent ? value * 100 : value;
4211
+ const toDigits = mode3 === "halfUpShortest" ? shortestDigits : exactDigits;
4212
+ let body;
4213
+ let isZero;
4214
+ if (p.exponent !== null) {
4215
+ const rounded = roundDigits(toDigits(x), p.maxFrac, mode3);
4216
+ const intDigits = Math.max(p.minInt, 1);
4217
+ isZero = rounded.digits === "";
4218
+ let exponent = isZero ? 0 : rounded.intLen - intDigits;
4219
+ let mant = roundDigits({ digits: rounded.digits, intLen: isZero ? 0 : intDigits }, p.maxFrac, mode3);
4220
+ if (mant.intLen > intDigits) {
4221
+ exponent += 1;
4222
+ mant = { digits: mant.digits, intLen: intDigits };
4223
+ }
4224
+ const e2 = String(Math.abs(exponent)).padStart(p.exponent, "0");
4225
+ body = layout(mant, p) + "E" + (exponent < 0 ? "-" : "") + e2;
4226
+ } else {
4227
+ const rounded = roundDigits(toDigits(x), p.hasDigits ? p.maxFrac : 0, mode3);
4228
+ isZero = rounded.digits === "";
4229
+ body = p.hasDigits ? layout(rounded, p) : layout(rounded, { ...p, minInt: 0, maxFrac: 0, minFrac: 0 });
4230
+ }
4231
+ const negative = x < 0 && (!isZero || !p.hasDigits);
4232
+ return (negative ? "-" : "") + p.prefix + body + p.suffix;
4233
+ }
4234
+
4235
+ // src/str/dateformat.ts
4236
+ var MONTHS2 = [
4237
+ "January",
4238
+ "February",
4239
+ "March",
4240
+ "April",
4241
+ "May",
4242
+ "June",
4243
+ "July",
4244
+ "August",
4245
+ "September",
4246
+ "October",
4247
+ "November",
4248
+ "December"
4249
+ ];
4250
+ var DAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
4251
+ var pad = (n, width) => String(n).padStart(width, "0");
4252
+ function zoneName(time2, timezone, offsetMs) {
4253
+ if (timezone === "Etc/UTC") return "UTC";
4254
+ if (/^(UTC|GMT)/.test(timezone)) {
4255
+ if (offsetMs === 0) return "GMT";
4256
+ const minutes = Math.abs(offsetMs) / 6e4;
4257
+ return `GMT${offsetMs < 0 ? "-" : "+"}${pad(Math.floor(minutes / 60), 2)}:${pad(minutes % 60, 2)}`;
4258
+ }
4259
+ const part = new Intl.DateTimeFormat("en-US", { timeZone: timezone, timeZoneName: "short" }).formatToParts(time2).find((p) => p.type === "timeZoneName");
4260
+ return part?.value ?? timezone;
4261
+ }
4262
+ function weekOfYear(year3, month3, day) {
4263
+ const date = Date.UTC(year3, month3 - 1, day);
4264
+ const dow = new Date(date).getUTCDay();
4265
+ const weekStart2 = date - dow * 864e5;
4266
+ if (weekStart2 + 6 * 864e5 >= Date.UTC(year3 + 1, 0, 1)) return 1;
4267
+ const jan1 = Date.UTC(year3, 0, 1);
4268
+ const jan1Dow = new Date(jan1).getUTCDay();
4269
+ return Math.floor((date - jan1 + jan1Dow * 864e5) / (7 * 864e5)) + 1;
4270
+ }
4271
+ function formatDate(time2, pattern, timezone) {
4272
+ if (Number.isNaN(time2)) return "NaN";
4273
+ const f = zonedFields(time2, timezone);
4274
+ const offset = zoneOffset(time2, timezone);
4275
+ const ms = (time2 % 1e3 + 1e3) % 1e3;
4276
+ const dayOfYear = (Date.UTC(f.year, f.month - 1, f.day) - Date.UTC(f.year, 0, 1)) / 864e5 + 1;
4277
+ let out = "";
4278
+ for (let i = 0; i < pattern.length; ) {
4279
+ const ch = pattern[i];
4280
+ if (ch === "'") {
4281
+ const end = pattern.indexOf("'", i + 1);
4282
+ if (end === i + 1) {
4283
+ out += "'";
4284
+ i += 2;
4285
+ } else {
4286
+ out += pattern.slice(i + 1, end === -1 ? void 0 : end);
4287
+ i = end === -1 ? pattern.length : end + 1;
4288
+ }
4289
+ continue;
4290
+ }
4291
+ if (!/[A-Za-z]/.test(ch)) {
4292
+ out += ch;
4293
+ i++;
4294
+ continue;
4295
+ }
4296
+ let n = 1;
4297
+ while (pattern[i + n] === ch) n++;
4298
+ i += n;
4299
+ const hour12 = f.hour % 12;
4300
+ switch (ch) {
4301
+ case "y":
4302
+ out += n === 2 ? pad(f.year % 100, 2) : pad(f.year, n);
4303
+ break;
4304
+ case "M":
4305
+ out += n >= 4 ? MONTHS2[f.month - 1] : n === 3 ? MONTHS2[f.month - 1].slice(0, 3) : pad(f.month, n);
4306
+ break;
4307
+ case "d":
4308
+ out += pad(f.day, n);
4309
+ break;
4310
+ case "E":
4311
+ out += n >= 4 ? DAYS[f.dayOfWeek - 1] : DAYS[f.dayOfWeek - 1].slice(0, 3);
4312
+ break;
4313
+ case "u":
4314
+ out += pad(f.dayOfWeek === 1 ? 7 : f.dayOfWeek - 1, n);
4315
+ break;
4316
+ case "D":
4317
+ out += pad(dayOfYear, n);
4318
+ break;
4319
+ case "w":
4320
+ out += pad(weekOfYear(f.year, f.month, f.day), n);
4321
+ break;
4322
+ case "H":
4323
+ out += pad(f.hour, n);
4324
+ break;
4325
+ case "k":
4326
+ out += pad(f.hour === 0 ? 24 : f.hour, n);
4327
+ break;
4328
+ case "K":
4329
+ out += pad(hour12, n);
4330
+ break;
4331
+ case "h":
4332
+ out += pad(hour12 === 0 ? 12 : hour12, n);
4333
+ break;
4334
+ case "a":
4335
+ out += f.hour < 12 ? "AM" : "PM";
4336
+ break;
4337
+ case "m":
4338
+ out += pad(f.minute, n);
4339
+ break;
4340
+ case "s":
4341
+ out += pad(f.second, n);
4342
+ break;
4343
+ case "S":
4344
+ out += pad(ms, n);
4345
+ break;
4346
+ case "Z": {
4347
+ const minutes = Math.abs(offset) / 6e4;
4348
+ out += (offset < 0 ? "-" : "+") + pad(Math.floor(minutes / 60), 2) + pad(minutes % 60, 2);
4349
+ break;
4350
+ }
4351
+ case "z":
4352
+ out += zoneName(time2, timezone, offset);
4353
+ break;
4354
+ default:
4355
+ throw new SyntaxError(`Unsupported date pattern letter "${ch}" in "${pattern}"`);
4356
+ }
4357
+ }
4358
+ return out;
4359
+ }
4360
+
4361
+ // src/str/messageformat.ts
4362
+ var DATE_STYLES = {
4363
+ short: "M/d/yy",
4364
+ medium: "MMM d, yyyy",
4365
+ long: "MMMM d, yyyy",
4366
+ full: "EEEE, MMMM d, yyyy"
4367
+ };
4368
+ var TIME_STYLES = {
4369
+ short: "h:mm\u202Fa",
4370
+ medium: "h:mm:ss\u202Fa",
4371
+ long: "h:mm:ss\u202Fa z",
4372
+ full: "h:mm:ss\u202Fa z"
4373
+ };
4374
+ function number(value, pattern) {
4375
+ return typeof value === "number" ? formatNumber(value, pattern, "halfEvenExact") : String(value);
4376
+ }
4377
+ function choice(value, spec) {
4378
+ const options = spec.split("|").map((part) => {
4379
+ const m = /^\s*(-?[\d.]+|-?∞)\s*([#<≤])(.*)$/.exec(part);
4380
+ if (!m) throw new SyntaxError(`Invalid choice format "${spec}"`);
4381
+ const limit = m[1].includes("\u221E") ? m[1].startsWith("-") ? -Infinity : Infinity : Number(m[1]);
4382
+ return { limit: m[2] === "<" ? limit + Number.EPSILON * Math.max(1, Math.abs(limit)) : limit, text: m[3] };
4383
+ });
4384
+ let chosen = options[0];
4385
+ for (const o of options) if (value >= o.limit) chosen = o;
4386
+ return chosen.text;
4387
+ }
4388
+ function formatArgument(value, type, style, timezone) {
4389
+ if (value === void 0) return "";
4390
+ if (!type) return typeof value === "number" ? number(value, "#,##0.###") : String(value);
4391
+ switch (type.trim()) {
4392
+ case "number": {
4393
+ const s = style?.trim();
4394
+ if (!s) return number(value, "#,##0.###");
4395
+ if (s === "integer") return number(value, "#,##0");
4396
+ if (s === "percent") return number(value, "#,##0%");
4397
+ if (s === "currency") return number(value, "'$'#,##0.00");
4398
+ return number(value, style);
4399
+ }
4400
+ case "date":
4401
+ case "time": {
4402
+ const styles = type.trim() === "date" ? DATE_STYLES : TIME_STYLES;
4403
+ const s = style?.trim() ?? "medium";
4404
+ return formatDate(Number(value), styles[s] ?? style, typeof timezone === "function" ? timezone() : timezone);
4405
+ }
4406
+ case "choice":
4407
+ return choice(Number(value), style ?? "");
4408
+ default:
4409
+ throw new SyntaxError(`Unknown format type "${type}"`);
4410
+ }
4411
+ }
4412
+ function formatMessage(pattern, args, timezone) {
4413
+ let out = "";
4414
+ for (let i = 0; i < pattern.length; ) {
4415
+ const ch = pattern[i];
4416
+ if (ch === "'") {
4417
+ if (pattern[i + 1] === "'") {
4418
+ out += "'";
4419
+ i += 2;
4420
+ continue;
4421
+ }
4422
+ const end = pattern.indexOf("'", i + 1);
4423
+ out += pattern.slice(i + 1, end === -1 ? void 0 : end);
4424
+ i = end === -1 ? pattern.length : end + 1;
4425
+ continue;
4426
+ }
4427
+ if (ch !== "{") {
4428
+ out += ch;
4429
+ i++;
4430
+ continue;
4431
+ }
4432
+ let depth = 1;
4433
+ let j = i + 1;
4434
+ let inQuote = false;
4435
+ for (; j < pattern.length && depth > 0; j++) {
4436
+ const c = pattern[j];
4437
+ if (c === "'") inQuote = !inQuote;
4438
+ else if (!inQuote && c === "{") depth++;
4439
+ else if (!inQuote && c === "}") depth--;
4440
+ }
4441
+ const inner = pattern.slice(i + 1, j - 1);
4442
+ const [index = "", type, ...rest] = inner.split(",");
4443
+ const style = rest.length ? rest.join(",") : void 0;
4444
+ const n = Number(index.trim());
4445
+ out += n < args.length ? formatArgument(args[n], type, style, timezone) : `{${inner}}`;
4446
+ i = j;
4447
+ }
4448
+ return out;
4449
+ }
4450
+
4451
+ // src/str/index.ts
4452
+ function length(str2) {
4453
+ return str2.length;
4454
+ }
4455
+ function tostring(value, format2) {
4456
+ if (typeof value !== "number") return String(value);
4457
+ if (!Number.isFinite(value)) return String(value);
4458
+ if (format2 === void 0 || format2 === "") {
4459
+ if (Math.abs(value) >= 1e21 && Number.isFinite(value)) {
4460
+ return String(value).replace("e+", "E").replace(/\.0+E/, "E");
4461
+ }
4462
+ return formatNumber(value, "#.##########", "halfUpShortest");
4463
+ }
4464
+ switch (format2) {
4465
+ case "percent":
4466
+ return formatNumber(value, "0.00", "halfUpShortest") + "%";
4467
+ case "volume": {
4468
+ const abs2 = Math.abs(value);
4469
+ for (const [size, unit] of [[1e12, "T"], [1e9, "B"], [1e6, "M"], [1e3, "K"]]) {
4470
+ if (abs2 >= size) return formatNumber(value / size, "#.###", "halfUpShortest") + unit;
4471
+ }
4472
+ return formatNumber(value, "#", "halfUpShortest");
4473
+ }
4474
+ case "mintick":
4475
+ throw new Error("str.tostring(x, format.mintick) needs the symbol tick size (syminfo.mintick), which is not known here");
4476
+ default:
4477
+ return formatNumber(value, format2, "halfUpShortest");
4478
+ }
4479
+ }
4480
+ function tonumber(str2) {
4481
+ const num = parseFloat(str2);
4482
+ return isNaN(num) ? null : num;
4483
+ }
4484
+ function substring(str2, begin, end) {
4485
+ return str2.substring(begin, end);
4486
+ }
4487
+ function upper(str2) {
4488
+ return str2.toUpperCase();
4489
+ }
4490
+ function lower(str2) {
4491
+ return str2.toLowerCase();
4492
+ }
4493
+ function contains(source, str2) {
4494
+ return source.includes(str2);
4495
+ }
4496
+ function pos(source, str2) {
4497
+ return source.indexOf(str2);
4498
+ }
4499
+ function replace(source, target, replacement, occurrence) {
4500
+ if (occurrence === 0) {
4501
+ return source.replace(target, replacement);
4502
+ } else {
4503
+ return source.replaceAll(target, replacement);
4504
+ }
4505
+ }
4506
+ function replace_all(source, target, replacement) {
4507
+ return source.replaceAll(target, replacement);
4508
+ }
4509
+ function split(str2, separator) {
4510
+ return str2.split(separator);
4511
+ }
4512
+ function concat(...strings) {
4513
+ return strings.join("");
4514
+ }
4515
+ function format(formatStr, ...args) {
4516
+ return formatMessage(formatStr, args, "Etc/UTC");
4517
+ }
4518
+ function startswith(source, str2) {
4519
+ return source.startsWith(str2);
4520
+ }
4521
+ function endswith(source, str2) {
4522
+ return source.endsWith(str2);
4523
+ }
4524
+ function charAt(str2, pos2) {
4525
+ return str2.charAt(pos2);
4526
+ }
4527
+ function trim(str2) {
4528
+ return str2.trim();
4529
+ }
4530
+ function trimLeft(str2) {
4531
+ return str2.trimStart();
4532
+ }
4533
+ function trimRight(str2) {
4534
+ return str2.trimEnd();
4535
+ }
4536
+ function match(source, regex) {
4537
+ return new RegExp(regex).test(source);
4538
+ }
4539
+ function repeat(source, count, separator = "") {
4540
+ if (source == null) return null;
4541
+ if (count <= 0) return "";
4542
+ return Array(count).fill(source).join(separator);
4543
+ }
4544
+ function format_time(time2, format2 = "yyyy-MM-dd'T'HH:mm:ssZ", timezone = "Etc/UTC") {
4545
+ return formatDate(time2, format2, timezone);
4546
+ }
4547
+
4548
+ // src/session/calendar.ts
4549
+ var toDateNum = (y, m, d) => y * 1e4 + m * 100 + d;
4550
+ var utcOf = (date) => Date.UTC(Math.floor(date / 1e4), Math.floor(date / 100) % 100 - 1, date % 100);
4551
+ var fromUtc = (ms) => {
4552
+ const d = new Date(ms);
4553
+ return toDateNum(d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate());
4554
+ };
4555
+ var addDays = (date, n) => fromUtc(utcOf(date) + n * 864e5);
4556
+ var weekdayOf = (date) => new Date(utcOf(date)).getUTCDay() + 1;
4557
+ var dateUtcMs = utcOf;
4558
+ function parseTime(token, spec) {
4559
+ const m = /^(\d{2})(\d{2})(?:F(\d+))?$/.exec(token.trim());
4560
+ if (!m) throw new SyntaxError(`Invalid session "${spec}"`);
4561
+ return { minutes: Number(m[1]) * 60 + Number(m[2]), offset: m[3] === void 0 ? void 0 : Number(m[3]) };
4562
+ }
4563
+ function parsePeriods(text2, spec) {
4564
+ if (text2.trim() === "24x7") return [{ start: 0, end: 1440, startOffset: 0, endOffset: 0 }];
4565
+ return text2.split(",").map((p) => {
4566
+ const [a = "", b2 = ""] = p.split("-");
4567
+ const s = parseTime(a, spec);
4568
+ const e2 = parseTime(b2, spec);
4569
+ if (s.minutes === 0 && e2.minutes === 0 && s.offset === void 0 && e2.offset === void 0) {
4570
+ return { start: 0, end: 1440, startOffset: 0, endOffset: 0 };
4571
+ }
4572
+ return {
4573
+ start: s.minutes,
4574
+ end: e2.minutes,
4575
+ startOffset: s.offset ?? (e2.minutes <= s.minutes ? 1 : 0),
4576
+ endOffset: e2.offset ?? 0
4577
+ };
4578
+ });
4579
+ }
4580
+ function parseVersion(text2, from, spec, rule) {
4581
+ const [periodText = "", dayText] = text2.trim().split(":");
4582
+ const periods = parsePeriods(periodText, spec);
4583
+ const allDays = periodText.trim() === "24x7" || rule === "pine" && periods.length === 1;
4584
+ const digits = dayText ?? (allDays ? "1234567" : "23456");
4585
+ if (!/^[1-7]+$/.test(digits)) throw new SyntaxError(`Invalid session days in "${spec}"`);
4586
+ const days = new Array(8).fill(false);
4587
+ for (const d of digits) days[Number(d)] = true;
4588
+ return { from, periods, days };
4589
+ }
4590
+ var TradingCalendar = class {
4591
+ /**
4592
+ * @param timezone - Time zone of the session hours (the exchange time zone)
4593
+ * @param spec - Session information (TradingView format)
4594
+ * @param rule - Days without ":days": 'symbol' (Monday to Friday) or 'pine' (PineScript session strings)
4595
+ */
4596
+ constructor(timezone, spec, rule = "symbol") {
4597
+ this.timezone = timezone;
4598
+ const [first = "", ...changes] = spec.session.split("#");
4599
+ this.versions = [parseVersion(first, 0, spec.session, rule)];
4600
+ for (const change3 of changes) {
4601
+ const m = /^(\d{8})\/(.+)$/.exec(change3.trim());
4602
+ if (!m) throw new SyntaxError(`Invalid session change in "${spec.session}"`);
4603
+ this.versions.push(parseVersion(m[2], Number(m[1]), spec.session, rule));
4604
+ }
4605
+ for (const part of (spec.corrections ?? "").split(";").filter((p) => p.trim())) {
4606
+ const i = part.lastIndexOf(":");
4607
+ const text2 = part.slice(0, i).trim();
4608
+ const periods = text2 === "dayoff" ? null : parsePeriods(text2, part);
4609
+ for (const date of part.slice(i + 1).split(",")) this.corrections.set(Number(date), periods);
4610
+ }
4611
+ const holidays = Array.isArray(spec.holidays) ? spec.holidays : (spec.holidays ?? "").split(",");
4612
+ this.holidays = new Set(holidays.filter((h) => h.trim()).map(Number));
4613
+ }
4614
+ timezone;
4615
+ versions;
4616
+ corrections = /* @__PURE__ */ new Map();
4617
+ holidays;
4618
+ cache = /* @__PURE__ */ new Map();
4619
+ /** Session periods [start, end) of the trading day `date`; empty when the day has no session. */
4620
+ periods(date) {
4621
+ let out = this.cache.get(date);
4622
+ if (out) return out;
4623
+ let periods = [];
4624
+ const correction = this.corrections.get(date);
4625
+ if (correction !== void 0) {
4626
+ periods = correction ?? [];
4627
+ } else if (!this.holidays.has(date)) {
4628
+ const version = [...this.versions].reverse().find((v) => v.from <= date);
4629
+ if (version.days[weekdayOf(date)]) periods = version.periods;
4630
+ }
4631
+ const y = Math.floor(date / 1e4);
4632
+ const m = Math.floor(date / 100) % 100;
4633
+ const d = date % 100;
4634
+ out = periods.map((p) => [
4635
+ zonedToUnix(this.timezone, y, m, d - p.startOffset, Math.floor(p.start / 60), p.start % 60),
4636
+ zonedToUnix(this.timezone, y, m, d - p.endOffset, Math.floor(p.end / 60), p.end % 60)
4637
+ ]);
4638
+ this.cache.set(date, out);
4639
+ return out;
4640
+ }
4641
+ isTradingDay(date) {
4642
+ return this.periods(date).length > 0;
4643
+ }
4644
+ /**
4645
+ * Trading day and period of a time: the period that contains it, else the last period that started
4646
+ * before it. Null when no trading day is found near the time.
4647
+ */
4648
+ locate(time2) {
4649
+ const f = zonedFields(time2, this.timezone);
4650
+ const local = toDateNum(f.year, f.month, f.day);
4651
+ for (let k = 0; k <= 5; k++) {
4652
+ const date = addDays(local, k);
4653
+ const index = this.periods(date).findIndex(([s, e2]) => s <= time2 && time2 < e2);
4654
+ if (index !== -1) return { date, index, inside: true };
4655
+ }
4656
+ for (let k = 5; k >= -7; k--) {
4657
+ const date = addDays(local, k);
4658
+ const periods = this.periods(date);
4659
+ let index = -1;
4660
+ periods.forEach(([s], i) => {
4661
+ if (s <= time2) index = i;
4662
+ });
4663
+ if (index !== -1) return { date, index, inside: false };
4664
+ }
4665
+ return null;
4666
+ }
4667
+ /** First trading day in [from, to] (dates), or null. */
4668
+ firstTradingDay(from, to) {
4669
+ for (let date = from; date <= to; date = addDays(date, 1)) if (this.isTradingDay(date)) return date;
4670
+ return null;
4671
+ }
4672
+ /** Last trading day in [from, to] (dates), or null. */
4673
+ lastTradingDay(from, to) {
4674
+ for (let date = to; date >= from; date = addDays(date, -1)) if (this.isTradingDay(date)) return date;
4675
+ return null;
4676
+ }
4677
+ };
4678
+ var weekStart = (date) => addDays(date, -((weekdayOf(date) + 5) % 7));
4679
+ var monthStart = (date) => Math.floor(date / 100) * 100 + 1;
4680
+ var monthEnd = (date) => addDays(monthStart(addDays(monthStart(date), 32)), -1);
4681
+
4682
+ // src/session/bars.ts
4683
+ function unitOf(tf) {
4684
+ return { unit: tf.isdaily ? "D" : tf.isweekly ? "W" : "M", n: tf.multiplier };
4685
+ }
4686
+ var yearOf = (date) => Math.floor(date / 1e4);
4687
+ var firstMonday = (year3) => {
4688
+ const jan1 = year3 * 1e4 + 101;
4689
+ const monday = weekStart(jan1);
4690
+ return monday === jan1 ? jan1 : addDays(monday, 7);
4691
+ };
4692
+ var SessionBars = class {
4693
+ constructor(calendar2, chartTimeframe2) {
4694
+ this.calendar = calendar2;
4695
+ this.chart = info(chartTimeframe2);
4696
+ }
4697
+ calendar;
4698
+ chart;
4699
+ yearDays = /* @__PURE__ */ new Map();
4700
+ /** Trading days of a calendar year, in order. */
4701
+ tradingDaysOf(year3) {
4702
+ let days = this.yearDays.get(year3);
4703
+ if (!days) {
4704
+ days = [];
4705
+ for (let date = year3 * 1e4 + 101; yearOf(date) === year3; date = addDays(date, 1)) {
4706
+ if (this.calendar.isTradingDay(date)) days.push(date);
4707
+ }
4708
+ this.yearDays.set(year3, days);
4709
+ }
4710
+ return days;
4711
+ }
4712
+ /**
4713
+ * Dates [from, to] of the `n`-`unit` period that contains `date` (for "D": its first and last trading days).
4714
+ * Periods restart each calendar year.
4715
+ */
4716
+ periodRange(date, unit, n) {
4717
+ if (unit === "D") {
4718
+ if (n === 1) return [date, date];
4719
+ const days = this.tradingDaysOf(yearOf(date));
4720
+ let k = days.findIndex((d) => d >= date);
4721
+ if (k === -1) return this.periodRange(yearOf(date) * 1e4 + 1e4 + 101, unit, n);
4722
+ k -= k % n;
4723
+ return [days[k], days[Math.min(k + n, days.length) - 1]];
4724
+ }
4725
+ if (unit === "W") {
4726
+ const monday = weekStart(date);
4727
+ const year4 = yearOf(monday);
4728
+ const first = firstMonday(year4);
4729
+ const next = firstMonday(year4 + 1);
4730
+ const k = Math.round((dateUtcMs(monday) - dateUtcMs(first)) / (7 * 864e5));
4731
+ const from = addDays(first, (k - k % n) * 7);
4732
+ const to = addDays(from, n * 7 - 1);
4733
+ return [from, to < next ? to : addDays(next, -1)];
4734
+ }
4735
+ const year3 = yearOf(date);
4736
+ const month3 = Math.floor(date / 100) % 100;
4737
+ const firstMonth = month3 - (month3 - 1) % n;
4738
+ const lastMonth = Math.min(firstMonth + n - 1, 12);
4739
+ return [monthStart(year3 * 1e4 + firstMonth * 100 + 1), monthEnd(year3 * 1e4 + lastMonth * 100 + 1)];
4740
+ }
4741
+ dayStart(date) {
4742
+ return this.calendar.periods(date)[0][0];
4743
+ }
4744
+ dayEnd(date) {
4745
+ const p = this.calendar.periods(date);
4746
+ return p[p.length - 1][1];
4747
+ }
4748
+ /** PineScript `time(tf)` for a bar that opens at `time`; NaN when no trading day is found. */
4749
+ timeOf(time2, timeframe2) {
4750
+ const tf = info(timeframe2);
4751
+ const at = this.calendar.locate(time2);
4752
+ if (!at) return NaN;
4753
+ if (tf.isintraday) {
4754
+ if (this.chart.isdwm) return time2;
4755
+ const [start] = this.calendar.periods(at.date)[at.index];
4756
+ const ms = in_seconds(tf.period) * 1e3;
4757
+ return start + Math.floor((time2 - start) / ms) * ms;
4758
+ }
4759
+ const { unit, n } = unitOf(tf);
4760
+ const [from, to] = this.periodRange(at.date, unit, n);
4761
+ const first = this.calendar.firstTradingDay(from, to);
4762
+ return first === null ? NaN : this.dayStart(first);
4763
+ }
4764
+ /** PineScript `time_close(tf)` for a bar that opens at `time`. */
4765
+ closeOf(time2, timeframe2) {
4766
+ const tf = info(timeframe2);
4767
+ const at = this.calendar.locate(time2);
4768
+ if (!at) return NaN;
4769
+ if (tf.isintraday) {
4770
+ const [, end] = this.calendar.periods(at.date)[at.index];
4771
+ if (this.chart.isdwm) return end;
4772
+ return Math.min(this.timeOf(time2, timeframe2) + in_seconds(tf.period) * 1e3, end);
4773
+ }
4774
+ const { unit, n } = unitOf(tf);
4775
+ const [from, to] = this.periodRange(at.date, unit, n);
4776
+ if (this.chart.isintraday && (unit !== "D" || n > 1)) {
4777
+ const [nextFrom, nextTo] = this.periodRange(addDays(to, 1), unit, n);
4778
+ const first = this.calendar.firstTradingDay(nextFrom, addDays(nextTo, 31));
4779
+ return first === null ? NaN : this.dayStart(first);
4780
+ }
4781
+ const last = this.calendar.lastTradingDay(from, to);
4782
+ return last === null ? NaN : this.dayEnd(last);
4783
+ }
4784
+ /** Trading day of a bar: on D / W / M charts the last trading day of the chart period. */
4785
+ tradingDay(time2) {
4786
+ const at = this.calendar.locate(time2);
4787
+ if (!at) return null;
4788
+ if (this.chart.isdwm) {
4789
+ const { unit, n } = unitOf(this.chart);
4790
+ const [from, to] = this.periodRange(at.date, unit, n);
4791
+ return this.calendar.lastTradingDay(from, to);
4792
+ }
4793
+ return at.date;
4794
+ }
4795
+ /**
4796
+ * End of the `timeframe` period that contains `time`: the intraday close, the session end of the day,
4797
+ * or the session end of the last trading day of the period. Used to know whether the last loaded
4798
+ * bar completes a higher-timeframe period (request.security).
4799
+ */
4800
+ periodEnd(time2, timeframe2) {
4801
+ const tf = info(timeframe2);
4802
+ const at = this.calendar.locate(time2);
4803
+ if (!at) return NaN;
4804
+ if (tf.isintraday) {
4805
+ const [, end] = this.calendar.periods(at.date)[at.index];
4806
+ return Math.min(this.timeOf(time2, timeframe2) + in_seconds(tf.period) * 1e3, end);
4807
+ }
4808
+ const { unit, n } = unitOf(tf);
4809
+ const [from, to] = this.periodRange(at.date, unit, n);
4810
+ const last = this.calendar.lastTradingDay(from, to);
4811
+ return last === null ? NaN : this.dayEnd(last);
4812
+ }
4813
+ /** PineScript `time_tradingday`: 00:00 UTC of the trading day. */
4814
+ tradingDayTime(time2) {
4815
+ const day = this.tradingDay(time2);
4816
+ return day === null ? NaN : dateUtcMs(day);
4817
+ }
4818
+ /** True when the bar at `time` is inside the session. */
4819
+ inside(time2) {
4820
+ return this.calendar.locate(time2)?.inside ?? false;
4821
+ }
4822
+ /** Session start and end of the trading day of `time`, or null. */
4823
+ dayBounds(time2) {
4824
+ const at = this.calendar.locate(time2);
4825
+ return at ? { date: at.date, start: this.dayStart(at.date), end: this.dayEnd(at.date) } : null;
4826
+ }
4827
+ };
4828
+ function sessionFlags(times, bars2, regular) {
4829
+ const n = times.length;
4830
+ const flag2 = () => new Array(n).fill(false);
4831
+ const out = {
4832
+ isfirstbar: flag2(),
4833
+ islastbar: flag2(),
4834
+ ismarket: flag2(),
4835
+ ispremarket: flag2(),
4836
+ ispostmarket: flag2(),
4837
+ isfirstbar_regular: flag2(),
4838
+ islastbar_regular: flag2()
4839
+ };
4840
+ const chart2 = bars2.chart;
4841
+ let previousPeriod = "";
4842
+ let previousRegular = "";
4843
+ for (let i = 0; i < n; i++) {
4844
+ const t2 = times[i];
4845
+ if (chart2.isdwm) {
4846
+ for (const k of ["isfirstbar", "islastbar", "ismarket", "isfirstbar_regular", "islastbar_regular"]) out[k][i] = true;
4847
+ continue;
4848
+ }
4849
+ const at = bars2.calendar.locate(t2);
4850
+ if (!at) {
4851
+ previousPeriod = previousRegular = "";
4852
+ continue;
4853
+ }
4854
+ const close2 = bars2.closeOf(t2, chart2.period);
4855
+ const [, end] = bars2.calendar.periods(at.date)[at.index];
4856
+ const period = `${at.date}/${at.index}`;
4857
+ out.isfirstbar[i] = period !== previousPeriod;
4858
+ out.islastbar[i] = close2 >= end;
4859
+ const regularPeriods = regular.calendar.periods(at.date);
4860
+ const r2 = regularPeriods.findIndex(([s, e2]) => s <= t2 && t2 < e2);
4861
+ const market = r2 !== -1;
4862
+ out.ismarket[i] = market;
4863
+ if (!market && regularPeriods.length) {
4864
+ out.ispremarket[i] = t2 < regularPeriods[0][0];
4865
+ out.ispostmarket[i] = t2 >= regularPeriods[regularPeriods.length - 1][1];
4866
+ }
4867
+ const regularPeriod = market ? `${at.date}/${r2}` : "";
4868
+ out.isfirstbar_regular[i] = market && regularPeriod !== previousRegular;
4869
+ out.islastbar_regular[i] = market && close2 >= regularPeriods[r2][1];
4870
+ previousPeriod = period;
4871
+ previousRegular = regularPeriod;
4872
+ }
4873
+ return out;
4874
+ }
4875
+
4876
+ // src/security/resample.ts
4877
+ function resample(bars2, periodStart) {
4878
+ const out = [];
4879
+ const group2 = [];
4880
+ bars2.forEach((b2, i) => {
4881
+ const start = periodStart[i];
4882
+ const last = out[out.length - 1];
4883
+ if (!last || last.time !== start) {
4884
+ out.push({ time: start, open: b2.open, high: b2.high, low: b2.low, close: b2.close, volume: b2.volume ?? NaN });
4885
+ } else {
4886
+ last.high = Math.max(last.high, b2.high);
4887
+ last.low = Math.min(last.low, b2.low);
4888
+ last.close = b2.close;
4889
+ last.volume = (last.volume ?? 0) + (b2.volume ?? NaN);
4890
+ }
4891
+ group2.push(out.length - 1);
4892
+ });
4893
+ return { bars: out, group: group2 };
4894
+ }
4895
+ function periodsOf(starts, dayPeriods, reaches) {
4896
+ const n = starts.length;
4897
+ const group2 = [];
4898
+ starts.forEach((s, i) => group2.push(i === 0 ? 0 : group2[i - 1] + (s !== starts[i - 1] ? 1 : 0)));
4899
+ const latest = [];
4900
+ starts.forEach((s, i) => {
4901
+ let done = i === 0 ? -1 : latest[i - 1];
4902
+ if (i > 0 && group2[i] !== group2[i - 1]) done = Math.max(done, group2[i] - 1);
4903
+ const ends = i < n - 1 ? starts[i + 1] !== s || dayPeriods[i + 1] !== dayPeriods[i] : true;
4904
+ if (ends && reaches[i]) done = Math.max(done, group2[i]);
4905
+ latest.push(done);
4906
+ });
4907
+ return { group: group2, latest };
4908
+ }
4909
+ function mapToChart(values, group2, latest, lookahead, gaps) {
4910
+ return group2.map((g2, i) => {
4911
+ if (lookahead) {
4912
+ const first = i === 0 || group2[i - 1] !== g2;
4913
+ return gaps && !first ? NaN : values[g2] ?? NaN;
4914
+ }
4915
+ const done = latest[i];
4916
+ if (done < 0 || gaps && i > 0 && latest[i - 1] === done) return NaN;
4917
+ return values[done] ?? NaN;
4918
+ });
4919
+ }
4920
+ function heikinAshi(bars2) {
4921
+ const out = [];
4922
+ bars2.forEach((b2, i) => {
4923
+ const close2 = (b2.open + b2.high + b2.low + b2.close) / 4;
4924
+ const prev = out[i - 1];
4925
+ const open2 = prev ? (prev.open + prev.close) / 2 : (b2.open + b2.close) / 2;
4926
+ out.push({ time: b2.time, open: open2, high: Math.max(b2.high, open2, close2), low: Math.min(b2.low, open2, close2), close: close2, volume: b2.volume });
4927
+ });
4928
+ return out;
4929
+ }
4930
+
4931
+ // src/math/index.ts
4932
+ var math_exports = {};
4933
+ __export(math_exports, {
4934
+ abs: () => abs,
4935
+ acos: () => acos,
4936
+ asin: () => asin,
4937
+ atan: () => atan,
4938
+ avg: () => avg,
4939
+ ceil: () => ceil,
4940
+ cos: () => cos,
4941
+ e: () => e,
4942
+ exp: () => exp,
4943
+ floor: () => floor,
4944
+ log: () => log,
4945
+ log10: () => log10,
4946
+ max: () => max3,
4947
+ min: () => min3,
4948
+ phi: () => phi,
4949
+ pi: () => pi,
4950
+ pow: () => pow,
4951
+ random: () => random,
4952
+ round: () => round,
4953
+ round_to_mintick: () => round_to_mintick,
4954
+ rphi: () => rphi,
4955
+ sign: () => sign,
4956
+ sin: () => sin,
4957
+ sqrt: () => sqrt,
4958
+ sum: () => sum,
4959
+ tan: () => tan,
4960
+ todegrees: () => todegrees,
4961
+ toradians: () => toradians
4962
+ });
4963
+ function abs(value) {
4964
+ if (value instanceof Series) {
4965
+ const bars2 = value.bars;
4966
+ const valueArray = value.toArray();
4967
+ const length2 = bars2.length;
4968
+ const result = [];
4969
+ for (let i = 0; i < length2; i++) {
4970
+ const v = valueArray[i] ?? NaN;
4971
+ result.push(Math.abs(v));
4972
+ }
4973
+ return Series.fromArray(bars2, result);
4974
+ }
4975
+ return Math.abs(value);
4976
+ }
4977
+ function ceil(value) {
4978
+ if (value instanceof Series) {
2917
4979
  const bars2 = value.bars;
2918
4980
  const valueArray = value.toArray();
2919
- const length = bars2.length;
4981
+ const length2 = bars2.length;
2920
4982
  const result = [];
2921
- for (let i = 0; i < length; i++) {
4983
+ for (let i = 0; i < length2; i++) {
4984
+ const v = valueArray[i] ?? NaN;
4985
+ result.push(Math.ceil(v));
4986
+ }
4987
+ return Series.fromArray(bars2, result);
4988
+ }
4989
+ return Math.ceil(value);
4990
+ }
4991
+ function floor(value) {
4992
+ if (value instanceof Series) {
4993
+ const bars2 = value.bars;
4994
+ const valueArray = value.toArray();
4995
+ const length2 = bars2.length;
4996
+ const result = [];
4997
+ for (let i = 0; i < length2; i++) {
2922
4998
  const v = valueArray[i] ?? NaN;
2923
4999
  result.push(Math.floor(v));
2924
5000
  }
@@ -2930,16 +5006,16 @@ function round(value, precision) {
2930
5006
  if (value instanceof Series) {
2931
5007
  const bars2 = value.bars;
2932
5008
  const valueArray = value.toArray();
2933
- const length = bars2.length;
5009
+ const length2 = bars2.length;
2934
5010
  const result = [];
2935
5011
  if (precision === void 0) {
2936
- for (let i = 0; i < length; i++) {
5012
+ for (let i = 0; i < length2; i++) {
2937
5013
  const v = valueArray[i] ?? NaN;
2938
5014
  result.push(Math.round(v));
2939
5015
  }
2940
5016
  } else {
2941
5017
  const multiplier2 = Math.pow(10, precision);
2942
- for (let i = 0; i < length; i++) {
5018
+ for (let i = 0; i < length2; i++) {
2943
5019
  const v = valueArray[i] ?? NaN;
2944
5020
  result.push(Math.round(v * multiplier2) / multiplier2);
2945
5021
  }
@@ -2959,12 +5035,12 @@ function max3(...values) {
2959
5035
  }
2960
5036
  const firstSeries = values.find((v) => v instanceof Series);
2961
5037
  const bars2 = firstSeries.bars;
2962
- const length = bars2.length;
5038
+ const length2 = bars2.length;
2963
5039
  const valueArrays = values.map(
2964
5040
  (v) => v instanceof Series ? v.toArray() : null
2965
5041
  );
2966
5042
  const result = [];
2967
- for (let i = 0; i < length; i++) {
5043
+ for (let i = 0; i < length2; i++) {
2968
5044
  const nums = values.map(
2969
5045
  (v, idx) => valueArrays[idx] ? valueArrays[idx][i] ?? NaN : v
2970
5046
  );
@@ -2979,12 +5055,12 @@ function min3(...values) {
2979
5055
  }
2980
5056
  const firstSeries = values.find((v) => v instanceof Series);
2981
5057
  const bars2 = firstSeries.bars;
2982
- const length = bars2.length;
5058
+ const length2 = bars2.length;
2983
5059
  const valueArrays = values.map(
2984
5060
  (v) => v instanceof Series ? v.toArray() : null
2985
5061
  );
2986
5062
  const result = [];
2987
- for (let i = 0; i < length; i++) {
5063
+ for (let i = 0; i < length2; i++) {
2988
5064
  const nums = values.map(
2989
5065
  (v, idx) => valueArrays[idx] ? valueArrays[idx][i] ?? NaN : v
2990
5066
  );
@@ -2999,12 +5075,12 @@ function avg(...values) {
2999
5075
  }
3000
5076
  const firstSeries = values.find((v) => v instanceof Series);
3001
5077
  const bars2 = firstSeries.bars;
3002
- const length = bars2.length;
5078
+ const length2 = bars2.length;
3003
5079
  const valueArrays = values.map(
3004
5080
  (v) => v instanceof Series ? v.toArray() : null
3005
5081
  );
3006
5082
  const result = [];
3007
- for (let i = 0; i < length; i++) {
5083
+ for (let i = 0; i < length2; i++) {
3008
5084
  const nums = values.map(
3009
5085
  (v, idx) => valueArrays[idx] ? valueArrays[idx][i] ?? NaN : v
3010
5086
  );
@@ -3013,15 +5089,15 @@ function avg(...values) {
3013
5089
  }
3014
5090
  return Series.fromArray(bars2, result);
3015
5091
  }
3016
- function sum(source, length) {
5092
+ function sum(source, length2) {
3017
5093
  const sourceArray = source instanceof Series ? source.toArray() : source;
3018
5094
  const result = [];
3019
5095
  for (let i = 0; i < sourceArray.length; i++) {
3020
- if (i < length - 1) {
5096
+ if (i < length2 - 1) {
3021
5097
  result.push(NaN);
3022
5098
  } else {
3023
5099
  let total = 0;
3024
- for (let j = 0; j < length; j++) {
5100
+ for (let j = 0; j < length2; j++) {
3025
5101
  total += sourceArray[i - j];
3026
5102
  }
3027
5103
  result.push(total);
@@ -3036,9 +5112,9 @@ function sqrt(value) {
3036
5112
  if (value instanceof Series) {
3037
5113
  const bars2 = value.bars;
3038
5114
  const valueArray = value.toArray();
3039
- const length = bars2.length;
5115
+ const length2 = bars2.length;
3040
5116
  const result = [];
3041
- for (let i = 0; i < length; i++) {
5117
+ for (let i = 0; i < length2; i++) {
3042
5118
  const v = valueArray[i] ?? NaN;
3043
5119
  result.push(Math.sqrt(v));
3044
5120
  }
@@ -3055,9 +5131,9 @@ function pow(base, exponent) {
3055
5131
  const bars2 = baseIsSeries ? base.bars : exponent.bars;
3056
5132
  const baseArray = baseIsSeries ? base.toArray() : null;
3057
5133
  const expArray = expIsSeries ? exponent.toArray() : null;
3058
- const length = bars2.length;
5134
+ const length2 = bars2.length;
3059
5135
  const result = [];
3060
- for (let i = 0; i < length; i++) {
5136
+ for (let i = 0; i < length2; i++) {
3061
5137
  const b2 = baseArray ? baseArray[i] ?? NaN : base;
3062
5138
  const e2 = expArray ? expArray[i] ?? NaN : exponent;
3063
5139
  result.push(Math.pow(b2, e2));
@@ -3068,9 +5144,9 @@ function exp(value) {
3068
5144
  if (value instanceof Series) {
3069
5145
  const bars2 = value.bars;
3070
5146
  const valueArray = value.toArray();
3071
- const length = bars2.length;
5147
+ const length2 = bars2.length;
3072
5148
  const result = [];
3073
- for (let i = 0; i < length; i++) {
5149
+ for (let i = 0; i < length2; i++) {
3074
5150
  const v = valueArray[i] ?? NaN;
3075
5151
  result.push(Math.exp(v));
3076
5152
  }
@@ -3082,9 +5158,9 @@ function log(value) {
3082
5158
  if (value instanceof Series) {
3083
5159
  const bars2 = value.bars;
3084
5160
  const valueArray = value.toArray();
3085
- const length = bars2.length;
5161
+ const length2 = bars2.length;
3086
5162
  const result = [];
3087
- for (let i = 0; i < length; i++) {
5163
+ for (let i = 0; i < length2; i++) {
3088
5164
  const v = valueArray[i] ?? NaN;
3089
5165
  result.push(Math.log(v));
3090
5166
  }
@@ -3096,9 +5172,9 @@ function log10(value) {
3096
5172
  if (value instanceof Series) {
3097
5173
  const bars2 = value.bars;
3098
5174
  const valueArray = value.toArray();
3099
- const length = bars2.length;
5175
+ const length2 = bars2.length;
3100
5176
  const result = [];
3101
- for (let i = 0; i < length; i++) {
5177
+ for (let i = 0; i < length2; i++) {
3102
5178
  const v = valueArray[i] ?? NaN;
3103
5179
  result.push(Math.log10(v));
3104
5180
  }
@@ -3110,9 +5186,9 @@ function sin(value) {
3110
5186
  if (value instanceof Series) {
3111
5187
  const bars2 = value.bars;
3112
5188
  const valueArray = value.toArray();
3113
- const length = bars2.length;
5189
+ const length2 = bars2.length;
3114
5190
  const result = [];
3115
- for (let i = 0; i < length; i++) {
5191
+ for (let i = 0; i < length2; i++) {
3116
5192
  const v = valueArray[i] ?? NaN;
3117
5193
  result.push(Math.sin(v));
3118
5194
  }
@@ -3124,9 +5200,9 @@ function cos(value) {
3124
5200
  if (value instanceof Series) {
3125
5201
  const bars2 = value.bars;
3126
5202
  const valueArray = value.toArray();
3127
- const length = bars2.length;
5203
+ const length2 = bars2.length;
3128
5204
  const result = [];
3129
- for (let i = 0; i < length; i++) {
5205
+ for (let i = 0; i < length2; i++) {
3130
5206
  const v = valueArray[i] ?? NaN;
3131
5207
  result.push(Math.cos(v));
3132
5208
  }
@@ -3138,9 +5214,9 @@ function tan(value) {
3138
5214
  if (value instanceof Series) {
3139
5215
  const bars2 = value.bars;
3140
5216
  const valueArray = value.toArray();
3141
- const length = bars2.length;
5217
+ const length2 = bars2.length;
3142
5218
  const result = [];
3143
- for (let i = 0; i < length; i++) {
5219
+ for (let i = 0; i < length2; i++) {
3144
5220
  const v = valueArray[i] ?? NaN;
3145
5221
  result.push(Math.tan(v));
3146
5222
  }
@@ -3152,9 +5228,9 @@ function asin(value) {
3152
5228
  if (value instanceof Series) {
3153
5229
  const bars2 = value.bars;
3154
5230
  const valueArray = value.toArray();
3155
- const length = bars2.length;
5231
+ const length2 = bars2.length;
3156
5232
  const result = [];
3157
- for (let i = 0; i < length; i++) {
5233
+ for (let i = 0; i < length2; i++) {
3158
5234
  const v = valueArray[i] ?? NaN;
3159
5235
  result.push(Math.asin(v));
3160
5236
  }
@@ -3166,9 +5242,9 @@ function acos(value) {
3166
5242
  if (value instanceof Series) {
3167
5243
  const bars2 = value.bars;
3168
5244
  const valueArray = value.toArray();
3169
- const length = bars2.length;
5245
+ const length2 = bars2.length;
3170
5246
  const result = [];
3171
- for (let i = 0; i < length; i++) {
5247
+ for (let i = 0; i < length2; i++) {
3172
5248
  const v = valueArray[i] ?? NaN;
3173
5249
  result.push(Math.acos(v));
3174
5250
  }
@@ -3180,9 +5256,9 @@ function atan(value) {
3180
5256
  if (value instanceof Series) {
3181
5257
  const bars2 = value.bars;
3182
5258
  const valueArray = value.toArray();
3183
- const length = bars2.length;
5259
+ const length2 = bars2.length;
3184
5260
  const result = [];
3185
- for (let i = 0; i < length; i++) {
5261
+ for (let i = 0; i < length2; i++) {
3186
5262
  const v = valueArray[i] ?? NaN;
3187
5263
  result.push(Math.atan(v));
3188
5264
  }
@@ -3194,9 +5270,9 @@ function toradians(degrees) {
3194
5270
  if (degrees instanceof Series) {
3195
5271
  const bars2 = degrees.bars;
3196
5272
  const valueArray = degrees.toArray();
3197
- const length = bars2.length;
5273
+ const length2 = bars2.length;
3198
5274
  const result = [];
3199
- for (let i = 0; i < length; i++) {
5275
+ for (let i = 0; i < length2; i++) {
3200
5276
  const v = valueArray[i] ?? NaN;
3201
5277
  result.push(v * (Math.PI / 180));
3202
5278
  }
@@ -3208,9 +5284,9 @@ function todegrees(radians) {
3208
5284
  if (radians instanceof Series) {
3209
5285
  const bars2 = radians.bars;
3210
5286
  const valueArray = radians.toArray();
3211
- const length = bars2.length;
5287
+ const length2 = bars2.length;
3212
5288
  const result = [];
3213
- for (let i = 0; i < length; i++) {
5289
+ for (let i = 0; i < length2; i++) {
3214
5290
  const v = valueArray[i] ?? NaN;
3215
5291
  result.push(v * (180 / Math.PI));
3216
5292
  }
@@ -3229,9 +5305,9 @@ function sign(value) {
3229
5305
  if (value instanceof Series) {
3230
5306
  const bars2 = value.bars;
3231
5307
  const valueArray = value.toArray();
3232
- const length = bars2.length;
5308
+ const length2 = bars2.length;
3233
5309
  const result = [];
3234
- for (let i = 0; i < length; i++) {
5310
+ for (let i = 0; i < length2; i++) {
3235
5311
  const v = valueArray[i] ?? NaN;
3236
5312
  result.push(v > 0 ? 1 : v < 0 ? -1 : 0);
3237
5313
  }
@@ -3239,11 +5315,11 @@ function sign(value) {
3239
5315
  }
3240
5316
  return value > 0 ? 1 : value < 0 ? -1 : 0;
3241
5317
  }
3242
- function round_to_mintick(number, mintick) {
3243
- if (number instanceof Series) {
3244
- const bars2 = number.bars;
3245
- const valueArray = number.toArray();
3246
- const length = bars2.length;
5318
+ function round_to_mintick(number2, mintick) {
5319
+ if (number2 instanceof Series) {
5320
+ const bars2 = number2.bars;
5321
+ const valueArray = number2.toArray();
5322
+ const length2 = bars2.length;
3247
5323
  if (mintick === void 0) {
3248
5324
  throw new Error(
3249
5325
  "math.round_to_mintick() requires mintick value. Either pass it explicitly or use createContext({ syminfo: { mintick } }) for implicit data."
@@ -3251,11 +5327,11 @@ function round_to_mintick(number, mintick) {
3251
5327
  }
3252
5328
  const result = [];
3253
5329
  if (mintick === 0) {
3254
- for (let i = 0; i < length; i++) {
5330
+ for (let i = 0; i < length2; i++) {
3255
5331
  result.push(valueArray[i] ?? NaN);
3256
5332
  }
3257
5333
  } else {
3258
- for (let i = 0; i < length; i++) {
5334
+ for (let i = 0; i < length2; i++) {
3259
5335
  const v = valueArray[i];
3260
5336
  if (v === void 0 || isNaN(v)) {
3261
5337
  result.push(NaN);
@@ -3266,7 +5342,7 @@ function round_to_mintick(number, mintick) {
3266
5342
  }
3267
5343
  return Series.fromArray(bars2, result);
3268
5344
  }
3269
- if (isNaN(number)) {
5345
+ if (isNaN(number2)) {
3270
5346
  return NaN;
3271
5347
  }
3272
5348
  if (mintick === void 0) {
@@ -3275,9 +5351,9 @@ function round_to_mintick(number, mintick) {
3275
5351
  );
3276
5352
  }
3277
5353
  if (mintick === 0) {
3278
- return number;
5354
+ return number2;
3279
5355
  }
3280
- return Math.round(number / mintick) * mintick;
5356
+ return Math.round(number2 / mintick) * mintick;
3281
5357
  }
3282
5358
  var pi = Math.PI;
3283
5359
  var e = Math.E;
@@ -3324,9 +5400,11 @@ function slugId(title, fallback, taken) {
3324
5400
  taken.add(id);
3325
5401
  return id;
3326
5402
  }
3327
- function executeScript(body, barsInput, inputs = {}) {
5403
+ function executeScript(body, barsInput, inputs = {}, chart2 = {}) {
3328
5404
  ctxBars.setAll(barsInput);
5405
+ chartCtx = { ...chart2 };
3329
5406
  ctx = freshCollector(inputs);
5407
+ resetDrawings();
3330
5408
  try {
3331
5409
  body();
3332
5410
  const c = ctx;
@@ -3367,6 +5445,12 @@ function indicator(title, options = {}) {
3367
5445
  c.overlay = options.overlay ?? true;
3368
5446
  c.precision = options.precision;
3369
5447
  c.format = options.format;
5448
+ setDrawingLimits({
5449
+ line: options.max_lines_count,
5450
+ label: options.max_labels_count,
5451
+ box: options.max_boxes_count,
5452
+ polyline: options.max_polylines_count
5453
+ });
3370
5454
  }
3371
5455
  function registerInput(config, fallbackId) {
3372
5456
  const c = collector();
@@ -3403,6 +5487,19 @@ var input = {
3403
5487
  source(defval = "close", title) {
3404
5488
  const name = registerInput({ type: "source", defval, title }, "input_source");
3405
5489
  return sourceSeries(name);
5490
+ },
5491
+ /** Timeframe string ("60", "1D", "W"). As in PineScript, "" means the chart timeframe. */
5492
+ timeframe(defval, title, opts = {}) {
5493
+ return registerInput({ type: "timeframe", defval, title, options: opts.options }, "input_timeframe");
5494
+ },
5495
+ /** Session string ("0930-1600", "0930-1600:23456"). */
5496
+ session(defval, title, opts = {}) {
5497
+ return registerInput({ type: "session", defval, title, options: opts.options }, "input_session");
5498
+ },
5499
+ /** Date and time as a UNIX time in milliseconds, e.g. `input.time(timestamp('2024-01-01'), 'Start')`. */
5500
+ time(defval, title) {
5501
+ const v = registerInput({ type: "time", defval, title }, "input_time");
5502
+ return typeof v === "number" ? v : defval;
3406
5503
  }
3407
5504
  };
3408
5505
  var open = Series.fromBars(ctxBars, "open");
@@ -3419,18 +5516,60 @@ function sourceSeries(name) {
3419
5516
  return SOURCES[name] ?? close;
3420
5517
  }
3421
5518
  var bars = () => ctxBars.bars;
5519
+ function barsSeries(compute) {
5520
+ let version = -1;
5521
+ let values = [];
5522
+ return new Series(ctxBars, (_bar, i, data) => {
5523
+ if (version !== ctxBars.version) {
5524
+ values = compute(data).toArray();
5525
+ version = ctxBars.version;
5526
+ }
5527
+ return values[i] ?? NaN;
5528
+ });
5529
+ }
3422
5530
  var ta2 = {
3423
5531
  ...ta_series_exports,
3424
5532
  tr: (handleNa = false) => tr2(bars(), handleNa),
3425
- atr: (length) => atr2(bars(), length),
5533
+ atr: (length2) => atr2(bars(), length2),
3426
5534
  sar: (start, inc, max4) => sar2(bars(), start, inc, max4),
3427
- wpr: (length) => wpr2(bars(), length),
5535
+ wpr: (length2) => wpr2(bars(), length2),
3428
5536
  supertrend: (factor, atrLength) => supertrend2(bars(), factor, atrLength),
3429
5537
  dmi: (diLength, adxSmoothing) => dmi2(bars(), diLength, adxSmoothing),
3430
- kc: (source, length, mult, useTrueRange) => kc2(bars(), source, length, mult, useTrueRange),
3431
- kcw: (source, length, mult, useTrueRange) => kcw2(bars(), source, length, mult, useTrueRange),
3432
- ichimoku: (conversionPeriods, basePeriods, laggingSpan2Periods, displacement) => ichimoku2(bars(), conversionPeriods, basePeriods, laggingSpan2Periods, displacement)
5538
+ kc: (source, length2, mult, useTrueRange) => kc2(bars(), source, length2, mult, useTrueRange),
5539
+ kcw: (source, length2, mult, useTrueRange) => kcw2(bars(), source, length2, mult, useTrueRange),
5540
+ ichimoku: (conversionPeriods, basePeriods, laggingSpan2Periods, displacement) => ichimoku2(bars(), conversionPeriods, basePeriods, laggingSpan2Periods, displacement),
5541
+ /** `ta.highest(source, length)` or `ta.highest(length)` (source = high). */
5542
+ highest: (sourceOrLength, length2) => typeof sourceOrLength === "number" ? highest2(high, sourceOrLength) : highest2(sourceOrLength, length2),
5543
+ /** `ta.lowest(source, length)` or `ta.lowest(length)` (source = low). */
5544
+ lowest: (sourceOrLength, length2) => typeof sourceOrLength === "number" ? lowest2(low, sourceOrLength) : lowest2(sourceOrLength, length2),
5545
+ /** `ta.highestbars(source, length)` or `ta.highestbars(length)` (source = high); offsets are 0 or negative. */
5546
+ highestbars: (sourceOrLength, length2) => typeof sourceOrLength === "number" ? highestbars2(high, sourceOrLength) : highestbars2(sourceOrLength, length2),
5547
+ /** `ta.lowestbars(source, length)` or `ta.lowestbars(length)` (source = low); offsets are 0 or negative. */
5548
+ lowestbars: (sourceOrLength, length2) => typeof sourceOrLength === "number" ? lowestbars2(low, sourceOrLength) : lowestbars2(sourceOrLength, length2),
5549
+ /** `ta.vwap(source, anchor?, stdev_mult?)` with the chart volume; the default anchor is a new trading
5550
+ * day (`timeframe.change("1D")`), which needs the chart context (timeframe, time zone, session). */
5551
+ vwap: ((source, anchor, stdev_mult) => {
5552
+ const a = anchor ?? changeOf("1D");
5553
+ return stdev_mult === void 0 ? vwap2(source, volume, a) : vwapBands(source, volume, a, stdev_mult);
5554
+ }),
5555
+ /** `ta.pivothigh(source, leftbars, rightbars)` or `ta.pivothigh(leftbars, rightbars)` (source = high).
5556
+ * The value appears `rightbars` bars after the pivot bar, as in PineScript. */
5557
+ pivothigh: (sourceOrLeft, leftOrRight, rightbars) => typeof sourceOrLeft === "number" ? pivothigh2(high, sourceOrLeft, leftOrRight) : pivothigh2(sourceOrLeft, leftOrRight, rightbars),
5558
+ /** `ta.pivotlow(source, leftbars, rightbars)` or `ta.pivotlow(leftbars, rightbars)` (source = low). */
5559
+ pivotlow: (sourceOrLeft, leftOrRight, rightbars) => typeof sourceOrLeft === "number" ? pivotlow2(low, sourceOrLeft, leftOrRight) : pivotlow2(sourceOrLeft, leftOrRight, rightbars),
5560
+ // PineScript variables of the chart bars: `ta.obv`, not `ta.obv()`.
5561
+ obv: barsSeries(obv2),
5562
+ pvt: barsSeries(pvt2),
5563
+ accdist: barsSeries(accdist2),
5564
+ nvi: barsSeries(nvi2),
5565
+ pvi: barsSeries(pvi2),
5566
+ iii: barsSeries(iii2),
5567
+ wad: barsSeries(wad2),
5568
+ wvad: barsSeries(wvad2)
3433
5569
  };
5570
+ function fixnan2(source) {
5571
+ return source instanceof Series ? Series.fromArray(ctxBars, fixnan(source.toArray())) : fixnan(source);
5572
+ }
3434
5573
  function colorWhen(cond, colorTrue, colorFalse) {
3435
5574
  return cond.toArray().map((v) => !isNA(v) && v !== 0 ? colorTrue : colorFalse);
3436
5575
  }
@@ -3442,8 +5581,8 @@ var color = {
3442
5581
  function plot(series, title, options = {}) {
3443
5582
  const c = collector();
3444
5583
  const id = `plot${c.plotConfig.length}`;
3445
- const perBar = Array.isArray(options.color) ? options.color : void 0;
3446
- const staticColor = typeof options.color === "string" ? options.color : perBar?.[perBar.length - 1] ?? "#2962FF";
5584
+ const perBar2 = Array.isArray(options.color) ? options.color : void 0;
5585
+ const staticColor = typeof options.color === "string" ? options.color : perBar2?.[perBar2.length - 1] ?? "#2962FF";
3447
5586
  c.plotConfig.push({
3448
5587
  id,
3449
5588
  title: title ?? id,
@@ -3459,7 +5598,7 @@ function plot(series, title, options = {}) {
3459
5598
  for (let i = 0; i < b2.length; i++) {
3460
5599
  const value = values[i];
3461
5600
  if (value === void 0 || Number.isNaN(value)) continue;
3462
- data.push(perBar ? { time: b2[i].time, value, color: perBar[i] } : { time: b2[i].time, value });
5601
+ data.push(perBar2 ? { time: b2[i].time, value, color: perBar2[i] } : { time: b2[i].time, value });
3463
5602
  }
3464
5603
  c.plots[id] = data;
3465
5604
  return { id, kind: "plot" };
@@ -3479,7 +5618,7 @@ function hline(price, title, options = {}) {
3479
5618
  }
3480
5619
  function fill(a, b2, options = {}) {
3481
5620
  const c = collector();
3482
- const perBar = Array.isArray(options.color) ? options.color : void 0;
5621
+ const perBar2 = Array.isArray(options.color) ? options.color : void 0;
3483
5622
  const staticColor = typeof options.color === "string" ? options.color : void 0;
3484
5623
  if (a.kind === "hline" && b2.kind === "hline") {
3485
5624
  c.fillConfig.push({
@@ -3487,7 +5626,7 @@ function fill(a, b2, options = {}) {
3487
5626
  plot1: a.id,
3488
5627
  plot2: b2.id,
3489
5628
  color: staticColor,
3490
- colors: perBar,
5629
+ colors: perBar2,
3491
5630
  title: options.title
3492
5631
  });
3493
5632
  return;
@@ -3496,7 +5635,7 @@ function fill(a, b2, options = {}) {
3496
5635
  plot1: a.id,
3497
5636
  plot2: b2.id,
3498
5637
  options: { color: staticColor, title: options.title },
3499
- colors: perBar
5638
+ colors: perBar2
3500
5639
  });
3501
5640
  }
3502
5641
  function emitMarkers(kind, condition, title, options) {
@@ -3555,11 +5694,11 @@ function emitBarColors(kind, colors, options) {
3555
5694
  const off = options.offset ?? 0;
3556
5695
  const target = kind === "bgcolor" ? c.bgcolors : c.barcolors;
3557
5696
  for (let i = 0; i < b2.length; i++) {
3558
- const col = typeof colors === "string" ? colors : colors[i];
3559
- if (!col) continue;
5697
+ const col2 = typeof colors === "string" ? colors : colors[i];
5698
+ if (!col2) continue;
3560
5699
  const j = i + off;
3561
5700
  if (j < 0 || j >= b2.length) continue;
3562
- target.push({ time: b2[j].time, color: col });
5701
+ target.push({ time: b2[j].time, color: col2 });
3563
5702
  }
3564
5703
  }
3565
5704
  function bgcolor(colors, options = {}) {
@@ -3611,12 +5750,335 @@ function eachBar(fn) {
3611
5750
  return j >= 0 ? out[j] : NaN;
3612
5751
  }
3613
5752
  };
3614
- for (idx = 0; idx < b2.length; idx++) {
3615
- const r2 = fn(ctx2);
3616
- out[idx] = typeof r2 === "number" ? r2 : typeof r2 === "boolean" ? r2 ? 1 : 0 : NaN;
5753
+ try {
5754
+ for (idx = 0; idx < b2.length; idx++) {
5755
+ currentBar = idx;
5756
+ const r2 = fn(ctx2);
5757
+ out[idx] = typeof r2 === "number" ? r2 : typeof r2 === "boolean" ? r2 ? 1 : 0 : NaN;
5758
+ }
5759
+ } finally {
5760
+ currentBar = -1;
3617
5761
  }
3618
5762
  return Series.fromArray(ctxBars, out);
3619
5763
  }
5764
+ var currentBar = -1;
5765
+ var chartCtx = {};
5766
+ function chartTimeframe() {
5767
+ collector();
5768
+ if (!chartCtx.timeframe) {
5769
+ throw new Error("The chart timeframe is not known: pass it as executeScript(body, bars, inputs, { timeframe }).");
5770
+ }
5771
+ return info(chartCtx.timeframe);
5772
+ }
5773
+ function exchangeTimezone() {
5774
+ collector();
5775
+ if (!chartCtx.timezone) {
5776
+ throw new Error("The exchange time zone is not known: pass it as executeScript(body, bars, inputs, { timezone }).");
5777
+ }
5778
+ return chartCtx.timezone;
5779
+ }
5780
+ var timeframe = {
5781
+ ...timeframe_exports,
5782
+ get period() {
5783
+ return chartTimeframe().period;
5784
+ },
5785
+ get main_period() {
5786
+ return chartTimeframe().period;
5787
+ },
5788
+ get multiplier() {
5789
+ return chartTimeframe().multiplier;
5790
+ },
5791
+ get isintraday() {
5792
+ return chartTimeframe().isintraday;
5793
+ },
5794
+ get isdaily() {
5795
+ return chartTimeframe().isdaily;
5796
+ },
5797
+ get isweekly() {
5798
+ return chartTimeframe().isweekly;
5799
+ },
5800
+ get ismonthly() {
5801
+ return chartTimeframe().ismonthly;
5802
+ },
5803
+ get isminutes() {
5804
+ return chartTimeframe().isminutes;
5805
+ },
5806
+ get isseconds() {
5807
+ return chartTimeframe().isseconds;
5808
+ },
5809
+ get isticks() {
5810
+ return chartTimeframe().isticks;
5811
+ },
5812
+ get isdwm() {
5813
+ return chartTimeframe().isdwm;
5814
+ },
5815
+ /** PineScript `timeframe.change(tf)`: 1 on bars that open a new `tf` period (0 on the first bar). */
5816
+ change(tf) {
5817
+ return changeOf(tf || chartTimeframe().period);
5818
+ },
5819
+ /** Seconds in `timeframe`; without it (or with "") the chart timeframe, as in PineScript. */
5820
+ in_seconds(tf) {
5821
+ return in_seconds(tf === void 0 || tf === "" ? chartTimeframe().period : tf);
5822
+ }
5823
+ };
5824
+ var syminfo = {
5825
+ get timezone() {
5826
+ return exchangeTimezone();
5827
+ },
5828
+ get tickerid() {
5829
+ collector();
5830
+ if (!chartCtx.tickerid) {
5831
+ throw new Error("The chart symbol is not known: pass it as executeScript(body, bars, inputs, { tickerid }).");
5832
+ }
5833
+ return chartCtx.tickerid;
5834
+ },
5835
+ get session() {
5836
+ collector();
5837
+ return chartCtx.sessionType ?? "regular";
5838
+ }
5839
+ };
5840
+ function calendar(fn) {
5841
+ return ((time2, timezone) => {
5842
+ const tz = timezone ?? exchangeTimezone();
5843
+ return time2 instanceof Series ? Series.fromArray(ctxBars, time2.toArray().map((t2) => fn(t2, tz))) : fn(time2, tz);
5844
+ });
5845
+ }
5846
+ var year2 = calendar(year);
5847
+ var month2 = calendar(month);
5848
+ var weekofyear2 = calendar(weekofyear);
5849
+ var dayofmonth2 = calendar(dayofmonth);
5850
+ var dayofweek2 = calendar(dayofweek);
5851
+ var hour2 = calendar(hour);
5852
+ var minute2 = calendar(minute);
5853
+ var second2 = calendar(second);
5854
+ function timestamp2(first, ...rest) {
5855
+ if (typeof first === "number") {
5856
+ const [m2, d2, h2, mi2, s2] = rest;
5857
+ return timestamp(exchangeTimezone(), first, m2, d2, h2, mi2, s2);
5858
+ }
5859
+ if (rest.length === 0) return timestamp(first);
5860
+ const [y, m, d, h, mi, s] = rest;
5861
+ return timestamp(first, y, m, d, h, mi, s);
5862
+ }
5863
+ function inSession3(time2, session2, timezone) {
5864
+ return inSession2(time2, session2, timezone ?? exchangeTimezone());
5865
+ }
5866
+ var str = {
5867
+ ...str_exports,
5868
+ format_time(time2, format2 = "yyyy-MM-dd'T'HH:mm:ssZ", timezone) {
5869
+ return format_time(time2, format2, timezone ?? exchangeTimezone());
5870
+ },
5871
+ format(pattern, ...args) {
5872
+ return formatMessage(pattern, args, exchangeTimezone);
5873
+ }
5874
+ };
5875
+ function barTime(bar) {
5876
+ return bar.time * (chartCtx.timeUnit === "ms" ? 1 : 1e3);
5877
+ }
5878
+ var toSpec = (s) => typeof s === "string" ? { session: s } : s;
5879
+ var sessionCache = null;
5880
+ function sessionBars() {
5881
+ const tz = exchangeTimezone();
5882
+ const tf = chartTimeframe().period;
5883
+ if (!chartCtx.session) {
5884
+ throw new Error("The session is not known: pass it as executeScript(body, bars, inputs, { session }).");
5885
+ }
5886
+ if (sessionCache?.ctx !== chartCtx) {
5887
+ const loaded = toSpec(chartCtx.session);
5888
+ const regular = chartCtx.regularSession ? toSpec(chartCtx.regularSession) : loaded;
5889
+ sessionCache = {
5890
+ ctx: chartCtx,
5891
+ bars: new SessionBars(new TradingCalendar(tz, loaded), tf),
5892
+ regular: new SessionBars(new TradingCalendar(tz, { holidays: loaded.holidays, ...regular }), tf)
5893
+ };
5894
+ }
5895
+ return sessionCache;
5896
+ }
5897
+ function calendarFor(session2, timezone) {
5898
+ const { bars: bars2 } = sessionBars();
5899
+ if (!session2 && !timezone) return { bars: bars2, test: false };
5900
+ const tz = timezone ?? exchangeTimezone();
5901
+ const spec = session2 ? { session: session2 } : { session: toSpec(chartCtx.session).session };
5902
+ return { bars: new SessionBars(new TradingCalendar(tz, spec, session2 ? "pine" : "symbol"), bars2.chart.period), test: true };
5903
+ }
5904
+ function perBar(fn) {
5905
+ const times = ctxBars.bars.map(barTime);
5906
+ return Series.fromArray(ctxBars, times.map((t2, i) => fn(t2, i, times)));
5907
+ }
5908
+ function callableSeries(series, fn) {
5909
+ Object.setPrototypeOf(fn, Series.prototype);
5910
+ Object.assign(fn, series);
5911
+ return fn;
5912
+ }
5913
+ function timeFunction(tf, session2, timezone) {
5914
+ collector();
5915
+ const { bars: bars2, test } = calendarFor(session2, timezone);
5916
+ const timeframeString = tf || chartTimeframe().period;
5917
+ return perBar((t2) => test && !bars2.inside(t2) ? NaN : bars2.timeOf(t2, timeframeString));
5918
+ }
5919
+ function timeCloseFunction(tf, session2, timezone) {
5920
+ collector();
5921
+ const { bars: bars2, test } = calendarFor(session2, timezone);
5922
+ const timeframeString = tf || chartTimeframe().period;
5923
+ return perBar((t2) => test && !bars2.inside(t2) ? NaN : bars2.closeOf(t2, timeframeString));
5924
+ }
5925
+ var time = callableSeries(new Series(ctxBars, (b2) => barTime(b2)), timeFunction);
5926
+ var time_close = callableSeries(
5927
+ new Series(ctxBars, (_b, i) => sessionBars().bars.closeOf(barTime(ctxBars.bars[i]), chartTimeframe().period)),
5928
+ timeCloseFunction
5929
+ );
5930
+ var time_tradingday = new Series(ctxBars, (b2) => sessionBars().bars.tradingDayTime(barTime(b2)));
5931
+ function changeOf(tf) {
5932
+ const { bars: bars2 } = sessionBars();
5933
+ return perBar((t2, i, times) => i > 0 && bars2.timeOf(t2, tf) !== bars2.timeOf(times[i - 1], tf) ? 1 : 0);
5934
+ }
5935
+ function flag(key) {
5936
+ const { bars: bars2, regular } = sessionBars();
5937
+ const values = sessionFlags(ctxBars.bars.map(barTime), bars2, regular)[key];
5938
+ return Series.fromArray(ctxBars, values.map((v) => v ? 1 : 0));
5939
+ }
5940
+ var session = {
5941
+ regular: "regular",
5942
+ extended: "extended",
5943
+ get isfirstbar() {
5944
+ return flag("isfirstbar");
5945
+ },
5946
+ get islastbar() {
5947
+ return flag("islastbar");
5948
+ },
5949
+ get ismarket() {
5950
+ return flag("ismarket");
5951
+ },
5952
+ get ispremarket() {
5953
+ return flag("ispremarket");
5954
+ },
5955
+ get ispostmarket() {
5956
+ return flag("ispostmarket");
5957
+ },
5958
+ get isfirstbar_regular() {
5959
+ return flag("isfirstbar_regular");
5960
+ },
5961
+ get islastbar_regular() {
5962
+ return flag("islastbar_regular");
5963
+ }
5964
+ };
5965
+ var barmerge = {
5966
+ gaps_on: "gaps_on",
5967
+ gaps_off: "gaps_off",
5968
+ lookahead_on: "lookahead_on",
5969
+ lookahead_off: "lookahead_off"
5970
+ };
5971
+ var HEIKIN_ASHI = "heikinashi:";
5972
+ var ticker = {
5973
+ heikinashi(symbol) {
5974
+ return HEIKIN_ASHI + symbol;
5975
+ },
5976
+ standard(symbol) {
5977
+ return symbol.startsWith(HEIKIN_ASHI) ? symbol.slice(HEIKIN_ASHI.length) : symbol;
5978
+ }
5979
+ };
5980
+ function valuesOf(value, length2) {
5981
+ return value instanceof Series ? value.toArray().slice() : new Array(length2).fill(Number(value));
5982
+ }
5983
+ function security(symbol, timeframe2, expression, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off) {
5984
+ collector();
5985
+ const heikin = symbol.startsWith(HEIKIN_ASHI);
5986
+ const base = heikin ? symbol.slice(HEIKIN_ASHI.length) : symbol;
5987
+ if (base !== "" && base !== chartCtx.tickerid) {
5988
+ throw new Error(`request.security: "${symbol}" is not the chart symbol; other symbols need external data.`);
5989
+ }
5990
+ const chart2 = chartTimeframe();
5991
+ const tf = info(timeframe2 || chart2.period).period;
5992
+ if (in_seconds(tf) < in_seconds(chart2.period)) {
5993
+ throw new Error(`request.security: timeframe "${tf}" is lower than the chart timeframe "${chart2.period}".`);
5994
+ }
5995
+ const chartBars = ctxBars.bars;
5996
+ const times = chartBars.map(barTime);
5997
+ let htf;
5998
+ let group2;
5999
+ let latest;
6000
+ if (tf === chart2.period) {
6001
+ htf = chartBars;
6002
+ group2 = chartBars.map((_, i) => i);
6003
+ latest = group2;
6004
+ } else {
6005
+ const { bars: loaded, regular } = sessionBars();
6006
+ const calendar2 = info(tf).isdwm ? regular : loaded;
6007
+ const starts = times.map((t2) => calendar2.timeOf(t2, tf));
6008
+ const dayPeriods = times.map((t2, i) => {
6009
+ const at = loaded.calendar.locate(t2);
6010
+ const periods = at ? calendar2.calendar.periods(at.date) : [];
6011
+ return periods.length ? calendar2.timeOf(periods[0][0], tf) : starts[i];
6012
+ });
6013
+ const reaches = times.map((t2) => loaded.closeOf(t2, chart2.period) >= calendar2.periodEnd(t2, tf));
6014
+ ({ group: group2, latest } = periodsOf(starts, dayPeriods, reaches));
6015
+ const unit = chartCtx.timeUnit === "ms" ? 1 : 1e3;
6016
+ htf = resample(chartBars, starts.map((s) => s / unit)).bars;
6017
+ }
6018
+ if (heikin) htf = heikinAshi(htf);
6019
+ const savedCtx = chartCtx;
6020
+ let result;
6021
+ let values;
6022
+ ctxBars.setAll(htf);
6023
+ chartCtx = { ...chartCtx, timeframe: tf };
6024
+ try {
6025
+ result = expression();
6026
+ const parts = Array.isArray(result) ? result : [result];
6027
+ values = parts.map((p) => valuesOf(p, htf.length));
6028
+ } finally {
6029
+ ctxBars.setAll(chartBars);
6030
+ chartCtx = savedCtx;
6031
+ }
6032
+ const mapped = values.map(
6033
+ (v) => Series.fromArray(ctxBars, mapToChart(v, group2, latest, lookahead === barmerge.lookahead_on, gaps === barmerge.gaps_on))
6034
+ );
6035
+ return Array.isArray(result) ? mapped : mapped[0];
6036
+ }
6037
+ var request = { security };
6038
+ var line = {
6039
+ ...line_exports,
6040
+ get all() {
6041
+ return all2();
6042
+ }
6043
+ };
6044
+ var label = {
6045
+ ...label_exports,
6046
+ get all() {
6047
+ return all3();
6048
+ }
6049
+ };
6050
+ var box = {
6051
+ ...box_exports,
6052
+ get all() {
6053
+ return all4();
6054
+ }
6055
+ };
6056
+ var linefill = {
6057
+ ...linefill_exports,
6058
+ get all() {
6059
+ return all5();
6060
+ }
6061
+ };
6062
+ var polyline = {
6063
+ ...polyline_exports,
6064
+ get all() {
6065
+ return all6();
6066
+ }
6067
+ };
6068
+ var text = { ...text_exports };
6069
+ var chart = {
6070
+ point: {
6071
+ ...chartpoint_exports,
6072
+ now(price) {
6073
+ collector();
6074
+ if (currentBar < 0) {
6075
+ throw new Error("chart.point.now() needs a current bar: call it inside eachBar().");
6076
+ }
6077
+ const bar = ctxBars.bars[currentBar];
6078
+ return new_point(barTime(bar), currentBar, price ?? bar.close);
6079
+ }
6080
+ }
6081
+ };
3620
6082
  function seriesOf(values) {
3621
6083
  collector();
3622
6084
  return Series.fromArray(ctxBars, values);