oakscriptjs 0.5.0 → 0.6.1

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