oakscriptjs 0.5.0 → 0.6.0

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