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
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
2
+ var __export = (target, all7) => {
3
+ for (var name in all7)
4
+ __defProp(target, name, { get: all7[name], enumerable: true });
5
5
  };
6
6
 
7
7
  // src/runtime/series.ts
@@ -146,8 +146,8 @@ var Series = class _Series {
146
146
  * @param field - Field to extract ('open', 'high', 'low', 'close', 'volume')
147
147
  * @returns Series with extracted field values
148
148
  */
149
- static fromBars(bars2, field) {
150
- return new _Series(bars2, (bar) => bar[field] ?? NaN);
149
+ static fromBars(bars2, field2) {
150
+ return new _Series(bars2, (bar) => bar[field2] ?? NaN);
151
151
  }
152
152
  /**
153
153
  * Create a constant series (same value for all bars)
@@ -521,6 +521,7 @@ var Series = class _Series {
521
521
  // src/ta-series.ts
522
522
  var ta_series_exports = {};
523
523
  __export(ta_series_exports, {
524
+ accdist: () => accdist2,
524
525
  alma: () => alma2,
525
526
  atr: () => atr2,
526
527
  barssince: () => barssince2,
@@ -543,6 +544,7 @@ __export(ta_series_exports, {
543
544
  highestbars: () => highestbars2,
544
545
  hma: () => hma2,
545
546
  ichimoku: () => ichimoku2,
547
+ iii: () => iii2,
546
548
  kc: () => kc2,
547
549
  kcw: () => kcw2,
548
550
  linreg: () => linreg2,
@@ -555,11 +557,15 @@ __export(ta_series_exports, {
555
557
  min: () => min2,
556
558
  mode: () => mode2,
557
559
  mom: () => mom2,
560
+ nvi: () => nvi2,
561
+ obv: () => obv2,
558
562
  percentile_linear_interpolation: () => percentile_linear_interpolation2,
559
563
  percentile_nearest_rank: () => percentile_nearest_rank2,
560
564
  percentrank: () => percentrank2,
561
565
  pivothigh: () => pivothigh2,
562
566
  pivotlow: () => pivotlow2,
567
+ pvi: () => pvi2,
568
+ pvt: () => pvt2,
563
569
  range: () => range2,
564
570
  rci: () => rci2,
565
571
  rising: () => rising2,
@@ -578,16 +584,19 @@ __export(ta_series_exports, {
578
584
  valuewhen: () => valuewhen2,
579
585
  variance: () => variance2,
580
586
  vwap: () => vwap2,
587
+ vwapBands: () => vwapBands,
581
588
  vwma: () => vwma2,
589
+ wad: () => wad2,
582
590
  wma: () => wma2,
583
591
  wpr: () => wpr2,
592
+ wvad: () => wvad2,
584
593
  zigzag: () => zigzag2
585
594
  });
586
595
 
587
596
  // src/ta/index.ts
588
- function sma(source, length) {
597
+ function sma(source, length2) {
589
598
  const result = [];
590
- const len = Math.floor(length);
599
+ const len = Math.floor(length2);
591
600
  for (let i = 0; i < source.length; i++) {
592
601
  if (i < len - 1) {
593
602
  result.push(NaN);
@@ -601,9 +610,9 @@ function sma(source, length) {
601
610
  }
602
611
  return result;
603
612
  }
604
- function ema(source, length) {
613
+ function ema(source, length2) {
605
614
  const result = [];
606
- const len = Math.floor(length);
615
+ const len = Math.floor(length2);
607
616
  const multiplier = 2 / (len + 1);
608
617
  let firstValidIndex = -1;
609
618
  let validCount = 0;
@@ -636,7 +645,7 @@ function ema(source, length) {
636
645
  }
637
646
  return result;
638
647
  }
639
- function rsi(source, length) {
648
+ function rsi(source, length2) {
640
649
  const result = [];
641
650
  const changes = [];
642
651
  for (let i = 1; i < source.length; i++) {
@@ -644,8 +653,8 @@ function rsi(source, length) {
644
653
  }
645
654
  const gains = changes.map((c) => c > 0 ? c : 0);
646
655
  const losses = changes.map((c) => c < 0 ? -c : 0);
647
- const avgGains = rma(gains, length);
648
- const avgLosses = rma(losses, length);
656
+ const avgGains = rma(gains, length2);
657
+ const avgLosses = rma(losses, length2);
649
658
  result.push(NaN);
650
659
  for (let i = 0; i < avgGains.length; i++) {
651
660
  if (avgLosses[i] === 0) {
@@ -671,34 +680,53 @@ function macd(source, fastLength, slowLength, signalLength) {
671
680
  }
672
681
  return [macdLine, signalLine, histogram];
673
682
  }
674
- function bb(series, length, mult) {
675
- const basis = sma(series, length);
676
- const dev3 = stdev(series, length);
677
- const upper = [];
678
- const lower = [];
683
+ function bb(series, length2, mult) {
684
+ const basis = sma(series, length2);
685
+ const dev3 = stdev(series, length2);
686
+ const upper2 = [];
687
+ const lower2 = [];
679
688
  for (let i = 0; i < series.length; i++) {
680
- upper.push(basis[i] + mult * dev3[i]);
681
- lower.push(basis[i] - mult * dev3[i]);
682
- }
683
- return [basis, upper, lower];
689
+ upper2.push(basis[i] + mult * dev3[i]);
690
+ lower2.push(basis[i] - mult * dev3[i]);
691
+ }
692
+ return [basis, upper2, lower2];
693
+ }
694
+ function stdev(source, length2, biased = true) {
695
+ const len = Math.floor(length2);
696
+ return source.map((_, i) => {
697
+ const values = lastValues(source, i, len);
698
+ if (!values) return NaN;
699
+ const mean = values.reduce((a, b2) => a + b2, 0) / len;
700
+ const squares = values.reduce((a, b2) => a + (b2 - mean) * (b2 - mean), 0);
701
+ return Math.sqrt(squares / (biased ? len : len - 1));
702
+ });
684
703
  }
685
- function stdev(source, length) {
686
- const result = [];
687
- const len = Math.floor(length);
688
- const avg2 = sma(source, len);
689
- for (let i = 0; i < source.length; i++) {
690
- if (i < len - 1) {
691
- result.push(NaN);
692
- } else {
693
- let sumSquares = 0;
694
- for (let j = 0; j < len; j++) {
695
- const diff = source[i - j] - avg2[i];
696
- sumSquares += diff * diff;
697
- }
698
- result.push(Math.sqrt(sumSquares / len));
699
- }
700
- }
701
- return result;
704
+ function lastValues(source, i, length2) {
705
+ const values = [];
706
+ for (let j = i; j >= 0 && values.length < length2; j--) {
707
+ const x = source[j];
708
+ if (!Number.isNaN(x)) values.push(x);
709
+ }
710
+ return values.length === length2 ? values : null;
711
+ }
712
+ function windowUntilNa(source, i, length2) {
713
+ const values = [];
714
+ for (let j = 0; j < length2 && i - j >= 0; j++) {
715
+ const x = source[i - j];
716
+ if (Number.isNaN(x)) break;
717
+ values.push([x, -j]);
718
+ }
719
+ return values;
720
+ }
721
+ function extremeOffset(source, length2, isHigher) {
722
+ return source.map((_, i) => {
723
+ if (i < length2 - 1) return NaN;
724
+ const w = windowUntilNa(source, i, length2);
725
+ if (w.length === 0) return 0;
726
+ let best = w[0];
727
+ for (const item of w) if (isHigher(item[0], best[0])) best = item;
728
+ return best[1];
729
+ });
702
730
  }
703
731
  function crossover(series1, series2) {
704
732
  const result = [];
@@ -722,13 +750,13 @@ function crossunder(series1, series2) {
722
750
  }
723
751
  return result;
724
752
  }
725
- function change(source, length = 1) {
753
+ function change(source, length2 = 1) {
726
754
  const result = [];
727
755
  for (let i = 0; i < source.length; i++) {
728
- if (i < length) {
756
+ if (i < length2) {
729
757
  result.push(NaN);
730
758
  } else {
731
- result.push(source[i] - source[i - length]);
759
+ result.push(source[i] - source[i - length2]);
732
760
  }
733
761
  }
734
762
  return result;
@@ -763,14 +791,14 @@ function tr(handle_na = false, high2, low2, close2) {
763
791
  }
764
792
  return result;
765
793
  }
766
- function atr(length, high2, low2, close2) {
794
+ function atr(length2, high2, low2, close2) {
767
795
  if (!high2 || !low2 || !close2) {
768
796
  throw new Error(
769
797
  "ta.atr() requires high, low, and close series. Either pass them explicitly or use createContext({ chart: { high, low, close } }) for implicit data."
770
798
  );
771
799
  }
772
800
  const trueRange = tr(false, high2, low2, close2);
773
- return rma(trueRange, length);
801
+ return rma(trueRange, length2);
774
802
  }
775
803
  function supertrend(factor, atrPeriod, high2, low2, close2, wicks = false) {
776
804
  if (!high2 || !low2 || !close2) {
@@ -822,9 +850,9 @@ function supertrend(factor, atrPeriod, high2, low2, close2, wicks = false) {
822
850
  }
823
851
  return [supertrendValues, directions];
824
852
  }
825
- function rma(source, length) {
853
+ function rma(source, length2) {
826
854
  const result = [];
827
- const len = Math.floor(length);
855
+ const len = Math.floor(length2);
828
856
  const alpha = 1 / len;
829
857
  let firstValidIndex = -1;
830
858
  let validCount = 0;
@@ -857,9 +885,9 @@ function rma(source, length) {
857
885
  }
858
886
  return result;
859
887
  }
860
- function wma(source, length) {
888
+ function wma(source, length2) {
861
889
  const result = [];
862
- const len = Math.floor(length);
890
+ const len = Math.floor(length2);
863
891
  for (let i = 0; i < source.length; i++) {
864
892
  if (i < len - 1) {
865
893
  result.push(NaN);
@@ -876,48 +904,27 @@ function wma(source, length) {
876
904
  }
877
905
  return result;
878
906
  }
879
- function highest(source, length) {
880
- const result = [];
881
- for (let i = 0; i < source.length; i++) {
882
- if (i < length - 1) {
883
- result.push(NaN);
884
- } else {
885
- let max4 = -Infinity;
886
- for (let j = 0; j < length; j++) {
887
- if (!isNaN(source[i - j])) {
888
- max4 = Math.max(max4, source[i - j]);
889
- }
890
- }
891
- result.push(max4 === -Infinity ? NaN : max4);
892
- }
893
- }
894
- return result;
907
+ function highest(source, length2) {
908
+ return source.map((_, i) => {
909
+ if (i < length2 - 1) return NaN;
910
+ const w = windowUntilNa(source, i, length2);
911
+ return w.length ? Math.max(...w.map((x) => x[0])) : NaN;
912
+ });
895
913
  }
896
- function lowest(source, length) {
897
- const result = [];
898
- for (let i = 0; i < source.length; i++) {
899
- if (i < length - 1) {
900
- result.push(NaN);
901
- } else {
902
- let min4 = Infinity;
903
- for (let j = 0; j < length; j++) {
904
- if (!isNaN(source[i - j])) {
905
- min4 = Math.min(min4, source[i - j]);
906
- }
907
- }
908
- result.push(min4 === Infinity ? NaN : min4);
909
- }
910
- }
911
- return result;
914
+ function lowest(source, length2) {
915
+ return source.map((_, i) => {
916
+ if (i < length2 - 1) return NaN;
917
+ const w = windowUntilNa(source, i, length2);
918
+ return w.length ? Math.min(...w.map((x) => x[0])) : NaN;
919
+ });
912
920
  }
913
921
  function cum(source) {
914
- const result = [];
915
922
  let sum2 = 0;
916
- for (let i = 0; i < source.length; i++) {
917
- sum2 += source[i];
918
- result.push(sum2);
919
- }
920
- return result;
923
+ return source.map((v) => {
924
+ if (Number.isNaN(v)) return NaN;
925
+ sum2 += v;
926
+ return sum2;
927
+ });
921
928
  }
922
929
  function cross(source1, source2) {
923
930
  const result = [];
@@ -932,14 +939,14 @@ function cross(source1, source2) {
932
939
  }
933
940
  return result;
934
941
  }
935
- function rising(source, length) {
942
+ function rising(source, length2) {
936
943
  const result = [];
937
944
  for (let i = 0; i < source.length; i++) {
938
- if (i < length) {
945
+ if (i < length2) {
939
946
  result.push(false);
940
947
  } else {
941
948
  let isRising = true;
942
- for (let j = 1; j <= length; j++) {
949
+ for (let j = 1; j <= length2; j++) {
943
950
  if (source[i - j + 1] <= source[i - j]) {
944
951
  isRising = false;
945
952
  break;
@@ -950,14 +957,14 @@ function rising(source, length) {
950
957
  }
951
958
  return result;
952
959
  }
953
- function falling(source, length) {
960
+ function falling(source, length2) {
954
961
  const result = [];
955
962
  for (let i = 0; i < source.length; i++) {
956
- if (i < length) {
963
+ if (i < length2) {
957
964
  result.push(false);
958
965
  } else {
959
966
  let isFalling = true;
960
- for (let j = 1; j <= length; j++) {
967
+ for (let j = 1; j <= length2; j++) {
961
968
  if (source[i - j + 1] >= source[i - j]) {
962
969
  isFalling = false;
963
970
  break;
@@ -968,13 +975,13 @@ function falling(source, length) {
968
975
  }
969
976
  return result;
970
977
  }
971
- function roc(source, length) {
978
+ function roc(source, length2) {
972
979
  const result = [];
973
980
  for (let i = 0; i < source.length; i++) {
974
- if (i < length) {
981
+ if (i < length2) {
975
982
  result.push(NaN);
976
983
  } else {
977
- const oldValue = source[i - length];
984
+ const oldValue = source[i - length2];
978
985
  if (oldValue === 0 || isNaN(oldValue) || isNaN(source[i])) {
979
986
  result.push(NaN);
980
987
  } else {
@@ -985,49 +992,49 @@ function roc(source, length) {
985
992
  }
986
993
  return result;
987
994
  }
988
- function mom(source, length) {
995
+ function mom(source, length2) {
989
996
  const result = [];
990
997
  for (let i = 0; i < source.length; i++) {
991
- if (i < length) {
998
+ if (i < length2) {
992
999
  result.push(NaN);
993
1000
  } else {
994
- if (isNaN(source[i]) || isNaN(source[i - length])) {
1001
+ if (isNaN(source[i]) || isNaN(source[i - length2])) {
995
1002
  result.push(NaN);
996
1003
  } else {
997
- result.push(source[i] - source[i - length]);
1004
+ result.push(source[i] - source[i - length2]);
998
1005
  }
999
1006
  }
1000
1007
  }
1001
1008
  return result;
1002
1009
  }
1003
- function dev(source, length) {
1010
+ function dev(source, length2) {
1004
1011
  const result = [];
1005
- const meanValues = sma(source, length);
1012
+ const meanValues = sma(source, length2);
1006
1013
  for (let i = 0; i < source.length; i++) {
1007
- if (i < length - 1 || isNaN(meanValues[i])) {
1014
+ if (i < length2 - 1 || isNaN(meanValues[i])) {
1008
1015
  result.push(NaN);
1009
1016
  } else {
1010
1017
  let sum2 = 0;
1011
- for (let j = 0; j < length; j++) {
1018
+ for (let j = 0; j < length2; j++) {
1012
1019
  if (!isNaN(source[i - j])) {
1013
1020
  sum2 += Math.abs(source[i - j] - meanValues[i]);
1014
1021
  }
1015
1022
  }
1016
- result.push(sum2 / length);
1023
+ result.push(sum2 / length2);
1017
1024
  }
1018
1025
  }
1019
1026
  return result;
1020
1027
  }
1021
- function variance(source, length, biased = true) {
1028
+ function variance(source, length2, biased = true) {
1022
1029
  const result = [];
1023
- const meanValues = sma(source, length);
1030
+ const meanValues = sma(source, length2);
1024
1031
  for (let i = 0; i < source.length; i++) {
1025
- if (i < length - 1 || isNaN(meanValues[i])) {
1032
+ if (i < length2 - 1 || isNaN(meanValues[i])) {
1026
1033
  result.push(NaN);
1027
1034
  } else {
1028
1035
  let sumSquares = 0;
1029
1036
  let count = 0;
1030
- for (let j = 0; j < length; j++) {
1037
+ for (let j = 0; j < length2; j++) {
1031
1038
  if (!isNaN(source[i - j])) {
1032
1039
  const diff = source[i - j] - meanValues[i];
1033
1040
  sumSquares += diff * diff;
@@ -1040,14 +1047,14 @@ function variance(source, length, biased = true) {
1040
1047
  }
1041
1048
  return result;
1042
1049
  }
1043
- function median(source, length) {
1050
+ function median(source, length2) {
1044
1051
  const result = [];
1045
1052
  for (let i = 0; i < source.length; i++) {
1046
- if (i < length - 1) {
1053
+ if (i < length2 - 1) {
1047
1054
  result.push(NaN);
1048
1055
  } else {
1049
1056
  const values = [];
1050
- for (let j = 0; j < length; j++) {
1057
+ for (let j = 0; j < length2; j++) {
1051
1058
  if (!isNaN(source[i - j])) {
1052
1059
  values.push(source[i - j]);
1053
1060
  }
@@ -1083,7 +1090,7 @@ function swma(source) {
1083
1090
  }
1084
1091
  return result;
1085
1092
  }
1086
- function vwma(source, length, volume2) {
1093
+ function vwma(source, length2, volume2) {
1087
1094
  if (!volume2) {
1088
1095
  throw new Error(
1089
1096
  "ta.vwma() requires volume series. Either pass it explicitly or use createContext({ chart: { ..., volume } }) for implicit data."
@@ -1093,8 +1100,8 @@ function vwma(source, length, volume2) {
1093
1100
  for (let i = 0; i < source.length; i++) {
1094
1101
  sourceTimesVolume.push(source[i] * volume2[i]);
1095
1102
  }
1096
- const numerator = sma(sourceTimesVolume, length);
1097
- const denominator = sma(volume2, length);
1103
+ const numerator = sma(sourceTimesVolume, length2);
1104
+ const denominator = sma(volume2, length2);
1098
1105
  const result = [];
1099
1106
  for (let i = 0; i < source.length; i++) {
1100
1107
  if (denominator[i] === 0 || isNaN(denominator[i])) {
@@ -1105,9 +1112,9 @@ function vwma(source, length, volume2) {
1105
1112
  }
1106
1113
  return result;
1107
1114
  }
1108
- function linreg(source, length, offset = 0) {
1115
+ function linreg(source, length2, offset = 0) {
1109
1116
  const result = [];
1110
- const len = Math.floor(length);
1117
+ const len = Math.floor(length2);
1111
1118
  for (let i = 0; i < source.length; i++) {
1112
1119
  if (i < len - 1) {
1113
1120
  result.push(NaN);
@@ -1143,14 +1150,14 @@ function linreg(source, length, offset = 0) {
1143
1150
  }
1144
1151
  return result;
1145
1152
  }
1146
- function correlation(source1, source2, length) {
1153
+ function correlation(source1, source2, length2) {
1147
1154
  const result = [];
1148
1155
  for (let i = 0; i < source1.length; i++) {
1149
- if (i < length - 1) {
1156
+ if (i < length2 - 1) {
1150
1157
  result.push(NaN);
1151
1158
  } else {
1152
1159
  const pairs = [];
1153
- for (let j = 0; j < length; j++) {
1160
+ for (let j = 0; j < length2; j++) {
1154
1161
  if (!isNaN(source1[i - j]) && !isNaN(source2[i - j])) {
1155
1162
  pairs.push([source1[i - j], source2[i - j]]);
1156
1163
  }
@@ -1187,10 +1194,10 @@ function correlation(source1, source2, length) {
1187
1194
  }
1188
1195
  return result;
1189
1196
  }
1190
- function percentrank(source, length) {
1197
+ function percentrank(source, length2) {
1191
1198
  const result = [];
1192
1199
  for (let i = 0; i < source.length; i++) {
1193
- if (i < length) {
1200
+ if (i < length2) {
1194
1201
  result.push(NaN);
1195
1202
  } else {
1196
1203
  if (isNaN(source[i])) {
@@ -1198,7 +1205,7 @@ function percentrank(source, length) {
1198
1205
  continue;
1199
1206
  }
1200
1207
  let hasNaN = false;
1201
- for (let j = 1; j <= length; j++) {
1208
+ for (let j = 1; j <= length2; j++) {
1202
1209
  if (isNaN(source[i - j])) {
1203
1210
  hasNaN = true;
1204
1211
  break;
@@ -1209,21 +1216,21 @@ function percentrank(source, length) {
1209
1216
  } else {
1210
1217
  const currentValue = source[i];
1211
1218
  let countLessOrEqual = 0;
1212
- for (let j = 1; j <= length; j++) {
1219
+ for (let j = 1; j <= length2; j++) {
1213
1220
  if (source[i - j] <= currentValue) {
1214
1221
  countLessOrEqual++;
1215
1222
  }
1216
1223
  }
1217
- result.push(countLessOrEqual / length * 100);
1224
+ result.push(countLessOrEqual / length2 * 100);
1218
1225
  }
1219
1226
  }
1220
1227
  }
1221
1228
  return result;
1222
1229
  }
1223
- function cci(source, length) {
1230
+ function cci(source, length2) {
1224
1231
  const result = [];
1225
- const smaValues = sma(source, length);
1226
- const devValues = dev(source, length);
1232
+ const smaValues = sma(source, length2);
1233
+ const devValues = dev(source, length2);
1227
1234
  for (let i = 0; i < source.length; i++) {
1228
1235
  if (isNaN(smaValues[i]) || isNaN(devValues[i]) || devValues[i] === 0) {
1229
1236
  result.push(NaN);
@@ -1234,10 +1241,10 @@ function cci(source, length) {
1234
1241
  }
1235
1242
  return result;
1236
1243
  }
1237
- function stoch(source, high2, low2, length) {
1244
+ function stoch(source, high2, low2, length2) {
1238
1245
  const result = [];
1239
- const lowestValues = lowest(low2, length);
1240
- const highestValues = highest(high2, length);
1246
+ const lowestValues = lowest(low2, length2);
1247
+ const highestValues = highest(high2, length2);
1241
1248
  for (let i = 0; i < source.length; i++) {
1242
1249
  if (isNaN(lowestValues[i]) || isNaN(highestValues[i])) {
1243
1250
  result.push(NaN);
@@ -1253,7 +1260,7 @@ function stoch(source, high2, low2, length) {
1253
1260
  }
1254
1261
  return result;
1255
1262
  }
1256
- function mfi(source, length, volume2) {
1263
+ function mfi(source, length2, volume2) {
1257
1264
  if (!volume2) {
1258
1265
  throw new Error(
1259
1266
  "ta.mfi() requires volume series. Either pass it explicitly or use createContext({ chart: { ..., volume } }) for implicit data."
@@ -1282,12 +1289,12 @@ function mfi(source, length, volume2) {
1282
1289
  }
1283
1290
  }
1284
1291
  for (let i = 0; i < source.length; i++) {
1285
- if (i < length) {
1292
+ if (i < length2) {
1286
1293
  result.push(NaN);
1287
1294
  } else {
1288
1295
  let posSum = 0;
1289
1296
  let negSum = 0;
1290
- for (let j = 0; j < length; j++) {
1297
+ for (let j = 0; j < length2; j++) {
1291
1298
  posSum += positiveFlow[i - j];
1292
1299
  negSum += negativeFlow[i - j];
1293
1300
  }
@@ -1302,11 +1309,11 @@ function mfi(source, length, volume2) {
1302
1309
  }
1303
1310
  return result;
1304
1311
  }
1305
- function hma(source, length) {
1306
- const halfLength = Math.floor(length / 2);
1307
- const sqrtLength = Math.floor(Math.sqrt(length));
1312
+ function hma(source, length2) {
1313
+ const halfLength = Math.floor(length2 / 2);
1314
+ const sqrtLength = Math.floor(Math.sqrt(length2));
1308
1315
  const wmaHalf = wma(source, halfLength);
1309
- const wmaFull = wma(source, length);
1316
+ const wmaFull = wma(source, length2);
1310
1317
  const diff = [];
1311
1318
  for (let i = 0; i < source.length; i++) {
1312
1319
  diff.push(2 * wmaHalf[i] - wmaFull[i]);
@@ -1390,89 +1397,44 @@ function sar(start, inc, max4, high2, low2, close2) {
1390
1397
  }
1391
1398
  return result;
1392
1399
  }
1400
+ function pivot(source, leftbars, rightbars, isHigh) {
1401
+ const beatsLeft = isHigh ? (x, v) => x > v : (x, v) => x < v;
1402
+ const beatsRight = isHigh ? (x, v) => x >= v : (x, v) => x <= v;
1403
+ return source.map((_, i) => {
1404
+ const center = i - rightbars;
1405
+ if (center - leftbars < 0) return NaN;
1406
+ const v = source[center];
1407
+ if (Number.isNaN(v)) return NaN;
1408
+ for (let j = 1; j <= leftbars; j++) {
1409
+ const x = source[center - j];
1410
+ if (Number.isNaN(x)) break;
1411
+ if (beatsLeft(x, v)) return NaN;
1412
+ }
1413
+ for (let j = 1; j <= rightbars; j++) {
1414
+ const x = source[center + j];
1415
+ if (Number.isNaN(x)) break;
1416
+ if (beatsRight(x, v)) return NaN;
1417
+ }
1418
+ return v;
1419
+ });
1420
+ }
1393
1421
  function pivothigh(sourceOrLeftbars, leftbarsOrRightbars, rightbars, high2) {
1394
- let source;
1395
- let leftbars;
1396
- let right;
1397
1422
  if (rightbars === void 0) {
1398
1423
  if (!high2) {
1399
1424
  throw new Error("ta.pivothigh() requires high series when using two-parameter version.");
1400
1425
  }
1401
- source = high2;
1402
- leftbars = sourceOrLeftbars;
1403
- right = leftbarsOrRightbars;
1404
- } else {
1405
- source = sourceOrLeftbars;
1406
- leftbars = leftbarsOrRightbars;
1407
- right = rightbars;
1408
- }
1409
- const result = [];
1410
- for (let i = 0; i < source.length; i++) {
1411
- if (i < leftbars || i + right >= source.length) {
1412
- result.push(NaN);
1413
- continue;
1414
- }
1415
- const centerValue = source[i];
1416
- let isPivot = true;
1417
- for (let j = 1; j <= leftbars; j++) {
1418
- if (source[i - j] >= centerValue) {
1419
- isPivot = false;
1420
- break;
1421
- }
1422
- }
1423
- if (isPivot) {
1424
- for (let j = 1; j <= right; j++) {
1425
- if (source[i + j] >= centerValue) {
1426
- isPivot = false;
1427
- break;
1428
- }
1429
- }
1430
- }
1431
- result.push(isPivot ? centerValue : NaN);
1426
+ return pivot(high2, sourceOrLeftbars, leftbarsOrRightbars, true);
1432
1427
  }
1433
- return result;
1428
+ return pivot(sourceOrLeftbars, leftbarsOrRightbars, rightbars, true);
1434
1429
  }
1435
1430
  function pivotlow(sourceOrLeftbars, leftbarsOrRightbars, rightbars, low2) {
1436
- let source;
1437
- let leftbars;
1438
- let right;
1439
1431
  if (rightbars === void 0) {
1440
1432
  if (!low2) {
1441
1433
  throw new Error("ta.pivotlow() requires low series when using two-parameter version.");
1442
1434
  }
1443
- source = low2;
1444
- leftbars = sourceOrLeftbars;
1445
- right = leftbarsOrRightbars;
1446
- } else {
1447
- source = sourceOrLeftbars;
1448
- leftbars = leftbarsOrRightbars;
1449
- right = rightbars;
1450
- }
1451
- const result = [];
1452
- for (let i = 0; i < source.length; i++) {
1453
- if (i < leftbars || i + right >= source.length) {
1454
- result.push(NaN);
1455
- continue;
1456
- }
1457
- const centerValue = source[i];
1458
- let isPivot = true;
1459
- for (let j = 1; j <= leftbars; j++) {
1460
- if (source[i - j] <= centerValue) {
1461
- isPivot = false;
1462
- break;
1463
- }
1464
- }
1465
- if (isPivot) {
1466
- for (let j = 1; j <= right; j++) {
1467
- if (source[i + j] <= centerValue) {
1468
- isPivot = false;
1469
- break;
1470
- }
1471
- }
1472
- }
1473
- result.push(isPivot ? centerValue : NaN);
1435
+ return pivot(low2, sourceOrLeftbars, leftbarsOrRightbars, false);
1474
1436
  }
1475
- return result;
1437
+ return pivot(sourceOrLeftbars, leftbarsOrRightbars, rightbars, false);
1476
1438
  }
1477
1439
  function barssince(condition) {
1478
1440
  const result = [];
@@ -1577,16 +1539,16 @@ function tsi(source, shortLength, longLength) {
1577
1539
  }
1578
1540
  return result;
1579
1541
  }
1580
- function cmo(source, length) {
1542
+ function cmo(source, length2) {
1581
1543
  const result = [];
1582
1544
  for (let i = 0; i < source.length; i++) {
1583
- if (i < length) {
1545
+ if (i < length2) {
1584
1546
  result.push(NaN);
1585
1547
  continue;
1586
1548
  }
1587
1549
  let sumGains = 0;
1588
1550
  let sumLosses = 0;
1589
- for (let j = 0; j < length; j++) {
1551
+ for (let j = 0; j < length2; j++) {
1590
1552
  const change3 = source[i - j] - source[i - j - 1];
1591
1553
  if (change3 > 0) {
1592
1554
  sumGains += change3;
@@ -1604,8 +1566,8 @@ function cmo(source, length) {
1604
1566
  }
1605
1567
  return result;
1606
1568
  }
1607
- function kc(source, length, mult, useTrueRange = true, high2, low2, close2) {
1608
- const middle = ema(source, length);
1569
+ function kc(source, length2, mult, useTrueRange = true, high2, low2, close2) {
1570
+ const middle = ema(source, length2);
1609
1571
  let range3;
1610
1572
  if (useTrueRange) {
1611
1573
  if (!high2 || !low2 || !close2) {
@@ -1621,38 +1583,38 @@ function kc(source, length, mult, useTrueRange = true, high2, low2, close2) {
1621
1583
  range3.push(high2[i] - low2[i]);
1622
1584
  }
1623
1585
  }
1624
- const rangeEma = ema(range3, length);
1625
- const upper = [];
1626
- const lower = [];
1586
+ const rangeEma = ema(range3, length2);
1587
+ const upper2 = [];
1588
+ const lower2 = [];
1627
1589
  for (let i = 0; i < middle.length; i++) {
1628
- upper.push(middle[i] + rangeEma[i] * mult);
1629
- lower.push(middle[i] - rangeEma[i] * mult);
1590
+ upper2.push(middle[i] + rangeEma[i] * mult);
1591
+ lower2.push(middle[i] - rangeEma[i] * mult);
1630
1592
  }
1631
- return [middle, upper, lower];
1593
+ return [middle, upper2, lower2];
1632
1594
  }
1633
- function bbw(source, length, mult) {
1634
- const [basis, upper, lower] = bb(source, length, mult);
1595
+ function bbw(source, length2, mult) {
1596
+ const [basis, upper2, lower2] = bb(source, length2, mult);
1635
1597
  const result = [];
1636
1598
  for (let i = 0; i < source.length; i++) {
1637
1599
  if (basis[i] === 0) {
1638
1600
  result.push(NaN);
1639
1601
  } else {
1640
- const width = (upper[i] - lower[i]) / basis[i] * 100;
1602
+ const width = (upper2[i] - lower2[i]) / basis[i] * 100;
1641
1603
  result.push(width);
1642
1604
  }
1643
1605
  }
1644
1606
  return result;
1645
1607
  }
1646
- function wpr(high2, low2, close2, length = 14) {
1608
+ function wpr(high2, low2, close2, length2 = 14) {
1647
1609
  const result = [];
1648
1610
  for (let i = 0; i < close2.length; i++) {
1649
- if (i < length - 1) {
1611
+ if (i < length2 - 1) {
1650
1612
  result.push(NaN);
1651
1613
  continue;
1652
1614
  }
1653
- let highestHigh = high2[i - length + 1];
1654
- let lowestLow = low2[i - length + 1];
1655
- for (let j = i - length + 2; j <= i; j++) {
1615
+ let highestHigh = high2[i - length2 + 1];
1616
+ let lowestLow = low2[i - length2 + 1];
1617
+ for (let j = i - length2 + 2; j <= i; j++) {
1656
1618
  if (high2[j] > highestHigh) highestHigh = high2[j];
1657
1619
  if (low2[j] < lowestLow) lowestLow = low2[j];
1658
1620
  }
@@ -1666,181 +1628,138 @@ function wpr(high2, low2, close2, length = 14) {
1666
1628
  }
1667
1629
  return result;
1668
1630
  }
1669
- function vwap(source, volume2) {
1631
+ function vwap(source, volume2, anchor, stdev_mult) {
1670
1632
  if (source.length !== volume2.length) {
1671
1633
  throw new Error("ta.vwap: source and volume must have the same length");
1672
1634
  }
1673
- const result = [];
1674
- let cumulativePV = 0;
1675
- let cumulativeVolume = 0;
1635
+ const mid = [];
1636
+ const upper2 = [];
1637
+ const lower2 = [];
1638
+ let sumPV = 0;
1639
+ let sumV = 0;
1640
+ let sumPPV = 0;
1676
1641
  for (let i = 0; i < source.length; i++) {
1677
- if (isNaN(source[i]) || isNaN(volume2[i])) {
1678
- result.push(NaN);
1679
- continue;
1642
+ if (anchor && anchor[i]) {
1643
+ sumPV = 0;
1644
+ sumV = 0;
1645
+ sumPPV = 0;
1680
1646
  }
1681
- cumulativePV += source[i] * volume2[i];
1682
- cumulativeVolume += volume2[i];
1683
- if (cumulativeVolume === 0) {
1684
- result.push(NaN);
1685
- } else {
1686
- result.push(cumulativePV / cumulativeVolume);
1647
+ const s = source[i];
1648
+ const v = volume2[i];
1649
+ if (!Number.isNaN(s) && !Number.isNaN(v)) {
1650
+ sumPV += s * v;
1651
+ sumV += v;
1652
+ sumPPV += s * s * v;
1653
+ }
1654
+ const m = sumV === 0 ? NaN : sumPV / sumV;
1655
+ mid.push(m);
1656
+ if (stdev_mult !== void 0) {
1657
+ const sd = Math.sqrt(Math.max(0, sumPPV / sumV - m * m));
1658
+ upper2.push(m + stdev_mult * sd);
1659
+ lower2.push(m - stdev_mult * sd);
1687
1660
  }
1688
1661
  }
1689
- return result;
1662
+ return stdev_mult === void 0 ? mid : [mid, upper2, lower2];
1690
1663
  }
1691
- function alma(source, length = 9, offset = 0.85, sigma = 6, floor2 = false) {
1664
+ function alma(source, length2 = 9, offset = 0.85, sigma = 6, floor2 = false) {
1692
1665
  const result = [];
1693
- const m = floor2 ? Math.floor(offset * (length - 1)) : offset * (length - 1);
1694
- const s = length / sigma;
1666
+ const m = floor2 ? Math.floor(offset * (length2 - 1)) : offset * (length2 - 1);
1667
+ const s = length2 / sigma;
1695
1668
  const weights = [];
1696
1669
  let weightSum = 0;
1697
- for (let i = 0; i < length; i++) {
1670
+ for (let i = 0; i < length2; i++) {
1698
1671
  const weight = Math.exp(-1 * Math.pow(i - m, 2) / (2 * Math.pow(s, 2)));
1699
1672
  weights.push(weight);
1700
1673
  weightSum += weight;
1701
1674
  }
1702
- for (let i = 0; i < length; i++) {
1675
+ for (let i = 0; i < length2; i++) {
1703
1676
  weights[i] /= weightSum;
1704
1677
  }
1705
1678
  for (let i = 0; i < source.length; i++) {
1706
- if (i < length - 1) {
1679
+ if (i < length2 - 1) {
1707
1680
  result.push(NaN);
1708
1681
  continue;
1709
1682
  }
1710
1683
  let almaValue = 0;
1711
- for (let j = 0; j < length; j++) {
1712
- almaValue += source[i - length + 1 + j] * weights[j];
1684
+ for (let j = 0; j < length2; j++) {
1685
+ almaValue += source[i - length2 + 1 + j] * weights[j];
1713
1686
  }
1714
1687
  result.push(almaValue);
1715
1688
  }
1716
1689
  return result;
1717
1690
  }
1718
- function kcw(source, length = 20, mult = 2, useTrueRange = true, high2, low2, close2) {
1719
- const [basis, upper, lower] = kc(source, length, mult, useTrueRange, high2, low2, close2);
1691
+ function kcw(source, length2 = 20, mult = 2, useTrueRange = true, high2, low2, close2) {
1692
+ const [basis, upper2, lower2] = kc(source, length2, mult, useTrueRange, high2, low2, close2);
1720
1693
  const result = [];
1721
1694
  for (let i = 0; i < source.length; i++) {
1722
1695
  if (isNaN(basis[i]) || basis[i] === 0) {
1723
1696
  result.push(NaN);
1724
1697
  } else {
1725
- const width = (upper[i] - lower[i]) / basis[i] * 100;
1698
+ const width = (upper2[i] - lower2[i]) / basis[i] * 100;
1726
1699
  result.push(width);
1727
1700
  }
1728
1701
  }
1729
1702
  return result;
1730
1703
  }
1731
- function range(high2, low2) {
1732
- if (high2.length !== low2.length) {
1733
- throw new Error("ta.range: high and low must have the same length");
1734
- }
1735
- const result = [];
1736
- for (let i = 0; i < high2.length; i++) {
1737
- if (isNaN(high2[i]) || isNaN(low2[i])) {
1738
- result.push(NaN);
1739
- } else {
1740
- result.push(high2[i] - low2[i]);
1741
- }
1742
- }
1743
- return result;
1704
+ function range(source, length2) {
1705
+ return source.map((_, i) => {
1706
+ const values = lastValues(source, i, length2);
1707
+ return values ? Math.max(...values) - Math.min(...values) : NaN;
1708
+ });
1744
1709
  }
1745
- function highestbars(source, length) {
1746
- const result = [];
1747
- for (let i = 0; i < source.length; i++) {
1748
- if (i < length - 1) {
1749
- result.push(NaN);
1750
- continue;
1751
- }
1752
- let highestValue = source[i - length + 1];
1753
- let highestOffset = length - 1;
1754
- for (let j = i - length + 2; j <= i; j++) {
1755
- if (source[j] > highestValue) {
1756
- highestValue = source[j];
1757
- highestOffset = i - j;
1758
- }
1759
- }
1760
- result.push(highestOffset);
1761
- }
1762
- return result;
1710
+ function highestbars(source, length2) {
1711
+ return extremeOffset(source, length2, (a, b2) => a >= b2);
1763
1712
  }
1764
- function lowestbars(source, length) {
1765
- const result = [];
1766
- for (let i = 0; i < source.length; i++) {
1767
- if (i < length - 1) {
1768
- result.push(NaN);
1769
- continue;
1770
- }
1771
- let lowestValue = source[i - length + 1];
1772
- let lowestOffset = length - 1;
1773
- for (let j = i - length + 2; j <= i; j++) {
1774
- if (source[j] < lowestValue) {
1775
- lowestValue = source[j];
1776
- lowestOffset = i - j;
1777
- }
1778
- }
1779
- result.push(lowestOffset);
1780
- }
1781
- return result;
1713
+ function lowestbars(source, length2) {
1714
+ return extremeOffset(source, length2, (a, b2) => a <= b2);
1782
1715
  }
1783
- function max(source1, source2) {
1784
- if (source1.length !== source2.length) {
1785
- throw new Error("ta.max: source1 and source2 must have the same length");
1786
- }
1787
- const result = [];
1788
- for (let i = 0; i < source1.length; i++) {
1789
- if (isNaN(source1[i]) || isNaN(source2[i])) {
1790
- result.push(NaN);
1791
- } else {
1792
- result.push(Math.max(source1[i], source2[i]));
1793
- }
1794
- }
1795
- return result;
1716
+ function max(source) {
1717
+ let best = NaN;
1718
+ return source.map((x) => {
1719
+ if (!Number.isNaN(x) && !(x <= best)) best = x;
1720
+ return best;
1721
+ });
1796
1722
  }
1797
- function min(source1, source2) {
1798
- if (source1.length !== source2.length) {
1799
- throw new Error("ta.min: source1 and source2 must have the same length");
1800
- }
1801
- const result = [];
1802
- for (let i = 0; i < source1.length; i++) {
1803
- if (isNaN(source1[i]) || isNaN(source2[i])) {
1804
- result.push(NaN);
1805
- } else {
1806
- result.push(Math.min(source1[i], source2[i]));
1807
- }
1808
- }
1809
- return result;
1723
+ function min(source) {
1724
+ let best = NaN;
1725
+ return source.map((x) => {
1726
+ if (!Number.isNaN(x) && !(x >= best)) best = x;
1727
+ return best;
1728
+ });
1810
1729
  }
1811
- function cog(source, length = 10) {
1730
+ function cog(source, length2 = 10) {
1812
1731
  const result = [];
1813
1732
  for (let i = 0; i < source.length; i++) {
1814
- if (i < length - 1) {
1733
+ if (i < length2 - 1) {
1815
1734
  result.push(NaN);
1816
1735
  continue;
1817
1736
  }
1818
1737
  let numerator = 0;
1819
1738
  let denominator = 0;
1820
- for (let j = 0; j < length; j++) {
1739
+ for (let j = 0; j < length2; j++) {
1821
1740
  const weight = j + 1;
1822
- const price = source[i - length + 1 + j];
1741
+ const price = source[i - length2 + 1 + j];
1823
1742
  numerator += weight * price;
1824
1743
  denominator += price;
1825
1744
  }
1826
1745
  if (denominator === 0) {
1827
1746
  result.push(NaN);
1828
1747
  } else {
1829
- const cog3 = -1 * (numerator / denominator) + (length + 1) / 2;
1748
+ const cog3 = -1 * (numerator / denominator) + (length2 + 1) / 2;
1830
1749
  result.push(cog3);
1831
1750
  }
1832
1751
  }
1833
1752
  return result;
1834
1753
  }
1835
- function mode(source, length) {
1754
+ function mode(source, length2) {
1836
1755
  const result = [];
1837
1756
  for (let i = 0; i < source.length; i++) {
1838
- if (i < length - 1) {
1757
+ if (i < length2 - 1) {
1839
1758
  result.push(NaN);
1840
1759
  continue;
1841
1760
  }
1842
1761
  const values = [];
1843
- for (let j = 0; j < length; j++) {
1762
+ for (let j = 0; j < length2; j++) {
1844
1763
  const value = source[i - j];
1845
1764
  if (!isNaN(value)) {
1846
1765
  values.push(value);
@@ -1870,15 +1789,15 @@ function mode(source, length) {
1870
1789
  }
1871
1790
  return result;
1872
1791
  }
1873
- function percentile_linear_interpolation(source, length, percentage) {
1792
+ function percentile_linear_interpolation(source, length2, percentage) {
1874
1793
  const result = [];
1875
1794
  for (let i = 0; i < source.length; i++) {
1876
- if (i < length - 1) {
1795
+ if (i < length2 - 1) {
1877
1796
  result.push(NaN);
1878
1797
  continue;
1879
1798
  }
1880
1799
  const values = [];
1881
- for (let j = 0; j < length; j++) {
1800
+ for (let j = 0; j < length2; j++) {
1882
1801
  const value = source[i - j];
1883
1802
  values.push(value);
1884
1803
  }
@@ -1900,15 +1819,15 @@ function percentile_linear_interpolation(source, length, percentage) {
1900
1819
  }
1901
1820
  return result;
1902
1821
  }
1903
- function percentile_nearest_rank(source, length, percentage) {
1822
+ function percentile_nearest_rank(source, length2, percentage) {
1904
1823
  const result = [];
1905
1824
  for (let i = 0; i < source.length; i++) {
1906
- if (i < length - 1) {
1825
+ if (i < length2 - 1) {
1907
1826
  result.push(NaN);
1908
1827
  continue;
1909
1828
  }
1910
1829
  const values = [];
1911
- for (let j = 0; j < length; j++) {
1830
+ for (let j = 0; j < length2; j++) {
1912
1831
  const value = source[i - j];
1913
1832
  if (!isNaN(value)) {
1914
1833
  values.push(value);
@@ -1929,16 +1848,16 @@ function percentile_nearest_rank(source, length, percentage) {
1929
1848
  }
1930
1849
  return result;
1931
1850
  }
1932
- function rci(source, length) {
1851
+ function rci(source, length2) {
1933
1852
  const result = [];
1934
1853
  for (let i = 0; i < source.length; i++) {
1935
- if (i < length - 1) {
1854
+ if (i < length2 - 1) {
1936
1855
  result.push(NaN);
1937
1856
  continue;
1938
1857
  }
1939
1858
  const values = [];
1940
- for (let j = 0; j < length; j++) {
1941
- values.push(source[i - length + 1 + j]);
1859
+ for (let j = 0; j < length2; j++) {
1860
+ values.push(source[i - length2 + 1 + j]);
1942
1861
  }
1943
1862
  if (values.some((v) => isNaN(v))) {
1944
1863
  result.push(NaN);
@@ -1946,7 +1865,7 @@ function rci(source, length) {
1946
1865
  }
1947
1866
  const indexed = values.map((value, index) => ({ value, index }));
1948
1867
  const sorted = [...indexed].sort((a, b2) => a.value - b2.value);
1949
- const ranks = new Array(length).fill(0);
1868
+ const ranks = new Array(length2).fill(0);
1950
1869
  let currentRank = 1;
1951
1870
  for (let j = 0; j < sorted.length; j++) {
1952
1871
  let tieCount = 1;
@@ -1961,12 +1880,12 @@ function rci(source, length) {
1961
1880
  currentRank += tieCount;
1962
1881
  }
1963
1882
  let sumSquaredDiff = 0;
1964
- for (let j = 0; j < length; j++) {
1883
+ for (let j = 0; j < length2; j++) {
1965
1884
  const timeRank = j + 1;
1966
1885
  const diff = ranks[j] - timeRank;
1967
1886
  sumSquaredDiff += diff * diff;
1968
1887
  }
1969
- const n = length;
1888
+ const n = length2;
1970
1889
  const base = (n * n * n - n) / 12;
1971
1890
  let tieCorrection = 0;
1972
1891
  for (let j = 0; j < sorted.length; ) {
@@ -1992,11 +1911,11 @@ function rci(source, length) {
1992
1911
  return result;
1993
1912
  }
1994
1913
  function ichimoku(conversionPeriods, basePeriods, laggingSpan2Periods, displacement, high2, low2, close2) {
1995
- const length = high2.length;
1914
+ const length2 = high2.length;
1996
1915
  const highestConversion = highest(high2, conversionPeriods);
1997
1916
  const lowestConversion = lowest(low2, conversionPeriods);
1998
1917
  const tenkanSen = [];
1999
- for (let i = 0; i < length; i++) {
1918
+ for (let i = 0; i < length2; i++) {
2000
1919
  if (isNaN(highestConversion[i]) || isNaN(lowestConversion[i])) {
2001
1920
  tenkanSen.push(NaN);
2002
1921
  } else {
@@ -2006,7 +1925,7 @@ function ichimoku(conversionPeriods, basePeriods, laggingSpan2Periods, displacem
2006
1925
  const highestBase = highest(high2, basePeriods);
2007
1926
  const lowestBase = lowest(low2, basePeriods);
2008
1927
  const kijunSen = [];
2009
- for (let i = 0; i < length; i++) {
1928
+ for (let i = 0; i < length2; i++) {
2010
1929
  if (isNaN(highestBase[i]) || isNaN(lowestBase[i])) {
2011
1930
  kijunSen.push(NaN);
2012
1931
  } else {
@@ -2014,7 +1933,7 @@ function ichimoku(conversionPeriods, basePeriods, laggingSpan2Periods, displacem
2014
1933
  }
2015
1934
  }
2016
1935
  const senkouSpanA = [];
2017
- for (let i = 0; i < length; i++) {
1936
+ for (let i = 0; i < length2; i++) {
2018
1937
  const sourceIndex = i - displacement;
2019
1938
  if (sourceIndex < 0 || isNaN(tenkanSen[sourceIndex]) || isNaN(kijunSen[sourceIndex])) {
2020
1939
  senkouSpanA.push(NaN);
@@ -2025,7 +1944,7 @@ function ichimoku(conversionPeriods, basePeriods, laggingSpan2Periods, displacem
2025
1944
  const highestLagging = highest(high2, laggingSpan2Periods);
2026
1945
  const lowestLagging = lowest(low2, laggingSpan2Periods);
2027
1946
  const senkouSpanB = [];
2028
- for (let i = 0; i < length; i++) {
1947
+ for (let i = 0; i < length2; i++) {
2029
1948
  const sourceIndex = i - displacement;
2030
1949
  if (sourceIndex < 0 || isNaN(highestLagging[sourceIndex]) || isNaN(lowestLagging[sourceIndex])) {
2031
1950
  senkouSpanB.push(NaN);
@@ -2034,9 +1953,9 @@ function ichimoku(conversionPeriods, basePeriods, laggingSpan2Periods, displacem
2034
1953
  }
2035
1954
  }
2036
1955
  const chikouSpan = [];
2037
- for (let i = 0; i < length; i++) {
1956
+ for (let i = 0; i < length2; i++) {
2038
1957
  const sourceIndex = i + displacement;
2039
- if (sourceIndex >= length || isNaN(close2[sourceIndex])) {
1958
+ if (sourceIndex >= length2 || isNaN(close2[sourceIndex])) {
2040
1959
  chikouSpan.push(NaN);
2041
1960
  } else {
2042
1961
  chikouSpan.push(close2[sourceIndex]);
@@ -2058,13 +1977,13 @@ function zigzag(deviation = 5, depth = 10, backstep = 3, source, high2, low2) {
2058
1977
  "ta.zigzag() requires either source series or high/low series. Either pass them explicitly or use createContext({ chart: { high, low, close } }) for implicit data."
2059
1978
  );
2060
1979
  }
2061
- const length = highSource.length;
2062
- if (lowSource.length !== length) {
1980
+ const length2 = highSource.length;
1981
+ if (lowSource.length !== length2) {
2063
1982
  throw new Error("ta.zigzag: high and low must have the same length");
2064
1983
  }
2065
- const zigzagValues = new Array(length).fill(NaN);
2066
- const directions = new Array(length).fill(0);
2067
- const isPivot = new Array(length).fill(false);
1984
+ const zigzagValues = new Array(length2).fill(NaN);
1985
+ const directions = new Array(length2).fill(0);
1986
+ const isPivot = new Array(length2).fill(false);
2068
1987
  const getDeviation = (price1, price2) => {
2069
1988
  if (Math.abs(price1) < 1e-10 || isNaN(price1) || isNaN(price2)) return 0;
2070
1989
  return Math.abs((price2 - price1) / price1) * 100;
@@ -2078,7 +1997,7 @@ function zigzag(deviation = 5, depth = 10, backstep = 3, source, high2, low2) {
2078
1997
  let initialLowest = Infinity;
2079
1998
  let initialHighIndex = -1;
2080
1999
  let initialLowIndex = -1;
2081
- for (let i = 0; i < Math.min(depth, length); i++) {
2000
+ for (let i = 0; i < Math.min(depth, length2); i++) {
2082
2001
  if (!isNaN(highSource[i]) && highSource[i] > initialHighest) {
2083
2002
  initialHighest = highSource[i];
2084
2003
  initialHighIndex = i;
@@ -2101,7 +2020,7 @@ function zigzag(deviation = 5, depth = 10, backstep = 3, source, high2, low2) {
2101
2020
  } else {
2102
2021
  startIndex = depth;
2103
2022
  }
2104
- for (let i = Math.max(startIndex, depth); i < length; i++) {
2023
+ for (let i = Math.max(startIndex, depth); i < length2; i++) {
2105
2024
  const currentHigh = highSource[i];
2106
2025
  const currentLow = lowSource[i];
2107
2026
  if (isNaN(currentHigh) || isNaN(currentLow)) {
@@ -2179,53 +2098,116 @@ function zigzag(deviation = 5, depth = 10, backstep = 3, source, high2, low2) {
2179
2098
  if (potentialPivot) {
2180
2099
  confirmedPivots.push(potentialPivot);
2181
2100
  }
2182
- for (const pivot of confirmedPivots) {
2183
- zigzagValues[pivot.index] = pivot.price;
2184
- isPivot[pivot.index] = true;
2101
+ for (const pivot2 of confirmedPivots) {
2102
+ zigzagValues[pivot2.index] = pivot2.price;
2103
+ isPivot[pivot2.index] = true;
2185
2104
  }
2186
2105
  let currentDir = 0;
2187
2106
  let pivotIdx = 0;
2188
2107
  const numConfirmed = lastPotentialWasAdded ? confirmedPivots.length - 1 : confirmedPivots.length;
2189
- for (let i = 0; i < length; i++) {
2108
+ for (let i = 0; i < length2; i++) {
2190
2109
  while (pivotIdx < numConfirmed && confirmedPivots[pivotIdx].index <= i) {
2191
- const pivot = confirmedPivots[pivotIdx];
2192
- currentDir = pivot.type === "low" ? 1 : -1;
2110
+ const pivot2 = confirmedPivots[pivotIdx];
2111
+ currentDir = pivot2.type === "low" ? 1 : -1;
2193
2112
  pivotIdx++;
2194
2113
  }
2195
2114
  directions[i] = currentDir;
2196
2115
  }
2197
2116
  return [zigzagValues, directions, isPivot];
2198
2117
  }
2118
+ function obv(close2, volume2) {
2119
+ return cum(close2.map((c, i) => i === 0 ? NaN : Math.sign(c - close2[i - 1]) * volume2[i]));
2120
+ }
2121
+ function pvt(close2, volume2) {
2122
+ return cum(
2123
+ close2.map((c, i) => i === 0 ? NaN : (c - close2[i - 1]) / close2[i - 1] * volume2[i])
2124
+ );
2125
+ }
2126
+ function accdist(high2, low2, close2, volume2) {
2127
+ return cum(
2128
+ close2.map((c, i) => {
2129
+ const h = high2[i];
2130
+ const l = low2[i];
2131
+ return h === l ? 0 : (2 * c - l - h) / (h - l) * volume2[i];
2132
+ })
2133
+ );
2134
+ }
2135
+ function iii(high2, low2, close2, volume2) {
2136
+ return close2.map((c, i) => {
2137
+ const range3 = high2[i] - low2[i];
2138
+ return range3 === 0 ? NaN : (2 * c - high2[i] - low2[i]) / range3 * volume2[i];
2139
+ });
2140
+ }
2141
+ function wvad(open2, high2, low2, close2, volume2) {
2142
+ return close2.map((c, i) => {
2143
+ const range3 = high2[i] - low2[i];
2144
+ return range3 === 0 ? NaN : (c - open2[i]) / range3 * volume2[i];
2145
+ });
2146
+ }
2147
+ function wad(high2, low2, close2) {
2148
+ return cum(
2149
+ close2.map((c, i) => {
2150
+ const prev = i === 0 ? NaN : close2[i - 1];
2151
+ const mom3 = c - prev;
2152
+ if (mom3 > 0) return c - Math.min(low2[i], prev);
2153
+ if (mom3 < 0) return c - Math.max(high2[i], prev);
2154
+ return 0;
2155
+ })
2156
+ );
2157
+ }
2158
+ function volumeIndex(close2, volume2, use) {
2159
+ const result = [];
2160
+ let prevIndex = NaN;
2161
+ for (let i = 0; i < close2.length; i++) {
2162
+ const prev = !prevIndex ? 1 : prevIndex;
2163
+ const c = close2[i];
2164
+ const prevC = i === 0 ? NaN : close2[i - 1];
2165
+ let value = prev;
2166
+ if (c && prevC) {
2167
+ const prevV = i === 0 || Number.isNaN(volume2[i - 1]) ? 0 : volume2[i - 1];
2168
+ if (use(volume2[i], prevV)) value = prev + (c - prevC) / prevC * prev;
2169
+ }
2170
+ result.push(value);
2171
+ prevIndex = value;
2172
+ }
2173
+ return result;
2174
+ }
2175
+ function nvi(close2, volume2) {
2176
+ return volumeIndex(close2, volume2, (v, prevV) => v < prevV);
2177
+ }
2178
+ function pvi(close2, volume2) {
2179
+ return volumeIndex(close2, volume2, (v, prevV) => v > prevV);
2180
+ }
2199
2181
 
2200
2182
  // src/ta-series.ts
2201
- function sma2(source, length) {
2183
+ function sma2(source, length2) {
2202
2184
  const bars2 = source.bars;
2203
2185
  const sourceValues = source.toArray();
2204
- const result = sma(sourceValues, length);
2186
+ const result = sma(sourceValues, length2);
2205
2187
  return Series.fromArray(bars2, result);
2206
2188
  }
2207
- function ema2(source, length) {
2189
+ function ema2(source, length2) {
2208
2190
  const bars2 = source.bars;
2209
2191
  const sourceValues = source.toArray();
2210
- const result = ema(sourceValues, length);
2192
+ const result = ema(sourceValues, length2);
2211
2193
  return Series.fromArray(bars2, result);
2212
2194
  }
2213
- function wma2(source, length) {
2195
+ function wma2(source, length2) {
2214
2196
  const bars2 = source.bars;
2215
2197
  const sourceValues = source.toArray();
2216
- const result = wma(sourceValues, length);
2198
+ const result = wma(sourceValues, length2);
2217
2199
  return Series.fromArray(bars2, result);
2218
2200
  }
2219
- function rma2(source, length) {
2201
+ function rma2(source, length2) {
2220
2202
  const bars2 = source.bars;
2221
2203
  const sourceValues = source.toArray();
2222
- const result = rma(sourceValues, length);
2204
+ const result = rma(sourceValues, length2);
2223
2205
  return Series.fromArray(bars2, result);
2224
2206
  }
2225
- function rsi2(source, length) {
2207
+ function rsi2(source, length2) {
2226
2208
  const bars2 = source.bars;
2227
2209
  const sourceValues = source.toArray();
2228
- const result = rsi(sourceValues, length);
2210
+ const result = rsi(sourceValues, length2);
2229
2211
  return Series.fromArray(bars2, result);
2230
2212
  }
2231
2213
  function macd2(source, fastLength, slowLength, signalLength) {
@@ -2237,26 +2219,24 @@ function macd2(source, fastLength, slowLength, signalLength) {
2237
2219
  const histSeries = Series.fromArray(bars2, histVals);
2238
2220
  return [macdSeries, signalSeries, histSeries];
2239
2221
  }
2240
- function bb2(source, length, mult) {
2222
+ function bb2(source, length2, mult) {
2241
2223
  const bars2 = source.bars;
2242
2224
  const sourceValues = source.toArray();
2243
- const [upperVals, basisVals, lowerVals] = bb(sourceValues, length, mult);
2225
+ const [upperVals, basisVals, lowerVals] = bb(sourceValues, length2, mult);
2244
2226
  const upperSeries = Series.fromArray(bars2, upperVals);
2245
2227
  const basisSeries = Series.fromArray(bars2, basisVals);
2246
2228
  const lowerSeries = Series.fromArray(bars2, lowerVals);
2247
2229
  return [upperSeries, basisSeries, lowerSeries];
2248
2230
  }
2249
- function stdev2(source, length) {
2231
+ function stdev2(source, length2, biased = true) {
2250
2232
  const bars2 = source.bars;
2251
- const sourceValues = source.toArray();
2252
- const result = stdev(sourceValues, length);
2253
- return Series.fromArray(bars2, result);
2233
+ return Series.fromArray(bars2, stdev(source.toArray(), length2, biased));
2254
2234
  }
2255
- function atr2(bars2, length) {
2235
+ function atr2(bars2, length2) {
2256
2236
  const high2 = bars2.map((b2) => b2.high);
2257
2237
  const low2 = bars2.map((b2) => b2.low);
2258
2238
  const close2 = bars2.map((b2) => b2.close);
2259
- const result = atr(length, high2, low2, close2);
2239
+ const result = atr(length2, high2, low2, close2);
2260
2240
  return Series.fromArray(bars2, result);
2261
2241
  }
2262
2242
  function tr2(bars2, handle_na = false) {
@@ -2266,12 +2246,46 @@ function tr2(bars2, handle_na = false) {
2266
2246
  const result = tr(handle_na, high2, low2, close2);
2267
2247
  return Series.fromArray(bars2, result);
2268
2248
  }
2269
- function stoch2(source, high2, low2, length) {
2249
+ var col = (bars2, f) => bars2.map((b2) => b2[f] ?? NaN);
2250
+ function obv2(bars2) {
2251
+ return Series.fromArray(bars2, obv(col(bars2, "close"), col(bars2, "volume")));
2252
+ }
2253
+ function pvt2(bars2) {
2254
+ return Series.fromArray(bars2, pvt(col(bars2, "close"), col(bars2, "volume")));
2255
+ }
2256
+ function accdist2(bars2) {
2257
+ return Series.fromArray(
2258
+ bars2,
2259
+ accdist(col(bars2, "high"), col(bars2, "low"), col(bars2, "close"), col(bars2, "volume"))
2260
+ );
2261
+ }
2262
+ function nvi2(bars2) {
2263
+ return Series.fromArray(bars2, nvi(col(bars2, "close"), col(bars2, "volume")));
2264
+ }
2265
+ function pvi2(bars2) {
2266
+ return Series.fromArray(bars2, pvi(col(bars2, "close"), col(bars2, "volume")));
2267
+ }
2268
+ function iii2(bars2) {
2269
+ return Series.fromArray(
2270
+ bars2,
2271
+ iii(col(bars2, "high"), col(bars2, "low"), col(bars2, "close"), col(bars2, "volume"))
2272
+ );
2273
+ }
2274
+ function wad2(bars2) {
2275
+ return Series.fromArray(bars2, wad(col(bars2, "high"), col(bars2, "low"), col(bars2, "close")));
2276
+ }
2277
+ function wvad2(bars2) {
2278
+ return Series.fromArray(
2279
+ bars2,
2280
+ wvad(col(bars2, "open"), col(bars2, "high"), col(bars2, "low"), col(bars2, "close"), col(bars2, "volume"))
2281
+ );
2282
+ }
2283
+ function stoch2(source, high2, low2, length2) {
2270
2284
  const bars2 = source.bars;
2271
2285
  const sourceValues = source.toArray();
2272
2286
  const highValues = high2.toArray();
2273
2287
  const lowValues = low2.toArray();
2274
- const result = stoch(sourceValues, highValues, lowValues, length);
2288
+ const result = stoch(sourceValues, highValues, lowValues, length2);
2275
2289
  return Series.fromArray(bars2, result);
2276
2290
  }
2277
2291
  function crossover2(source1, source2) {
@@ -2298,47 +2312,47 @@ function cross2(source1, source2) {
2298
2312
  const numResult = result.map((b2) => b2 ? 1 : 0);
2299
2313
  return Series.fromArray(bars2, numResult);
2300
2314
  }
2301
- function change2(source, length = 1) {
2315
+ function change2(source, length2 = 1) {
2302
2316
  const bars2 = source.bars;
2303
2317
  const sourceValues = source.toArray();
2304
- const result = change(sourceValues, length);
2318
+ const result = change(sourceValues, length2);
2305
2319
  return Series.fromArray(bars2, result);
2306
2320
  }
2307
- function mom2(source, length) {
2321
+ function mom2(source, length2) {
2308
2322
  const bars2 = source.bars;
2309
2323
  const sourceValues = source.toArray();
2310
- const result = mom(sourceValues, length);
2324
+ const result = mom(sourceValues, length2);
2311
2325
  return Series.fromArray(bars2, result);
2312
2326
  }
2313
- function roc2(source, length) {
2327
+ function roc2(source, length2) {
2314
2328
  const bars2 = source.bars;
2315
2329
  const sourceValues = source.toArray();
2316
- const result = roc(sourceValues, length);
2330
+ const result = roc(sourceValues, length2);
2317
2331
  return Series.fromArray(bars2, result);
2318
2332
  }
2319
- function highest2(source, length) {
2333
+ function highest2(source, length2) {
2320
2334
  const bars2 = source.bars;
2321
2335
  const sourceValues = source.toArray();
2322
- const result = highest(sourceValues, length);
2336
+ const result = highest(sourceValues, length2);
2323
2337
  return Series.fromArray(bars2, result);
2324
2338
  }
2325
- function lowest2(source, length) {
2339
+ function lowest2(source, length2) {
2326
2340
  const bars2 = source.bars;
2327
2341
  const sourceValues = source.toArray();
2328
- const result = lowest(sourceValues, length);
2342
+ const result = lowest(sourceValues, length2);
2329
2343
  return Series.fromArray(bars2, result);
2330
2344
  }
2331
- function rising2(source, length) {
2345
+ function rising2(source, length2) {
2332
2346
  const bars2 = source.bars;
2333
2347
  const sourceValues = source.toArray();
2334
- const result = rising(sourceValues, length);
2348
+ const result = rising(sourceValues, length2);
2335
2349
  const numResult = result.map((b2) => b2 ? 1 : 0);
2336
2350
  return Series.fromArray(bars2, numResult);
2337
2351
  }
2338
- function falling2(source, length) {
2352
+ function falling2(source, length2) {
2339
2353
  const bars2 = source.bars;
2340
2354
  const sourceValues = source.toArray();
2341
- const result = falling(sourceValues, length);
2355
+ const result = falling(sourceValues, length2);
2342
2356
  const numResult = result.map((b2) => b2 ? 1 : 0);
2343
2357
  return Series.fromArray(bars2, numResult);
2344
2358
  }
@@ -2357,12 +2371,14 @@ function supertrend2(bars2, factor, atrLength) {
2357
2371
  const dirSeries = Series.fromArray(bars2, dirVals);
2358
2372
  return [trendSeries, dirSeries];
2359
2373
  }
2360
- function vwap2(source, volume2) {
2374
+ function vwap2(source, volume2, anchor) {
2361
2375
  const bars2 = source.bars;
2362
- const sourceValues = source.toArray();
2363
- const volumeValues = volume2.toArray();
2364
- const result = vwap(sourceValues, volumeValues);
2365
- return Series.fromArray(bars2, result);
2376
+ return Series.fromArray(bars2, vwap(source.toArray(), volume2.toArray(), anchor?.toArray()));
2377
+ }
2378
+ function vwapBands(source, volume2, anchor, stdev_mult) {
2379
+ const bars2 = source.bars;
2380
+ const [m, u, l] = vwap(source.toArray(), volume2.toArray(), anchor?.toArray(), stdev_mult);
2381
+ return [Series.fromArray(bars2, m), Series.fromArray(bars2, u), Series.fromArray(bars2, l)];
2366
2382
  }
2367
2383
  function ichimoku2(bars2, conversionPeriods, basePeriods, laggingSpan2Periods, displacement) {
2368
2384
  const high2 = bars2.map((b2) => b2.high);
@@ -2385,23 +2401,23 @@ function ichimoku2(bars2, conversionPeriods, basePeriods, laggingSpan2Periods, d
2385
2401
  Series.fromArray(bars2, chikou)
2386
2402
  ];
2387
2403
  }
2388
- function vwma2(source, length, volume2) {
2404
+ function vwma2(source, length2, volume2) {
2389
2405
  const bars2 = source.bars;
2390
2406
  const sourceValues = source.toArray();
2391
2407
  const volumeValues = volume2.toArray();
2392
- const result = vwma(sourceValues, length, volumeValues);
2408
+ const result = vwma(sourceValues, length2, volumeValues);
2393
2409
  return Series.fromArray(bars2, result);
2394
2410
  }
2395
- function linreg2(source, length, offset = 0) {
2411
+ function linreg2(source, length2, offset = 0) {
2396
2412
  const bars2 = source.bars;
2397
2413
  const sourceValues = source.toArray();
2398
- const result = linreg(sourceValues, length, offset);
2414
+ const result = linreg(sourceValues, length2, offset);
2399
2415
  return Series.fromArray(bars2, result);
2400
2416
  }
2401
- function alma2(source, length = 9, offset = 0.85, sigma = 6, floor2 = false) {
2417
+ function alma2(source, length2 = 9, offset = 0.85, sigma = 6, floor2 = false) {
2402
2418
  const bars2 = source.bars;
2403
2419
  const sourceValues = source.toArray();
2404
- const result = alma(sourceValues, length, offset, sigma, floor2);
2420
+ const result = alma(sourceValues, length2, offset, sigma, floor2);
2405
2421
  return Series.fromArray(bars2, result);
2406
2422
  }
2407
2423
  function zigzag2(bars2, deviation = 5, depth = 10, backstep = 3) {
@@ -2421,10 +2437,10 @@ function zigzag2(bars2, deviation = 5, depth = 10, backstep = 3) {
2421
2437
  Series.fromArray(bars2, pivotVals.map((b2) => b2 ? 1 : 0))
2422
2438
  ];
2423
2439
  }
2424
- function cci2(source, length) {
2440
+ function cci2(source, length2) {
2425
2441
  const bars2 = source.bars;
2426
2442
  const sourceValues = source.toArray();
2427
- const result = cci(sourceValues, length);
2443
+ const result = cci(sourceValues, length2);
2428
2444
  return Series.fromArray(bars2, result);
2429
2445
  }
2430
2446
  function sar2(bars2, start = 0.02, inc = 0.02, max4 = 0.2) {
@@ -2434,19 +2450,19 @@ function sar2(bars2, start = 0.02, inc = 0.02, max4 = 0.2) {
2434
2450
  const result = sar(start, inc, max4, high2, low2, close2);
2435
2451
  return Series.fromArray(bars2, result);
2436
2452
  }
2437
- function dev2(source, length) {
2453
+ function dev2(source, length2) {
2438
2454
  const bars2 = source.bars;
2439
- const result = dev(source.toArray(), length);
2455
+ const result = dev(source.toArray(), length2);
2440
2456
  return Series.fromArray(bars2, result);
2441
2457
  }
2442
- function variance2(source, length, biased = true) {
2458
+ function variance2(source, length2, biased = true) {
2443
2459
  const bars2 = source.bars;
2444
- const result = variance(source.toArray(), length, biased);
2460
+ const result = variance(source.toArray(), length2, biased);
2445
2461
  return Series.fromArray(bars2, result);
2446
2462
  }
2447
- function median2(source, length) {
2463
+ function median2(source, length2) {
2448
2464
  const bars2 = source.bars;
2449
- const result = median(source.toArray(), length);
2465
+ const result = median(source.toArray(), length2);
2450
2466
  return Series.fromArray(bars2, result);
2451
2467
  }
2452
2468
  function swma2(source) {
@@ -2454,24 +2470,24 @@ function swma2(source) {
2454
2470
  const result = swma(source.toArray());
2455
2471
  return Series.fromArray(bars2, result);
2456
2472
  }
2457
- function correlation2(source1, source2, length) {
2473
+ function correlation2(source1, source2, length2) {
2458
2474
  const bars2 = source1.bars;
2459
- const result = correlation(source1.toArray(), source2.toArray(), length);
2475
+ const result = correlation(source1.toArray(), source2.toArray(), length2);
2460
2476
  return Series.fromArray(bars2, result);
2461
2477
  }
2462
- function percentrank2(source, length) {
2478
+ function percentrank2(source, length2) {
2463
2479
  const bars2 = source.bars;
2464
- const result = percentrank(source.toArray(), length);
2480
+ const result = percentrank(source.toArray(), length2);
2465
2481
  return Series.fromArray(bars2, result);
2466
2482
  }
2467
- function mfi2(source, length, volume2) {
2483
+ function mfi2(source, length2, volume2) {
2468
2484
  const bars2 = source.bars;
2469
- const result = mfi(source.toArray(), length, volume2.toArray());
2485
+ const result = mfi(source.toArray(), length2, volume2.toArray());
2470
2486
  return Series.fromArray(bars2, result);
2471
2487
  }
2472
- function hma2(source, length) {
2488
+ function hma2(source, length2) {
2473
2489
  const bars2 = source.bars;
2474
- const result = hma(source.toArray(), length);
2490
+ const result = hma(source.toArray(), length2);
2475
2491
  return Series.fromArray(bars2, result);
2476
2492
  }
2477
2493
  function pivothigh2(source, leftbars, rightbars) {
@@ -2512,89 +2528,86 @@ function tsi2(source, shortLength, longLength) {
2512
2528
  const result = tsi(source.toArray(), shortLength, longLength);
2513
2529
  return Series.fromArray(bars2, result);
2514
2530
  }
2515
- function cmo2(source, length) {
2531
+ function cmo2(source, length2) {
2516
2532
  const bars2 = source.bars;
2517
- const result = cmo(source.toArray(), length);
2533
+ const result = cmo(source.toArray(), length2);
2518
2534
  return Series.fromArray(bars2, result);
2519
2535
  }
2520
- function kc2(bars2, source, length, mult, useTrueRange = true) {
2536
+ function kc2(bars2, source, length2, mult, useTrueRange = true) {
2521
2537
  const high2 = bars2.map((b2) => b2.high);
2522
2538
  const low2 = bars2.map((b2) => b2.low);
2523
2539
  const close2 = bars2.map((b2) => b2.close);
2524
- const [middle, upper, lower] = kc(source.toArray(), length, mult, useTrueRange, high2, low2, close2);
2540
+ const [middle, upper2, lower2] = kc(source.toArray(), length2, mult, useTrueRange, high2, low2, close2);
2525
2541
  return [
2526
2542
  Series.fromArray(bars2, middle),
2527
- Series.fromArray(bars2, upper),
2528
- Series.fromArray(bars2, lower)
2543
+ Series.fromArray(bars2, upper2),
2544
+ Series.fromArray(bars2, lower2)
2529
2545
  ];
2530
2546
  }
2531
- function bbw2(source, length, mult) {
2547
+ function bbw2(source, length2, mult) {
2532
2548
  const bars2 = source.bars;
2533
- const result = bbw(source.toArray(), length, mult);
2549
+ const result = bbw(source.toArray(), length2, mult);
2534
2550
  return Series.fromArray(bars2, result);
2535
2551
  }
2536
- function wpr2(bars2, length = 14) {
2552
+ function wpr2(bars2, length2 = 14) {
2537
2553
  const high2 = bars2.map((b2) => b2.high);
2538
2554
  const low2 = bars2.map((b2) => b2.low);
2539
2555
  const close2 = bars2.map((b2) => b2.close);
2540
- const result = wpr(high2, low2, close2, length);
2556
+ const result = wpr(high2, low2, close2, length2);
2541
2557
  return Series.fromArray(bars2, result);
2542
2558
  }
2543
- function kcw2(bars2, source, length = 20, mult = 2, useTrueRange = true) {
2559
+ function kcw2(bars2, source, length2 = 20, mult = 2, useTrueRange = true) {
2544
2560
  const high2 = bars2.map((b2) => b2.high);
2545
2561
  const low2 = bars2.map((b2) => b2.low);
2546
2562
  const close2 = bars2.map((b2) => b2.close);
2547
- const result = kcw(source.toArray(), length, mult, useTrueRange, high2, low2, close2);
2563
+ const result = kcw(source.toArray(), length2, mult, useTrueRange, high2, low2, close2);
2548
2564
  return Series.fromArray(bars2, result);
2549
2565
  }
2550
- function range2(high2, low2) {
2551
- const bars2 = high2.bars;
2552
- const result = range(high2.toArray(), low2.toArray());
2553
- return Series.fromArray(bars2, result);
2566
+ function range2(source, length2) {
2567
+ const bars2 = source.bars;
2568
+ return Series.fromArray(bars2, range(source.toArray(), length2));
2554
2569
  }
2555
- function highestbars2(source, length) {
2570
+ function highestbars2(source, length2) {
2556
2571
  const bars2 = source.bars;
2557
- const result = highestbars(source.toArray(), length);
2572
+ const result = highestbars(source.toArray(), length2);
2558
2573
  return Series.fromArray(bars2, result);
2559
2574
  }
2560
- function lowestbars2(source, length) {
2575
+ function lowestbars2(source, length2) {
2561
2576
  const bars2 = source.bars;
2562
- const result = lowestbars(source.toArray(), length);
2577
+ const result = lowestbars(source.toArray(), length2);
2563
2578
  return Series.fromArray(bars2, result);
2564
2579
  }
2565
- function max2(source1, source2) {
2566
- const bars2 = source1.bars;
2567
- const result = max(source1.toArray(), source2.toArray());
2568
- return Series.fromArray(bars2, result);
2580
+ function max2(source) {
2581
+ const bars2 = source.bars;
2582
+ return Series.fromArray(bars2, max(source.toArray()));
2569
2583
  }
2570
- function min2(source1, source2) {
2571
- const bars2 = source1.bars;
2572
- const result = min(source1.toArray(), source2.toArray());
2573
- return Series.fromArray(bars2, result);
2584
+ function min2(source) {
2585
+ const bars2 = source.bars;
2586
+ return Series.fromArray(bars2, min(source.toArray()));
2574
2587
  }
2575
- function cog2(source, length = 10) {
2588
+ function cog2(source, length2 = 10) {
2576
2589
  const bars2 = source.bars;
2577
- const result = cog(source.toArray(), length);
2590
+ const result = cog(source.toArray(), length2);
2578
2591
  return Series.fromArray(bars2, result);
2579
2592
  }
2580
- function mode2(source, length) {
2593
+ function mode2(source, length2) {
2581
2594
  const bars2 = source.bars;
2582
- const result = mode(source.toArray(), length);
2595
+ const result = mode(source.toArray(), length2);
2583
2596
  return Series.fromArray(bars2, result);
2584
2597
  }
2585
- function percentile_linear_interpolation2(source, length, percentage) {
2598
+ function percentile_linear_interpolation2(source, length2, percentage) {
2586
2599
  const bars2 = source.bars;
2587
- const result = percentile_linear_interpolation(source.toArray(), length, percentage);
2600
+ const result = percentile_linear_interpolation(source.toArray(), length2, percentage);
2588
2601
  return Series.fromArray(bars2, result);
2589
2602
  }
2590
- function percentile_nearest_rank2(source, length, percentage) {
2603
+ function percentile_nearest_rank2(source, length2, percentage) {
2591
2604
  const bars2 = source.bars;
2592
- const result = percentile_nearest_rank(source.toArray(), length, percentage);
2605
+ const result = percentile_nearest_rank(source.toArray(), length2, percentage);
2593
2606
  return Series.fromArray(bars2, result);
2594
2607
  }
2595
- function rci2(source, length) {
2608
+ function rci2(source, length2) {
2596
2609
  const bars2 = source.bars;
2597
- const result = rci(source.toArray(), length);
2610
+ const result = rci(source.toArray(), length2);
2598
2611
  return Series.fromArray(bars2, result);
2599
2612
  }
2600
2613
  var ta = {
@@ -2653,6 +2666,15 @@ var ta = {
2653
2666
  lowestbars: lowestbars2,
2654
2667
  max: max2,
2655
2668
  min: min2,
2669
+ vwapBands,
2670
+ obv: obv2,
2671
+ pvt: pvt2,
2672
+ accdist: accdist2,
2673
+ nvi: nvi2,
2674
+ pvi: pvi2,
2675
+ iii: iii2,
2676
+ wad: wad2,
2677
+ wvad: wvad2,
2656
2678
  cog: cog2,
2657
2679
  mode: mode2,
2658
2680
  percentile_linear_interpolation: percentile_linear_interpolation2,
@@ -2725,13 +2747,13 @@ function t(clr) {
2725
2747
  }
2726
2748
  function parseColor(clr) {
2727
2749
  if (typeof clr === "string") {
2728
- const match = clr.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
2729
- if (match) {
2750
+ const match2 = clr.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
2751
+ if (match2) {
2730
2752
  return {
2731
- r: parseInt(match[1]),
2732
- g: parseInt(match[2]),
2733
- b: parseInt(match[3]),
2734
- t: match[4] ? (1 - parseFloat(match[4])) * 100 : 0
2753
+ r: parseInt(match2[1]),
2754
+ g: parseInt(match2[2]),
2755
+ b: parseInt(match2[3]),
2756
+ t: match2[4] ? (1 - parseFloat(match2[4])) * 100 : 0
2735
2757
  };
2736
2758
  }
2737
2759
  }
@@ -2755,22 +2777,22 @@ var teal = "#008080";
2755
2777
  var white = "#FFFFFF";
2756
2778
  var yellow = "#FFFF00";
2757
2779
  function from_gradient(value, bottom_value, top_value, bottom_color, top_color) {
2758
- const parseColor2 = (col) => {
2759
- if (typeof col === "string") {
2760
- if (col.startsWith("#")) {
2761
- const hex = col.slice(1);
2780
+ const parseColor2 = (col2) => {
2781
+ if (typeof col2 === "string") {
2782
+ if (col2.startsWith("#")) {
2783
+ const hex = col2.slice(1);
2762
2784
  const r4 = parseInt(hex.slice(0, 2), 16);
2763
2785
  const g4 = parseInt(hex.slice(2, 4), 16);
2764
2786
  const b4 = parseInt(hex.slice(4, 6), 16);
2765
2787
  return [r4, g4, b4, 1];
2766
2788
  }
2767
- const match = col.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
2768
- if (match) {
2789
+ const match2 = col2.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
2790
+ if (match2) {
2769
2791
  return [
2770
- parseInt(match[1]),
2771
- parseInt(match[2]),
2772
- parseInt(match[3]),
2773
- match[4] ? parseFloat(match[4]) : 1
2792
+ parseInt(match2[1]),
2793
+ parseInt(match2[2]),
2794
+ parseInt(match2[3]),
2795
+ match2[4] ? parseFloat(match2[4]) : 1
2774
2796
  ];
2775
2797
  }
2776
2798
  }
@@ -2796,102 +2818,2086 @@ function from_gradient(value, bottom_value, top_value, bottom_color, top_color)
2796
2818
  return `rgba(${r3}, ${g3}, ${b3}, ${a})`;
2797
2819
  }
2798
2820
 
2821
+ // src/drawing/registry.ts
2822
+ var DEFAULT_MAX_COUNT = 50;
2823
+ var SLACK = 5;
2824
+ var live = { line: [], label: [], box: [], polyline: [], linefill: [] };
2825
+ var limits = {
2826
+ line: DEFAULT_MAX_COUNT,
2827
+ label: DEFAULT_MAX_COUNT,
2828
+ box: DEFAULT_MAX_COUNT,
2829
+ polyline: DEFAULT_MAX_COUNT
2830
+ };
2831
+ var deleted = /* @__PURE__ */ new WeakSet();
2832
+ var COORDINATES = {
2833
+ line: ["x1", "y1", "x2", "y2"],
2834
+ label: ["x", "y"],
2835
+ box: ["left", "top", "right", "bottom"],
2836
+ polyline: [],
2837
+ linefill: []
2838
+ };
2839
+ function markDeleted(kind, obj, explicit) {
2840
+ deleted.add(obj);
2841
+ for (const field2 of COORDINATES[kind]) obj[field2] = NaN;
2842
+ if (kind === "line" && explicit) {
2843
+ for (const fill2 of live.linefill.filter((f) => f.line1 === obj || f.line2 === obj)) remove("linefill", fill2);
2844
+ }
2845
+ }
2846
+ function register(kind, obj) {
2847
+ const list = live[kind];
2848
+ list.push(obj);
2849
+ const max4 = limits[kind === "linefill" ? "line" : kind];
2850
+ if (list.length > max4 + SLACK) {
2851
+ for (const old of list.splice(0, list.length - max4)) markDeleted(kind, old, false);
2852
+ }
2853
+ return obj;
2854
+ }
2855
+ function remove(kind, obj) {
2856
+ const list = live[kind];
2857
+ const index = list.indexOf(obj);
2858
+ if (index !== -1) list.splice(index, 1);
2859
+ if (!deleted.has(obj)) markDeleted(kind, obj, true);
2860
+ }
2861
+ function isDeleted(obj) {
2862
+ return typeof obj === "object" && obj !== null && deleted.has(obj);
2863
+ }
2864
+ function all(kind) {
2865
+ return [...live[kind]];
2866
+ }
2867
+ function resetDrawings(newLimits = {}) {
2868
+ for (const kind of Object.keys(live)) live[kind].length = 0;
2869
+ limits = {
2870
+ line: newLimits.line ?? DEFAULT_MAX_COUNT,
2871
+ label: newLimits.label ?? DEFAULT_MAX_COUNT,
2872
+ box: newLimits.box ?? DEFAULT_MAX_COUNT,
2873
+ polyline: newLimits.polyline ?? DEFAULT_MAX_COUNT
2874
+ };
2875
+ }
2876
+ function setDrawingLimits(newLimits) {
2877
+ limits = { ...limits, ...Object.fromEntries(Object.entries(newLimits).filter(([, v]) => v !== void 0)) };
2878
+ }
2879
+
2799
2880
  // src/utils/index.ts
2800
2881
  function isNA(value) {
2801
- return value === null || value === void 0 || Number.isNaN(value);
2882
+ return value === null || value === void 0 || Number.isNaN(value) || isDeleted(value);
2802
2883
  }
2803
2884
  function nz(value, defaultValue = 0) {
2804
2885
  return isNA(value) ? defaultValue : value;
2805
2886
  }
2887
+ function fixnan(source) {
2888
+ let last;
2889
+ let seen = false;
2890
+ return source.map((v) => {
2891
+ if (!isNA(v)) {
2892
+ last = v;
2893
+ seen = true;
2894
+ return v;
2895
+ }
2896
+ return seen ? last : v;
2897
+ });
2898
+ }
2806
2899
 
2807
- // src/math/index.ts
2808
- var math_exports = {};
2809
- __export(math_exports, {
2810
- abs: () => abs,
2811
- acos: () => acos,
2812
- asin: () => asin,
2813
- atan: () => atan,
2814
- avg: () => avg,
2815
- ceil: () => ceil,
2816
- cos: () => cos,
2817
- e: () => e,
2818
- exp: () => exp,
2819
- floor: () => floor,
2820
- log: () => log,
2821
- log10: () => log10,
2822
- max: () => max3,
2823
- min: () => min3,
2824
- phi: () => phi,
2825
- pi: () => pi,
2826
- pow: () => pow,
2827
- random: () => random,
2828
- round: () => round,
2829
- round_to_mintick: () => round_to_mintick,
2830
- rphi: () => rphi,
2831
- sign: () => sign,
2832
- sin: () => sin,
2833
- sqrt: () => sqrt,
2834
- sum: () => sum,
2835
- tan: () => tan,
2836
- todegrees: () => todegrees,
2837
- toradians: () => toradians
2900
+ // src/line/index.ts
2901
+ var line_exports = {};
2902
+ __export(line_exports, {
2903
+ all: () => all2,
2904
+ copy: () => copy,
2905
+ delete: () => delete_line,
2906
+ delete_line: () => delete_line,
2907
+ get_price: () => get_price,
2908
+ get_x1: () => get_x1,
2909
+ get_x2: () => get_x2,
2910
+ get_y1: () => get_y1,
2911
+ get_y2: () => get_y2,
2912
+ new: () => new_line,
2913
+ new_line: () => new_line,
2914
+ set_color: () => set_color,
2915
+ set_extend: () => set_extend,
2916
+ set_first_point: () => set_first_point,
2917
+ set_second_point: () => set_second_point,
2918
+ set_style: () => set_style,
2919
+ set_width: () => set_width,
2920
+ set_x1: () => set_x1,
2921
+ set_x2: () => set_x2,
2922
+ set_xloc: () => set_xloc,
2923
+ set_xy1: () => set_xy1,
2924
+ set_xy2: () => set_xy2,
2925
+ set_y1: () => set_y1,
2926
+ set_y2: () => set_y2
2838
2927
  });
2839
- function abs(value) {
2840
- if (value instanceof Series) {
2841
- const bars2 = value.bars;
2842
- const valueArray = value.toArray();
2843
- const length = bars2.length;
2844
- const result = [];
2845
- for (let i = 0; i < length; i++) {
2846
- const v = valueArray[i] ?? NaN;
2847
- result.push(Math.abs(v));
2848
- }
2849
- return Series.fromArray(bars2, result);
2850
- }
2851
- return Math.abs(value);
2928
+ function new_line(...args) {
2929
+ let x1, y1, x2, y2, rest;
2930
+ if (typeof args[0] === "object" && args[0] !== null) {
2931
+ const [p1, p2, ...others] = args;
2932
+ const xloc2 = others[0] ?? "bar_index";
2933
+ [x1, y1, x2, y2, rest] = [pointX(p1, xloc2), p1.price, pointX(p2, xloc2), p2.price, others];
2934
+ } else {
2935
+ [x1, y1, x2, y2] = args;
2936
+ rest = args.slice(4);
2937
+ }
2938
+ const [xloc, extend, lineColor, style, width, force_overlay] = rest;
2939
+ return register("line", {
2940
+ x1,
2941
+ y1,
2942
+ x2,
2943
+ y2,
2944
+ xloc: xloc ?? "bar_index",
2945
+ extend: extend ?? "none",
2946
+ color: lineColor,
2947
+ style: style || "solid",
2948
+ width: width || 1,
2949
+ force_overlay: force_overlay ?? false
2950
+ });
2852
2951
  }
2853
- function ceil(value) {
2854
- if (value instanceof Series) {
2855
- const bars2 = value.bars;
2856
- const valueArray = value.toArray();
2857
- const length = bars2.length;
2858
- const result = [];
2859
- for (let i = 0; i < length; i++) {
2860
- const v = valueArray[i] ?? NaN;
2861
- result.push(Math.ceil(v));
2862
- }
2863
- return Series.fromArray(bars2, result);
2952
+ function get_price(id, x) {
2953
+ const { x1, y1, x2, y2, extend, xloc } = id;
2954
+ if (xloc === "bar_time") {
2955
+ throw new Error("line.get_price() only works with xloc.bar_index lines, not xloc.bar_time");
2864
2956
  }
2865
- return Math.ceil(value);
2866
- }
2867
- function floor(value) {
2868
- if (value instanceof Series) {
2869
- const bars2 = value.bars;
2870
- const valueArray = value.toArray();
2871
- const length = bars2.length;
2872
- const result = [];
2873
- for (let i = 0; i < length; i++) {
2874
- const v = valueArray[i] ?? NaN;
2875
- result.push(Math.floor(v));
2957
+ if (x2 === x1) {
2958
+ return NaN;
2959
+ }
2960
+ const slope = (y2 - y1) / (x2 - x1);
2961
+ const price = y1 + slope * (x - x1);
2962
+ if (extend === "none") {
2963
+ if (x < Math.min(x1, x2) || x > Math.max(x1, x2)) {
2964
+ return NaN;
2965
+ }
2966
+ } else if (extend === "left") {
2967
+ if (x > Math.max(x1, x2)) {
2968
+ return NaN;
2969
+ }
2970
+ } else if (extend === "right") {
2971
+ if (x < Math.min(x1, x2)) {
2972
+ return NaN;
2876
2973
  }
2877
- return Series.fromArray(bars2, result);
2878
2974
  }
2879
- return Math.floor(value);
2975
+ return price;
2880
2976
  }
2881
- function round(value, precision) {
2882
- if (value instanceof Series) {
2883
- const bars2 = value.bars;
2977
+ function get_x1(id) {
2978
+ return id.x1;
2979
+ }
2980
+ function get_x2(id) {
2981
+ return id.x2;
2982
+ }
2983
+ function get_y1(id) {
2984
+ return id.y1;
2985
+ }
2986
+ function get_y2(id) {
2987
+ return id.y2;
2988
+ }
2989
+ function copy(id) {
2990
+ return register("line", { ...id });
2991
+ }
2992
+ function set_x1(id, x) {
2993
+ if (isDeleted(id)) return id;
2994
+ id.x1 = x;
2995
+ return id;
2996
+ }
2997
+ function set_x2(id, x) {
2998
+ if (isDeleted(id)) return id;
2999
+ id.x2 = x;
3000
+ return id;
3001
+ }
3002
+ function set_y1(id, y) {
3003
+ if (isDeleted(id)) return id;
3004
+ id.y1 = y;
3005
+ return id;
3006
+ }
3007
+ function set_y2(id, y) {
3008
+ if (isDeleted(id)) return id;
3009
+ id.y2 = y;
3010
+ return id;
3011
+ }
3012
+ function set_xy1(id, x, y) {
3013
+ if (isDeleted(id)) return id;
3014
+ id.x1 = x;
3015
+ id.y1 = y;
3016
+ return id;
3017
+ }
3018
+ function set_xy2(id, x, y) {
3019
+ if (isDeleted(id)) return id;
3020
+ id.x2 = x;
3021
+ id.y2 = y;
3022
+ return id;
3023
+ }
3024
+ function set_xloc(id, x1, x2, xloc) {
3025
+ if (isDeleted(id)) return id;
3026
+ id.x1 = x1;
3027
+ id.x2 = x2;
3028
+ id.xloc = xloc;
3029
+ return id;
3030
+ }
3031
+ function set_extend(id, extend) {
3032
+ if (isDeleted(id)) return id;
3033
+ id.extend = extend;
3034
+ return id;
3035
+ }
3036
+ function set_color(id, lineColor) {
3037
+ if (isDeleted(id)) return id;
3038
+ id.color = lineColor;
3039
+ return id;
3040
+ }
3041
+ function set_style(id, style) {
3042
+ if (isDeleted(id)) return id;
3043
+ id.style = style;
3044
+ return id;
3045
+ }
3046
+ function set_width(id, width) {
3047
+ if (isDeleted(id)) return id;
3048
+ id.width = width;
3049
+ return id;
3050
+ }
3051
+ function delete_line(id) {
3052
+ remove("line", id);
3053
+ }
3054
+ function pointX(point, xloc) {
3055
+ const x = xloc === "bar_time" ? point.time : point.index;
3056
+ return x ?? NaN;
3057
+ }
3058
+ function all2() {
3059
+ return all("line");
3060
+ }
3061
+ function set_first_point(id, point) {
3062
+ if (isDeleted(id)) return id;
3063
+ id.x1 = pointX(point, id.xloc);
3064
+ id.y1 = point.price;
3065
+ return id;
3066
+ }
3067
+ function set_second_point(id, point) {
3068
+ if (isDeleted(id)) return id;
3069
+ id.x2 = pointX(point, id.xloc);
3070
+ id.y2 = point.price;
3071
+ return id;
3072
+ }
3073
+
3074
+ // src/label/index.ts
3075
+ var label_exports = {};
3076
+ __export(label_exports, {
3077
+ all: () => all3,
3078
+ copy: () => copy2,
3079
+ delete: () => delete_label,
3080
+ delete_label: () => delete_label,
3081
+ get_text: () => get_text,
3082
+ get_x: () => get_x,
3083
+ get_y: () => get_y,
3084
+ new: () => new_label,
3085
+ new_label: () => new_label,
3086
+ set_color: () => set_color2,
3087
+ set_point: () => set_point,
3088
+ set_size: () => set_size,
3089
+ set_style: () => set_style2,
3090
+ set_text: () => set_text,
3091
+ set_text_font_family: () => set_text_font_family,
3092
+ set_text_formatting: () => set_text_formatting,
3093
+ set_textalign: () => set_textalign,
3094
+ set_textcolor: () => set_textcolor,
3095
+ set_tooltip: () => set_tooltip,
3096
+ set_x: () => set_x,
3097
+ set_xloc: () => set_xloc2,
3098
+ set_xy: () => set_xy,
3099
+ set_y: () => set_y,
3100
+ set_yloc: () => set_yloc
3101
+ });
3102
+ function new_label(...args) {
3103
+ let x, y, rest;
3104
+ if (typeof args[0] === "object" && args[0] !== null) {
3105
+ const point = args[0];
3106
+ rest = args.slice(1);
3107
+ x = pointX2(point, rest[1] ?? "bar_index");
3108
+ y = point.price;
3109
+ } else {
3110
+ [x, y] = args;
3111
+ rest = args.slice(2);
3112
+ }
3113
+ const [
3114
+ text2,
3115
+ xloc,
3116
+ yloc,
3117
+ labelColor,
3118
+ style,
3119
+ textcolor,
3120
+ size,
3121
+ textalign,
3122
+ tooltip,
3123
+ text_font_family,
3124
+ force_overlay,
3125
+ text_formatting
3126
+ ] = rest;
3127
+ return register("label", {
3128
+ x,
3129
+ y,
3130
+ xloc: xloc ?? "bar_index",
3131
+ yloc: yloc ?? "price",
3132
+ text: text2,
3133
+ tooltip,
3134
+ color: labelColor,
3135
+ style,
3136
+ textcolor,
3137
+ size,
3138
+ textalign,
3139
+ text_font_family,
3140
+ force_overlay: force_overlay ?? false,
3141
+ text_formatting
3142
+ });
3143
+ }
3144
+ function get_x(id) {
3145
+ return id.x;
3146
+ }
3147
+ function get_y(id) {
3148
+ return id.y;
3149
+ }
3150
+ function get_text(id) {
3151
+ return id.text;
3152
+ }
3153
+ function copy2(id) {
3154
+ return register("label", { ...id });
3155
+ }
3156
+ function set_x(id, x) {
3157
+ if (isDeleted(id)) return id;
3158
+ id.x = x;
3159
+ return id;
3160
+ }
3161
+ function set_y(id, y) {
3162
+ if (isDeleted(id)) return id;
3163
+ id.y = y;
3164
+ return id;
3165
+ }
3166
+ function set_xy(id, x, y) {
3167
+ if (isDeleted(id)) return id;
3168
+ id.x = x;
3169
+ id.y = y;
3170
+ return id;
3171
+ }
3172
+ function set_xloc2(id, x, xloc) {
3173
+ if (isDeleted(id)) return id;
3174
+ id.x = x;
3175
+ id.xloc = xloc;
3176
+ return id;
3177
+ }
3178
+ function set_yloc(id, yloc) {
3179
+ if (isDeleted(id)) return id;
3180
+ id.yloc = yloc;
3181
+ return id;
3182
+ }
3183
+ function set_text(id, text2) {
3184
+ if (isDeleted(id)) return id;
3185
+ id.text = text2;
3186
+ return id;
3187
+ }
3188
+ function set_tooltip(id, tooltip) {
3189
+ if (isDeleted(id)) return id;
3190
+ id.tooltip = tooltip;
3191
+ return id;
3192
+ }
3193
+ function set_color2(id, labelColor) {
3194
+ if (isDeleted(id)) return id;
3195
+ id.color = labelColor;
3196
+ return id;
3197
+ }
3198
+ function set_textcolor(id, textColor) {
3199
+ if (isDeleted(id)) return id;
3200
+ id.textcolor = textColor;
3201
+ return id;
3202
+ }
3203
+ function set_style2(id, style) {
3204
+ if (isDeleted(id)) return id;
3205
+ id.style = style;
3206
+ return id;
3207
+ }
3208
+ function set_size(id, size) {
3209
+ if (isDeleted(id)) return id;
3210
+ id.size = size;
3211
+ return id;
3212
+ }
3213
+ function set_textalign(id, align) {
3214
+ if (isDeleted(id)) return id;
3215
+ id.textalign = align;
3216
+ return id;
3217
+ }
3218
+ function set_text_font_family(id, font) {
3219
+ if (isDeleted(id)) return id;
3220
+ id.text_font_family = font;
3221
+ return id;
3222
+ }
3223
+ function delete_label(id) {
3224
+ remove("label", id);
3225
+ }
3226
+ function pointX2(point, xloc) {
3227
+ const x = xloc === "bar_time" ? point.time : point.index;
3228
+ return x ?? NaN;
3229
+ }
3230
+ function all3() {
3231
+ return all("label");
3232
+ }
3233
+ function set_point(id, point) {
3234
+ if (isDeleted(id)) return id;
3235
+ id.x = pointX2(point, id.xloc);
3236
+ id.y = point.price;
3237
+ return id;
3238
+ }
3239
+ function set_text_formatting(id, formatting) {
3240
+ if (isDeleted(id)) return id;
3241
+ id.text_formatting = formatting;
3242
+ return id;
3243
+ }
3244
+
3245
+ // src/box/index.ts
3246
+ var box_exports = {};
3247
+ __export(box_exports, {
3248
+ all: () => all4,
3249
+ copy: () => copy3,
3250
+ delete: () => delete_box,
3251
+ delete_box: () => delete_box,
3252
+ get_bottom: () => get_bottom,
3253
+ get_left: () => get_left,
3254
+ get_right: () => get_right,
3255
+ get_top: () => get_top,
3256
+ new: () => new_box,
3257
+ new_box: () => new_box,
3258
+ set_bgcolor: () => set_bgcolor,
3259
+ set_border_color: () => set_border_color,
3260
+ set_border_style: () => set_border_style,
3261
+ set_border_width: () => set_border_width,
3262
+ set_bottom: () => set_bottom,
3263
+ set_bottom_right_point: () => set_bottom_right_point,
3264
+ set_extend: () => set_extend2,
3265
+ set_left: () => set_left,
3266
+ set_lefttop: () => set_lefttop,
3267
+ set_right: () => set_right,
3268
+ set_rightbottom: () => set_rightbottom,
3269
+ set_text: () => set_text2,
3270
+ set_text_color: () => set_text_color,
3271
+ set_text_font_family: () => set_text_font_family2,
3272
+ set_text_formatting: () => set_text_formatting2,
3273
+ set_text_halign: () => set_text_halign,
3274
+ set_text_size: () => set_text_size,
3275
+ set_text_valign: () => set_text_valign,
3276
+ set_text_wrap: () => set_text_wrap,
3277
+ set_top: () => set_top,
3278
+ set_top_left_point: () => set_top_left_point,
3279
+ set_xloc: () => set_xloc3
3280
+ });
3281
+ function new_box(...args) {
3282
+ let left, top, right, bottom, rest;
3283
+ if (typeof args[0] === "object" && args[0] !== null) {
3284
+ const [tl, br, ...others] = args;
3285
+ const xloc2 = others[4] ?? "bar_index";
3286
+ [left, top, right, bottom, rest] = [pointX3(tl, xloc2), tl.price, pointX3(br, xloc2), br.price, others];
3287
+ } else {
3288
+ [left, top, right, bottom] = args;
3289
+ rest = args.slice(4);
3290
+ }
3291
+ const [
3292
+ border_color,
3293
+ border_width,
3294
+ border_style,
3295
+ extend,
3296
+ xloc,
3297
+ bgcolor2,
3298
+ text2,
3299
+ text_size,
3300
+ text_color,
3301
+ text_halign,
3302
+ text_valign,
3303
+ text_wrap,
3304
+ text_font_family,
3305
+ force_overlay,
3306
+ text_formatting
3307
+ ] = rest;
3308
+ return register("box", {
3309
+ left,
3310
+ top,
3311
+ right,
3312
+ bottom,
3313
+ xloc: xloc ?? "bar_index",
3314
+ extend: extend ?? "none",
3315
+ border_color,
3316
+ border_width: border_width || 1,
3317
+ border_style: border_style || "solid",
3318
+ bgcolor: bgcolor2,
3319
+ text: text2,
3320
+ text_size,
3321
+ text_color,
3322
+ text_halign,
3323
+ text_valign,
3324
+ text_wrap,
3325
+ text_font_family,
3326
+ force_overlay: force_overlay ?? false,
3327
+ text_formatting
3328
+ });
3329
+ }
3330
+ function get_left(id) {
3331
+ return id.left;
3332
+ }
3333
+ function get_right(id) {
3334
+ return id.right;
3335
+ }
3336
+ function get_top(id) {
3337
+ return id.top;
3338
+ }
3339
+ function get_bottom(id) {
3340
+ return id.bottom;
3341
+ }
3342
+ function copy3(id) {
3343
+ return register("box", { ...id });
3344
+ }
3345
+ function set_left(id, left) {
3346
+ if (isDeleted(id)) return id;
3347
+ id.left = left;
3348
+ return id;
3349
+ }
3350
+ function set_right(id, right) {
3351
+ if (isDeleted(id)) return id;
3352
+ id.right = right;
3353
+ return id;
3354
+ }
3355
+ function set_top(id, top) {
3356
+ if (isDeleted(id)) return id;
3357
+ id.top = top;
3358
+ return id;
3359
+ }
3360
+ function set_bottom(id, bottom) {
3361
+ if (isDeleted(id)) return id;
3362
+ id.bottom = bottom;
3363
+ return id;
3364
+ }
3365
+ function set_lefttop(id, left, top) {
3366
+ if (isDeleted(id)) return id;
3367
+ id.left = left;
3368
+ id.top = top;
3369
+ return id;
3370
+ }
3371
+ function set_rightbottom(id, right, bottom) {
3372
+ if (isDeleted(id)) return id;
3373
+ id.right = right;
3374
+ id.bottom = bottom;
3375
+ return id;
3376
+ }
3377
+ function set_xloc3(id, left, right, xloc) {
3378
+ if (isDeleted(id)) return id;
3379
+ id.left = left;
3380
+ id.right = right;
3381
+ id.xloc = xloc;
3382
+ return id;
3383
+ }
3384
+ function set_extend2(id, extend) {
3385
+ if (isDeleted(id)) return id;
3386
+ id.extend = extend;
3387
+ return id;
3388
+ }
3389
+ function set_border_color(id, borderColor) {
3390
+ if (isDeleted(id)) return id;
3391
+ id.border_color = borderColor;
3392
+ return id;
3393
+ }
3394
+ function set_border_width(id, width) {
3395
+ if (isDeleted(id)) return id;
3396
+ id.border_width = width;
3397
+ return id;
3398
+ }
3399
+ function set_border_style(id, style) {
3400
+ if (isDeleted(id)) return id;
3401
+ id.border_style = style;
3402
+ return id;
3403
+ }
3404
+ function set_bgcolor(id, bgColor) {
3405
+ if (isDeleted(id)) return id;
3406
+ id.bgcolor = bgColor;
3407
+ return id;
3408
+ }
3409
+ function set_text2(id, text2) {
3410
+ if (isDeleted(id)) return id;
3411
+ id.text = text2;
3412
+ return id;
3413
+ }
3414
+ function set_text_color(id, textColor) {
3415
+ if (isDeleted(id)) return id;
3416
+ id.text_color = textColor;
3417
+ return id;
3418
+ }
3419
+ function set_text_size(id, size) {
3420
+ if (isDeleted(id)) return id;
3421
+ id.text_size = size;
3422
+ return id;
3423
+ }
3424
+ function set_text_halign(id, align) {
3425
+ if (isDeleted(id)) return id;
3426
+ id.text_halign = align;
3427
+ return id;
3428
+ }
3429
+ function set_text_valign(id, align) {
3430
+ if (isDeleted(id)) return id;
3431
+ id.text_valign = align;
3432
+ return id;
3433
+ }
3434
+ function set_text_wrap(id, wrap) {
3435
+ if (isDeleted(id)) return id;
3436
+ id.text_wrap = wrap;
3437
+ return id;
3438
+ }
3439
+ function set_text_font_family2(id, font) {
3440
+ if (isDeleted(id)) return id;
3441
+ id.text_font_family = font;
3442
+ return id;
3443
+ }
3444
+ function delete_box(id) {
3445
+ remove("box", id);
3446
+ }
3447
+ function pointX3(point, xloc) {
3448
+ const x = xloc === "bar_time" ? point.time : point.index;
3449
+ return x ?? NaN;
3450
+ }
3451
+ function all4() {
3452
+ return all("box");
3453
+ }
3454
+ function set_top_left_point(id, point) {
3455
+ if (isDeleted(id)) return id;
3456
+ id.left = pointX3(point, id.xloc);
3457
+ id.top = point.price;
3458
+ return id;
3459
+ }
3460
+ function set_bottom_right_point(id, point) {
3461
+ if (isDeleted(id)) return id;
3462
+ id.right = pointX3(point, id.xloc);
3463
+ id.bottom = point.price;
3464
+ return id;
3465
+ }
3466
+ function set_text_formatting2(id, formatting) {
3467
+ if (isDeleted(id)) return id;
3468
+ id.text_formatting = formatting;
3469
+ return id;
3470
+ }
3471
+
3472
+ // src/linefill/index.ts
3473
+ var linefill_exports = {};
3474
+ __export(linefill_exports, {
3475
+ all: () => all5,
3476
+ delete: () => delete_linefill,
3477
+ delete_linefill: () => delete_linefill,
3478
+ get_line1: () => get_line1,
3479
+ get_line2: () => get_line2,
3480
+ new: () => new_linefill,
3481
+ new_linefill: () => new_linefill,
3482
+ set_color: () => set_color3
3483
+ });
3484
+ function new_linefill(line1, line2, fillColor) {
3485
+ return register("linefill", {
3486
+ line1,
3487
+ line2,
3488
+ color: fillColor
3489
+ });
3490
+ }
3491
+ function get_line1(id) {
3492
+ return id.line1;
3493
+ }
3494
+ function get_line2(id) {
3495
+ return id.line2;
3496
+ }
3497
+ function set_color3(id, fillColor) {
3498
+ if (isDeleted(id)) return id;
3499
+ id.color = fillColor;
3500
+ return id;
3501
+ }
3502
+ function delete_linefill(id) {
3503
+ remove("linefill", id);
3504
+ }
3505
+ function all5() {
3506
+ return all("linefill");
3507
+ }
3508
+
3509
+ // src/polyline/index.ts
3510
+ var polyline_exports = {};
3511
+ __export(polyline_exports, {
3512
+ all: () => all6,
3513
+ clear_all: () => clear_all,
3514
+ delete: () => delete_polyline,
3515
+ delete_polyline: () => delete_polyline,
3516
+ get_all: () => get_all,
3517
+ new: () => new_polyline,
3518
+ new_polyline: () => new_polyline,
3519
+ reset_id_counter: () => reset_id_counter
3520
+ });
3521
+ var polylineIdCounter = 0;
3522
+ function generateId() {
3523
+ return `polyline_${++polylineIdCounter}`;
3524
+ }
3525
+ 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) {
3526
+ if (curved) {
3527
+ console.warn(
3528
+ "polyline.new(): curved polylines are not yet supported. Using straight-line connections."
3529
+ );
3530
+ }
3531
+ if (line_width < 1) {
3532
+ console.warn("polyline.new(): line_width must be at least 1. Using 1.");
3533
+ line_width = 1;
3534
+ }
3535
+ const polyline2 = {
3536
+ id: generateId(),
3537
+ points: [...points],
3538
+ // Create a copy of the points array
3539
+ curved,
3540
+ closed,
3541
+ xloc,
3542
+ line_color,
3543
+ fill_color,
3544
+ line_style,
3545
+ line_width,
3546
+ force_overlay
3547
+ };
3548
+ return register("polyline", polyline2);
3549
+ }
3550
+ function delete_polyline(id) {
3551
+ remove("polyline", id);
3552
+ }
3553
+ function get_all() {
3554
+ return all("polyline");
3555
+ }
3556
+ function all6() {
3557
+ return all("polyline");
3558
+ }
3559
+ function clear_all() {
3560
+ for (const p of all("polyline")) remove("polyline", p);
3561
+ }
3562
+ function reset_id_counter() {
3563
+ polylineIdCounter = 0;
3564
+ }
3565
+
3566
+ // src/chartpoint/index.ts
3567
+ var chartpoint_exports = {};
3568
+ __export(chartpoint_exports, {
3569
+ copy: () => copy4,
3570
+ from_index: () => from_index,
3571
+ from_time: () => from_time,
3572
+ new: () => new_point,
3573
+ new_point: () => new_point
3574
+ });
3575
+ function new_point(time2, index, price) {
3576
+ return {
3577
+ time: time2,
3578
+ index,
3579
+ price
3580
+ };
3581
+ }
3582
+ function from_time(time2, price) {
3583
+ return {
3584
+ time: time2,
3585
+ index: null,
3586
+ price
3587
+ };
3588
+ }
3589
+ function from_index(index, price) {
3590
+ return {
3591
+ time: null,
3592
+ index,
3593
+ price
3594
+ };
3595
+ }
3596
+ function copy4(point) {
3597
+ return {
3598
+ time: point.time,
3599
+ index: point.index,
3600
+ price: point.price
3601
+ };
3602
+ }
3603
+
3604
+ // src/text/index.ts
3605
+ var text_exports = {};
3606
+ __export(text_exports, {
3607
+ format_bold: () => format_bold,
3608
+ format_italic: () => format_italic,
3609
+ format_none: () => format_none
3610
+ });
3611
+ var format_none = 0;
3612
+ var format_bold = 1;
3613
+ var format_italic = 2;
3614
+
3615
+ // src/timeframe/index.ts
3616
+ var timeframe_exports = {};
3617
+ __export(timeframe_exports, {
3618
+ from_seconds: () => from_seconds,
3619
+ in_seconds: () => in_seconds,
3620
+ info: () => info
3621
+ });
3622
+ var SECONDS_PER_MINUTE = 60;
3623
+ var SECONDS_PER_DAY = 86400;
3624
+ var SECONDS_PER_WEEK = 604800;
3625
+ var SECONDS_PER_MONTH = 2628003;
3626
+ var SECONDS_365_DAYS = 365 * SECONDS_PER_DAY;
3627
+ var UNIT_SECONDS = {
3628
+ S: 1,
3629
+ "": SECONDS_PER_MINUTE,
3630
+ D: SECONDS_PER_DAY,
3631
+ W: SECONDS_PER_WEEK,
3632
+ M: SECONDS_PER_MONTH
3633
+ };
3634
+ var SECOND_TIMEFRAMES = [1, 5, 10, 15, 30];
3635
+ function in_seconds(timeframe2) {
3636
+ const text2 = timeframe2.trim();
3637
+ if (text2 === "") {
3638
+ throw new RangeError("timeframe.in_seconds() needs a timeframe: the chart timeframe is not known here");
3639
+ }
3640
+ const before = /^(\d*)([SDWMT]?)$/.exec(text2);
3641
+ const after = before ? null : /^([SDWMT])(\d+)$/.exec(text2);
3642
+ if (!before && !after) throw new RangeError(`Invalid timeframe "${timeframe2}"`);
3643
+ const [digits, unit] = before ? [before[1], before[2]] : [after[2], after[1]];
3644
+ if (unit === "T") return NaN;
3645
+ const multiplier = digits === "" ? 1 : Number(digits);
3646
+ return multiplier * UNIT_SECONDS[unit];
3647
+ }
3648
+ function from_seconds(seconds) {
3649
+ if (Number.isNaN(seconds)) throw new RangeError("timeframe.from_seconds() needs a number of seconds");
3650
+ if (seconds >= SECONDS_365_DAYS) return "12M";
3651
+ if (seconds > 0) {
3652
+ if (seconds % SECONDS_PER_MONTH === 0) return `${seconds / SECONDS_PER_MONTH}M`;
3653
+ if (seconds % SECONDS_PER_WEEK === 0) return `${seconds / SECONDS_PER_WEEK}W`;
3654
+ if (seconds % SECONDS_PER_DAY === 0) return `${seconds / SECONDS_PER_DAY}D`;
3655
+ if (seconds % SECONDS_PER_MINUTE === 0 && seconds < SECONDS_PER_DAY) return `${seconds / SECONDS_PER_MINUTE}`;
3656
+ }
3657
+ const second3 = SECOND_TIMEFRAMES.find((m) => seconds <= m);
3658
+ if (second3 !== void 0) return `${second3}S`;
3659
+ if (seconds < SECONDS_PER_DAY) return `${Math.ceil(seconds / SECONDS_PER_MINUTE)}`;
3660
+ return `${Math.ceil(seconds / SECONDS_PER_DAY)}D`;
3661
+ }
3662
+ function info(timeframe2) {
3663
+ const text2 = timeframe2.trim();
3664
+ const m = /^(\d*)([SDWMT]?)$/.exec(text2);
3665
+ if (!m || text2 === "") throw new RangeError(`Invalid timeframe "${timeframe2}"`);
3666
+ const unit = m[2];
3667
+ const multiplier = m[1] === "" ? 1 : Number(m[1]);
3668
+ return {
3669
+ period: unit === "" ? String(multiplier) : `${multiplier}${unit}`,
3670
+ multiplier,
3671
+ isintraday: unit === "" || unit === "S" || unit === "T",
3672
+ isdaily: unit === "D",
3673
+ isweekly: unit === "W",
3674
+ ismonthly: unit === "M",
3675
+ isminutes: unit === "",
3676
+ isseconds: unit === "S",
3677
+ isticks: unit === "T",
3678
+ isdwm: unit === "D" || unit === "W" || unit === "M"
3679
+ };
3680
+ }
3681
+
3682
+ // src/time/timezone.ts
3683
+ var MS_PER_SECOND = 1e3;
3684
+ var MS_PER_DAY = 864e5;
3685
+ var MAX_OFFSET_SECONDS = 18 * 3600;
3686
+ var OFFSET_NOTATION = /^(?:UTC|GMT)(?:([+-])(\d{1,2})(?::?(\d{2})(?::?(\d{2}))?)?)?$/;
3687
+ var REJECTED_NAMES = /* @__PURE__ */ new Set(["EST", "MST", "HST"]);
3688
+ var canonicalNames;
3689
+ function hasTimeZoneCase(name) {
3690
+ if (name.split("/").some((segment) => !/^[A-Z]/.test(segment))) return false;
3691
+ canonicalNames ??= new Map(Intl.supportedValuesOf("timeZone").map((n) => [n.toLowerCase(), n]));
3692
+ const canonical = canonicalNames.get(name.toLowerCase());
3693
+ return canonical === void 0 || canonical === name;
3694
+ }
3695
+ var zones = /* @__PURE__ */ new Map();
3696
+ function resolveZone(timezone) {
3697
+ let zone = zones.get(timezone);
3698
+ if (zone) return zone;
3699
+ const invalid = () => new RangeError(
3700
+ `Invalid time zone "${timezone}": use UTC/GMT offset notation ("UTC-5", "GMT+0530") or an IANA name ("America/New_York")`
3701
+ );
3702
+ const m = OFFSET_NOTATION.exec(timezone);
3703
+ if (m) {
3704
+ const [, sign2, h = "0", mi = "0", s] = m;
3705
+ const minutes = Number(mi);
3706
+ const seconds = s === void 0 ? 0 : Number(s);
3707
+ if (minutes > 59 || seconds > 59 || s !== void 0 && h.length !== 2) throw invalid();
3708
+ const offsetSeconds = Number(h) * 3600 + minutes * 60 + seconds;
3709
+ if (offsetSeconds > MAX_OFFSET_SECONDS) throw invalid();
3710
+ zone = { kind: "fixed", offsetMs: (sign2 === "-" ? -offsetSeconds : offsetSeconds) * MS_PER_SECOND };
3711
+ } else {
3712
+ if (REJECTED_NAMES.has(timezone) || !hasTimeZoneCase(timezone)) throw invalid();
3713
+ let format2;
3714
+ try {
3715
+ format2 = new Intl.DateTimeFormat("en-US", {
3716
+ timeZone: timezone,
3717
+ hourCycle: "h23",
3718
+ year: "numeric",
3719
+ month: "numeric",
3720
+ day: "numeric",
3721
+ hour: "numeric",
3722
+ minute: "numeric",
3723
+ second: "numeric"
3724
+ });
3725
+ } catch {
3726
+ throw invalid();
3727
+ }
3728
+ zone = { kind: "iana", format: format2 };
3729
+ }
3730
+ zones.set(timezone, zone);
3731
+ return zone;
3732
+ }
3733
+ function offsetAt(zone, time2) {
3734
+ if (zone.kind === "fixed") return zone.offsetMs;
3735
+ const wholeSecond = Math.floor(time2 / 1e3) * 1e3;
3736
+ const f = {};
3737
+ for (const part of zone.format.formatToParts(wholeSecond)) {
3738
+ if (part.type !== "literal") f[part.type] = Number(part.value);
3739
+ }
3740
+ const local = Date.UTC(f.year, f.month - 1, f.day, f.hour, f.minute, f.second);
3741
+ return local - wholeSecond;
3742
+ }
3743
+ function zoneOffset(time2, timezone) {
3744
+ return offsetAt(resolveZone(timezone), time2);
3745
+ }
3746
+ function zonedFields(time2, timezone) {
3747
+ const local = new Date(time2 + offsetAt(resolveZone(timezone), time2));
3748
+ return {
3749
+ year: local.getUTCFullYear(),
3750
+ month: local.getUTCMonth() + 1,
3751
+ day: local.getUTCDate(),
3752
+ hour: local.getUTCHours(),
3753
+ minute: local.getUTCMinutes(),
3754
+ second: local.getUTCSeconds(),
3755
+ dayOfWeek: local.getUTCDay() + 1
3756
+ };
3757
+ }
3758
+ function zonedToUnix(timezone, year3, month3, day, hour3 = 0, minute3 = 0, second3 = 0) {
3759
+ const zone = resolveZone(timezone);
3760
+ const local = Date.UTC(year3, month3 - 1, day, hour3, minute3, second3);
3761
+ if (zone.kind === "fixed") return local - zone.offsetMs;
3762
+ const before = offsetAt(zone, local - MS_PER_DAY);
3763
+ const after = offsetAt(zone, local + MS_PER_DAY);
3764
+ const candidates = [local - before, local - after].filter((t2) => local - offsetAt(zone, t2) === t2);
3765
+ if (candidates.length) return Math.max(...candidates);
3766
+ return local - before;
3767
+ }
3768
+
3769
+ // src/time/datestring.ts
3770
+ var MONTHS = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
3771
+ var FULL_MONTHS = [
3772
+ "january",
3773
+ "february",
3774
+ "march",
3775
+ "april",
3776
+ "may",
3777
+ "june",
3778
+ "july",
3779
+ "august",
3780
+ "september",
3781
+ "october",
3782
+ "november",
3783
+ "december"
3784
+ ];
3785
+ var ZONE_NAMES = {
3786
+ ut: 0,
3787
+ utc: 0,
3788
+ gmt: 0,
3789
+ est: -5,
3790
+ edt: -4,
3791
+ cst: -6,
3792
+ cdt: -5,
3793
+ mst: -7,
3794
+ mdt: -6,
3795
+ pst: -8,
3796
+ pdt: -7
3797
+ };
3798
+ var TIME = String.raw`(\d{1,2}):(\d{2})(?::(\d{2})(?:\.(\d{1,3})\d*)?)?`;
3799
+ var ZONE = String.raw`(ut|utc|gmt|[ecmp][sd]t|(?:utc|gmt)?\s*[+-]\d{1,2}(?::?\d{2})?)`;
3800
+ var NUMERIC_ZONE = String.raw`([+-]\d{2}(?::?\d{2})?)`;
3801
+ var DATE = String.raw`(\d{4})([-/])(\d{1,2})\2(\d{1,2})`;
3802
+ var WEEKDAY = String.raw`(?:[a-z]{3,9},?\s+)?`;
3803
+ var ISO_T = new RegExp(String.raw`^${DATE}t${TIME}\s*${NUMERIC_ZONE}?$`, "i");
3804
+ var ISO = new RegExp(String.raw`^${DATE}(?:\s+${TIME})?\s*${ZONE}?$`, "i");
3805
+ var DAY_FIRST = new RegExp(String.raw`^${WEEKDAY}(\d{1,2})(?:\s+|-)([a-z]+)\.?,?(?:\s+|-)(\d{4})(?:,?\s+${TIME})?\s*${ZONE}?$`, "i");
3806
+ var MONTH_FIRST = new RegExp(String.raw`^${WEEKDAY}([a-z]+)\.?\s+(\d{1,2}),?\s+(\d{4})(?:,?\s+${TIME})?\s*${ZONE}?$`, "i");
3807
+ function monthNumber(name) {
3808
+ const lower2 = name.toLowerCase();
3809
+ const i = FULL_MONTHS.findIndex((full, k) => lower2.startsWith(MONTHS[k]) && full.startsWith(lower2));
3810
+ return i + 1;
3811
+ }
3812
+ function zoneMinutes(zone) {
3813
+ if (!zone) return 0;
3814
+ const lower2 = zone.toLowerCase().replace(/\s+/g, "");
3815
+ const named = ZONE_NAMES[lower2];
3816
+ if (named !== void 0) return named * 60;
3817
+ const m = /^(?:utc|gmt)?([+-])(\d{1,2})(?::?(\d{2}))?$/.exec(lower2);
3818
+ if (!m) return NaN;
3819
+ const minutes = Number(m[2]) * 60 + (m[3] ? Number(m[3]) : 0);
3820
+ return m[1] === "-" ? -minutes : minutes;
3821
+ }
3822
+ function parseDateString(dateString) {
3823
+ const text2 = dateString.trim();
3824
+ let year3, month3, day;
3825
+ let rest;
3826
+ let m;
3827
+ if (m = ISO_T.exec(text2) ?? ISO.exec(text2)) {
3828
+ [year3, month3, day] = [m[1], Number(m[3]), m[4]];
3829
+ rest = m.slice(5);
3830
+ } else if (m = DAY_FIRST.exec(text2)) {
3831
+ [day, month3, year3] = [m[1], monthNumber(m[2]), m[3]];
3832
+ rest = m.slice(4);
3833
+ } else if (m = MONTH_FIRST.exec(text2)) {
3834
+ [month3, day, year3] = [monthNumber(m[1]), m[2], m[3]];
3835
+ rest = m.slice(4);
3836
+ } else {
3837
+ throw new SyntaxError(`Invalid date string "${dateString}": use RFC 2822 or ISO 8601 ("20 Feb 2020", "2020-02-20T14:48:00")`);
3838
+ }
3839
+ const [hour3 = "0", minute3 = "0", second3 = "0", millis = "0", zone] = rest;
3840
+ const d = Number(day);
3841
+ const h = Number(hour3);
3842
+ const mi = Number(minute3);
3843
+ const s = Number(second3);
3844
+ const offset = zoneMinutes(zone);
3845
+ const endOfDay = h === 24 && mi === 0 && s === 0 && Number(millis) === 0;
3846
+ if (month3 < 1 || month3 > 12 || d < 1 || d > 31 || h > 23 && !endOfDay || mi > 59 || s > 59 || Number.isNaN(offset)) {
3847
+ throw new SyntaxError(`Invalid date string "${dateString}": a field is out of range`);
3848
+ }
3849
+ const ms = Number(millis.padEnd(3, "0"));
3850
+ return Date.UTC(Number(year3), month3 - 1, d, h, mi, s, ms) - offset * 6e4;
3851
+ }
3852
+
3853
+ // src/time/session.ts
3854
+ var PERIOD = /^(\d{2})(\d{2})-(\d{2})(\d{2})$/;
3855
+ var sessions = /* @__PURE__ */ new Map();
3856
+ function parseSession(session2) {
3857
+ let parsed = sessions.get(session2);
3858
+ if (parsed) return parsed;
3859
+ const invalid = () => new SyntaxError(`Invalid session "${session2}": expected "HHmm-HHmm[,HHmm-HHmm...][:days]"`);
3860
+ const text2 = session2.trim() === "24x7" ? "0000-0000" : session2.replace(/\s+/g, "");
3861
+ const [periodText = "", dayText, extra] = text2.split(":");
3862
+ if (extra !== void 0 || periodText === "") throw invalid();
3863
+ const periods = periodText.split(",").map((p) => {
3864
+ const m = PERIOD.exec(p);
3865
+ if (!m) throw invalid();
3866
+ const [h1, m1, h2, m2] = [m[1], m[2], m[3], m[4]].map(Number);
3867
+ if (h1 > 23 || h2 > 23 || m1 > 59 || m2 > 59) throw invalid();
3868
+ return { start: h1 * 60 + m1, end: h2 * 60 + m2 };
3869
+ });
3870
+ const dayDigits = dayText ?? (periods.length > 1 ? "23456" : "1234567");
3871
+ if (!/^[1-7]+$/.test(dayDigits)) throw invalid();
3872
+ const days = new Array(8).fill(false);
3873
+ for (const d of dayDigits) days[Number(d)] = true;
3874
+ parsed = { periods, days };
3875
+ sessions.set(session2, parsed);
3876
+ return parsed;
3877
+ }
3878
+ function inSession(time2, session2, timezone) {
3879
+ if (Number.isNaN(time2)) return false;
3880
+ const { periods, days } = parseSession(session2);
3881
+ const f = zonedFields(time2, timezone);
3882
+ const minute3 = f.hour * 60 + f.minute;
3883
+ const nextDay = f.dayOfWeek % 7 + 1;
3884
+ for (const { start, end } of periods) {
3885
+ if (start < end || start === 0 && end === 0) {
3886
+ if (minute3 >= start && (minute3 < end || end === 0) && days[f.dayOfWeek]) return true;
3887
+ } else {
3888
+ if (minute3 >= start && days[nextDay]) return true;
3889
+ if (minute3 < end && days[f.dayOfWeek]) return true;
3890
+ }
3891
+ }
3892
+ return false;
3893
+ }
3894
+
3895
+ // src/time/index.ts
3896
+ function timestamp(first, ...rest) {
3897
+ if (typeof first === "string") {
3898
+ if (rest.length === 0) return parseDateString(first);
3899
+ const [year3, month4, day2, hour4, minute4, second4] = rest;
3900
+ return zonedToUnix(first, year3, month4, day2, hour4 ?? 0, minute4 ?? 0, second4 ?? 0);
3901
+ }
3902
+ const [month3, day, hour3, minute3, second3] = rest;
3903
+ return new Date(first, month3 - 1, day, hour3 || 0, minute3 || 0, second3 || 0).getTime();
3904
+ }
3905
+ function field(time2, timezone, pick) {
3906
+ return Number.isNaN(time2) ? NaN : pick(zonedFields(time2, timezone));
3907
+ }
3908
+ function year(time2, timezone) {
3909
+ return field(time2, timezone, (f) => f.year);
3910
+ }
3911
+ function month(time2, timezone) {
3912
+ return field(time2, timezone, (f) => f.month);
3913
+ }
3914
+ function dayofmonth(time2, timezone) {
3915
+ return field(time2, timezone, (f) => f.day);
3916
+ }
3917
+ function dayofweek(time2, timezone) {
3918
+ return field(time2, timezone, (f) => f.dayOfWeek);
3919
+ }
3920
+ function weekofyear(time2, timezone) {
3921
+ return field(time2, timezone, (f) => {
3922
+ const date = Date.UTC(f.year, f.month - 1, f.day);
3923
+ const mondayBased = (f.dayOfWeek + 5) % 7;
3924
+ const thursday = new Date(date + (3 - mondayBased) * 864e5);
3925
+ const yearStart = Date.UTC(thursday.getUTCFullYear(), 0, 1);
3926
+ return 1 + Math.floor((thursday.getTime() - yearStart) / (7 * 864e5));
3927
+ });
3928
+ }
3929
+ function hour(time2, timezone) {
3930
+ return field(time2, timezone, (f) => f.hour);
3931
+ }
3932
+ function minute(time2, timezone) {
3933
+ return field(time2, timezone, (f) => f.minute);
3934
+ }
3935
+ function second(time2, timezone) {
3936
+ return field(time2, timezone, (f) => f.second);
3937
+ }
3938
+ function inSession2(time2, session2, timezone) {
3939
+ return inSession(time2, session2, timezone);
3940
+ }
3941
+
3942
+ // src/str/index.ts
3943
+ var str_exports = {};
3944
+ __export(str_exports, {
3945
+ charAt: () => charAt,
3946
+ concat: () => concat,
3947
+ contains: () => contains,
3948
+ endswith: () => endswith,
3949
+ format: () => format,
3950
+ format_time: () => format_time,
3951
+ length: () => length,
3952
+ lower: () => lower,
3953
+ match: () => match,
3954
+ pos: () => pos,
3955
+ repeat: () => repeat,
3956
+ replace: () => replace,
3957
+ replace_all: () => replace_all,
3958
+ split: () => split,
3959
+ startswith: () => startswith,
3960
+ substring: () => substring,
3961
+ tonumber: () => tonumber,
3962
+ tostring: () => tostring,
3963
+ trim: () => trim,
3964
+ trimLeft: () => trimLeft,
3965
+ trimRight: () => trimRight,
3966
+ upper: () => upper
3967
+ });
3968
+
3969
+ // src/str/numberformat.ts
3970
+ var patterns = /* @__PURE__ */ new Map();
3971
+ function parsePattern(pattern) {
3972
+ const cached = patterns.get(pattern);
3973
+ if (cached) return cached;
3974
+ let prefix = "";
3975
+ let suffix = "";
3976
+ let number2 = "";
3977
+ let percent = false;
3978
+ let phase = "prefix";
3979
+ for (let i = 0; i < pattern.length; i++) {
3980
+ const ch = pattern[i];
3981
+ let literal;
3982
+ if (ch === "'") {
3983
+ const end = pattern.indexOf("'", i + 1);
3984
+ if (end === i + 1) {
3985
+ literal = "'";
3986
+ i = end;
3987
+ } else {
3988
+ literal = pattern.slice(i + 1, end === -1 ? void 0 : end);
3989
+ i = end === -1 ? pattern.length : end;
3990
+ }
3991
+ } else if (phase !== "suffix" && ("#0,.".includes(ch) || phase === "number" && ch === "E")) {
3992
+ phase = "number";
3993
+ number2 += ch;
3994
+ continue;
3995
+ } else {
3996
+ if (ch === "%") percent = true;
3997
+ literal = ch;
3998
+ }
3999
+ if (phase === "number") phase = "suffix";
4000
+ if (phase === "prefix") prefix += literal;
4001
+ else suffix += literal;
4002
+ }
4003
+ const [mantissa = "", exp2] = number2.split("E");
4004
+ const [intPart = "", fracPart = ""] = mantissa.split(".");
4005
+ const lastComma = intPart.lastIndexOf(",");
4006
+ const parsed = {
4007
+ prefix,
4008
+ suffix,
4009
+ // as in Java, a pattern with a decimal point and no '0' at all ("#.##") shows one integer digit
4010
+ minInt: !mantissa.includes("0") && mantissa.includes(".") ? 1 : [...intPart].filter((c) => c === "0").length,
4011
+ minFrac: [...fracPart].filter((c) => c === "0").length,
4012
+ maxFrac: [...fracPart].filter((c) => c === "0" || c === "#").length,
4013
+ grouping: lastComma === -1 ? 0 : intPart.length - lastComma - 1,
4014
+ percent,
4015
+ exponent: exp2 === void 0 ? null : exp2.length,
4016
+ hasDigits: /[0#]/.test(mantissa)
4017
+ };
4018
+ patterns.set(pattern, parsed);
4019
+ return parsed;
4020
+ }
4021
+ function shortestDigits(x) {
4022
+ const m = /^(\d+)(?:\.(\d+))?(?:e([+-]\d+))?$/.exec(String(Math.abs(x)));
4023
+ const all7 = m[1] + (m[2] ?? "");
4024
+ let intLen = m[1].length + Number(m[3] ?? 0);
4025
+ const lead = all7.length - all7.replace(/^0+/, "").length;
4026
+ intLen -= lead;
4027
+ const digits = all7.slice(lead).replace(/0+$/, "");
4028
+ return { digits, intLen: digits ? intLen : 0 };
4029
+ }
4030
+ function exactDigits(x) {
4031
+ const abs2 = Math.abs(x);
4032
+ if (abs2 === 0) return { digits: "", intLen: 0 };
4033
+ const view = new DataView(new ArrayBuffer(8));
4034
+ view.setFloat64(0, abs2);
4035
+ const bits = view.getBigUint64(0);
4036
+ const expBits = Number(bits >> 52n & 0x7ffn);
4037
+ let mant = bits & 0xfffffffffffffn;
4038
+ const e2 = expBits === 0 ? -1074 : expBits - 1075;
4039
+ if (expBits !== 0) mant |= 1n << 52n;
4040
+ let str2;
4041
+ let fracDigits;
4042
+ if (e2 >= 0) {
4043
+ str2 = (mant << BigInt(e2)).toString();
4044
+ fracDigits = 0;
4045
+ } else {
4046
+ str2 = (mant * 5n ** BigInt(-e2)).toString();
4047
+ fracDigits = -e2;
4048
+ }
4049
+ const intLen = str2.length - fracDigits;
4050
+ const lead = str2.length - str2.replace(/^0+/, "").length;
4051
+ const digits = str2.slice(lead).replace(/0+$/, "");
4052
+ return { digits, intLen: intLen - lead };
4053
+ }
4054
+ function roundDigits(d, frac, mode3) {
4055
+ const keep = d.intLen + frac;
4056
+ if (keep >= d.digits.length) return d;
4057
+ if (keep < 0) return { digits: "", intLen: 0 };
4058
+ const first = d.digits.charCodeAt(keep) - 48;
4059
+ let up;
4060
+ if (mode3 === "halfUpShortest") up = first >= 5;
4061
+ else if (first !== 5) up = first > 5;
4062
+ else if (d.digits.length > keep + 1) up = true;
4063
+ else up = keep > 0 && (d.digits.charCodeAt(keep - 1) - 48) % 2 === 1;
4064
+ let kept = d.digits.slice(0, keep);
4065
+ let intLen = d.intLen;
4066
+ if (up) {
4067
+ const n = (BigInt(kept || "0") + 1n).toString();
4068
+ if (n.length > kept.length) intLen += 1;
4069
+ kept = n;
4070
+ }
4071
+ kept = kept.replace(/0+$/, "");
4072
+ return { digits: kept, intLen: kept ? intLen : 0 };
4073
+ }
4074
+ function group(int, size) {
4075
+ if (!size || int.length <= size) return int;
4076
+ const parts = [];
4077
+ for (let end = int.length; end > 0; end -= size) parts.unshift(int.slice(Math.max(0, end - size), end));
4078
+ return parts.join(",");
4079
+ }
4080
+ function layout(d, p) {
4081
+ let int = d.intLen > 0 ? d.digits.slice(0, d.intLen).padEnd(d.intLen, "0") : "";
4082
+ int = int.replace(/^0+/, "").padStart(p.minInt, "0");
4083
+ let frac = d.intLen < 0 ? "0".repeat(-d.intLen) + d.digits : d.digits.slice(Math.max(0, d.intLen));
4084
+ frac = frac.slice(0, p.maxFrac).replace(/0+$/, "").padEnd(p.minFrac, "0");
4085
+ if (!int && !frac) int = "0";
4086
+ return group(int, p.grouping) + (frac ? "." + frac : "");
4087
+ }
4088
+ function formatNumber(value, pattern, mode3) {
4089
+ if (Number.isNaN(value)) return "NaN";
4090
+ const p = parsePattern(pattern);
4091
+ if (!Number.isFinite(value)) return (value < 0 ? "-" : "") + p.prefix + "\u221E" + p.suffix;
4092
+ const x = p.percent ? value * 100 : value;
4093
+ const toDigits = mode3 === "halfUpShortest" ? shortestDigits : exactDigits;
4094
+ let body;
4095
+ let isZero;
4096
+ if (p.exponent !== null) {
4097
+ const rounded = roundDigits(toDigits(x), p.maxFrac, mode3);
4098
+ const intDigits = Math.max(p.minInt, 1);
4099
+ isZero = rounded.digits === "";
4100
+ let exponent = isZero ? 0 : rounded.intLen - intDigits;
4101
+ let mant = roundDigits({ digits: rounded.digits, intLen: isZero ? 0 : intDigits }, p.maxFrac, mode3);
4102
+ if (mant.intLen > intDigits) {
4103
+ exponent += 1;
4104
+ mant = { digits: mant.digits, intLen: intDigits };
4105
+ }
4106
+ const e2 = String(Math.abs(exponent)).padStart(p.exponent, "0");
4107
+ body = layout(mant, p) + "E" + (exponent < 0 ? "-" : "") + e2;
4108
+ } else {
4109
+ const rounded = roundDigits(toDigits(x), p.hasDigits ? p.maxFrac : 0, mode3);
4110
+ isZero = rounded.digits === "";
4111
+ body = p.hasDigits ? layout(rounded, p) : layout(rounded, { ...p, minInt: 0, maxFrac: 0, minFrac: 0 });
4112
+ }
4113
+ const negative = x < 0 && (!isZero || !p.hasDigits);
4114
+ return (negative ? "-" : "") + p.prefix + body + p.suffix;
4115
+ }
4116
+
4117
+ // src/str/dateformat.ts
4118
+ var MONTHS2 = [
4119
+ "January",
4120
+ "February",
4121
+ "March",
4122
+ "April",
4123
+ "May",
4124
+ "June",
4125
+ "July",
4126
+ "August",
4127
+ "September",
4128
+ "October",
4129
+ "November",
4130
+ "December"
4131
+ ];
4132
+ var DAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
4133
+ var pad = (n, width) => String(n).padStart(width, "0");
4134
+ function zoneName(time2, timezone, offsetMs) {
4135
+ if (timezone === "Etc/UTC") return "UTC";
4136
+ if (/^(UTC|GMT)/.test(timezone)) {
4137
+ if (offsetMs === 0) return "GMT";
4138
+ const minutes = Math.abs(offsetMs) / 6e4;
4139
+ return `GMT${offsetMs < 0 ? "-" : "+"}${pad(Math.floor(minutes / 60), 2)}:${pad(minutes % 60, 2)}`;
4140
+ }
4141
+ const part = new Intl.DateTimeFormat("en-US", { timeZone: timezone, timeZoneName: "short" }).formatToParts(time2).find((p) => p.type === "timeZoneName");
4142
+ return part?.value ?? timezone;
4143
+ }
4144
+ function weekOfYear(year3, month3, day) {
4145
+ const date = Date.UTC(year3, month3 - 1, day);
4146
+ const dow = new Date(date).getUTCDay();
4147
+ const weekStart2 = date - dow * 864e5;
4148
+ if (weekStart2 + 6 * 864e5 >= Date.UTC(year3 + 1, 0, 1)) return 1;
4149
+ const jan1 = Date.UTC(year3, 0, 1);
4150
+ const jan1Dow = new Date(jan1).getUTCDay();
4151
+ return Math.floor((date - jan1 + jan1Dow * 864e5) / (7 * 864e5)) + 1;
4152
+ }
4153
+ function formatDate(time2, pattern, timezone) {
4154
+ if (Number.isNaN(time2)) return "NaN";
4155
+ const f = zonedFields(time2, timezone);
4156
+ const offset = zoneOffset(time2, timezone);
4157
+ const ms = (time2 % 1e3 + 1e3) % 1e3;
4158
+ const dayOfYear = (Date.UTC(f.year, f.month - 1, f.day) - Date.UTC(f.year, 0, 1)) / 864e5 + 1;
4159
+ let out = "";
4160
+ for (let i = 0; i < pattern.length; ) {
4161
+ const ch = pattern[i];
4162
+ if (ch === "'") {
4163
+ const end = pattern.indexOf("'", i + 1);
4164
+ if (end === i + 1) {
4165
+ out += "'";
4166
+ i += 2;
4167
+ } else {
4168
+ out += pattern.slice(i + 1, end === -1 ? void 0 : end);
4169
+ i = end === -1 ? pattern.length : end + 1;
4170
+ }
4171
+ continue;
4172
+ }
4173
+ if (!/[A-Za-z]/.test(ch)) {
4174
+ out += ch;
4175
+ i++;
4176
+ continue;
4177
+ }
4178
+ let n = 1;
4179
+ while (pattern[i + n] === ch) n++;
4180
+ i += n;
4181
+ const hour12 = f.hour % 12;
4182
+ switch (ch) {
4183
+ case "y":
4184
+ out += n === 2 ? pad(f.year % 100, 2) : pad(f.year, n);
4185
+ break;
4186
+ case "M":
4187
+ out += n >= 4 ? MONTHS2[f.month - 1] : n === 3 ? MONTHS2[f.month - 1].slice(0, 3) : pad(f.month, n);
4188
+ break;
4189
+ case "d":
4190
+ out += pad(f.day, n);
4191
+ break;
4192
+ case "E":
4193
+ out += n >= 4 ? DAYS[f.dayOfWeek - 1] : DAYS[f.dayOfWeek - 1].slice(0, 3);
4194
+ break;
4195
+ case "u":
4196
+ out += pad(f.dayOfWeek === 1 ? 7 : f.dayOfWeek - 1, n);
4197
+ break;
4198
+ case "D":
4199
+ out += pad(dayOfYear, n);
4200
+ break;
4201
+ case "w":
4202
+ out += pad(weekOfYear(f.year, f.month, f.day), n);
4203
+ break;
4204
+ case "H":
4205
+ out += pad(f.hour, n);
4206
+ break;
4207
+ case "k":
4208
+ out += pad(f.hour === 0 ? 24 : f.hour, n);
4209
+ break;
4210
+ case "K":
4211
+ out += pad(hour12, n);
4212
+ break;
4213
+ case "h":
4214
+ out += pad(hour12 === 0 ? 12 : hour12, n);
4215
+ break;
4216
+ case "a":
4217
+ out += f.hour < 12 ? "AM" : "PM";
4218
+ break;
4219
+ case "m":
4220
+ out += pad(f.minute, n);
4221
+ break;
4222
+ case "s":
4223
+ out += pad(f.second, n);
4224
+ break;
4225
+ case "S":
4226
+ out += pad(ms, n);
4227
+ break;
4228
+ case "Z": {
4229
+ const minutes = Math.abs(offset) / 6e4;
4230
+ out += (offset < 0 ? "-" : "+") + pad(Math.floor(minutes / 60), 2) + pad(minutes % 60, 2);
4231
+ break;
4232
+ }
4233
+ case "z":
4234
+ out += zoneName(time2, timezone, offset);
4235
+ break;
4236
+ default:
4237
+ throw new SyntaxError(`Unsupported date pattern letter "${ch}" in "${pattern}"`);
4238
+ }
4239
+ }
4240
+ return out;
4241
+ }
4242
+
4243
+ // src/str/messageformat.ts
4244
+ var DATE_STYLES = {
4245
+ short: "M/d/yy",
4246
+ medium: "MMM d, yyyy",
4247
+ long: "MMMM d, yyyy",
4248
+ full: "EEEE, MMMM d, yyyy"
4249
+ };
4250
+ var TIME_STYLES = {
4251
+ short: "h:mm\u202Fa",
4252
+ medium: "h:mm:ss\u202Fa",
4253
+ long: "h:mm:ss\u202Fa z",
4254
+ full: "h:mm:ss\u202Fa z"
4255
+ };
4256
+ function number(value, pattern) {
4257
+ return typeof value === "number" ? formatNumber(value, pattern, "halfEvenExact") : String(value);
4258
+ }
4259
+ function choice(value, spec) {
4260
+ const options = spec.split("|").map((part) => {
4261
+ const m = /^\s*(-?[\d.]+|-?∞)\s*([#<≤])(.*)$/.exec(part);
4262
+ if (!m) throw new SyntaxError(`Invalid choice format "${spec}"`);
4263
+ const limit = m[1].includes("\u221E") ? m[1].startsWith("-") ? -Infinity : Infinity : Number(m[1]);
4264
+ return { limit: m[2] === "<" ? limit + Number.EPSILON * Math.max(1, Math.abs(limit)) : limit, text: m[3] };
4265
+ });
4266
+ let chosen = options[0];
4267
+ for (const o of options) if (value >= o.limit) chosen = o;
4268
+ return chosen.text;
4269
+ }
4270
+ function formatArgument(value, type, style, timezone) {
4271
+ if (value === void 0) return "";
4272
+ if (!type) return typeof value === "number" ? number(value, "#,##0.###") : String(value);
4273
+ switch (type.trim()) {
4274
+ case "number": {
4275
+ const s = style?.trim();
4276
+ if (!s) return number(value, "#,##0.###");
4277
+ if (s === "integer") return number(value, "#,##0");
4278
+ if (s === "percent") return number(value, "#,##0%");
4279
+ if (s === "currency") return number(value, "'$'#,##0.00");
4280
+ return number(value, style);
4281
+ }
4282
+ case "date":
4283
+ case "time": {
4284
+ const styles = type.trim() === "date" ? DATE_STYLES : TIME_STYLES;
4285
+ const s = style?.trim() ?? "medium";
4286
+ return formatDate(Number(value), styles[s] ?? style, typeof timezone === "function" ? timezone() : timezone);
4287
+ }
4288
+ case "choice":
4289
+ return choice(Number(value), style ?? "");
4290
+ default:
4291
+ throw new SyntaxError(`Unknown format type "${type}"`);
4292
+ }
4293
+ }
4294
+ function formatMessage(pattern, args, timezone) {
4295
+ let out = "";
4296
+ for (let i = 0; i < pattern.length; ) {
4297
+ const ch = pattern[i];
4298
+ if (ch === "'") {
4299
+ if (pattern[i + 1] === "'") {
4300
+ out += "'";
4301
+ i += 2;
4302
+ continue;
4303
+ }
4304
+ const end = pattern.indexOf("'", i + 1);
4305
+ out += pattern.slice(i + 1, end === -1 ? void 0 : end);
4306
+ i = end === -1 ? pattern.length : end + 1;
4307
+ continue;
4308
+ }
4309
+ if (ch !== "{") {
4310
+ out += ch;
4311
+ i++;
4312
+ continue;
4313
+ }
4314
+ let depth = 1;
4315
+ let j = i + 1;
4316
+ let inQuote = false;
4317
+ for (; j < pattern.length && depth > 0; j++) {
4318
+ const c = pattern[j];
4319
+ if (c === "'") inQuote = !inQuote;
4320
+ else if (!inQuote && c === "{") depth++;
4321
+ else if (!inQuote && c === "}") depth--;
4322
+ }
4323
+ const inner = pattern.slice(i + 1, j - 1);
4324
+ const [index = "", type, ...rest] = inner.split(",");
4325
+ const style = rest.length ? rest.join(",") : void 0;
4326
+ const n = Number(index.trim());
4327
+ out += n < args.length ? formatArgument(args[n], type, style, timezone) : `{${inner}}`;
4328
+ i = j;
4329
+ }
4330
+ return out;
4331
+ }
4332
+
4333
+ // src/str/index.ts
4334
+ function length(str2) {
4335
+ return str2.length;
4336
+ }
4337
+ function tostring(value, format2) {
4338
+ if (typeof value !== "number") return String(value);
4339
+ if (!Number.isFinite(value)) return String(value);
4340
+ if (format2 === void 0 || format2 === "") {
4341
+ if (Math.abs(value) >= 1e21 && Number.isFinite(value)) {
4342
+ return String(value).replace("e+", "E").replace(/\.0+E/, "E");
4343
+ }
4344
+ return formatNumber(value, "#.##########", "halfUpShortest");
4345
+ }
4346
+ switch (format2) {
4347
+ case "percent":
4348
+ return formatNumber(value, "0.00", "halfUpShortest") + "%";
4349
+ case "volume": {
4350
+ const abs2 = Math.abs(value);
4351
+ for (const [size, unit] of [[1e12, "T"], [1e9, "B"], [1e6, "M"], [1e3, "K"]]) {
4352
+ if (abs2 >= size) return formatNumber(value / size, "#.###", "halfUpShortest") + unit;
4353
+ }
4354
+ return formatNumber(value, "#", "halfUpShortest");
4355
+ }
4356
+ case "mintick":
4357
+ throw new Error("str.tostring(x, format.mintick) needs the symbol tick size (syminfo.mintick), which is not known here");
4358
+ default:
4359
+ return formatNumber(value, format2, "halfUpShortest");
4360
+ }
4361
+ }
4362
+ function tonumber(str2) {
4363
+ const num = parseFloat(str2);
4364
+ return isNaN(num) ? null : num;
4365
+ }
4366
+ function substring(str2, begin, end) {
4367
+ return str2.substring(begin, end);
4368
+ }
4369
+ function upper(str2) {
4370
+ return str2.toUpperCase();
4371
+ }
4372
+ function lower(str2) {
4373
+ return str2.toLowerCase();
4374
+ }
4375
+ function contains(source, str2) {
4376
+ return source.includes(str2);
4377
+ }
4378
+ function pos(source, str2) {
4379
+ return source.indexOf(str2);
4380
+ }
4381
+ function replace(source, target, replacement, occurrence) {
4382
+ if (occurrence === 0) {
4383
+ return source.replace(target, replacement);
4384
+ } else {
4385
+ return source.replaceAll(target, replacement);
4386
+ }
4387
+ }
4388
+ function replace_all(source, target, replacement) {
4389
+ return source.replaceAll(target, replacement);
4390
+ }
4391
+ function split(str2, separator) {
4392
+ return str2.split(separator);
4393
+ }
4394
+ function concat(...strings) {
4395
+ return strings.join("");
4396
+ }
4397
+ function format(formatStr, ...args) {
4398
+ return formatMessage(formatStr, args, "Etc/UTC");
4399
+ }
4400
+ function startswith(source, str2) {
4401
+ return source.startsWith(str2);
4402
+ }
4403
+ function endswith(source, str2) {
4404
+ return source.endsWith(str2);
4405
+ }
4406
+ function charAt(str2, pos2) {
4407
+ return str2.charAt(pos2);
4408
+ }
4409
+ function trim(str2) {
4410
+ return str2.trim();
4411
+ }
4412
+ function trimLeft(str2) {
4413
+ return str2.trimStart();
4414
+ }
4415
+ function trimRight(str2) {
4416
+ return str2.trimEnd();
4417
+ }
4418
+ function match(source, regex) {
4419
+ return new RegExp(regex).test(source);
4420
+ }
4421
+ function repeat(source, count, separator = "") {
4422
+ if (source == null) return null;
4423
+ if (count <= 0) return "";
4424
+ return Array(count).fill(source).join(separator);
4425
+ }
4426
+ function format_time(time2, format2 = "yyyy-MM-dd'T'HH:mm:ssZ", timezone = "Etc/UTC") {
4427
+ return formatDate(time2, format2, timezone);
4428
+ }
4429
+
4430
+ // src/session/calendar.ts
4431
+ var toDateNum = (y, m, d) => y * 1e4 + m * 100 + d;
4432
+ var utcOf = (date) => Date.UTC(Math.floor(date / 1e4), Math.floor(date / 100) % 100 - 1, date % 100);
4433
+ var fromUtc = (ms) => {
4434
+ const d = new Date(ms);
4435
+ return toDateNum(d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate());
4436
+ };
4437
+ var addDays = (date, n) => fromUtc(utcOf(date) + n * 864e5);
4438
+ var weekdayOf = (date) => new Date(utcOf(date)).getUTCDay() + 1;
4439
+ var dateUtcMs = utcOf;
4440
+ function parseTime(token, spec) {
4441
+ const m = /^(\d{2})(\d{2})(?:F(\d+))?$/.exec(token.trim());
4442
+ if (!m) throw new SyntaxError(`Invalid session "${spec}"`);
4443
+ return { minutes: Number(m[1]) * 60 + Number(m[2]), offset: m[3] === void 0 ? void 0 : Number(m[3]) };
4444
+ }
4445
+ function parsePeriods(text2, spec) {
4446
+ if (text2.trim() === "24x7") return [{ start: 0, end: 1440, startOffset: 0, endOffset: 0 }];
4447
+ return text2.split(",").map((p) => {
4448
+ const [a = "", b2 = ""] = p.split("-");
4449
+ const s = parseTime(a, spec);
4450
+ const e2 = parseTime(b2, spec);
4451
+ if (s.minutes === 0 && e2.minutes === 0 && s.offset === void 0 && e2.offset === void 0) {
4452
+ return { start: 0, end: 1440, startOffset: 0, endOffset: 0 };
4453
+ }
4454
+ return {
4455
+ start: s.minutes,
4456
+ end: e2.minutes,
4457
+ startOffset: s.offset ?? (e2.minutes <= s.minutes ? 1 : 0),
4458
+ endOffset: e2.offset ?? 0
4459
+ };
4460
+ });
4461
+ }
4462
+ function parseVersion(text2, from, spec, rule) {
4463
+ const [periodText = "", dayText] = text2.trim().split(":");
4464
+ const periods = parsePeriods(periodText, spec);
4465
+ const allDays = periodText.trim() === "24x7" || rule === "pine" && periods.length === 1;
4466
+ const digits = dayText ?? (allDays ? "1234567" : "23456");
4467
+ if (!/^[1-7]+$/.test(digits)) throw new SyntaxError(`Invalid session days in "${spec}"`);
4468
+ const days = new Array(8).fill(false);
4469
+ for (const d of digits) days[Number(d)] = true;
4470
+ return { from, periods, days };
4471
+ }
4472
+ var TradingCalendar = class {
4473
+ /**
4474
+ * @param timezone - Time zone of the session hours (the exchange time zone)
4475
+ * @param spec - Session information (TradingView format)
4476
+ * @param rule - Days without ":days": 'symbol' (Monday to Friday) or 'pine' (PineScript session strings)
4477
+ */
4478
+ constructor(timezone, spec, rule = "symbol") {
4479
+ this.timezone = timezone;
4480
+ const [first = "", ...changes] = spec.session.split("#");
4481
+ this.versions = [parseVersion(first, 0, spec.session, rule)];
4482
+ for (const change3 of changes) {
4483
+ const m = /^(\d{8})\/(.+)$/.exec(change3.trim());
4484
+ if (!m) throw new SyntaxError(`Invalid session change in "${spec.session}"`);
4485
+ this.versions.push(parseVersion(m[2], Number(m[1]), spec.session, rule));
4486
+ }
4487
+ for (const part of (spec.corrections ?? "").split(";").filter((p) => p.trim())) {
4488
+ const i = part.lastIndexOf(":");
4489
+ const text2 = part.slice(0, i).trim();
4490
+ const periods = text2 === "dayoff" ? null : parsePeriods(text2, part);
4491
+ for (const date of part.slice(i + 1).split(",")) this.corrections.set(Number(date), periods);
4492
+ }
4493
+ const holidays = Array.isArray(spec.holidays) ? spec.holidays : (spec.holidays ?? "").split(",");
4494
+ this.holidays = new Set(holidays.filter((h) => h.trim()).map(Number));
4495
+ }
4496
+ timezone;
4497
+ versions;
4498
+ corrections = /* @__PURE__ */ new Map();
4499
+ holidays;
4500
+ cache = /* @__PURE__ */ new Map();
4501
+ /** Session periods [start, end) of the trading day `date`; empty when the day has no session. */
4502
+ periods(date) {
4503
+ let out = this.cache.get(date);
4504
+ if (out) return out;
4505
+ let periods = [];
4506
+ const correction = this.corrections.get(date);
4507
+ if (correction !== void 0) {
4508
+ periods = correction ?? [];
4509
+ } else if (!this.holidays.has(date)) {
4510
+ const version = [...this.versions].reverse().find((v) => v.from <= date);
4511
+ if (version.days[weekdayOf(date)]) periods = version.periods;
4512
+ }
4513
+ const y = Math.floor(date / 1e4);
4514
+ const m = Math.floor(date / 100) % 100;
4515
+ const d = date % 100;
4516
+ out = periods.map((p) => [
4517
+ zonedToUnix(this.timezone, y, m, d - p.startOffset, Math.floor(p.start / 60), p.start % 60),
4518
+ zonedToUnix(this.timezone, y, m, d - p.endOffset, Math.floor(p.end / 60), p.end % 60)
4519
+ ]);
4520
+ this.cache.set(date, out);
4521
+ return out;
4522
+ }
4523
+ isTradingDay(date) {
4524
+ return this.periods(date).length > 0;
4525
+ }
4526
+ /**
4527
+ * Trading day and period of a time: the period that contains it, else the last period that started
4528
+ * before it. Null when no trading day is found near the time.
4529
+ */
4530
+ locate(time2) {
4531
+ const f = zonedFields(time2, this.timezone);
4532
+ const local = toDateNum(f.year, f.month, f.day);
4533
+ for (let k = 0; k <= 5; k++) {
4534
+ const date = addDays(local, k);
4535
+ const index = this.periods(date).findIndex(([s, e2]) => s <= time2 && time2 < e2);
4536
+ if (index !== -1) return { date, index, inside: true };
4537
+ }
4538
+ for (let k = 5; k >= -7; k--) {
4539
+ const date = addDays(local, k);
4540
+ const periods = this.periods(date);
4541
+ let index = -1;
4542
+ periods.forEach(([s], i) => {
4543
+ if (s <= time2) index = i;
4544
+ });
4545
+ if (index !== -1) return { date, index, inside: false };
4546
+ }
4547
+ return null;
4548
+ }
4549
+ /** First trading day in [from, to] (dates), or null. */
4550
+ firstTradingDay(from, to) {
4551
+ for (let date = from; date <= to; date = addDays(date, 1)) if (this.isTradingDay(date)) return date;
4552
+ return null;
4553
+ }
4554
+ /** Last trading day in [from, to] (dates), or null. */
4555
+ lastTradingDay(from, to) {
4556
+ for (let date = to; date >= from; date = addDays(date, -1)) if (this.isTradingDay(date)) return date;
4557
+ return null;
4558
+ }
4559
+ };
4560
+ var weekStart = (date) => addDays(date, -((weekdayOf(date) + 5) % 7));
4561
+ var monthStart = (date) => Math.floor(date / 100) * 100 + 1;
4562
+ var monthEnd = (date) => addDays(monthStart(addDays(monthStart(date), 32)), -1);
4563
+
4564
+ // src/session/bars.ts
4565
+ function unitOf(tf) {
4566
+ return { unit: tf.isdaily ? "D" : tf.isweekly ? "W" : "M", n: tf.multiplier };
4567
+ }
4568
+ var yearOf = (date) => Math.floor(date / 1e4);
4569
+ var firstMonday = (year3) => {
4570
+ const jan1 = year3 * 1e4 + 101;
4571
+ const monday = weekStart(jan1);
4572
+ return monday === jan1 ? jan1 : addDays(monday, 7);
4573
+ };
4574
+ var SessionBars = class {
4575
+ constructor(calendar2, chartTimeframe2) {
4576
+ this.calendar = calendar2;
4577
+ this.chart = info(chartTimeframe2);
4578
+ }
4579
+ calendar;
4580
+ chart;
4581
+ yearDays = /* @__PURE__ */ new Map();
4582
+ /** Trading days of a calendar year, in order. */
4583
+ tradingDaysOf(year3) {
4584
+ let days = this.yearDays.get(year3);
4585
+ if (!days) {
4586
+ days = [];
4587
+ for (let date = year3 * 1e4 + 101; yearOf(date) === year3; date = addDays(date, 1)) {
4588
+ if (this.calendar.isTradingDay(date)) days.push(date);
4589
+ }
4590
+ this.yearDays.set(year3, days);
4591
+ }
4592
+ return days;
4593
+ }
4594
+ /**
4595
+ * Dates [from, to] of the `n`-`unit` period that contains `date` (for "D": its first and last trading days).
4596
+ * Periods restart each calendar year.
4597
+ */
4598
+ periodRange(date, unit, n) {
4599
+ if (unit === "D") {
4600
+ if (n === 1) return [date, date];
4601
+ const days = this.tradingDaysOf(yearOf(date));
4602
+ let k = days.findIndex((d) => d >= date);
4603
+ if (k === -1) return this.periodRange(yearOf(date) * 1e4 + 1e4 + 101, unit, n);
4604
+ k -= k % n;
4605
+ return [days[k], days[Math.min(k + n, days.length) - 1]];
4606
+ }
4607
+ if (unit === "W") {
4608
+ const monday = weekStart(date);
4609
+ const year4 = yearOf(monday);
4610
+ const first = firstMonday(year4);
4611
+ const next = firstMonday(year4 + 1);
4612
+ const k = Math.round((dateUtcMs(monday) - dateUtcMs(first)) / (7 * 864e5));
4613
+ const from = addDays(first, (k - k % n) * 7);
4614
+ const to = addDays(from, n * 7 - 1);
4615
+ return [from, to < next ? to : addDays(next, -1)];
4616
+ }
4617
+ const year3 = yearOf(date);
4618
+ const month3 = Math.floor(date / 100) % 100;
4619
+ const firstMonth = month3 - (month3 - 1) % n;
4620
+ const lastMonth = Math.min(firstMonth + n - 1, 12);
4621
+ return [monthStart(year3 * 1e4 + firstMonth * 100 + 1), monthEnd(year3 * 1e4 + lastMonth * 100 + 1)];
4622
+ }
4623
+ dayStart(date) {
4624
+ return this.calendar.periods(date)[0][0];
4625
+ }
4626
+ dayEnd(date) {
4627
+ const p = this.calendar.periods(date);
4628
+ return p[p.length - 1][1];
4629
+ }
4630
+ /** PineScript `time(tf)` for a bar that opens at `time`; NaN when no trading day is found. */
4631
+ timeOf(time2, timeframe2) {
4632
+ const tf = info(timeframe2);
4633
+ const at = this.calendar.locate(time2);
4634
+ if (!at) return NaN;
4635
+ if (tf.isintraday) {
4636
+ if (this.chart.isdwm) return time2;
4637
+ const [start] = this.calendar.periods(at.date)[at.index];
4638
+ const ms = in_seconds(tf.period) * 1e3;
4639
+ return start + Math.floor((time2 - start) / ms) * ms;
4640
+ }
4641
+ const { unit, n } = unitOf(tf);
4642
+ const [from, to] = this.periodRange(at.date, unit, n);
4643
+ const first = this.calendar.firstTradingDay(from, to);
4644
+ return first === null ? NaN : this.dayStart(first);
4645
+ }
4646
+ /** PineScript `time_close(tf)` for a bar that opens at `time`. */
4647
+ closeOf(time2, timeframe2) {
4648
+ const tf = info(timeframe2);
4649
+ const at = this.calendar.locate(time2);
4650
+ if (!at) return NaN;
4651
+ if (tf.isintraday) {
4652
+ const [, end] = this.calendar.periods(at.date)[at.index];
4653
+ if (this.chart.isdwm) return end;
4654
+ return Math.min(this.timeOf(time2, timeframe2) + in_seconds(tf.period) * 1e3, end);
4655
+ }
4656
+ const { unit, n } = unitOf(tf);
4657
+ const [from, to] = this.periodRange(at.date, unit, n);
4658
+ if (this.chart.isintraday && (unit !== "D" || n > 1)) {
4659
+ const [nextFrom, nextTo] = this.periodRange(addDays(to, 1), unit, n);
4660
+ const first = this.calendar.firstTradingDay(nextFrom, addDays(nextTo, 31));
4661
+ return first === null ? NaN : this.dayStart(first);
4662
+ }
4663
+ const last = this.calendar.lastTradingDay(from, to);
4664
+ return last === null ? NaN : this.dayEnd(last);
4665
+ }
4666
+ /** Trading day of a bar: on D / W / M charts the last trading day of the chart period. */
4667
+ tradingDay(time2) {
4668
+ const at = this.calendar.locate(time2);
4669
+ if (!at) return null;
4670
+ if (this.chart.isdwm) {
4671
+ const { unit, n } = unitOf(this.chart);
4672
+ const [from, to] = this.periodRange(at.date, unit, n);
4673
+ return this.calendar.lastTradingDay(from, to);
4674
+ }
4675
+ return at.date;
4676
+ }
4677
+ /**
4678
+ * End of the `timeframe` period that contains `time`: the intraday close, the session end of the day,
4679
+ * or the session end of the last trading day of the period. Used to know whether the last loaded
4680
+ * bar completes a higher-timeframe period (request.security).
4681
+ */
4682
+ periodEnd(time2, timeframe2) {
4683
+ const tf = info(timeframe2);
4684
+ const at = this.calendar.locate(time2);
4685
+ if (!at) return NaN;
4686
+ if (tf.isintraday) {
4687
+ const [, end] = this.calendar.periods(at.date)[at.index];
4688
+ return Math.min(this.timeOf(time2, timeframe2) + in_seconds(tf.period) * 1e3, end);
4689
+ }
4690
+ const { unit, n } = unitOf(tf);
4691
+ const [from, to] = this.periodRange(at.date, unit, n);
4692
+ const last = this.calendar.lastTradingDay(from, to);
4693
+ return last === null ? NaN : this.dayEnd(last);
4694
+ }
4695
+ /** PineScript `time_tradingday`: 00:00 UTC of the trading day. */
4696
+ tradingDayTime(time2) {
4697
+ const day = this.tradingDay(time2);
4698
+ return day === null ? NaN : dateUtcMs(day);
4699
+ }
4700
+ /** True when the bar at `time` is inside the session. */
4701
+ inside(time2) {
4702
+ return this.calendar.locate(time2)?.inside ?? false;
4703
+ }
4704
+ /** Session start and end of the trading day of `time`, or null. */
4705
+ dayBounds(time2) {
4706
+ const at = this.calendar.locate(time2);
4707
+ return at ? { date: at.date, start: this.dayStart(at.date), end: this.dayEnd(at.date) } : null;
4708
+ }
4709
+ };
4710
+ function sessionFlags(times, bars2, regular) {
4711
+ const n = times.length;
4712
+ const flag2 = () => new Array(n).fill(false);
4713
+ const out = {
4714
+ isfirstbar: flag2(),
4715
+ islastbar: flag2(),
4716
+ ismarket: flag2(),
4717
+ ispremarket: flag2(),
4718
+ ispostmarket: flag2(),
4719
+ isfirstbar_regular: flag2(),
4720
+ islastbar_regular: flag2()
4721
+ };
4722
+ const chart2 = bars2.chart;
4723
+ let previousPeriod = "";
4724
+ let previousRegular = "";
4725
+ for (let i = 0; i < n; i++) {
4726
+ const t2 = times[i];
4727
+ if (chart2.isdwm) {
4728
+ for (const k of ["isfirstbar", "islastbar", "ismarket", "isfirstbar_regular", "islastbar_regular"]) out[k][i] = true;
4729
+ continue;
4730
+ }
4731
+ const at = bars2.calendar.locate(t2);
4732
+ if (!at) {
4733
+ previousPeriod = previousRegular = "";
4734
+ continue;
4735
+ }
4736
+ const close2 = bars2.closeOf(t2, chart2.period);
4737
+ const [, end] = bars2.calendar.periods(at.date)[at.index];
4738
+ const period = `${at.date}/${at.index}`;
4739
+ out.isfirstbar[i] = period !== previousPeriod;
4740
+ out.islastbar[i] = close2 >= end;
4741
+ const regularPeriods = regular.calendar.periods(at.date);
4742
+ const r2 = regularPeriods.findIndex(([s, e2]) => s <= t2 && t2 < e2);
4743
+ const market = r2 !== -1;
4744
+ out.ismarket[i] = market;
4745
+ if (!market && regularPeriods.length) {
4746
+ out.ispremarket[i] = t2 < regularPeriods[0][0];
4747
+ out.ispostmarket[i] = t2 >= regularPeriods[regularPeriods.length - 1][1];
4748
+ }
4749
+ const regularPeriod = market ? `${at.date}/${r2}` : "";
4750
+ out.isfirstbar_regular[i] = market && regularPeriod !== previousRegular;
4751
+ out.islastbar_regular[i] = market && close2 >= regularPeriods[r2][1];
4752
+ previousPeriod = period;
4753
+ previousRegular = regularPeriod;
4754
+ }
4755
+ return out;
4756
+ }
4757
+
4758
+ // src/security/resample.ts
4759
+ function resample(bars2, periodStart) {
4760
+ const out = [];
4761
+ const group2 = [];
4762
+ bars2.forEach((b2, i) => {
4763
+ const start = periodStart[i];
4764
+ const last = out[out.length - 1];
4765
+ if (!last || last.time !== start) {
4766
+ out.push({ time: start, open: b2.open, high: b2.high, low: b2.low, close: b2.close, volume: b2.volume ?? NaN });
4767
+ } else {
4768
+ last.high = Math.max(last.high, b2.high);
4769
+ last.low = Math.min(last.low, b2.low);
4770
+ last.close = b2.close;
4771
+ last.volume = (last.volume ?? 0) + (b2.volume ?? NaN);
4772
+ }
4773
+ group2.push(out.length - 1);
4774
+ });
4775
+ return { bars: out, group: group2 };
4776
+ }
4777
+ function periodsOf(starts, dayPeriods, reaches) {
4778
+ const n = starts.length;
4779
+ const group2 = [];
4780
+ starts.forEach((s, i) => group2.push(i === 0 ? 0 : group2[i - 1] + (s !== starts[i - 1] ? 1 : 0)));
4781
+ const latest = [];
4782
+ starts.forEach((s, i) => {
4783
+ let done = i === 0 ? -1 : latest[i - 1];
4784
+ if (i > 0 && group2[i] !== group2[i - 1]) done = Math.max(done, group2[i] - 1);
4785
+ const ends = i < n - 1 ? starts[i + 1] !== s || dayPeriods[i + 1] !== dayPeriods[i] : true;
4786
+ if (ends && reaches[i]) done = Math.max(done, group2[i]);
4787
+ latest.push(done);
4788
+ });
4789
+ return { group: group2, latest };
4790
+ }
4791
+ function mapToChart(values, group2, latest, lookahead, gaps) {
4792
+ return group2.map((g2, i) => {
4793
+ if (lookahead) {
4794
+ const first = i === 0 || group2[i - 1] !== g2;
4795
+ return gaps && !first ? NaN : values[g2] ?? NaN;
4796
+ }
4797
+ const done = latest[i];
4798
+ if (done < 0 || gaps && i > 0 && latest[i - 1] === done) return NaN;
4799
+ return values[done] ?? NaN;
4800
+ });
4801
+ }
4802
+ function heikinAshi(bars2) {
4803
+ const out = [];
4804
+ bars2.forEach((b2, i) => {
4805
+ const close2 = (b2.open + b2.high + b2.low + b2.close) / 4;
4806
+ const prev = out[i - 1];
4807
+ const open2 = prev ? (prev.open + prev.close) / 2 : (b2.open + b2.close) / 2;
4808
+ 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 });
4809
+ });
4810
+ return out;
4811
+ }
4812
+
4813
+ // src/math/index.ts
4814
+ var math_exports = {};
4815
+ __export(math_exports, {
4816
+ abs: () => abs,
4817
+ acos: () => acos,
4818
+ asin: () => asin,
4819
+ atan: () => atan,
4820
+ avg: () => avg,
4821
+ ceil: () => ceil,
4822
+ cos: () => cos,
4823
+ e: () => e,
4824
+ exp: () => exp,
4825
+ floor: () => floor,
4826
+ log: () => log,
4827
+ log10: () => log10,
4828
+ max: () => max3,
4829
+ min: () => min3,
4830
+ phi: () => phi,
4831
+ pi: () => pi,
4832
+ pow: () => pow,
4833
+ random: () => random,
4834
+ round: () => round,
4835
+ round_to_mintick: () => round_to_mintick,
4836
+ rphi: () => rphi,
4837
+ sign: () => sign,
4838
+ sin: () => sin,
4839
+ sqrt: () => sqrt,
4840
+ sum: () => sum,
4841
+ tan: () => tan,
4842
+ todegrees: () => todegrees,
4843
+ toradians: () => toradians
4844
+ });
4845
+ function abs(value) {
4846
+ if (value instanceof Series) {
4847
+ const bars2 = value.bars;
2884
4848
  const valueArray = value.toArray();
2885
- const length = bars2.length;
4849
+ const length2 = bars2.length;
4850
+ const result = [];
4851
+ for (let i = 0; i < length2; i++) {
4852
+ const v = valueArray[i] ?? NaN;
4853
+ result.push(Math.abs(v));
4854
+ }
4855
+ return Series.fromArray(bars2, result);
4856
+ }
4857
+ return Math.abs(value);
4858
+ }
4859
+ function ceil(value) {
4860
+ if (value instanceof Series) {
4861
+ const bars2 = value.bars;
4862
+ const valueArray = value.toArray();
4863
+ const length2 = bars2.length;
4864
+ const result = [];
4865
+ for (let i = 0; i < length2; i++) {
4866
+ const v = valueArray[i] ?? NaN;
4867
+ result.push(Math.ceil(v));
4868
+ }
4869
+ return Series.fromArray(bars2, result);
4870
+ }
4871
+ return Math.ceil(value);
4872
+ }
4873
+ function floor(value) {
4874
+ if (value instanceof Series) {
4875
+ const bars2 = value.bars;
4876
+ const valueArray = value.toArray();
4877
+ const length2 = bars2.length;
4878
+ const result = [];
4879
+ for (let i = 0; i < length2; i++) {
4880
+ const v = valueArray[i] ?? NaN;
4881
+ result.push(Math.floor(v));
4882
+ }
4883
+ return Series.fromArray(bars2, result);
4884
+ }
4885
+ return Math.floor(value);
4886
+ }
4887
+ function round(value, precision) {
4888
+ if (value instanceof Series) {
4889
+ const bars2 = value.bars;
4890
+ const valueArray = value.toArray();
4891
+ const length2 = bars2.length;
2886
4892
  const result = [];
2887
4893
  if (precision === void 0) {
2888
- for (let i = 0; i < length; i++) {
4894
+ for (let i = 0; i < length2; i++) {
2889
4895
  const v = valueArray[i] ?? NaN;
2890
4896
  result.push(Math.round(v));
2891
4897
  }
2892
4898
  } else {
2893
4899
  const multiplier2 = Math.pow(10, precision);
2894
- for (let i = 0; i < length; i++) {
4900
+ for (let i = 0; i < length2; i++) {
2895
4901
  const v = valueArray[i] ?? NaN;
2896
4902
  result.push(Math.round(v * multiplier2) / multiplier2);
2897
4903
  }
@@ -2911,12 +4917,12 @@ function max3(...values) {
2911
4917
  }
2912
4918
  const firstSeries = values.find((v) => v instanceof Series);
2913
4919
  const bars2 = firstSeries.bars;
2914
- const length = bars2.length;
4920
+ const length2 = bars2.length;
2915
4921
  const valueArrays = values.map(
2916
4922
  (v) => v instanceof Series ? v.toArray() : null
2917
4923
  );
2918
4924
  const result = [];
2919
- for (let i = 0; i < length; i++) {
4925
+ for (let i = 0; i < length2; i++) {
2920
4926
  const nums = values.map(
2921
4927
  (v, idx) => valueArrays[idx] ? valueArrays[idx][i] ?? NaN : v
2922
4928
  );
@@ -2931,12 +4937,12 @@ function min3(...values) {
2931
4937
  }
2932
4938
  const firstSeries = values.find((v) => v instanceof Series);
2933
4939
  const bars2 = firstSeries.bars;
2934
- const length = bars2.length;
4940
+ const length2 = bars2.length;
2935
4941
  const valueArrays = values.map(
2936
4942
  (v) => v instanceof Series ? v.toArray() : null
2937
4943
  );
2938
4944
  const result = [];
2939
- for (let i = 0; i < length; i++) {
4945
+ for (let i = 0; i < length2; i++) {
2940
4946
  const nums = values.map(
2941
4947
  (v, idx) => valueArrays[idx] ? valueArrays[idx][i] ?? NaN : v
2942
4948
  );
@@ -2951,12 +4957,12 @@ function avg(...values) {
2951
4957
  }
2952
4958
  const firstSeries = values.find((v) => v instanceof Series);
2953
4959
  const bars2 = firstSeries.bars;
2954
- const length = bars2.length;
4960
+ const length2 = bars2.length;
2955
4961
  const valueArrays = values.map(
2956
4962
  (v) => v instanceof Series ? v.toArray() : null
2957
4963
  );
2958
4964
  const result = [];
2959
- for (let i = 0; i < length; i++) {
4965
+ for (let i = 0; i < length2; i++) {
2960
4966
  const nums = values.map(
2961
4967
  (v, idx) => valueArrays[idx] ? valueArrays[idx][i] ?? NaN : v
2962
4968
  );
@@ -2965,15 +4971,15 @@ function avg(...values) {
2965
4971
  }
2966
4972
  return Series.fromArray(bars2, result);
2967
4973
  }
2968
- function sum(source, length) {
4974
+ function sum(source, length2) {
2969
4975
  const sourceArray = source instanceof Series ? source.toArray() : source;
2970
4976
  const result = [];
2971
4977
  for (let i = 0; i < sourceArray.length; i++) {
2972
- if (i < length - 1) {
4978
+ if (i < length2 - 1) {
2973
4979
  result.push(NaN);
2974
4980
  } else {
2975
4981
  let total = 0;
2976
- for (let j = 0; j < length; j++) {
4982
+ for (let j = 0; j < length2; j++) {
2977
4983
  total += sourceArray[i - j];
2978
4984
  }
2979
4985
  result.push(total);
@@ -2988,9 +4994,9 @@ function sqrt(value) {
2988
4994
  if (value instanceof Series) {
2989
4995
  const bars2 = value.bars;
2990
4996
  const valueArray = value.toArray();
2991
- const length = bars2.length;
4997
+ const length2 = bars2.length;
2992
4998
  const result = [];
2993
- for (let i = 0; i < length; i++) {
4999
+ for (let i = 0; i < length2; i++) {
2994
5000
  const v = valueArray[i] ?? NaN;
2995
5001
  result.push(Math.sqrt(v));
2996
5002
  }
@@ -3007,9 +5013,9 @@ function pow(base, exponent) {
3007
5013
  const bars2 = baseIsSeries ? base.bars : exponent.bars;
3008
5014
  const baseArray = baseIsSeries ? base.toArray() : null;
3009
5015
  const expArray = expIsSeries ? exponent.toArray() : null;
3010
- const length = bars2.length;
5016
+ const length2 = bars2.length;
3011
5017
  const result = [];
3012
- for (let i = 0; i < length; i++) {
5018
+ for (let i = 0; i < length2; i++) {
3013
5019
  const b2 = baseArray ? baseArray[i] ?? NaN : base;
3014
5020
  const e2 = expArray ? expArray[i] ?? NaN : exponent;
3015
5021
  result.push(Math.pow(b2, e2));
@@ -3020,9 +5026,9 @@ function exp(value) {
3020
5026
  if (value instanceof Series) {
3021
5027
  const bars2 = value.bars;
3022
5028
  const valueArray = value.toArray();
3023
- const length = bars2.length;
5029
+ const length2 = bars2.length;
3024
5030
  const result = [];
3025
- for (let i = 0; i < length; i++) {
5031
+ for (let i = 0; i < length2; i++) {
3026
5032
  const v = valueArray[i] ?? NaN;
3027
5033
  result.push(Math.exp(v));
3028
5034
  }
@@ -3034,9 +5040,9 @@ function log(value) {
3034
5040
  if (value instanceof Series) {
3035
5041
  const bars2 = value.bars;
3036
5042
  const valueArray = value.toArray();
3037
- const length = bars2.length;
5043
+ const length2 = bars2.length;
3038
5044
  const result = [];
3039
- for (let i = 0; i < length; i++) {
5045
+ for (let i = 0; i < length2; i++) {
3040
5046
  const v = valueArray[i] ?? NaN;
3041
5047
  result.push(Math.log(v));
3042
5048
  }
@@ -3048,9 +5054,9 @@ function log10(value) {
3048
5054
  if (value instanceof Series) {
3049
5055
  const bars2 = value.bars;
3050
5056
  const valueArray = value.toArray();
3051
- const length = bars2.length;
5057
+ const length2 = bars2.length;
3052
5058
  const result = [];
3053
- for (let i = 0; i < length; i++) {
5059
+ for (let i = 0; i < length2; i++) {
3054
5060
  const v = valueArray[i] ?? NaN;
3055
5061
  result.push(Math.log10(v));
3056
5062
  }
@@ -3062,9 +5068,9 @@ function sin(value) {
3062
5068
  if (value instanceof Series) {
3063
5069
  const bars2 = value.bars;
3064
5070
  const valueArray = value.toArray();
3065
- const length = bars2.length;
5071
+ const length2 = bars2.length;
3066
5072
  const result = [];
3067
- for (let i = 0; i < length; i++) {
5073
+ for (let i = 0; i < length2; i++) {
3068
5074
  const v = valueArray[i] ?? NaN;
3069
5075
  result.push(Math.sin(v));
3070
5076
  }
@@ -3076,9 +5082,9 @@ function cos(value) {
3076
5082
  if (value instanceof Series) {
3077
5083
  const bars2 = value.bars;
3078
5084
  const valueArray = value.toArray();
3079
- const length = bars2.length;
5085
+ const length2 = bars2.length;
3080
5086
  const result = [];
3081
- for (let i = 0; i < length; i++) {
5087
+ for (let i = 0; i < length2; i++) {
3082
5088
  const v = valueArray[i] ?? NaN;
3083
5089
  result.push(Math.cos(v));
3084
5090
  }
@@ -3090,9 +5096,9 @@ function tan(value) {
3090
5096
  if (value instanceof Series) {
3091
5097
  const bars2 = value.bars;
3092
5098
  const valueArray = value.toArray();
3093
- const length = bars2.length;
5099
+ const length2 = bars2.length;
3094
5100
  const result = [];
3095
- for (let i = 0; i < length; i++) {
5101
+ for (let i = 0; i < length2; i++) {
3096
5102
  const v = valueArray[i] ?? NaN;
3097
5103
  result.push(Math.tan(v));
3098
5104
  }
@@ -3104,9 +5110,9 @@ function asin(value) {
3104
5110
  if (value instanceof Series) {
3105
5111
  const bars2 = value.bars;
3106
5112
  const valueArray = value.toArray();
3107
- const length = bars2.length;
5113
+ const length2 = bars2.length;
3108
5114
  const result = [];
3109
- for (let i = 0; i < length; i++) {
5115
+ for (let i = 0; i < length2; i++) {
3110
5116
  const v = valueArray[i] ?? NaN;
3111
5117
  result.push(Math.asin(v));
3112
5118
  }
@@ -3118,9 +5124,9 @@ function acos(value) {
3118
5124
  if (value instanceof Series) {
3119
5125
  const bars2 = value.bars;
3120
5126
  const valueArray = value.toArray();
3121
- const length = bars2.length;
5127
+ const length2 = bars2.length;
3122
5128
  const result = [];
3123
- for (let i = 0; i < length; i++) {
5129
+ for (let i = 0; i < length2; i++) {
3124
5130
  const v = valueArray[i] ?? NaN;
3125
5131
  result.push(Math.acos(v));
3126
5132
  }
@@ -3132,9 +5138,9 @@ function atan(value) {
3132
5138
  if (value instanceof Series) {
3133
5139
  const bars2 = value.bars;
3134
5140
  const valueArray = value.toArray();
3135
- const length = bars2.length;
5141
+ const length2 = bars2.length;
3136
5142
  const result = [];
3137
- for (let i = 0; i < length; i++) {
5143
+ for (let i = 0; i < length2; i++) {
3138
5144
  const v = valueArray[i] ?? NaN;
3139
5145
  result.push(Math.atan(v));
3140
5146
  }
@@ -3146,9 +5152,9 @@ function toradians(degrees) {
3146
5152
  if (degrees instanceof Series) {
3147
5153
  const bars2 = degrees.bars;
3148
5154
  const valueArray = degrees.toArray();
3149
- const length = bars2.length;
5155
+ const length2 = bars2.length;
3150
5156
  const result = [];
3151
- for (let i = 0; i < length; i++) {
5157
+ for (let i = 0; i < length2; i++) {
3152
5158
  const v = valueArray[i] ?? NaN;
3153
5159
  result.push(v * (Math.PI / 180));
3154
5160
  }
@@ -3160,9 +5166,9 @@ function todegrees(radians) {
3160
5166
  if (radians instanceof Series) {
3161
5167
  const bars2 = radians.bars;
3162
5168
  const valueArray = radians.toArray();
3163
- const length = bars2.length;
5169
+ const length2 = bars2.length;
3164
5170
  const result = [];
3165
- for (let i = 0; i < length; i++) {
5171
+ for (let i = 0; i < length2; i++) {
3166
5172
  const v = valueArray[i] ?? NaN;
3167
5173
  result.push(v * (180 / Math.PI));
3168
5174
  }
@@ -3181,9 +5187,9 @@ function sign(value) {
3181
5187
  if (value instanceof Series) {
3182
5188
  const bars2 = value.bars;
3183
5189
  const valueArray = value.toArray();
3184
- const length = bars2.length;
5190
+ const length2 = bars2.length;
3185
5191
  const result = [];
3186
- for (let i = 0; i < length; i++) {
5192
+ for (let i = 0; i < length2; i++) {
3187
5193
  const v = valueArray[i] ?? NaN;
3188
5194
  result.push(v > 0 ? 1 : v < 0 ? -1 : 0);
3189
5195
  }
@@ -3191,11 +5197,11 @@ function sign(value) {
3191
5197
  }
3192
5198
  return value > 0 ? 1 : value < 0 ? -1 : 0;
3193
5199
  }
3194
- function round_to_mintick(number, mintick) {
3195
- if (number instanceof Series) {
3196
- const bars2 = number.bars;
3197
- const valueArray = number.toArray();
3198
- const length = bars2.length;
5200
+ function round_to_mintick(number2, mintick) {
5201
+ if (number2 instanceof Series) {
5202
+ const bars2 = number2.bars;
5203
+ const valueArray = number2.toArray();
5204
+ const length2 = bars2.length;
3199
5205
  if (mintick === void 0) {
3200
5206
  throw new Error(
3201
5207
  "math.round_to_mintick() requires mintick value. Either pass it explicitly or use createContext({ syminfo: { mintick } }) for implicit data."
@@ -3203,11 +5209,11 @@ function round_to_mintick(number, mintick) {
3203
5209
  }
3204
5210
  const result = [];
3205
5211
  if (mintick === 0) {
3206
- for (let i = 0; i < length; i++) {
5212
+ for (let i = 0; i < length2; i++) {
3207
5213
  result.push(valueArray[i] ?? NaN);
3208
5214
  }
3209
5215
  } else {
3210
- for (let i = 0; i < length; i++) {
5216
+ for (let i = 0; i < length2; i++) {
3211
5217
  const v = valueArray[i];
3212
5218
  if (v === void 0 || isNaN(v)) {
3213
5219
  result.push(NaN);
@@ -3218,7 +5224,7 @@ function round_to_mintick(number, mintick) {
3218
5224
  }
3219
5225
  return Series.fromArray(bars2, result);
3220
5226
  }
3221
- if (isNaN(number)) {
5227
+ if (isNaN(number2)) {
3222
5228
  return NaN;
3223
5229
  }
3224
5230
  if (mintick === void 0) {
@@ -3227,9 +5233,9 @@ function round_to_mintick(number, mintick) {
3227
5233
  );
3228
5234
  }
3229
5235
  if (mintick === 0) {
3230
- return number;
5236
+ return number2;
3231
5237
  }
3232
- return Math.round(number / mintick) * mintick;
5238
+ return Math.round(number2 / mintick) * mintick;
3233
5239
  }
3234
5240
  var pi = Math.PI;
3235
5241
  var e = Math.E;
@@ -3276,9 +5282,11 @@ function slugId(title, fallback, taken) {
3276
5282
  taken.add(id);
3277
5283
  return id;
3278
5284
  }
3279
- function executeScript(body, barsInput, inputs = {}) {
5285
+ function executeScript(body, barsInput, inputs = {}, chart2 = {}) {
3280
5286
  ctxBars.setAll(barsInput);
5287
+ chartCtx = { ...chart2 };
3281
5288
  ctx = freshCollector(inputs);
5289
+ resetDrawings();
3282
5290
  try {
3283
5291
  body();
3284
5292
  const c = ctx;
@@ -3319,6 +5327,12 @@ function indicator(title, options = {}) {
3319
5327
  c.overlay = options.overlay ?? true;
3320
5328
  c.precision = options.precision;
3321
5329
  c.format = options.format;
5330
+ setDrawingLimits({
5331
+ line: options.max_lines_count,
5332
+ label: options.max_labels_count,
5333
+ box: options.max_boxes_count,
5334
+ polyline: options.max_polylines_count
5335
+ });
3322
5336
  }
3323
5337
  function registerInput(config, fallbackId) {
3324
5338
  const c = collector();
@@ -3355,6 +5369,19 @@ var input = {
3355
5369
  source(defval = "close", title) {
3356
5370
  const name = registerInput({ type: "source", defval, title }, "input_source");
3357
5371
  return sourceSeries(name);
5372
+ },
5373
+ /** Timeframe string ("60", "1D", "W"). As in PineScript, "" means the chart timeframe. */
5374
+ timeframe(defval, title, opts = {}) {
5375
+ return registerInput({ type: "timeframe", defval, title, options: opts.options }, "input_timeframe");
5376
+ },
5377
+ /** Session string ("0930-1600", "0930-1600:23456"). */
5378
+ session(defval, title, opts = {}) {
5379
+ return registerInput({ type: "session", defval, title, options: opts.options }, "input_session");
5380
+ },
5381
+ /** Date and time as a UNIX time in milliseconds, e.g. `input.time(timestamp('2024-01-01'), 'Start')`. */
5382
+ time(defval, title) {
5383
+ const v = registerInput({ type: "time", defval, title }, "input_time");
5384
+ return typeof v === "number" ? v : defval;
3358
5385
  }
3359
5386
  };
3360
5387
  var open = Series.fromBars(ctxBars, "open");
@@ -3371,18 +5398,60 @@ function sourceSeries(name) {
3371
5398
  return SOURCES[name] ?? close;
3372
5399
  }
3373
5400
  var bars = () => ctxBars.bars;
5401
+ function barsSeries(compute) {
5402
+ let version = -1;
5403
+ let values = [];
5404
+ return new Series(ctxBars, (_bar, i, data) => {
5405
+ if (version !== ctxBars.version) {
5406
+ values = compute(data).toArray();
5407
+ version = ctxBars.version;
5408
+ }
5409
+ return values[i] ?? NaN;
5410
+ });
5411
+ }
3374
5412
  var ta2 = {
3375
5413
  ...ta_series_exports,
3376
5414
  tr: (handleNa = false) => tr2(bars(), handleNa),
3377
- atr: (length) => atr2(bars(), length),
5415
+ atr: (length2) => atr2(bars(), length2),
3378
5416
  sar: (start, inc, max4) => sar2(bars(), start, inc, max4),
3379
- wpr: (length) => wpr2(bars(), length),
5417
+ wpr: (length2) => wpr2(bars(), length2),
3380
5418
  supertrend: (factor, atrLength) => supertrend2(bars(), factor, atrLength),
3381
5419
  dmi: (diLength, adxSmoothing) => dmi2(bars(), diLength, adxSmoothing),
3382
- kc: (source, length, mult, useTrueRange) => kc2(bars(), source, length, mult, useTrueRange),
3383
- kcw: (source, length, mult, useTrueRange) => kcw2(bars(), source, length, mult, useTrueRange),
3384
- ichimoku: (conversionPeriods, basePeriods, laggingSpan2Periods, displacement) => ichimoku2(bars(), conversionPeriods, basePeriods, laggingSpan2Periods, displacement)
5420
+ kc: (source, length2, mult, useTrueRange) => kc2(bars(), source, length2, mult, useTrueRange),
5421
+ kcw: (source, length2, mult, useTrueRange) => kcw2(bars(), source, length2, mult, useTrueRange),
5422
+ ichimoku: (conversionPeriods, basePeriods, laggingSpan2Periods, displacement) => ichimoku2(bars(), conversionPeriods, basePeriods, laggingSpan2Periods, displacement),
5423
+ /** `ta.highest(source, length)` or `ta.highest(length)` (source = high). */
5424
+ highest: (sourceOrLength, length2) => typeof sourceOrLength === "number" ? highest2(high, sourceOrLength) : highest2(sourceOrLength, length2),
5425
+ /** `ta.lowest(source, length)` or `ta.lowest(length)` (source = low). */
5426
+ lowest: (sourceOrLength, length2) => typeof sourceOrLength === "number" ? lowest2(low, sourceOrLength) : lowest2(sourceOrLength, length2),
5427
+ /** `ta.highestbars(source, length)` or `ta.highestbars(length)` (source = high); offsets are 0 or negative. */
5428
+ highestbars: (sourceOrLength, length2) => typeof sourceOrLength === "number" ? highestbars2(high, sourceOrLength) : highestbars2(sourceOrLength, length2),
5429
+ /** `ta.lowestbars(source, length)` or `ta.lowestbars(length)` (source = low); offsets are 0 or negative. */
5430
+ lowestbars: (sourceOrLength, length2) => typeof sourceOrLength === "number" ? lowestbars2(low, sourceOrLength) : lowestbars2(sourceOrLength, length2),
5431
+ /** `ta.vwap(source, anchor?, stdev_mult?)` with the chart volume; the default anchor is a new trading
5432
+ * day (`timeframe.change("1D")`), which needs the chart context (timeframe, time zone, session). */
5433
+ vwap: ((source, anchor, stdev_mult) => {
5434
+ const a = anchor ?? changeOf("1D");
5435
+ return stdev_mult === void 0 ? vwap2(source, volume, a) : vwapBands(source, volume, a, stdev_mult);
5436
+ }),
5437
+ /** `ta.pivothigh(source, leftbars, rightbars)` or `ta.pivothigh(leftbars, rightbars)` (source = high).
5438
+ * The value appears `rightbars` bars after the pivot bar, as in PineScript. */
5439
+ pivothigh: (sourceOrLeft, leftOrRight, rightbars) => typeof sourceOrLeft === "number" ? pivothigh2(high, sourceOrLeft, leftOrRight) : pivothigh2(sourceOrLeft, leftOrRight, rightbars),
5440
+ /** `ta.pivotlow(source, leftbars, rightbars)` or `ta.pivotlow(leftbars, rightbars)` (source = low). */
5441
+ pivotlow: (sourceOrLeft, leftOrRight, rightbars) => typeof sourceOrLeft === "number" ? pivotlow2(low, sourceOrLeft, leftOrRight) : pivotlow2(sourceOrLeft, leftOrRight, rightbars),
5442
+ // PineScript variables of the chart bars: `ta.obv`, not `ta.obv()`.
5443
+ obv: barsSeries(obv2),
5444
+ pvt: barsSeries(pvt2),
5445
+ accdist: barsSeries(accdist2),
5446
+ nvi: barsSeries(nvi2),
5447
+ pvi: barsSeries(pvi2),
5448
+ iii: barsSeries(iii2),
5449
+ wad: barsSeries(wad2),
5450
+ wvad: barsSeries(wvad2)
3385
5451
  };
5452
+ function fixnan2(source) {
5453
+ return source instanceof Series ? Series.fromArray(ctxBars, fixnan(source.toArray())) : fixnan(source);
5454
+ }
3386
5455
  function colorWhen(cond, colorTrue, colorFalse) {
3387
5456
  return cond.toArray().map((v) => !isNA(v) && v !== 0 ? colorTrue : colorFalse);
3388
5457
  }
@@ -3394,8 +5463,8 @@ var color = {
3394
5463
  function plot(series, title, options = {}) {
3395
5464
  const c = collector();
3396
5465
  const id = `plot${c.plotConfig.length}`;
3397
- const perBar = Array.isArray(options.color) ? options.color : void 0;
3398
- const staticColor = typeof options.color === "string" ? options.color : perBar?.[perBar.length - 1] ?? "#2962FF";
5466
+ const perBar2 = Array.isArray(options.color) ? options.color : void 0;
5467
+ const staticColor = typeof options.color === "string" ? options.color : perBar2?.[perBar2.length - 1] ?? "#2962FF";
3399
5468
  c.plotConfig.push({
3400
5469
  id,
3401
5470
  title: title ?? id,
@@ -3411,7 +5480,7 @@ function plot(series, title, options = {}) {
3411
5480
  for (let i = 0; i < b2.length; i++) {
3412
5481
  const value = values[i];
3413
5482
  if (value === void 0 || Number.isNaN(value)) continue;
3414
- data.push(perBar ? { time: b2[i].time, value, color: perBar[i] } : { time: b2[i].time, value });
5483
+ data.push(perBar2 ? { time: b2[i].time, value, color: perBar2[i] } : { time: b2[i].time, value });
3415
5484
  }
3416
5485
  c.plots[id] = data;
3417
5486
  return { id, kind: "plot" };
@@ -3431,7 +5500,7 @@ function hline(price, title, options = {}) {
3431
5500
  }
3432
5501
  function fill(a, b2, options = {}) {
3433
5502
  const c = collector();
3434
- const perBar = Array.isArray(options.color) ? options.color : void 0;
5503
+ const perBar2 = Array.isArray(options.color) ? options.color : void 0;
3435
5504
  const staticColor = typeof options.color === "string" ? options.color : void 0;
3436
5505
  if (a.kind === "hline" && b2.kind === "hline") {
3437
5506
  c.fillConfig.push({
@@ -3439,7 +5508,7 @@ function fill(a, b2, options = {}) {
3439
5508
  plot1: a.id,
3440
5509
  plot2: b2.id,
3441
5510
  color: staticColor,
3442
- colors: perBar,
5511
+ colors: perBar2,
3443
5512
  title: options.title
3444
5513
  });
3445
5514
  return;
@@ -3448,7 +5517,7 @@ function fill(a, b2, options = {}) {
3448
5517
  plot1: a.id,
3449
5518
  plot2: b2.id,
3450
5519
  options: { color: staticColor, title: options.title },
3451
- colors: perBar
5520
+ colors: perBar2
3452
5521
  });
3453
5522
  }
3454
5523
  function emitMarkers(kind, condition, title, options) {
@@ -3507,11 +5576,11 @@ function emitBarColors(kind, colors, options) {
3507
5576
  const off = options.offset ?? 0;
3508
5577
  const target = kind === "bgcolor" ? c.bgcolors : c.barcolors;
3509
5578
  for (let i = 0; i < b2.length; i++) {
3510
- const col = typeof colors === "string" ? colors : colors[i];
3511
- if (!col) continue;
5579
+ const col2 = typeof colors === "string" ? colors : colors[i];
5580
+ if (!col2) continue;
3512
5581
  const j = i + off;
3513
5582
  if (j < 0 || j >= b2.length) continue;
3514
- target.push({ time: b2[j].time, color: col });
5583
+ target.push({ time: b2[j].time, color: col2 });
3515
5584
  }
3516
5585
  }
3517
5586
  function bgcolor(colors, options = {}) {
@@ -3563,12 +5632,335 @@ function eachBar(fn) {
3563
5632
  return j >= 0 ? out[j] : NaN;
3564
5633
  }
3565
5634
  };
3566
- for (idx = 0; idx < b2.length; idx++) {
3567
- const r2 = fn(ctx2);
3568
- out[idx] = typeof r2 === "number" ? r2 : typeof r2 === "boolean" ? r2 ? 1 : 0 : NaN;
5635
+ try {
5636
+ for (idx = 0; idx < b2.length; idx++) {
5637
+ currentBar = idx;
5638
+ const r2 = fn(ctx2);
5639
+ out[idx] = typeof r2 === "number" ? r2 : typeof r2 === "boolean" ? r2 ? 1 : 0 : NaN;
5640
+ }
5641
+ } finally {
5642
+ currentBar = -1;
3569
5643
  }
3570
5644
  return Series.fromArray(ctxBars, out);
3571
5645
  }
5646
+ var currentBar = -1;
5647
+ var chartCtx = {};
5648
+ function chartTimeframe() {
5649
+ collector();
5650
+ if (!chartCtx.timeframe) {
5651
+ throw new Error("The chart timeframe is not known: pass it as executeScript(body, bars, inputs, { timeframe }).");
5652
+ }
5653
+ return info(chartCtx.timeframe);
5654
+ }
5655
+ function exchangeTimezone() {
5656
+ collector();
5657
+ if (!chartCtx.timezone) {
5658
+ throw new Error("The exchange time zone is not known: pass it as executeScript(body, bars, inputs, { timezone }).");
5659
+ }
5660
+ return chartCtx.timezone;
5661
+ }
5662
+ var timeframe = {
5663
+ ...timeframe_exports,
5664
+ get period() {
5665
+ return chartTimeframe().period;
5666
+ },
5667
+ get main_period() {
5668
+ return chartTimeframe().period;
5669
+ },
5670
+ get multiplier() {
5671
+ return chartTimeframe().multiplier;
5672
+ },
5673
+ get isintraday() {
5674
+ return chartTimeframe().isintraday;
5675
+ },
5676
+ get isdaily() {
5677
+ return chartTimeframe().isdaily;
5678
+ },
5679
+ get isweekly() {
5680
+ return chartTimeframe().isweekly;
5681
+ },
5682
+ get ismonthly() {
5683
+ return chartTimeframe().ismonthly;
5684
+ },
5685
+ get isminutes() {
5686
+ return chartTimeframe().isminutes;
5687
+ },
5688
+ get isseconds() {
5689
+ return chartTimeframe().isseconds;
5690
+ },
5691
+ get isticks() {
5692
+ return chartTimeframe().isticks;
5693
+ },
5694
+ get isdwm() {
5695
+ return chartTimeframe().isdwm;
5696
+ },
5697
+ /** PineScript `timeframe.change(tf)`: 1 on bars that open a new `tf` period (0 on the first bar). */
5698
+ change(tf) {
5699
+ return changeOf(tf || chartTimeframe().period);
5700
+ },
5701
+ /** Seconds in `timeframe`; without it (or with "") the chart timeframe, as in PineScript. */
5702
+ in_seconds(tf) {
5703
+ return in_seconds(tf === void 0 || tf === "" ? chartTimeframe().period : tf);
5704
+ }
5705
+ };
5706
+ var syminfo = {
5707
+ get timezone() {
5708
+ return exchangeTimezone();
5709
+ },
5710
+ get tickerid() {
5711
+ collector();
5712
+ if (!chartCtx.tickerid) {
5713
+ throw new Error("The chart symbol is not known: pass it as executeScript(body, bars, inputs, { tickerid }).");
5714
+ }
5715
+ return chartCtx.tickerid;
5716
+ },
5717
+ get session() {
5718
+ collector();
5719
+ return chartCtx.sessionType ?? "regular";
5720
+ }
5721
+ };
5722
+ function calendar(fn) {
5723
+ return ((time2, timezone) => {
5724
+ const tz = timezone ?? exchangeTimezone();
5725
+ return time2 instanceof Series ? Series.fromArray(ctxBars, time2.toArray().map((t2) => fn(t2, tz))) : fn(time2, tz);
5726
+ });
5727
+ }
5728
+ var year2 = calendar(year);
5729
+ var month2 = calendar(month);
5730
+ var weekofyear2 = calendar(weekofyear);
5731
+ var dayofmonth2 = calendar(dayofmonth);
5732
+ var dayofweek2 = calendar(dayofweek);
5733
+ var hour2 = calendar(hour);
5734
+ var minute2 = calendar(minute);
5735
+ var second2 = calendar(second);
5736
+ function timestamp2(first, ...rest) {
5737
+ if (typeof first === "number") {
5738
+ const [m2, d2, h2, mi2, s2] = rest;
5739
+ return timestamp(exchangeTimezone(), first, m2, d2, h2, mi2, s2);
5740
+ }
5741
+ if (rest.length === 0) return timestamp(first);
5742
+ const [y, m, d, h, mi, s] = rest;
5743
+ return timestamp(first, y, m, d, h, mi, s);
5744
+ }
5745
+ function inSession3(time2, session2, timezone) {
5746
+ return inSession2(time2, session2, timezone ?? exchangeTimezone());
5747
+ }
5748
+ var str = {
5749
+ ...str_exports,
5750
+ format_time(time2, format2 = "yyyy-MM-dd'T'HH:mm:ssZ", timezone) {
5751
+ return format_time(time2, format2, timezone ?? exchangeTimezone());
5752
+ },
5753
+ format(pattern, ...args) {
5754
+ return formatMessage(pattern, args, exchangeTimezone);
5755
+ }
5756
+ };
5757
+ function barTime(bar) {
5758
+ return bar.time * (chartCtx.timeUnit === "ms" ? 1 : 1e3);
5759
+ }
5760
+ var toSpec = (s) => typeof s === "string" ? { session: s } : s;
5761
+ var sessionCache = null;
5762
+ function sessionBars() {
5763
+ const tz = exchangeTimezone();
5764
+ const tf = chartTimeframe().period;
5765
+ if (!chartCtx.session) {
5766
+ throw new Error("The session is not known: pass it as executeScript(body, bars, inputs, { session }).");
5767
+ }
5768
+ if (sessionCache?.ctx !== chartCtx) {
5769
+ const loaded = toSpec(chartCtx.session);
5770
+ const regular = chartCtx.regularSession ? toSpec(chartCtx.regularSession) : loaded;
5771
+ sessionCache = {
5772
+ ctx: chartCtx,
5773
+ bars: new SessionBars(new TradingCalendar(tz, loaded), tf),
5774
+ regular: new SessionBars(new TradingCalendar(tz, { holidays: loaded.holidays, ...regular }), tf)
5775
+ };
5776
+ }
5777
+ return sessionCache;
5778
+ }
5779
+ function calendarFor(session2, timezone) {
5780
+ const { bars: bars2 } = sessionBars();
5781
+ if (!session2 && !timezone) return { bars: bars2, test: false };
5782
+ const tz = timezone ?? exchangeTimezone();
5783
+ const spec = session2 ? { session: session2 } : { session: toSpec(chartCtx.session).session };
5784
+ return { bars: new SessionBars(new TradingCalendar(tz, spec, session2 ? "pine" : "symbol"), bars2.chart.period), test: true };
5785
+ }
5786
+ function perBar(fn) {
5787
+ const times = ctxBars.bars.map(barTime);
5788
+ return Series.fromArray(ctxBars, times.map((t2, i) => fn(t2, i, times)));
5789
+ }
5790
+ function callableSeries(series, fn) {
5791
+ Object.setPrototypeOf(fn, Series.prototype);
5792
+ Object.assign(fn, series);
5793
+ return fn;
5794
+ }
5795
+ function timeFunction(tf, session2, timezone) {
5796
+ collector();
5797
+ const { bars: bars2, test } = calendarFor(session2, timezone);
5798
+ const timeframeString = tf || chartTimeframe().period;
5799
+ return perBar((t2) => test && !bars2.inside(t2) ? NaN : bars2.timeOf(t2, timeframeString));
5800
+ }
5801
+ function timeCloseFunction(tf, session2, timezone) {
5802
+ collector();
5803
+ const { bars: bars2, test } = calendarFor(session2, timezone);
5804
+ const timeframeString = tf || chartTimeframe().period;
5805
+ return perBar((t2) => test && !bars2.inside(t2) ? NaN : bars2.closeOf(t2, timeframeString));
5806
+ }
5807
+ var time = callableSeries(new Series(ctxBars, (b2) => barTime(b2)), timeFunction);
5808
+ var time_close = callableSeries(
5809
+ new Series(ctxBars, (_b, i) => sessionBars().bars.closeOf(barTime(ctxBars.bars[i]), chartTimeframe().period)),
5810
+ timeCloseFunction
5811
+ );
5812
+ var time_tradingday = new Series(ctxBars, (b2) => sessionBars().bars.tradingDayTime(barTime(b2)));
5813
+ function changeOf(tf) {
5814
+ const { bars: bars2 } = sessionBars();
5815
+ return perBar((t2, i, times) => i > 0 && bars2.timeOf(t2, tf) !== bars2.timeOf(times[i - 1], tf) ? 1 : 0);
5816
+ }
5817
+ function flag(key) {
5818
+ const { bars: bars2, regular } = sessionBars();
5819
+ const values = sessionFlags(ctxBars.bars.map(barTime), bars2, regular)[key];
5820
+ return Series.fromArray(ctxBars, values.map((v) => v ? 1 : 0));
5821
+ }
5822
+ var session = {
5823
+ regular: "regular",
5824
+ extended: "extended",
5825
+ get isfirstbar() {
5826
+ return flag("isfirstbar");
5827
+ },
5828
+ get islastbar() {
5829
+ return flag("islastbar");
5830
+ },
5831
+ get ismarket() {
5832
+ return flag("ismarket");
5833
+ },
5834
+ get ispremarket() {
5835
+ return flag("ispremarket");
5836
+ },
5837
+ get ispostmarket() {
5838
+ return flag("ispostmarket");
5839
+ },
5840
+ get isfirstbar_regular() {
5841
+ return flag("isfirstbar_regular");
5842
+ },
5843
+ get islastbar_regular() {
5844
+ return flag("islastbar_regular");
5845
+ }
5846
+ };
5847
+ var barmerge = {
5848
+ gaps_on: "gaps_on",
5849
+ gaps_off: "gaps_off",
5850
+ lookahead_on: "lookahead_on",
5851
+ lookahead_off: "lookahead_off"
5852
+ };
5853
+ var HEIKIN_ASHI = "heikinashi:";
5854
+ var ticker = {
5855
+ heikinashi(symbol) {
5856
+ return HEIKIN_ASHI + symbol;
5857
+ },
5858
+ standard(symbol) {
5859
+ return symbol.startsWith(HEIKIN_ASHI) ? symbol.slice(HEIKIN_ASHI.length) : symbol;
5860
+ }
5861
+ };
5862
+ function valuesOf(value, length2) {
5863
+ return value instanceof Series ? value.toArray().slice() : new Array(length2).fill(Number(value));
5864
+ }
5865
+ function security(symbol, timeframe2, expression, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off) {
5866
+ collector();
5867
+ const heikin = symbol.startsWith(HEIKIN_ASHI);
5868
+ const base = heikin ? symbol.slice(HEIKIN_ASHI.length) : symbol;
5869
+ if (base !== "" && base !== chartCtx.tickerid) {
5870
+ throw new Error(`request.security: "${symbol}" is not the chart symbol; other symbols need external data.`);
5871
+ }
5872
+ const chart2 = chartTimeframe();
5873
+ const tf = info(timeframe2 || chart2.period).period;
5874
+ if (in_seconds(tf) < in_seconds(chart2.period)) {
5875
+ throw new Error(`request.security: timeframe "${tf}" is lower than the chart timeframe "${chart2.period}".`);
5876
+ }
5877
+ const chartBars = ctxBars.bars;
5878
+ const times = chartBars.map(barTime);
5879
+ let htf;
5880
+ let group2;
5881
+ let latest;
5882
+ if (tf === chart2.period) {
5883
+ htf = chartBars;
5884
+ group2 = chartBars.map((_, i) => i);
5885
+ latest = group2;
5886
+ } else {
5887
+ const { bars: loaded, regular } = sessionBars();
5888
+ const calendar2 = info(tf).isdwm ? regular : loaded;
5889
+ const starts = times.map((t2) => calendar2.timeOf(t2, tf));
5890
+ const dayPeriods = times.map((t2, i) => {
5891
+ const at = loaded.calendar.locate(t2);
5892
+ const periods = at ? calendar2.calendar.periods(at.date) : [];
5893
+ return periods.length ? calendar2.timeOf(periods[0][0], tf) : starts[i];
5894
+ });
5895
+ const reaches = times.map((t2) => loaded.closeOf(t2, chart2.period) >= calendar2.periodEnd(t2, tf));
5896
+ ({ group: group2, latest } = periodsOf(starts, dayPeriods, reaches));
5897
+ const unit = chartCtx.timeUnit === "ms" ? 1 : 1e3;
5898
+ htf = resample(chartBars, starts.map((s) => s / unit)).bars;
5899
+ }
5900
+ if (heikin) htf = heikinAshi(htf);
5901
+ const savedCtx = chartCtx;
5902
+ let result;
5903
+ let values;
5904
+ ctxBars.setAll(htf);
5905
+ chartCtx = { ...chartCtx, timeframe: tf };
5906
+ try {
5907
+ result = expression();
5908
+ const parts = Array.isArray(result) ? result : [result];
5909
+ values = parts.map((p) => valuesOf(p, htf.length));
5910
+ } finally {
5911
+ ctxBars.setAll(chartBars);
5912
+ chartCtx = savedCtx;
5913
+ }
5914
+ const mapped = values.map(
5915
+ (v) => Series.fromArray(ctxBars, mapToChart(v, group2, latest, lookahead === barmerge.lookahead_on, gaps === barmerge.gaps_on))
5916
+ );
5917
+ return Array.isArray(result) ? mapped : mapped[0];
5918
+ }
5919
+ var request = { security };
5920
+ var line = {
5921
+ ...line_exports,
5922
+ get all() {
5923
+ return all2();
5924
+ }
5925
+ };
5926
+ var label = {
5927
+ ...label_exports,
5928
+ get all() {
5929
+ return all3();
5930
+ }
5931
+ };
5932
+ var box = {
5933
+ ...box_exports,
5934
+ get all() {
5935
+ return all4();
5936
+ }
5937
+ };
5938
+ var linefill = {
5939
+ ...linefill_exports,
5940
+ get all() {
5941
+ return all5();
5942
+ }
5943
+ };
5944
+ var polyline = {
5945
+ ...polyline_exports,
5946
+ get all() {
5947
+ return all6();
5948
+ }
5949
+ };
5950
+ var text = { ...text_exports };
5951
+ var chart = {
5952
+ point: {
5953
+ ...chartpoint_exports,
5954
+ now(price) {
5955
+ collector();
5956
+ if (currentBar < 0) {
5957
+ throw new Error("chart.point.now() needs a current bar: call it inside eachBar().");
5958
+ }
5959
+ const bar = ctxBars.bars[currentBar];
5960
+ return new_point(barTime(bar), currentBar, price ?? bar.close);
5961
+ }
5962
+ }
5963
+ };
3572
5964
  function seriesOf(values) {
3573
5965
  collector();
3574
5966
  return Series.fromArray(ctxBars, values);
@@ -3585,21 +5977,34 @@ export {
3585
5977
  Series,
3586
5978
  alertcondition,
3587
5979
  barcolor,
5980
+ barmerge,
3588
5981
  bgcolor,
5982
+ box,
5983
+ chart,
3589
5984
  close,
3590
5985
  color,
5986
+ dayofmonth2 as dayofmonth,
5987
+ dayofweek2 as dayofweek,
3591
5988
  eachBar,
3592
5989
  executeScript,
3593
5990
  fill,
5991
+ fixnan2 as fixnan,
3594
5992
  high,
3595
5993
  hl2,
3596
5994
  hlc3,
3597
5995
  hlcc4,
3598
5996
  hline,
5997
+ hour2 as hour,
5998
+ inSession3 as inSession,
3599
5999
  indicator,
3600
6000
  input,
6001
+ label,
6002
+ line,
6003
+ linefill,
3601
6004
  low,
3602
6005
  math_exports as math,
6006
+ minute2 as minute,
6007
+ month2 as month,
3603
6008
  isNA as na,
3604
6009
  nz,
3605
6010
  ohlc4,
@@ -3607,7 +6012,22 @@ export {
3607
6012
  plot,
3608
6013
  plotchar,
3609
6014
  plotshape,
6015
+ polyline,
6016
+ request,
6017
+ second2 as second,
3610
6018
  seriesOf,
6019
+ session,
6020
+ str,
6021
+ syminfo,
3611
6022
  ta2 as ta,
3612
- volume
6023
+ text,
6024
+ ticker,
6025
+ time,
6026
+ time_close,
6027
+ time_tradingday,
6028
+ timeframe,
6029
+ timestamp2 as timestamp,
6030
+ volume,
6031
+ weekofyear2 as weekofyear,
6032
+ year2 as year
3613
6033
  };