oakscriptjs 0.11.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/array/index.d.ts +8 -2
- package/dist/cjs/array/index.d.ts.map +1 -1
- package/dist/cjs/array/index.js +2 -1
- package/dist/cjs/array/index.js.map +2 -2
- package/dist/cjs/box/index.js +6 -6
- package/dist/cjs/box/index.js.map +2 -2
- package/dist/cjs/callsite/index.js +1 -1
- package/dist/cjs/callsite/index.js.map +2 -2
- package/dist/cjs/drawing/registry.d.ts +15 -6
- package/dist/cjs/drawing/registry.d.ts.map +1 -1
- package/dist/cjs/drawing/registry.js +16 -2
- package/dist/cjs/drawing/registry.js.map +2 -2
- package/dist/cjs/index.d.ts +3 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/input.d.ts +9 -1
- package/dist/cjs/input.d.ts.map +1 -1
- package/dist/cjs/input.js +16 -0
- package/dist/cjs/input.js.map +2 -2
- package/dist/cjs/label/index.js +3 -3
- package/dist/cjs/label/index.js.map +2 -2
- package/dist/cjs/line/index.d.ts +10 -27
- package/dist/cjs/line/index.d.ts.map +1 -1
- package/dist/cjs/line/index.js +10 -27
- package/dist/cjs/line/index.js.map +2 -2
- package/dist/cjs/linefill/index.d.ts +3 -0
- package/dist/cjs/linefill/index.d.ts.map +1 -1
- package/dist/cjs/linefill/index.js +15 -1
- package/dist/cjs/linefill/index.js.map +3 -3
- package/dist/cjs/runtime/adapters/SimpleInputAdapter.js +1 -1
- package/dist/cjs/runtime/adapters/SimpleInputAdapter.js.map +2 -2
- package/dist/cjs/runtime/index.d.ts +1 -1
- package/dist/cjs/runtime/index.d.ts.map +1 -1
- package/dist/cjs/runtime/index.js +1 -0
- package/dist/cjs/runtime/index.js.map +2 -2
- package/dist/cjs/runtime/inputs.d.ts +9 -0
- package/dist/cjs/runtime/inputs.d.ts.map +1 -1
- package/dist/cjs/runtime/inputs.js +8 -0
- package/dist/cjs/runtime/inputs.js.map +2 -2
- package/dist/cjs/runtime/types.d.ts +1 -1
- package/dist/cjs/runtime/types.d.ts.map +1 -1
- package/dist/cjs/runtime/types.js.map +1 -1
- package/dist/cjs/script/index.d.ts +65 -12
- package/dist/cjs/script/index.d.ts.map +1 -1
- package/dist/cjs/script/index.js +168 -19
- package/dist/cjs/script/index.js.map +3 -3
- package/dist/cjs/security/other.d.ts +92 -0
- package/dist/cjs/security/other.d.ts.map +1 -0
- package/dist/cjs/security/other.js +164 -0
- package/dist/cjs/security/other.js.map +7 -0
- package/dist/cjs/session/bars.d.ts +10 -1
- package/dist/cjs/session/bars.d.ts.map +1 -1
- package/dist/cjs/session/bars.js +16 -2
- package/dist/cjs/session/bars.js.map +2 -2
- package/dist/cjs/session/calendar.d.ts +4 -1
- package/dist/cjs/session/calendar.d.ts.map +1 -1
- package/dist/cjs/session/calendar.js +11 -7
- package/dist/cjs/session/calendar.js.map +2 -2
- package/dist/cjs/session/context.d.ts +2 -1
- package/dist/cjs/session/context.d.ts.map +1 -1
- package/dist/cjs/session/context.js +2 -1
- package/dist/cjs/session/context.js.map +2 -2
- package/dist/cjs/str/floatingdecimal.d.ts +31 -0
- package/dist/cjs/str/floatingdecimal.d.ts.map +1 -0
- package/dist/cjs/str/floatingdecimal.js +298 -0
- package/dist/cjs/str/floatingdecimal.js.map +7 -0
- package/dist/cjs/str/index.d.ts +4 -3
- package/dist/cjs/str/index.d.ts.map +1 -1
- package/dist/cjs/str/index.js +1 -1
- package/dist/cjs/str/index.js.map +2 -2
- package/dist/cjs/str/numberformat.d.ts +6 -4
- package/dist/cjs/str/numberformat.d.ts.map +1 -1
- package/dist/cjs/str/numberformat.js +3 -2
- package/dist/cjs/str/numberformat.js.map +2 -2
- package/dist/cjs/ta/index.d.ts +34 -17
- package/dist/cjs/ta/index.d.ts.map +1 -1
- package/dist/cjs/ta/index.js +132 -116
- package/dist/cjs/ta/index.js.map +2 -2
- package/dist/cjs/ta/limits.d.ts +11 -0
- package/dist/cjs/ta/limits.d.ts.map +1 -1
- package/dist/cjs/ta/limits.js +15 -1
- package/dist/cjs/ta/limits.js.map +2 -2
- package/dist/cjs/ta/running-sum.js +1 -1
- package/dist/cjs/ta/running-sum.js.map +2 -2
- package/dist/cjs/ta-series.d.ts +1 -1
- package/dist/cjs/ta-series.d.ts.map +1 -1
- package/dist/cjs/ta-series.js +1 -1
- package/dist/cjs/ta-series.js.map +2 -2
- package/dist/cjs/table/index.d.ts +3 -1
- package/dist/cjs/table/index.d.ts.map +1 -1
- package/dist/cjs/table/index.js +1 -0
- package/dist/cjs/table/index.js.map +3 -3
- package/dist/cjs/time/session.d.ts +9 -0
- package/dist/cjs/time/session.d.ts.map +1 -1
- package/dist/cjs/time/session.js +42 -14
- package/dist/cjs/time/session.js.map +3 -3
- package/dist/cjs/time/timezone.d.ts +6 -1
- package/dist/cjs/time/timezone.d.ts.map +1 -1
- package/dist/cjs/time/timezone.js +2 -2
- package/dist/cjs/time/timezone.js.map +2 -2
- package/dist/cjs/types/metadata.d.ts +1 -1
- package/dist/cjs/types/metadata.d.ts.map +1 -1
- package/dist/cjs/types/metadata.js.map +1 -1
- package/dist/esm/array/index.d.ts +8 -2
- package/dist/esm/array/index.d.ts.map +1 -1
- package/dist/esm/array/index.js +12 -3
- package/dist/esm/array/index.js.map +1 -1
- package/dist/esm/box/index.js +6 -6
- package/dist/esm/box/index.js.map +1 -1
- package/dist/esm/callsite/index.js +1 -1
- package/dist/esm/callsite/index.js.map +1 -1
- package/dist/esm/drawing/registry.d.ts +15 -6
- package/dist/esm/drawing/registry.d.ts.map +1 -1
- package/dist/esm/drawing/registry.js +30 -7
- package/dist/esm/drawing/registry.js.map +1 -1
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +4 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/input.d.ts +9 -1
- package/dist/esm/input.d.ts.map +1 -1
- package/dist/esm/input.js +16 -0
- package/dist/esm/input.js.map +1 -1
- package/dist/esm/label/index.js +3 -3
- package/dist/esm/label/index.js.map +1 -1
- package/dist/esm/line/index.d.ts +10 -27
- package/dist/esm/line/index.d.ts.map +1 -1
- package/dist/esm/line/index.js +20 -64
- package/dist/esm/line/index.js.map +1 -1
- package/dist/esm/linefill/index.d.ts +3 -0
- package/dist/esm/linefill/index.d.ts.map +1 -1
- package/dist/esm/linefill/index.js +20 -1
- package/dist/esm/linefill/index.js.map +1 -1
- package/dist/esm/runtime/adapters/SimpleInputAdapter.js +1 -1
- package/dist/esm/runtime/adapters/SimpleInputAdapter.js.map +1 -1
- package/dist/esm/runtime/index.d.ts +1 -1
- package/dist/esm/runtime/index.d.ts.map +1 -1
- package/dist/esm/runtime/index.js +1 -1
- package/dist/esm/runtime/index.js.map +1 -1
- package/dist/esm/runtime/inputs.d.ts +9 -0
- package/dist/esm/runtime/inputs.d.ts.map +1 -1
- package/dist/esm/runtime/inputs.js +15 -0
- package/dist/esm/runtime/inputs.js.map +1 -1
- package/dist/esm/runtime/types.d.ts +1 -1
- package/dist/esm/runtime/types.d.ts.map +1 -1
- package/dist/esm/script/index.d.ts +65 -12
- package/dist/esm/script/index.d.ts.map +1 -1
- package/dist/esm/script/index.js +217 -29
- package/dist/esm/script/index.js.map +1 -1
- package/dist/esm/security/other.d.ts +92 -0
- package/dist/esm/security/other.d.ts.map +1 -0
- package/dist/esm/security/other.js +211 -0
- package/dist/esm/security/other.js.map +1 -0
- package/dist/esm/session/bars.d.ts +10 -1
- package/dist/esm/session/bars.d.ts.map +1 -1
- package/dist/esm/session/bars.js +26 -1
- package/dist/esm/session/bars.js.map +1 -1
- package/dist/esm/session/calendar.d.ts +4 -1
- package/dist/esm/session/calendar.d.ts.map +1 -1
- package/dist/esm/session/calendar.js +19 -7
- package/dist/esm/session/calendar.js.map +1 -1
- package/dist/esm/session/context.d.ts +2 -1
- package/dist/esm/session/context.d.ts.map +1 -1
- package/dist/esm/session/context.js +5 -3
- package/dist/esm/session/context.js.map +1 -1
- package/dist/esm/str/floatingdecimal.d.ts +31 -0
- package/dist/esm/str/floatingdecimal.d.ts.map +1 -0
- package/dist/esm/str/floatingdecimal.js +272 -0
- package/dist/esm/str/floatingdecimal.js.map +1 -0
- package/dist/esm/str/index.d.ts +4 -3
- package/dist/esm/str/index.d.ts.map +1 -1
- package/dist/esm/str/index.js +6 -5
- package/dist/esm/str/index.js.map +1 -1
- package/dist/esm/str/numberformat.d.ts +6 -4
- package/dist/esm/str/numberformat.d.ts.map +1 -1
- package/dist/esm/str/numberformat.js +9 -5
- package/dist/esm/str/numberformat.js.map +1 -1
- package/dist/esm/ta/index.d.ts +34 -17
- package/dist/esm/ta/index.d.ts.map +1 -1
- package/dist/esm/ta/index.js +155 -185
- package/dist/esm/ta/index.js.map +1 -1
- package/dist/esm/ta/limits.d.ts +11 -0
- package/dist/esm/ta/limits.d.ts.map +1 -1
- package/dist/esm/ta/limits.js +27 -2
- package/dist/esm/ta/limits.js.map +1 -1
- package/dist/esm/ta/running-sum.js +1 -1
- package/dist/esm/ta/running-sum.js.map +1 -1
- package/dist/esm/ta-series.d.ts +1 -1
- package/dist/esm/ta-series.d.ts.map +1 -1
- package/dist/esm/ta-series.js +2 -1
- package/dist/esm/ta-series.js.map +1 -1
- package/dist/esm/table/index.d.ts +3 -1
- package/dist/esm/table/index.d.ts.map +1 -1
- package/dist/esm/table/index.js +6 -1
- package/dist/esm/table/index.js.map +1 -1
- package/dist/esm/time/session.d.ts +9 -0
- package/dist/esm/time/session.d.ts.map +1 -1
- package/dist/esm/time/session.js +53 -15
- package/dist/esm/time/session.js.map +1 -1
- package/dist/esm/time/timezone.d.ts +6 -1
- package/dist/esm/time/timezone.d.ts.map +1 -1
- package/dist/esm/time/timezone.js +8 -2
- package/dist/esm/time/timezone.js.map +1 -1
- package/dist/esm/types/metadata.d.ts +1 -1
- package/dist/esm/types/metadata.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/array/index.ts +11 -3
- package/src/box/index.ts +6 -6
- package/src/callsite/index.ts +1 -1
- package/src/drawing/registry.ts +30 -7
- package/src/index.ts +11 -1
- package/src/input.ts +18 -1
- package/src/label/index.ts +3 -3
- package/src/line/index.ts +20 -68
- package/src/linefill/index.ts +20 -1
- package/src/runtime/adapters/SimpleInputAdapter.ts +1 -1
- package/src/runtime/index.ts +1 -0
- package/src/runtime/inputs.ts +16 -0
- package/src/runtime/types.ts +1 -1
- package/src/script/index.ts +292 -30
- package/src/security/other.ts +269 -0
- package/src/session/bars.ts +24 -1
- package/src/session/calendar.ts +23 -7
- package/src/session/context.ts +5 -3
- package/src/str/floatingdecimal.ts +268 -0
- package/src/str/index.ts +6 -5
- package/src/str/numberformat.ts +11 -6
- package/src/ta/index.ts +157 -183
- package/src/ta/limits.ts +28 -1
- package/src/ta/running-sum.ts +1 -1
- package/src/ta-series.ts +3 -2
- package/src/table/index.ts +4 -1
- package/src/time/session.ts +58 -16
- package/src/time/timezone.ts +9 -2
- package/src/types/metadata.ts +1 -1
|
@@ -15,7 +15,12 @@ export declare function size<T>(id: PineArray<T>): int;
|
|
|
15
15
|
* Returns the element at the specified index.
|
|
16
16
|
*
|
|
17
17
|
* PineScript rules: a negative index counts from the end (`get(a, -1)` is the last element); an index outside
|
|
18
|
-
* `-size .. size - 1` is a runtime error (throws)
|
|
18
|
+
* `-size .. size - 1` is a runtime error (throws "In 'array.get()' function. Index 5 is out of bounds, array size
|
|
19
|
+
* is 3."); an `na` index gives `na`.
|
|
20
|
+
*
|
|
21
|
+
* Negative indexes are a PineScript v6 rule, which oakscriptjs follows: a version 5 script stops on them with the
|
|
22
|
+
* same out of bounds error (`array.get(a, -1)`, #176). A port of a v5 script that the original stops must check the
|
|
23
|
+
* index itself.
|
|
19
24
|
*/
|
|
20
25
|
export declare function get<T>(id: PineArray<T>, index: simple_int): T;
|
|
21
26
|
/**
|
|
@@ -576,7 +581,8 @@ export declare function binary_search_rightmost(id: PineArray<float>, val: float
|
|
|
576
581
|
* - Formula: Cov(X,Y) = E[(X - μX)(Y - μY)]
|
|
577
582
|
*
|
|
578
583
|
* PineScript rules: a pair where either value is `na` is skipped and the count is the number of pairs kept; both
|
|
579
|
-
* means first, then the sum of the products from the first to the last pair
|
|
584
|
+
* means first, then the sum of the products from the first to the last pair, set to 0 whenever it is within 1e-10 of
|
|
585
|
+
* zero (#177: five equal closes give 0, not -1.7e-18). One pair gives 0 biased, NaN unbiased.
|
|
580
586
|
*/
|
|
581
587
|
export declare function covariance(id1: PineArray<float>, id2: PineArray<float>, biased?: bool): float;
|
|
582
588
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/array/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE3H;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAMlF;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAE7C;AAyBD
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/array/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE3H;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAMlF;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAE7C;AAyBD;;;;;;;;;;GAUG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,GAAG,CAAC,CAG7D;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAG1E;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAExD;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAE1C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAE3D;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAE5C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAE/C;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAM7E;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,GAAG,CAAC,CAGhE;AAaD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,GAAG,CAK1D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,GAAG,CAK9D;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAEtD;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAG5E;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,SAAS,GAAE,MAAY,GAAG,MAAM,CAExE;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAEjD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,CAQtG;AA6DD,yGAAyG;AACzG,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC;AAqBpE;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,GAAE,SAAiB,GAAG,IAAI,CAGxE;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,CAU/C;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,CAG/C;AAcD;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,GAAE,UAAc,GAAG,KAAK,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,GAAE,UAAc,GAAG,KAAK,CAEpE;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,CAKlD;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,CAchD;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAE,IAAW,GAAG,KAAK,CAEtE;AAWD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAE,IAAW,GAAG,KAAK,CAQzE;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,GAAE,UAAc,EAAE,QAAQ,CAAC,EAAE,UAAU,GAAG,IAAI,CAU3G;AAED;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAEpD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAI5C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAI3C;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAE9C;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAE/C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,GAAE,IAAY,GAAG,SAAS,CAAC,IAAI,CAAC,CAE3F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,GAAE,KAAW,GAAG,SAAS,CAAC,KAAK,CAAC,CAE5F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,OAAO,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,GAAE,GAAS,GAAG,SAAS,CAAC,GAAG,CAAC,CAEtF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAE1F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAEvF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,QAAQ,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAEpF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,OAAO,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAEjF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAEvF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,CAEhG;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAEvF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAE1D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,CAKjD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,CAmBnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,CAI5E;AAyBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,CAI7E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAE,IAAW,GAAG,KAAK,CA4BnG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,+BAA+B,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,KAAK,GAAG,KAAK,CAiB9F;AAeD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,KAAK,GAAG,KAAK,CAStF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,GAAG,KAAK,CAoBnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,GAAE,SAAiB,GAAG,SAAS,CAAC,GAAG,CAAC,CAE1F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAYlE;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,GAAE,UAAc,EAAE,aAAa,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAIhF"}
|
package/dist/cjs/array/index.js
CHANGED
|
@@ -96,7 +96,7 @@ function position(name, id, index, extra = 0) {
|
|
|
96
96
|
const i = Math.trunc(index);
|
|
97
97
|
const n = id.length;
|
|
98
98
|
if (i < -n || i >= n + extra) {
|
|
99
|
-
throw new Error(`array.${name}
|
|
99
|
+
throw new Error(`In 'array.${name}()' function. Index ${i} is out of bounds, array size is ${n}.`);
|
|
100
100
|
}
|
|
101
101
|
return i < 0 ? i + n : i;
|
|
102
102
|
}
|
|
@@ -454,6 +454,7 @@ function covariance(id1, id2, biased = true) {
|
|
|
454
454
|
let sum2 = 0;
|
|
455
455
|
for (let i = 0; i < n; i++) {
|
|
456
456
|
sum2 += (xs[i] - mean1) * (ys[i] - mean2);
|
|
457
|
+
if (Math.abs(sum2) <= 1e-10) sum2 = 0;
|
|
457
458
|
}
|
|
458
459
|
return sum2 / (biased ? n : n - 1);
|
|
459
460
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/array/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Array namespace\n * Mirrors PineScript's array.* functions\n */\n\nimport type { PineArray, int, float, bool, simple_int, color, Line, Box, Label, Linefill, Table } from '../types/index.js';\n\n/**\n * Creates a new array with initial size and default value\n */\nexport function new_array<T>(size: simple_int = 0, initial_value?: T): PineArray<T> {\n const arr: PineArray<T> = [];\n for (let i = 0; i < size; i++) {\n arr.push(initial_value as T);\n }\n return arr;\n}\n\n/**\n * Returns the number of elements in an array\n */\nexport function size<T>(id: PineArray<T>): int {\n return id.length;\n}\n\n/** True for a PineScript `na` element: NaN, null or undefined. */\nfunction isNa(v: unknown): boolean {\n return v === undefined || v === null || (typeof v === 'number' && Number.isNaN(v));\n}\n\n/** The `na` of the array's element type: NaN for a numeric (or empty) array, undefined otherwise. */\nfunction naOf<T>(id: PineArray<T>): T {\n return (id.length === 0 || typeof id[0] === 'number' ? NaN : undefined) as T;\n}\n\n/**\n * Position addressed by a PineScript index: truncated, a negative index counts from the end. An index outside\n * `-size .. size - 1 + extra` is a runtime error.\n */\nfunction position(name: string, id: PineArray<unknown>, index: number, extra = 0): number {\n const i = Math.trunc(index);\n const n = id.length;\n if (i < -n || i >= n + extra) {\n throw new Error(`array.${name}: index ${i} is out of bounds, array size is ${n}`);\n }\n return i < 0 ? i + n : i;\n}\n\n/**\n * Returns the element at the specified index.\n *\n * PineScript rules: a negative index counts from the end (`get(a, -1)` is the last element); an index outside\n * `-size .. size - 1` is a runtime error (throws); an `na` index gives `na`.\n */\nexport function get<T>(id: PineArray<T>, index: simple_int): T {\n if (Number.isNaN(index)) return naOf(id);\n return id[position('get', id, index)]!;\n}\n\n/**\n * Sets the value of the element at the specified index.\n *\n * PineScript rules: a negative index counts from the end; an index outside `-size .. size - 1` is a runtime error\n * (throws); an `na` index does nothing.\n */\nexport function set<T>(id: PineArray<T>, index: simple_int, value: T): void {\n if (Number.isNaN(index)) return;\n id[position('set', id, index)] = value;\n}\n\n/**\n * Appends a value to the end of the array\n */\nexport function push<T>(id: PineArray<T>, value: T): void {\n id.push(value);\n}\n\n/**\n * Removes and returns the last element of the array\n */\nexport function pop<T>(id: PineArray<T>): T {\n return id.pop() as T;\n}\n\n/**\n * Inserts a value at the beginning of the array\n */\nexport function unshift<T>(id: PineArray<T>, value: T): void {\n id.unshift(value);\n}\n\n/**\n * Removes and returns the first element of the array\n */\nexport function shift<T>(id: PineArray<T>): T {\n return id.shift() as T;\n}\n\n/**\n * Removes all elements from the array\n */\nexport function clear<T>(id: PineArray<T>): void {\n id.length = 0;\n}\n\n/**\n * Inserts a value at the specified index.\n *\n * PineScript rules: a negative index counts from the end and `size` appends, so `-size .. size` is valid; any other\n * index is a runtime error (throws); an `na` index appends.\n */\nexport function insert<T>(id: PineArray<T>, index: simple_int, value: T): void {\n if (Number.isNaN(index)) {\n id.push(value);\n return;\n }\n id.splice(position('insert', id, index, 1), 0, value);\n}\n\n/**\n * Removes the element at the specified index and returns it.\n *\n * PineScript rules: a negative index counts from the end; an index outside `-size .. size - 1` is a runtime error\n * (throws); an `na` index removes nothing and gives `na`.\n */\nexport function remove<T>(id: PineArray<T>, index: simple_int): T {\n if (Number.isNaN(index)) return naOf(id);\n return id.splice(position('remove', id, index), 1)[0]!;\n}\n\n/** PineScript `==` of two elements: numbers are equal when |a - b| <= 1e-10; `na` never equals anything. */\nfunction pineEqual(a: unknown, b: unknown): boolean {\n if (isNa(a) || isNa(b)) return false;\n if (a === b) return true;\n if (typeof a === 'number' && typeof b === 'number') {\n const d = a - b;\n return -1e-10 <= d && d <= 1e-10;\n }\n return false;\n}\n\n/**\n * Returns true if the array contains the value.\n *\n * PineScript rules: numbers are compared with a 1e-10 tolerance (|a - b| <= 1e-10); `na` is never found.\n */\nexport function includes<T>(id: PineArray<T>, value: T): bool {\n return indexof(id, value) >= 0;\n}\n\n/**\n * Returns the index of the first occurrence of the value, -1 when not found.\n *\n * PineScript rules: numbers are compared with a 1e-10 tolerance (|a - b| <= 1e-10); `na` is never found.\n */\nexport function indexof<T>(id: PineArray<T>, value: T): int {\n for (let i = 0; i < id.length; i++) {\n if (pineEqual(id[i], value)) return i;\n }\n return -1;\n}\n\n/**\n * Returns the index of the last occurrence of the value, -1 when not found.\n *\n * PineScript rules: numbers are compared with a 1e-10 tolerance (|a - b| <= 1e-10); `na` is never found.\n */\nexport function lastindexof<T>(id: PineArray<T>, value: T): int {\n for (let i = id.length - 1; i >= 0; i--) {\n if (pineEqual(id[i], value)) return i;\n }\n return -1;\n}\n\n/**\n * Returns a shallow copy of the array\n */\nexport function copy<T>(id: PineArray<T>): PineArray<T> {\n return [...id] as PineArray<T>;\n}\n\n/**\n * Appends the elements of `id2` to `id1` and returns `id1` (PineScript `array.concat` changes `id1`).\n */\nexport function concat<T>(id1: PineArray<T>, id2: PineArray<T>): PineArray<T> {\n for (const v of Array.from(id2)) id1.push(v);\n return id1;\n}\n\n/**\n * Joins all elements into a string\n */\nexport function join(id: PineArray<any>, separator: string = ','): string {\n return id.join(separator);\n}\n\n/**\n * Reverses the array in place\n */\nexport function reverse<T>(id: PineArray<T>): void {\n id.reverse();\n}\n\n/**\n * Returns the elements from `index_from` (included) to `index_to` (excluded, default: the size) as a live view of\n * the array (PineScript `array.slice`).\n *\n * PineScript rules:\n * - the slice shares the elements of the original array: a change of an element of the slice changes the original\n * array, and adding / removing elements of the slice adds / removes them in the original array, inside the slice\n * bounds (a push to the slice inserts at the end of the slice)\n * - `index_from` must address an element (`0 .. size - 1`) and `index_to` may be `size`; other bounds, or\n * `index_from > index_to`, are a runtime error (throws); an `na` bound means the start / the end of the array\n */\nexport function slice<T>(id: PineArray<T>, index_from: simple_int, index_to?: simple_int): PineArray<T> {\n const n = id.length;\n const start = Number.isNaN(index_from) ? 0 : Math.trunc(index_from);\n const stop = index_to === undefined || Number.isNaN(index_to) ? n : Math.trunc(index_to);\n if (start < 0 || start >= n) throw new Error(`array.slice: index ${start} is out of bounds, array size is ${n}`);\n if (stop < 0 || stop > n) throw new Error(`array.slice: index ${stop} is out of bounds, array size is ${n}`);\n if (start > stop) throw new Error(`array.slice: index_from ${start} is greater than index_to ${stop}`);\n return sliceView(id, start, stop - start);\n}\n\n/** Index of a property key that is an array index, -1 otherwise. */\nfunction indexKey(p: string | symbol): number {\n if (typeof p !== 'string') return -1;\n const i = Number(p);\n return Number.isInteger(i) && i >= 0 && String(i) === p ? i : -1;\n}\n\n/**\n * Live view of `size` elements of `parent` from `start`: an array (a Proxy) whose element reads and writes go to\n * `parent`, and whose size changes insert / remove elements in `parent` at the end of the view.\n */\nfunction sliceView<T>(parent: PineArray<T>, start: number, size: number): PineArray<T> {\n const resize = (target: number): void => {\n if (target > size) parent.splice(start + size, 0, ...Array<T>(target - size).fill(undefined as T));\n else if (target < size) parent.splice(start + target, size - target);\n size = target;\n };\n return new Proxy<T[]>([], {\n get(target, p, receiver) {\n const i = indexKey(p);\n if (i >= 0) return i < size ? parent[start + i] : undefined;\n if (p === 'length') return size;\n return Reflect.get(target, p, receiver);\n },\n set(target, p, value, receiver) {\n const i = indexKey(p);\n if (i >= 0) {\n if (i >= size) resize(i + 1);\n parent[start + i] = value;\n return true;\n }\n if (p === 'length') {\n resize(Number(value));\n return true;\n }\n return Reflect.set(target, p, value, receiver);\n },\n has(target, p) {\n const i = indexKey(p);\n return i >= 0 ? i < size : Reflect.has(target, p);\n },\n // Array methods delete the slots past the new end before they set the length, which does the removal.\n deleteProperty(target, p) {\n return indexKey(p) >= 0 ? true : Reflect.deleteProperty(target, p);\n },\n ownKeys(target) {\n return [...Array.from({ length: size }, (_, i) => String(i)), ...Reflect.ownKeys(target)];\n },\n getOwnPropertyDescriptor(target, p) {\n const i = indexKey(p);\n if (i >= 0) {\n return i < size ? { value: parent[start + i], writable: true, enumerable: true, configurable: true } : undefined;\n }\n if (p === 'length') return { value: size, writable: true, enumerable: false, configurable: false };\n return Reflect.getOwnPropertyDescriptor(target, p);\n },\n });\n}\n\n/** Sort order of array.sort / array.sort_indices (PineScript `order.ascending` / `order.descending`). */\nexport type SortOrder = 'asc' | 'desc' | 'ascending' | 'descending';\n\n/**\n * Positions of the elements in PineScript sorted order: ascending values, `na` after the numbers (before the\n * strings of a string array), stable; descending is the ascending result reversed.\n */\nfunction sortedPositions<T>(id: PineArray<T>, order: SortOrder): number[] {\n const values: number[] = [];\n const nas: number[] = [];\n for (let i = 0; i < id.length; i++) (isNa(id[i]) ? nas : values).push(i);\n values.sort((a, b) => {\n const x = id[a] as unknown as number;\n const y = id[b] as unknown as number;\n return x < y ? -1 : x > y ? 1 : 0;\n });\n const naFirst = values.length > 0 && typeof id[values[0]!] === 'string';\n const positions = naFirst ? [...nas, ...values] : [...values, ...nas];\n if (order === 'desc' || order === 'descending') positions.reverse();\n return positions;\n}\n\n/**\n * Sorts the array in place.\n *\n * PineScript rules: `na` goes after the numbers in ascending order and before them in descending order (the\n * ascending result reversed); in a string array `na` goes first in ascending order.\n */\nexport function sort<T>(id: PineArray<T>, order: SortOrder = 'asc'): void {\n const sorted = sortedPositions(id, order).map((p) => id[p]!);\n for (let i = 0; i < sorted.length; i++) id[i] = sorted[i]!;\n}\n\n/**\n * Sum of the non-na elements (PineScript `array.sum(id)`), added from left to right; an array without values gives NaN.\n * As PineScript, the running sum is set to 0 after a step when its absolute value is <= 1e-10.\n */\nexport function sum(id: PineArray<float>): float {\n let total = 0;\n let count = 0;\n for (const v of id) {\n if (Number.isNaN(v)) continue;\n count++;\n total += v;\n if (Math.abs(total) <= 1e-10) total = 0;\n }\n return count ? total : NaN;\n}\n\n/**\n * Average of the non-na elements (PineScript `array.avg(id)`); an array without values gives NaN.\n */\nexport function avg(id: PineArray<float>): float {\n const values = id.filter((v) => !Number.isNaN(v));\n return values.length ? values.reduce((a, b) => a + b, 0) / values.length : NaN;\n}\n\n/** The `nth` value of the non-na elements sorted with `compare` (array.min / array.max). */\nfunction nthValue(name: string, id: PineArray<float>, nth: number, compare: (a: number, b: number) => number): float {\n const rank = Number.isNaN(nth) ? 0 : Math.trunc(nth);\n const values = id.filter((v) => !Number.isNaN(v));\n if (!values.length) return NaN;\n if (rank < 0 || rank >= id.length) {\n throw new Error(`array.${name}: nth ${rank} is out of bounds, array size is ${id.length}`);\n }\n values.sort(compare);\n return values[Math.min(rank, values.length - 1)]!;\n}\n\n/**\n * The `nth` smallest value (0 = the smallest) of the non-na elements (PineScript `array.min(id, nth)`).\n *\n * PineScript rules: an `nth` past the non-na values but inside the array size gives the greatest value; an `nth`\n * outside `0 .. size - 1` is a runtime error (throws); an `na` nth counts as 0; an array without values gives NaN.\n */\nexport function min(id: PineArray<float>, nth: simple_int = 0): float {\n return nthValue('min', id, nth, (a, b) => a - b);\n}\n\n/**\n * The `nth` greatest value (0 = the greatest) of the non-na elements (PineScript `array.max(id, nth)`).\n *\n * PineScript rules: an `nth` past the non-na values but inside the array size gives the smallest value; an `nth`\n * outside `0 .. size - 1` is a runtime error (throws); an `na` nth counts as 0; an array without values gives NaN.\n */\nexport function max(id: PineArray<float>, nth: simple_int = 0): float {\n return nthValue('max', id, nth, (a, b) => b - a);\n}\n\n/**\n * Median of the non-na elements (PineScript `array.median(id)`): the middle value, or the mean of the two middle\n * values for an even count; an array without values gives NaN.\n */\nexport function median(id: PineArray<float>): float {\n const sorted = id.filter((v) => !Number.isNaN(v)).sort((a, b) => a - b);\n if (!sorted.length) return NaN;\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;\n}\n\n/**\n * Most frequent non-na element (PineScript `array.mode(id)`), compared exactly.\n *\n * PineScript rules: with several values of the same frequency, the smallest one; an array without values gives NaN.\n */\nexport function mode(id: PineArray<float>): float {\n const frequency = new Map<float, int>();\n for (const v of id) {\n if (!Number.isNaN(v)) frequency.set(v, (frequency.get(v) ?? 0) + 1);\n }\n let best = NaN;\n let bestCount = 0;\n for (const [v, count] of frequency) {\n if (count > bestCount || (count === bestCount && v < best)) {\n best = v;\n bestCount = count;\n }\n }\n return best;\n}\n\n/**\n * Standard deviation of the non-na elements (PineScript `array.stdev(id, biased)`): the square root of\n * `array.variance(id, biased)`.\n */\nexport function stdev(id: PineArray<float>, biased: bool = true): float {\n return Math.sqrt(variance(id, biased));\n}\n\n/** Sum of the values and sum of their squares, both added from the first to the last value. */\nfunction moments(values: number[]): [number, number] {\n let p = 0;\n let q = 0;\n for (const v of values) p += v;\n for (const v of values) q += v * v;\n return [p, q];\n}\n\n/**\n * Variance of the non-na elements (PineScript `array.variance(id, biased)`).\n *\n * PineScript rule (moment form): with `p` the sum of the values, `q` the sum of their squares, `n` the count and\n * `m = p / n`: biased (default) `max(0, q / n - m * m)`, unbiased `max(0, q / (n - 1) - (p / (n - 1)) * m)`.\n * One value gives 0 biased and NaN unbiased; an array without values gives NaN.\n */\nexport function variance(id: PineArray<float>, biased: bool = true): float {\n const values = id.filter((v) => !Number.isNaN(v));\n const n = values.length;\n if (!n) return NaN;\n if (n < 2) return biased ? 0 : NaN;\n const [p, q] = moments(values);\n const mean = p / n;\n return biased ? Math.max(0, q / n - mean * mean) : Math.max(0, q / (n - 1) - (p / (n - 1)) * mean);\n}\n\n/**\n * Fills the array with the specified value\n */\nexport function fill<T>(id: PineArray<T>, value: T, index_from: simple_int = 0, index_to?: simple_int): void {\n // PineScript: an na bound is the start / the end; a bound past the end is a runtime error\n const start = index_from === undefined || index_from === null || Number.isNaN(index_from) ? 0 : index_from;\n const end = index_to === undefined || index_to === null || Number.isNaN(index_to) ? id.length : index_to;\n for (const i of [start, end]) {\n if (i < 0 || i > id.length) throw new Error(`array.fill: index ${i} is out of bounds, array size is ${id.length}`);\n }\n for (let i = start; i < end; i++) {\n id[i] = value;\n }\n}\n\n/**\n * Creates an array from its arguments (PineScript `array.from(arg0, arg1, ...)`).\n * `na` values are kept.\n *\n * @example\n * ```typescript\n * array.from(0.236, 0.382, 0.5, 0.618); // [0.236, 0.382, 0.5, 0.618]\n * ```\n */\nexport function from<T>(...values: T[]): PineArray<T> {\n return [...values];\n}\n\n/**\n * Returns the first element of the array\n *\n * @param id - The array\n * @returns The first element, or undefined if array is empty\n *\n * @remarks\n * - Equivalent to `array.get(id, 0)`\n * - Returns undefined for empty arrays\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const firstElement = array.first(arr); // Returns: 1\n * ```\n */\nexport function first<T>(id: PineArray<T>): T {\n // PineScript: a runtime error on an empty array\n if (id.length === 0) throw new Error('Cannot call array.first() if array is empty');\n return id[0]!;\n}\n\n/**\n * Returns the last element of the array\n *\n * @param id - The array\n * @returns The last element, or undefined if array is empty\n *\n * @remarks\n * - Equivalent to `array.get(id, array.size(id) - 1)`\n * - Returns undefined for empty arrays\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const lastElement = array.last(arr); // Returns: 5\n * ```\n */\nexport function last<T>(id: PineArray<T>): T {\n // PineScript: a runtime error on an empty array (as array.first)\n if (id.length === 0) throw new Error('Cannot call array.last() if array is empty');\n return id[id.length - 1]!;\n}\n\n/**\n * True when at least one element of a bool array is true (PineScript `array.some(id)`).\n * An empty array gives false.\n */\nexport function some(id: PineArray<bool>): bool {\n return id.some((v) => v === true);\n}\n\n/**\n * True when every element of a bool array is true (PineScript `array.every(id)`).\n * An empty array gives false, as in PineScript.\n */\nexport function every(id: PineArray<bool>): bool {\n return id.length > 0 && id.every((v) => v === true);\n}\n\n/**\n * Create new boolean array\n *\n * Creates a new array object of bool type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: false)\n * @returns New boolean array\n *\n * @example\n * ```typescript\n * const arr = array.new_bool(5, true);\n * // Creates: [true, true, true, true, true]\n * ```\n */\nexport function new_bool(size: simple_int = 0, initial_value: bool = false): PineArray<bool> {\n return new_array<bool>(size, initial_value);\n}\n\n/**\n * Create new float array\n *\n * Creates a new array object of float type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: NaN)\n * @returns New float array\n *\n * @example\n * ```typescript\n * const arr = array.new_float(5, 0.0);\n * // Creates: [0.0, 0.0, 0.0, 0.0, 0.0]\n * ```\n */\nexport function new_float(size: simple_int = 0, initial_value: float = NaN): PineArray<float> {\n return new_array<float>(size, initial_value);\n}\n\n/**\n * Create new integer array\n *\n * Creates a new array object of int type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: NaN)\n * @returns New integer array\n *\n * @example\n * ```typescript\n * const arr = array.new_int(5, 0);\n * // Creates: [0, 0, 0, 0, 0]\n * ```\n */\nexport function new_int(size: simple_int = 0, initial_value: int = NaN): PineArray<int> {\n return new_array<int>(size, initial_value);\n}\n\n/**\n * Create new string array\n *\n * Creates a new array object of string type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New string array\n *\n * @example\n * ```typescript\n * const arr = array.new_string(5, \"text\");\n * // Creates: [\"text\", \"text\", \"text\", \"text\", \"text\"]\n * ```\n */\nexport function new_string(size: simple_int = 0, initial_value?: string): PineArray<string> {\n return new_array<string>(size, initial_value);\n}\n\n/**\n * Create new color array\n *\n * Creates a new array object of color type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New color array\n *\n * @example\n * ```typescript\n * const arr = array.new_color(5, \"#FF0000\");\n * // Creates: [\"#FF0000\", \"#FF0000\", \"#FF0000\", \"#FF0000\", \"#FF0000\"]\n * ```\n */\nexport function new_color(size: simple_int = 0, initial_value?: color): PineArray<color> {\n return new_array<color>(size, initial_value);\n}\n\n/**\n * Create new line array\n *\n * Creates a new array object of line type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New line array\n *\n * @example\n * ```typescript\n * import { array, line } from 'oakscriptjs';\n *\n * // Create array to store last 15 lines\n * const lines = array.new_line();\n * const trendLine = line.new(0, 100, 50, 150);\n * array.push(lines, trendLine);\n *\n * // Manage line count\n * if (array.size(lines) > 15) {\n * const oldLine = array.shift(lines);\n * }\n * ```\n *\n * @remarks\n * Useful for managing collections of trend lines, support/resistance levels, or channel lines.\n * In PineScript, this is typically used with line.delete() to manage chart object limits.\n */\nexport function new_line(size: simple_int = 0, initial_value?: Line): PineArray<Line> {\n return new_array<Line>(size, initial_value);\n}\n\n/**\n * Create new box array\n *\n * Creates a new array object of box type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New box array\n *\n * @example\n * ```typescript\n * import { array, box } from 'oakscriptjs';\n *\n * // Create array to store gap boxes\n * const gaps = array.new_box();\n * const gapBox = box.new(10, 120, 15, 110);\n * array.push(gaps, gapBox);\n *\n * // Track multiple gaps\n * for (let i = 0; i < array.size(gaps); i++) {\n * const gap = array.get(gaps, i);\n * const gapTop = box.get_top(gap);\n * const gapBottom = box.get_bottom(gap);\n * // Check if gap filled...\n * }\n * ```\n *\n * @remarks\n * Useful for tracking ranges, gaps, consolidation zones, or rectangle patterns.\n * Enables systematic analysis of multiple box objects.\n */\nexport function new_box(size: simple_int = 0, initial_value?: Box): PineArray<Box> {\n return new_array<Box>(size, initial_value);\n}\n\n/**\n * Create new label array\n *\n * Creates a new array object of label type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New label array\n *\n * @example\n * ```typescript\n * import { array, label } from 'oakscriptjs';\n *\n * // Create array to store pivot labels\n * const pivotLabels = array.new_label();\n *\n * // Add labels for pivot highs\n * const pivotLabel = label.new(50, 155.5, 'PH', 'bar_index', 'abovebar');\n * array.push(pivotLabels, pivotLabel);\n *\n * // Limit number of labels shown\n * const maxLabels = 50;\n * if (array.size(pivotLabels) > maxLabels) {\n * array.shift(pivotLabels);\n * }\n * ```\n *\n * @remarks\n * Useful for managing collections of annotations, pivot markers, or signal labels.\n * Helps limit the number of labels displayed by removing old ones.\n */\nexport function new_label(size: simple_int = 0, initial_value?: Label): PineArray<Label> {\n return new_array<Label>(size, initial_value);\n}\n\n/**\n * Create new linefill array\n *\n * Creates a new array object of linefill type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New linefill array\n *\n * @example\n * ```typescript\n * import { array, line, linefill } from 'oakscriptjs';\n *\n * // Create array to store channel fills\n * const channels = array.new_linefill();\n *\n * // Create channel\n * const upperLine = line.new(0, 120, 50, 130);\n * const lowerLine = line.new(0, 100, 50, 110);\n * const channelFill = linefill.new(upperLine, lowerLine, '#0000FF15');\n *\n * array.push(channels, channelFill);\n * ```\n *\n * @remarks\n * Useful for managing collections of channel fills, Bollinger Band fills, or regression channel fills.\n * Enables dynamic color changes across multiple channels.\n */\nexport function new_linefill(size: simple_int = 0, initial_value?: Linefill): PineArray<Linefill> {\n return new_array<Linefill>(size, initial_value);\n}\n\n/**\n * Creates a new array of tables (PineScript `array.new_table`).\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New table array\n */\nexport function new_table(size: simple_int = 0, initial_value?: Table): PineArray<Table> {\n return new_array<Table>(size, initial_value);\n}\n\n/**\n * Absolute value of array elements\n *\n * Returns an array containing the absolute value of each element in the original array.\n *\n * @param id - Array of numeric values\n * @returns New array with absolute values\n *\n * @example\n * ```typescript\n * const arr = [-1, -2, 3, -4, 5];\n * const result = array.abs(arr);\n * // Returns: [1, 2, 3, 4, 5]\n * ```\n */\nexport function abs(id: PineArray<float>): PineArray<float> {\n return id.map(x => Math.abs(x)) as PineArray<float>;\n}\n\n/**\n * Range of array values\n *\n * Returns the difference between the maximum and minimum values in the array.\n *\n * @param id - Array of numeric values\n * @returns Difference between max and min (range)\n *\n * @example\n * ```typescript\n * const arr = [1, 5, 3, 9, 2];\n * const result = array.range(arr);\n * // Returns: 8 (9 - 1)\n * ```\n *\n * @remarks\n * Returns NaN if the array is empty.\n */\nexport function range(id: PineArray<float>): float {\n if (id.length === 0) {\n return NaN;\n }\n return max(id) - min(id);\n}\n\n/**\n * Binary Search\n *\n * Searches for a value in a sorted array using binary search algorithm.\n * Returns the index of the value if found, or -1 if not found.\n *\n * @param id - Sorted array (ascending order)\n * @param val - Value to search for\n * @returns Index of the value, or -1 if not found\n *\n * @example\n * ```typescript\n * const arr = [-2, 0, 1, 5, 9]; // Must be sorted\n * const index = array.binary_search(arr, 5);\n * // Returns: 3\n * ```\n *\n * @remarks\n * - Array must be sorted in ascending order\n * - Uses standard binary search algorithm\n * - Time complexity: O(log n)\n */\nexport function binary_search(id: PineArray<float>, val: float): int {\n let left = 0;\n let right = id.length - 1;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n\n if (id[mid]! === val) {\n return mid;\n }\n\n if (id[mid]! < val) {\n left = mid + 1;\n } else {\n right = mid - 1;\n }\n }\n\n return -1; // Not found\n}\n\n/**\n * Binary Search Leftmost\n *\n * Returns the index of the value if found. When not found, returns the index\n * of the next smallest element to the left of where the value would be.\n *\n * @param id - Sorted array (ascending order)\n * @param val - Value to search for\n * @returns Index of value or insertion point to the left\n *\n * @example\n * ```typescript\n * const arr = [-2, 0, 1, 5, 9];\n * const index = array.binary_search_leftmost(arr, 3);\n * // Returns: 2 (index of 1, which is left of where 3 would be)\n * ```\n *\n * @example\n * ```typescript\n * const arr = [4, 5, 5, 5];\n * const index = array.binary_search_leftmost(arr, 5);\n * // Returns: 1 (index of first instance of 5)\n * ```\n *\n * @remarks\n * - Array must be sorted in ascending order\n * - For duplicate values, returns leftmost occurrence\n * - When value not found, returns position of next smaller element\n * - PineScript rules: a value below every element gives 0; `na` counts as greater than every number (an array\n * without na gives `size - 1`); the comparison is exact (no 1e-10 tolerance)\n */\nexport function binary_search_leftmost(id: PineArray<float>, val: float): int {\n if (id.length === 0) return -1;\n const at = searchBound(id, val, false);\n return at < id.length && compareSorted(id[at]!, val) === 0 ? at : Math.max(0, at - 1);\n}\n\n/**\n * Order of the PineScript binary searches: numbers in ascending order, na above every number (equal to na).\n */\nfunction compareSorted(a: float, b: float): number {\n const an = Number.isNaN(a);\n const bn = Number.isNaN(b);\n if (an || bn) return an === bn ? 0 : an ? 1 : -1;\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/** First index whose element is >= `val` (`after` false) or > `val` (`after` true); `id.length` when none. */\nfunction searchBound(id: PineArray<float>, val: float, after: boolean): int {\n let lo = 0;\n let hi = id.length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n const c = compareSorted(id[mid]!, val);\n if (c < 0 || (after && c === 0)) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\n/**\n * Binary Search Rightmost\n *\n * Returns the index of the value if found. When not found, returns the index\n * of the element to the right of where the value would be.\n *\n * @param id - Sorted array (ascending order)\n * @param val - Value to search for\n * @returns Index of value or insertion point to the right\n *\n * @example\n * ```typescript\n * const arr = [-2, 0, 1, 5, 9];\n * const index = array.binary_search_rightmost(arr, 3);\n * // Returns: 3 (index of 5, which is right of where 3 would be)\n * ```\n *\n * @example\n * ```typescript\n * const arr = [4, 5, 5, 5];\n * const index = array.binary_search_rightmost(arr, 5);\n * // Returns: 3 (index of last instance of 5)\n * ```\n *\n * @remarks\n * - Array must be sorted in ascending order\n * - For duplicate values, returns rightmost occurrence\n * - When value not found, returns position of next larger element\n * - PineScript rules: a value above every element gives `size` (the position after the last element); `na` counts\n * as greater than every number (an array without na gives `size`); the comparison is exact (no 1e-10 tolerance)\n */\nexport function binary_search_rightmost(id: PineArray<float>, val: float): int {\n if (id.length === 0) return -1;\n const at = searchBound(id, val, true);\n return at > 0 && compareSorted(id[at - 1]!, val) === 0 ? at - 1 : at;\n}\n\n/**\n * Covariance\n *\n * Returns the covariance between two arrays.\n *\n * @param id1 - First array\n * @param id2 - Second array\n * @param biased - If true, uses biased estimate (population). If false, uses unbiased estimate (sample). Default: true\n * @returns Covariance between the two arrays\n *\n * @example\n * ```typescript\n * const prices = [100, 102, 98, 105, 103];\n * const volume = [1000, 1200, 950, 1300, 1100];\n * const cov = array.covariance(prices, volume);\n * // Returns covariance between price and volume\n * ```\n *\n * @remarks\n * - Biased (true): divides by n (population covariance)\n * - Unbiased (false): divides by n-1 (sample covariance)\n * - Returns NaN if arrays are empty or have different lengths\n * - Formula: Cov(X,Y) = E[(X - \u03BCX)(Y - \u03BCY)]\n *\n * PineScript rules: a pair where either value is `na` is skipped and the count is the number of pairs kept; both\n * means first, then the sum of the products from the first to the last pair. One pair gives 0 biased, NaN unbiased.\n */\nexport function covariance(id1: PineArray<float>, id2: PineArray<float>, biased: bool = true): float {\n if (id1.length !== id2.length) {\n return NaN;\n }\n const xs: number[] = [];\n const ys: number[] = [];\n for (let i = 0; i < id1.length; i++) {\n if (Number.isNaN(id1[i]!) || Number.isNaN(id2[i]!)) continue;\n xs.push(id1[i]!);\n ys.push(id2[i]!);\n }\n const n = xs.length;\n if (!n || (!biased && n < 2)) return NaN;\n let mean1 = 0;\n let mean2 = 0;\n for (let i = 0; i < n; i++) {\n mean1 += xs[i]!;\n mean2 += ys[i]!;\n }\n mean1 /= n;\n mean2 /= n;\n let sum = 0;\n for (let i = 0; i < n; i++) {\n sum += (xs[i]! - mean1) * (ys[i]! - mean2);\n }\n return sum / (biased ? n : n - 1);\n}\n\n/**\n * Percentile Linear Interpolation\n *\n * Returns the value for which the specified percentage of array values are\n * less than or equal to it, using linear interpolation.\n *\n * @param id - Array of numeric values\n * @param percentage - Percentage (0-100)\n * @returns Percentile value using linear interpolation\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const p50 = array.percentile_linear_interpolation(arr, 50);\n * // Returns: 3 (median)\n * ```\n *\n * @remarks\n * - Uses linear interpolation between adjacent values\n * - Result may not be a member of the array\n * - Returns NaN if array is empty\n *\n * PineScript rules:\n * - 1-based position in the sorted array: `size * percentage / 100 + 0.5` (snapped to an integer within 1e-9),\n * clamped to the first / last value; between two values `lo * (1 - frac) + hi * frac`\n * - `na` values are sorted after all numbers; with an `na` in the array, a position between two values gives `na`\n * - an `na` percentage gives `na`; a percentage outside 0 .. 100 is a runtime error (throws)\n */\nexport function percentile_linear_interpolation(id: PineArray<float>, percentage: float): float {\n if (id.length === 0 || Number.isNaN(percentage)) {\n return NaN;\n }\n checkPercentage('percentile_linear_interpolation', percentage);\n const s = sortedNaLast(id);\n const n = s.length;\n let pos = (n * percentage) / 100 + 0.5;\n const nearest = Math.round(pos);\n if (Math.abs(pos - nearest) < 1e-9) pos = nearest;\n if (pos <= 1) return s[0]!;\n if (pos >= n) return s[n - 1]!;\n const lower = Math.floor(pos);\n const frac = pos - lower;\n if (frac === 0) return s[lower - 1]!;\n if (Number.isNaN(s[n - 1]!)) return NaN;\n return s[lower - 1]! * (1 - frac) + s[lower]! * frac;\n}\n\n/** Array values sorted ascending, `na` values after the numbers (array.percentile_*). */\nfunction sortedNaLast(id: PineArray<float>): number[] {\n const numbers = id.filter((v) => !Number.isNaN(v)).sort((a, b) => a - b);\n return [...numbers, ...Array<number>(id.length - numbers.length).fill(NaN)];\n}\n\n/** A percentage outside 0 .. 100 is a PineScript runtime error. */\nfunction checkPercentage(name: string, percentage: number): void {\n if (!(percentage >= 0 && percentage <= 100)) {\n throw new Error(`array.${name}: percentage ${percentage} must be between 0 and 100`);\n }\n}\n\n/**\n * Percentile Nearest Rank\n *\n * Returns the value for which the specified percentage of array values are\n * less than or equal to it, using the nearest-rank method.\n *\n * @param id - Array of numeric values\n * @param percentage - Percentage (0-100)\n * @returns Percentile value using nearest rank\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const p50 = array.percentile_nearest_rank(arr, 50);\n * // Returns: 3 (median, always a member of array)\n * ```\n *\n * @remarks\n * - Result is always a member of the array\n * - Uses nearest-rank method (no interpolation)\n * - Returns NaN if array is empty\n *\n * PineScript rules:\n * - the value at rank `ceil(percentage * size / 100)` (clamped to 1 .. size) of the sorted array\n * - `na` values are sorted after all numbers (na when that rank holds an `na`)\n * - an `na` percentage counts as 0; a percentage outside 0 .. 100 is a runtime error (throws)\n */\nexport function percentile_nearest_rank(id: PineArray<float>, percentage: float): float {\n if (id.length === 0) {\n return NaN;\n }\n const pct = Number.isNaN(percentage) ? 0 : percentage;\n checkPercentage('percentile_nearest_rank', pct);\n const s = sortedNaLast(id);\n const rank = Math.min(s.length, Math.max(1, Math.ceil((pct * s.length) / 100)));\n return s[rank - 1]!;\n}\n\n/**\n * Percent Rank\n *\n * Returns the percentile rank of the element at the specified index.\n * The percentile rank is the percentage of elements that are less than\n * or equal to the reference value.\n *\n * @param id - Array of numeric values\n * @param index - Index of element to rank\n * @returns Percentile rank (0-100)\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const rank = array.percentrank(arr, 2); // Value at index 2 is 3\n * // Returns: 50 ((3 - 1) * 100 / (5 - 1))\n * ```\n *\n * @remarks\n * - Range: 0 to 100\n *\n * PineScript rules:\n * - `(count - 1) * 100 / (size - 1)`, with `count` the number of non-na elements <= the element (exact\n * comparison, no 1e-10 tolerance); `na` elements count in the size\n * - an `na` element, a one-element array or an empty array gives NaN\n * - an `na` index counts as 0; an index outside `0 .. size - 1` is a runtime error (throws)\n */\nexport function percentrank(id: PineArray<float>, index: int): float {\n const i = Number.isNaN(index) ? 0 : Math.trunc(index);\n if (id.length === 0) {\n return NaN;\n }\n if (i < 0 || i >= id.length) {\n throw new Error(`array.percentrank: index ${i} is out of bounds, array size is ${id.length}`);\n }\n if (id.length === 1) {\n return NaN;\n }\n const value = id[i]!;\n if (Number.isNaN(value)) {\n return NaN;\n }\n let count = 0;\n for (const v of id) {\n if (v <= value) count++;\n }\n return ((count - 1) * 100) / (id.length - 1);\n}\n\n/**\n * Sort Indices\n *\n * Returns an array of indices which, when used to index the original array,\n * will access its elements in their sorted order. Does not modify the original array.\n *\n * @param id - Array to get sorted indices from\n * @param order - Sort order: 'asc' or 'desc' (default: 'asc')\n * @returns Array of indices in sorted order\n *\n * @example\n * ```typescript\n * const arr = [5, -2, 0, 9, 1];\n * const indices = array.sort_indices(arr); // [1, 2, 4, 0, 3]\n * // arr[1] = -2 (smallest)\n * // arr[2] = 0\n * // arr[4] = 1\n * // arr[0] = 5\n * // arr[3] = 9 (largest)\n * ```\n *\n * @remarks\n * - Original array is not modified\n * - Returns indices that would sort the array\n * - Useful for maintaining correspondence with other arrays\n * - PineScript rule: the indices of `na` elements go where `array.sort` puts them (after the numbers in ascending\n * order, in their original order: `sort_indices([na, na, 5, 1])` is `[3, 2, 0, 1]`)\n */\nexport function sort_indices<T>(id: PineArray<T>, order: SortOrder = 'asc'): PineArray<int> {\n return sortedPositions(id, order);\n}\n\n/**\n * Standardize\n *\n * Returns an array of standardized elements (z-score normalization).\n * Each element is transformed to (value - mean) / stddev.\n *\n * @param id - Array of numeric values\n * @returns Array of standardized values (z-scores)\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const standardized = array.standardize(arr);\n * // Mean = 3, StdDev \u2248 1.414\n * // Result \u2248 [-1.414, -0.707, 0, 0.707, 1.414]\n * ```\n *\n * @remarks\n * - Formula: z = (x - \u03BC) / \u03C3\n * - Result has mean of 0 and standard deviation of 1\n * - Useful for comparing values on different scales\n *\n * PineScript rules:\n * - \u03BC and \u03C3 are the population mean and standard deviation of the non-na elements, as `array.variance` (moment\n * form); `na` elements stay `na`\n * - when \u03C3 is 0 (all values equal) every non-na element gives 1\n */\nexport function standardize(id: PineArray<float>): PineArray<float> {\n const values = id.filter((v) => !Number.isNaN(v));\n if (!values.length) {\n return id.map(() => NaN);\n }\n const [p, q] = moments(values);\n const mean = p / values.length;\n const stdDev = Math.sqrt(Math.max(0, q / values.length - mean * mean));\n if (stdDev === 0) {\n return id.map((v) => (Number.isNaN(v) ? NaN : 1));\n }\n return id.map((v) => (Number.isNaN(v) ? NaN : (v - mean) / stdDev));\n}\n\n/**\n * New Type (User-Defined Type Array)\n *\n * Creates a new array of user-defined type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements\n * @returns New array of user-defined type\n *\n * @example\n * ```typescript\n * // NOTE: User-defined types (UDTs) are not fully supported yet\n * // This is a placeholder for future implementation\n * const arr = array.newtype<MyType>(5);\n * ```\n *\n * @remarks\n * - **\u26A0\uFE0F LIMITED SUPPORT**: User-defined types (UDTs) require a type system\n * that is not yet fully implemented in this library\n * - This function currently works like `new_array<T>()` for basic types\n * - Full UDT support will be added in a future version\n * - See PineScript documentation for UDT usage patterns\n */\nexport function newtype<T>(size: simple_int = 0, initial_value?: T): PineArray<T> {\n // For now, this is just an alias for new_array\n // Full UDT support requires implementing the type system\n return new_array<T>(size, initial_value);\n}\n\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Array namespace\n * Mirrors PineScript's array.* functions\n */\n\nimport type { PineArray, int, float, bool, simple_int, color, Line, Box, Label, Linefill, Table } from '../types/index.js';\n\n/**\n * Creates a new array with initial size and default value\n */\nexport function new_array<T>(size: simple_int = 0, initial_value?: T): PineArray<T> {\n const arr: PineArray<T> = [];\n for (let i = 0; i < size; i++) {\n arr.push(initial_value as T);\n }\n return arr;\n}\n\n/**\n * Returns the number of elements in an array\n */\nexport function size<T>(id: PineArray<T>): int {\n return id.length;\n}\n\n/** True for a PineScript `na` element: NaN, null or undefined. */\nfunction isNa(v: unknown): boolean {\n return v === undefined || v === null || (typeof v === 'number' && Number.isNaN(v));\n}\n\n/** The `na` of the array's element type: NaN for a numeric (or empty) array, undefined otherwise. */\nfunction naOf<T>(id: PineArray<T>): T {\n return (id.length === 0 || typeof id[0] === 'number' ? NaN : undefined) as T;\n}\n\n/**\n * Position addressed by a PineScript index: truncated, a negative index counts from the end. An index outside\n * `-size .. size - 1 + extra` is a runtime error.\n */\nfunction position(name: string, id: PineArray<unknown>, index: number, extra = 0): number {\n const i = Math.trunc(index);\n const n = id.length;\n if (i < -n || i >= n + extra) {\n throw new Error(`In 'array.${name}()' function. Index ${i} is out of bounds, array size is ${n}.`);\n }\n return i < 0 ? i + n : i;\n}\n\n/**\n * Returns the element at the specified index.\n *\n * PineScript rules: a negative index counts from the end (`get(a, -1)` is the last element); an index outside\n * `-size .. size - 1` is a runtime error (throws \"In 'array.get()' function. Index 5 is out of bounds, array size\n * is 3.\"); an `na` index gives `na`.\n *\n * Negative indexes are a PineScript v6 rule, which oakscriptjs follows: a version 5 script stops on them with the\n * same out of bounds error (`array.get(a, -1)`, #176). A port of a v5 script that the original stops must check the\n * index itself.\n */\nexport function get<T>(id: PineArray<T>, index: simple_int): T {\n if (Number.isNaN(index)) return naOf(id);\n return id[position('get', id, index)]!;\n}\n\n/**\n * Sets the value of the element at the specified index.\n *\n * PineScript rules: a negative index counts from the end; an index outside `-size .. size - 1` is a runtime error\n * (throws); an `na` index does nothing.\n */\nexport function set<T>(id: PineArray<T>, index: simple_int, value: T): void {\n if (Number.isNaN(index)) return;\n id[position('set', id, index)] = value;\n}\n\n/**\n * Appends a value to the end of the array\n */\nexport function push<T>(id: PineArray<T>, value: T): void {\n id.push(value);\n}\n\n/**\n * Removes and returns the last element of the array\n */\nexport function pop<T>(id: PineArray<T>): T {\n return id.pop() as T;\n}\n\n/**\n * Inserts a value at the beginning of the array\n */\nexport function unshift<T>(id: PineArray<T>, value: T): void {\n id.unshift(value);\n}\n\n/**\n * Removes and returns the first element of the array\n */\nexport function shift<T>(id: PineArray<T>): T {\n return id.shift() as T;\n}\n\n/**\n * Removes all elements from the array\n */\nexport function clear<T>(id: PineArray<T>): void {\n id.length = 0;\n}\n\n/**\n * Inserts a value at the specified index.\n *\n * PineScript rules: a negative index counts from the end and `size` appends, so `-size .. size` is valid; any other\n * index is a runtime error (throws); an `na` index appends.\n */\nexport function insert<T>(id: PineArray<T>, index: simple_int, value: T): void {\n if (Number.isNaN(index)) {\n id.push(value);\n return;\n }\n id.splice(position('insert', id, index, 1), 0, value);\n}\n\n/**\n * Removes the element at the specified index and returns it.\n *\n * PineScript rules: a negative index counts from the end; an index outside `-size .. size - 1` is a runtime error\n * (throws); an `na` index removes nothing and gives `na`.\n */\nexport function remove<T>(id: PineArray<T>, index: simple_int): T {\n if (Number.isNaN(index)) return naOf(id);\n return id.splice(position('remove', id, index), 1)[0]!;\n}\n\n/** PineScript `==` of two elements: numbers are equal when |a - b| <= 1e-10; `na` never equals anything. */\nfunction pineEqual(a: unknown, b: unknown): boolean {\n if (isNa(a) || isNa(b)) return false;\n if (a === b) return true;\n if (typeof a === 'number' && typeof b === 'number') {\n const d = a - b;\n return -1e-10 <= d && d <= 1e-10;\n }\n return false;\n}\n\n/**\n * Returns true if the array contains the value.\n *\n * PineScript rules: numbers are compared with a 1e-10 tolerance (|a - b| <= 1e-10); `na` is never found.\n */\nexport function includes<T>(id: PineArray<T>, value: T): bool {\n return indexof(id, value) >= 0;\n}\n\n/**\n * Returns the index of the first occurrence of the value, -1 when not found.\n *\n * PineScript rules: numbers are compared with a 1e-10 tolerance (|a - b| <= 1e-10); `na` is never found.\n */\nexport function indexof<T>(id: PineArray<T>, value: T): int {\n for (let i = 0; i < id.length; i++) {\n if (pineEqual(id[i], value)) return i;\n }\n return -1;\n}\n\n/**\n * Returns the index of the last occurrence of the value, -1 when not found.\n *\n * PineScript rules: numbers are compared with a 1e-10 tolerance (|a - b| <= 1e-10); `na` is never found.\n */\nexport function lastindexof<T>(id: PineArray<T>, value: T): int {\n for (let i = id.length - 1; i >= 0; i--) {\n if (pineEqual(id[i], value)) return i;\n }\n return -1;\n}\n\n/**\n * Returns a shallow copy of the array\n */\nexport function copy<T>(id: PineArray<T>): PineArray<T> {\n return [...id] as PineArray<T>;\n}\n\n/**\n * Appends the elements of `id2` to `id1` and returns `id1` (PineScript `array.concat` changes `id1`).\n */\nexport function concat<T>(id1: PineArray<T>, id2: PineArray<T>): PineArray<T> {\n for (const v of Array.from(id2)) id1.push(v);\n return id1;\n}\n\n/**\n * Joins all elements into a string\n */\nexport function join(id: PineArray<any>, separator: string = ','): string {\n return id.join(separator);\n}\n\n/**\n * Reverses the array in place\n */\nexport function reverse<T>(id: PineArray<T>): void {\n id.reverse();\n}\n\n/**\n * Returns the elements from `index_from` (included) to `index_to` (excluded, default: the size) as a live view of\n * the array (PineScript `array.slice`).\n *\n * PineScript rules:\n * - the slice shares the elements of the original array: a change of an element of the slice changes the original\n * array, and adding / removing elements of the slice adds / removes them in the original array, inside the slice\n * bounds (a push to the slice inserts at the end of the slice)\n * - `index_from` must address an element (`0 .. size - 1`) and `index_to` may be `size`; other bounds, or\n * `index_from > index_to`, are a runtime error (throws); an `na` bound means the start / the end of the array\n */\nexport function slice<T>(id: PineArray<T>, index_from: simple_int, index_to?: simple_int): PineArray<T> {\n const n = id.length;\n const start = Number.isNaN(index_from) ? 0 : Math.trunc(index_from);\n const stop = index_to === undefined || Number.isNaN(index_to) ? n : Math.trunc(index_to);\n if (start < 0 || start >= n) throw new Error(`array.slice: index ${start} is out of bounds, array size is ${n}`);\n if (stop < 0 || stop > n) throw new Error(`array.slice: index ${stop} is out of bounds, array size is ${n}`);\n if (start > stop) throw new Error(`array.slice: index_from ${start} is greater than index_to ${stop}`);\n return sliceView(id, start, stop - start);\n}\n\n/** Index of a property key that is an array index, -1 otherwise. */\nfunction indexKey(p: string | symbol): number {\n if (typeof p !== 'string') return -1;\n const i = Number(p);\n return Number.isInteger(i) && i >= 0 && String(i) === p ? i : -1;\n}\n\n/**\n * Live view of `size` elements of `parent` from `start`: an array (a Proxy) whose element reads and writes go to\n * `parent`, and whose size changes insert / remove elements in `parent` at the end of the view.\n */\nfunction sliceView<T>(parent: PineArray<T>, start: number, size: number): PineArray<T> {\n const resize = (target: number): void => {\n if (target > size) parent.splice(start + size, 0, ...Array<T>(target - size).fill(undefined as T));\n else if (target < size) parent.splice(start + target, size - target);\n size = target;\n };\n return new Proxy<T[]>([], {\n get(target, p, receiver) {\n const i = indexKey(p);\n if (i >= 0) return i < size ? parent[start + i] : undefined;\n if (p === 'length') return size;\n return Reflect.get(target, p, receiver);\n },\n set(target, p, value, receiver) {\n const i = indexKey(p);\n if (i >= 0) {\n if (i >= size) resize(i + 1);\n parent[start + i] = value;\n return true;\n }\n if (p === 'length') {\n resize(Number(value));\n return true;\n }\n return Reflect.set(target, p, value, receiver);\n },\n has(target, p) {\n const i = indexKey(p);\n return i >= 0 ? i < size : Reflect.has(target, p);\n },\n // Array methods delete the slots past the new end before they set the length, which does the removal.\n deleteProperty(target, p) {\n return indexKey(p) >= 0 ? true : Reflect.deleteProperty(target, p);\n },\n ownKeys(target) {\n return [...Array.from({ length: size }, (_, i) => String(i)), ...Reflect.ownKeys(target)];\n },\n getOwnPropertyDescriptor(target, p) {\n const i = indexKey(p);\n if (i >= 0) {\n return i < size ? { value: parent[start + i], writable: true, enumerable: true, configurable: true } : undefined;\n }\n if (p === 'length') return { value: size, writable: true, enumerable: false, configurable: false };\n return Reflect.getOwnPropertyDescriptor(target, p);\n },\n });\n}\n\n/** Sort order of array.sort / array.sort_indices (PineScript `order.ascending` / `order.descending`). */\nexport type SortOrder = 'asc' | 'desc' | 'ascending' | 'descending';\n\n/**\n * Positions of the elements in PineScript sorted order: ascending values, `na` after the numbers (before the\n * strings of a string array), stable; descending is the ascending result reversed.\n */\nfunction sortedPositions<T>(id: PineArray<T>, order: SortOrder): number[] {\n const values: number[] = [];\n const nas: number[] = [];\n for (let i = 0; i < id.length; i++) (isNa(id[i]) ? nas : values).push(i);\n values.sort((a, b) => {\n const x = id[a] as unknown as number;\n const y = id[b] as unknown as number;\n return x < y ? -1 : x > y ? 1 : 0;\n });\n const naFirst = values.length > 0 && typeof id[values[0]!] === 'string';\n const positions = naFirst ? [...nas, ...values] : [...values, ...nas];\n if (order === 'desc' || order === 'descending') positions.reverse();\n return positions;\n}\n\n/**\n * Sorts the array in place.\n *\n * PineScript rules: `na` goes after the numbers in ascending order and before them in descending order (the\n * ascending result reversed); in a string array `na` goes first in ascending order.\n */\nexport function sort<T>(id: PineArray<T>, order: SortOrder = 'asc'): void {\n const sorted = sortedPositions(id, order).map((p) => id[p]!);\n for (let i = 0; i < sorted.length; i++) id[i] = sorted[i]!;\n}\n\n/**\n * Sum of the non-na elements (PineScript `array.sum(id)`), added from left to right; an array without values gives NaN.\n * As PineScript, the running sum is set to 0 after a step when its absolute value is <= 1e-10.\n */\nexport function sum(id: PineArray<float>): float {\n let total = 0;\n let count = 0;\n for (const v of id) {\n if (Number.isNaN(v)) continue;\n count++;\n total += v;\n if (Math.abs(total) <= 1e-10) total = 0;\n }\n return count ? total : NaN;\n}\n\n/**\n * Average of the non-na elements (PineScript `array.avg(id)`); an array without values gives NaN.\n */\nexport function avg(id: PineArray<float>): float {\n const values = id.filter((v) => !Number.isNaN(v));\n return values.length ? values.reduce((a, b) => a + b, 0) / values.length : NaN;\n}\n\n/** The `nth` value of the non-na elements sorted with `compare` (array.min / array.max). */\nfunction nthValue(name: string, id: PineArray<float>, nth: number, compare: (a: number, b: number) => number): float {\n const rank = Number.isNaN(nth) ? 0 : Math.trunc(nth);\n const values = id.filter((v) => !Number.isNaN(v));\n if (!values.length) return NaN;\n if (rank < 0 || rank >= id.length) {\n throw new Error(`array.${name}: nth ${rank} is out of bounds, array size is ${id.length}`);\n }\n values.sort(compare);\n return values[Math.min(rank, values.length - 1)]!;\n}\n\n/**\n * The `nth` smallest value (0 = the smallest) of the non-na elements (PineScript `array.min(id, nth)`).\n *\n * PineScript rules: an `nth` past the non-na values but inside the array size gives the greatest value; an `nth`\n * outside `0 .. size - 1` is a runtime error (throws); an `na` nth counts as 0; an array without values gives NaN.\n */\nexport function min(id: PineArray<float>, nth: simple_int = 0): float {\n return nthValue('min', id, nth, (a, b) => a - b);\n}\n\n/**\n * The `nth` greatest value (0 = the greatest) of the non-na elements (PineScript `array.max(id, nth)`).\n *\n * PineScript rules: an `nth` past the non-na values but inside the array size gives the smallest value; an `nth`\n * outside `0 .. size - 1` is a runtime error (throws); an `na` nth counts as 0; an array without values gives NaN.\n */\nexport function max(id: PineArray<float>, nth: simple_int = 0): float {\n return nthValue('max', id, nth, (a, b) => b - a);\n}\n\n/**\n * Median of the non-na elements (PineScript `array.median(id)`): the middle value, or the mean of the two middle\n * values for an even count; an array without values gives NaN.\n */\nexport function median(id: PineArray<float>): float {\n const sorted = id.filter((v) => !Number.isNaN(v)).sort((a, b) => a - b);\n if (!sorted.length) return NaN;\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;\n}\n\n/**\n * Most frequent non-na element (PineScript `array.mode(id)`), compared exactly.\n *\n * PineScript rules: with several values of the same frequency, the smallest one; an array without values gives NaN.\n */\nexport function mode(id: PineArray<float>): float {\n const frequency = new Map<float, int>();\n for (const v of id) {\n if (!Number.isNaN(v)) frequency.set(v, (frequency.get(v) ?? 0) + 1);\n }\n let best = NaN;\n let bestCount = 0;\n for (const [v, count] of frequency) {\n if (count > bestCount || (count === bestCount && v < best)) {\n best = v;\n bestCount = count;\n }\n }\n return best;\n}\n\n/**\n * Standard deviation of the non-na elements (PineScript `array.stdev(id, biased)`): the square root of\n * `array.variance(id, biased)`.\n */\nexport function stdev(id: PineArray<float>, biased: bool = true): float {\n return Math.sqrt(variance(id, biased));\n}\n\n/** Sum of the values and sum of their squares, both added from the first to the last value. */\nfunction moments(values: number[]): [number, number] {\n let p = 0;\n let q = 0;\n for (const v of values) p += v;\n for (const v of values) q += v * v;\n return [p, q];\n}\n\n/**\n * Variance of the non-na elements (PineScript `array.variance(id, biased)`).\n *\n * PineScript rule (moment form): with `p` the sum of the values, `q` the sum of their squares, `n` the count and\n * `m = p / n`: biased (default) `max(0, q / n - m * m)`, unbiased `max(0, q / (n - 1) - (p / (n - 1)) * m)`.\n * One value gives 0 biased and NaN unbiased; an array without values gives NaN.\n */\nexport function variance(id: PineArray<float>, biased: bool = true): float {\n const values = id.filter((v) => !Number.isNaN(v));\n const n = values.length;\n if (!n) return NaN;\n if (n < 2) return biased ? 0 : NaN;\n const [p, q] = moments(values);\n const mean = p / n;\n return biased ? Math.max(0, q / n - mean * mean) : Math.max(0, q / (n - 1) - (p / (n - 1)) * mean);\n}\n\n/**\n * Fills the array with the specified value\n */\nexport function fill<T>(id: PineArray<T>, value: T, index_from: simple_int = 0, index_to?: simple_int): void {\n // PineScript: an na bound is the start / the end; a bound past the end is a runtime error\n const start = index_from === undefined || index_from === null || Number.isNaN(index_from) ? 0 : index_from;\n const end = index_to === undefined || index_to === null || Number.isNaN(index_to) ? id.length : index_to;\n for (const i of [start, end]) {\n if (i < 0 || i > id.length) throw new Error(`array.fill: index ${i} is out of bounds, array size is ${id.length}`);\n }\n for (let i = start; i < end; i++) {\n id[i] = value;\n }\n}\n\n/**\n * Creates an array from its arguments (PineScript `array.from(arg0, arg1, ...)`).\n * `na` values are kept.\n *\n * @example\n * ```typescript\n * array.from(0.236, 0.382, 0.5, 0.618); // [0.236, 0.382, 0.5, 0.618]\n * ```\n */\nexport function from<T>(...values: T[]): PineArray<T> {\n return [...values];\n}\n\n/**\n * Returns the first element of the array\n *\n * @param id - The array\n * @returns The first element, or undefined if array is empty\n *\n * @remarks\n * - Equivalent to `array.get(id, 0)`\n * - Returns undefined for empty arrays\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const firstElement = array.first(arr); // Returns: 1\n * ```\n */\nexport function first<T>(id: PineArray<T>): T {\n // PineScript: a runtime error on an empty array\n if (id.length === 0) throw new Error('Cannot call array.first() if array is empty');\n return id[0]!;\n}\n\n/**\n * Returns the last element of the array\n *\n * @param id - The array\n * @returns The last element, or undefined if array is empty\n *\n * @remarks\n * - Equivalent to `array.get(id, array.size(id) - 1)`\n * - Returns undefined for empty arrays\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const lastElement = array.last(arr); // Returns: 5\n * ```\n */\nexport function last<T>(id: PineArray<T>): T {\n // PineScript: a runtime error on an empty array (as array.first)\n if (id.length === 0) throw new Error('Cannot call array.last() if array is empty');\n return id[id.length - 1]!;\n}\n\n/**\n * True when at least one element of a bool array is true (PineScript `array.some(id)`).\n * An empty array gives false.\n */\nexport function some(id: PineArray<bool>): bool {\n return id.some((v) => v === true);\n}\n\n/**\n * True when every element of a bool array is true (PineScript `array.every(id)`).\n * An empty array gives false, as in PineScript.\n */\nexport function every(id: PineArray<bool>): bool {\n return id.length > 0 && id.every((v) => v === true);\n}\n\n/**\n * Create new boolean array\n *\n * Creates a new array object of bool type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: false)\n * @returns New boolean array\n *\n * @example\n * ```typescript\n * const arr = array.new_bool(5, true);\n * // Creates: [true, true, true, true, true]\n * ```\n */\nexport function new_bool(size: simple_int = 0, initial_value: bool = false): PineArray<bool> {\n return new_array<bool>(size, initial_value);\n}\n\n/**\n * Create new float array\n *\n * Creates a new array object of float type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: NaN)\n * @returns New float array\n *\n * @example\n * ```typescript\n * const arr = array.new_float(5, 0.0);\n * // Creates: [0.0, 0.0, 0.0, 0.0, 0.0]\n * ```\n */\nexport function new_float(size: simple_int = 0, initial_value: float = NaN): PineArray<float> {\n return new_array<float>(size, initial_value);\n}\n\n/**\n * Create new integer array\n *\n * Creates a new array object of int type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: NaN)\n * @returns New integer array\n *\n * @example\n * ```typescript\n * const arr = array.new_int(5, 0);\n * // Creates: [0, 0, 0, 0, 0]\n * ```\n */\nexport function new_int(size: simple_int = 0, initial_value: int = NaN): PineArray<int> {\n return new_array<int>(size, initial_value);\n}\n\n/**\n * Create new string array\n *\n * Creates a new array object of string type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New string array\n *\n * @example\n * ```typescript\n * const arr = array.new_string(5, \"text\");\n * // Creates: [\"text\", \"text\", \"text\", \"text\", \"text\"]\n * ```\n */\nexport function new_string(size: simple_int = 0, initial_value?: string): PineArray<string> {\n return new_array<string>(size, initial_value);\n}\n\n/**\n * Create new color array\n *\n * Creates a new array object of color type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New color array\n *\n * @example\n * ```typescript\n * const arr = array.new_color(5, \"#FF0000\");\n * // Creates: [\"#FF0000\", \"#FF0000\", \"#FF0000\", \"#FF0000\", \"#FF0000\"]\n * ```\n */\nexport function new_color(size: simple_int = 0, initial_value?: color): PineArray<color> {\n return new_array<color>(size, initial_value);\n}\n\n/**\n * Create new line array\n *\n * Creates a new array object of line type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New line array\n *\n * @example\n * ```typescript\n * import { array, line } from 'oakscriptjs';\n *\n * // Create array to store last 15 lines\n * const lines = array.new_line();\n * const trendLine = line.new(0, 100, 50, 150);\n * array.push(lines, trendLine);\n *\n * // Manage line count\n * if (array.size(lines) > 15) {\n * const oldLine = array.shift(lines);\n * }\n * ```\n *\n * @remarks\n * Useful for managing collections of trend lines, support/resistance levels, or channel lines.\n * In PineScript, this is typically used with line.delete() to manage chart object limits.\n */\nexport function new_line(size: simple_int = 0, initial_value?: Line): PineArray<Line> {\n return new_array<Line>(size, initial_value);\n}\n\n/**\n * Create new box array\n *\n * Creates a new array object of box type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New box array\n *\n * @example\n * ```typescript\n * import { array, box } from 'oakscriptjs';\n *\n * // Create array to store gap boxes\n * const gaps = array.new_box();\n * const gapBox = box.new(10, 120, 15, 110);\n * array.push(gaps, gapBox);\n *\n * // Track multiple gaps\n * for (let i = 0; i < array.size(gaps); i++) {\n * const gap = array.get(gaps, i);\n * const gapTop = box.get_top(gap);\n * const gapBottom = box.get_bottom(gap);\n * // Check if gap filled...\n * }\n * ```\n *\n * @remarks\n * Useful for tracking ranges, gaps, consolidation zones, or rectangle patterns.\n * Enables systematic analysis of multiple box objects.\n */\nexport function new_box(size: simple_int = 0, initial_value?: Box): PineArray<Box> {\n return new_array<Box>(size, initial_value);\n}\n\n/**\n * Create new label array\n *\n * Creates a new array object of label type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New label array\n *\n * @example\n * ```typescript\n * import { array, label } from 'oakscriptjs';\n *\n * // Create array to store pivot labels\n * const pivotLabels = array.new_label();\n *\n * // Add labels for pivot highs\n * const pivotLabel = label.new(50, 155.5, 'PH', 'bar_index', 'abovebar');\n * array.push(pivotLabels, pivotLabel);\n *\n * // Limit number of labels shown\n * const maxLabels = 50;\n * if (array.size(pivotLabels) > maxLabels) {\n * array.shift(pivotLabels);\n * }\n * ```\n *\n * @remarks\n * Useful for managing collections of annotations, pivot markers, or signal labels.\n * Helps limit the number of labels displayed by removing old ones.\n */\nexport function new_label(size: simple_int = 0, initial_value?: Label): PineArray<Label> {\n return new_array<Label>(size, initial_value);\n}\n\n/**\n * Create new linefill array\n *\n * Creates a new array object of linefill type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New linefill array\n *\n * @example\n * ```typescript\n * import { array, line, linefill } from 'oakscriptjs';\n *\n * // Create array to store channel fills\n * const channels = array.new_linefill();\n *\n * // Create channel\n * const upperLine = line.new(0, 120, 50, 130);\n * const lowerLine = line.new(0, 100, 50, 110);\n * const channelFill = linefill.new(upperLine, lowerLine, '#0000FF15');\n *\n * array.push(channels, channelFill);\n * ```\n *\n * @remarks\n * Useful for managing collections of channel fills, Bollinger Band fills, or regression channel fills.\n * Enables dynamic color changes across multiple channels.\n */\nexport function new_linefill(size: simple_int = 0, initial_value?: Linefill): PineArray<Linefill> {\n return new_array<Linefill>(size, initial_value);\n}\n\n/**\n * Creates a new array of tables (PineScript `array.new_table`).\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements (default: undefined)\n * @returns New table array\n */\nexport function new_table(size: simple_int = 0, initial_value?: Table): PineArray<Table> {\n return new_array<Table>(size, initial_value);\n}\n\n/**\n * Absolute value of array elements\n *\n * Returns an array containing the absolute value of each element in the original array.\n *\n * @param id - Array of numeric values\n * @returns New array with absolute values\n *\n * @example\n * ```typescript\n * const arr = [-1, -2, 3, -4, 5];\n * const result = array.abs(arr);\n * // Returns: [1, 2, 3, 4, 5]\n * ```\n */\nexport function abs(id: PineArray<float>): PineArray<float> {\n return id.map(x => Math.abs(x)) as PineArray<float>;\n}\n\n/**\n * Range of array values\n *\n * Returns the difference between the maximum and minimum values in the array.\n *\n * @param id - Array of numeric values\n * @returns Difference between max and min (range)\n *\n * @example\n * ```typescript\n * const arr = [1, 5, 3, 9, 2];\n * const result = array.range(arr);\n * // Returns: 8 (9 - 1)\n * ```\n *\n * @remarks\n * Returns NaN if the array is empty.\n */\nexport function range(id: PineArray<float>): float {\n if (id.length === 0) {\n return NaN;\n }\n return max(id) - min(id);\n}\n\n/**\n * Binary Search\n *\n * Searches for a value in a sorted array using binary search algorithm.\n * Returns the index of the value if found, or -1 if not found.\n *\n * @param id - Sorted array (ascending order)\n * @param val - Value to search for\n * @returns Index of the value, or -1 if not found\n *\n * @example\n * ```typescript\n * const arr = [-2, 0, 1, 5, 9]; // Must be sorted\n * const index = array.binary_search(arr, 5);\n * // Returns: 3\n * ```\n *\n * @remarks\n * - Array must be sorted in ascending order\n * - Uses standard binary search algorithm\n * - Time complexity: O(log n)\n */\nexport function binary_search(id: PineArray<float>, val: float): int {\n let left = 0;\n let right = id.length - 1;\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n\n if (id[mid]! === val) {\n return mid;\n }\n\n if (id[mid]! < val) {\n left = mid + 1;\n } else {\n right = mid - 1;\n }\n }\n\n return -1; // Not found\n}\n\n/**\n * Binary Search Leftmost\n *\n * Returns the index of the value if found. When not found, returns the index\n * of the next smallest element to the left of where the value would be.\n *\n * @param id - Sorted array (ascending order)\n * @param val - Value to search for\n * @returns Index of value or insertion point to the left\n *\n * @example\n * ```typescript\n * const arr = [-2, 0, 1, 5, 9];\n * const index = array.binary_search_leftmost(arr, 3);\n * // Returns: 2 (index of 1, which is left of where 3 would be)\n * ```\n *\n * @example\n * ```typescript\n * const arr = [4, 5, 5, 5];\n * const index = array.binary_search_leftmost(arr, 5);\n * // Returns: 1 (index of first instance of 5)\n * ```\n *\n * @remarks\n * - Array must be sorted in ascending order\n * - For duplicate values, returns leftmost occurrence\n * - When value not found, returns position of next smaller element\n * - PineScript rules: a value below every element gives 0; `na` counts as greater than every number (an array\n * without na gives `size - 1`); the comparison is exact (no 1e-10 tolerance)\n */\nexport function binary_search_leftmost(id: PineArray<float>, val: float): int {\n if (id.length === 0) return -1;\n const at = searchBound(id, val, false);\n return at < id.length && compareSorted(id[at]!, val) === 0 ? at : Math.max(0, at - 1);\n}\n\n/**\n * Order of the PineScript binary searches: numbers in ascending order, na above every number (equal to na).\n */\nfunction compareSorted(a: float, b: float): number {\n const an = Number.isNaN(a);\n const bn = Number.isNaN(b);\n if (an || bn) return an === bn ? 0 : an ? 1 : -1;\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/** First index whose element is >= `val` (`after` false) or > `val` (`after` true); `id.length` when none. */\nfunction searchBound(id: PineArray<float>, val: float, after: boolean): int {\n let lo = 0;\n let hi = id.length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n const c = compareSorted(id[mid]!, val);\n if (c < 0 || (after && c === 0)) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\n/**\n * Binary Search Rightmost\n *\n * Returns the index of the value if found. When not found, returns the index\n * of the element to the right of where the value would be.\n *\n * @param id - Sorted array (ascending order)\n * @param val - Value to search for\n * @returns Index of value or insertion point to the right\n *\n * @example\n * ```typescript\n * const arr = [-2, 0, 1, 5, 9];\n * const index = array.binary_search_rightmost(arr, 3);\n * // Returns: 3 (index of 5, which is right of where 3 would be)\n * ```\n *\n * @example\n * ```typescript\n * const arr = [4, 5, 5, 5];\n * const index = array.binary_search_rightmost(arr, 5);\n * // Returns: 3 (index of last instance of 5)\n * ```\n *\n * @remarks\n * - Array must be sorted in ascending order\n * - For duplicate values, returns rightmost occurrence\n * - When value not found, returns position of next larger element\n * - PineScript rules: a value above every element gives `size` (the position after the last element); `na` counts\n * as greater than every number (an array without na gives `size`); the comparison is exact (no 1e-10 tolerance)\n */\nexport function binary_search_rightmost(id: PineArray<float>, val: float): int {\n if (id.length === 0) return -1;\n const at = searchBound(id, val, true);\n return at > 0 && compareSorted(id[at - 1]!, val) === 0 ? at - 1 : at;\n}\n\n/**\n * Covariance\n *\n * Returns the covariance between two arrays.\n *\n * @param id1 - First array\n * @param id2 - Second array\n * @param biased - If true, uses biased estimate (population). If false, uses unbiased estimate (sample). Default: true\n * @returns Covariance between the two arrays\n *\n * @example\n * ```typescript\n * const prices = [100, 102, 98, 105, 103];\n * const volume = [1000, 1200, 950, 1300, 1100];\n * const cov = array.covariance(prices, volume);\n * // Returns covariance between price and volume\n * ```\n *\n * @remarks\n * - Biased (true): divides by n (population covariance)\n * - Unbiased (false): divides by n-1 (sample covariance)\n * - Returns NaN if arrays are empty or have different lengths\n * - Formula: Cov(X,Y) = E[(X - \u03BCX)(Y - \u03BCY)]\n *\n * PineScript rules: a pair where either value is `na` is skipped and the count is the number of pairs kept; both\n * means first, then the sum of the products from the first to the last pair, set to 0 whenever it is within 1e-10 of\n * zero (#177: five equal closes give 0, not -1.7e-18). One pair gives 0 biased, NaN unbiased.\n */\nexport function covariance(id1: PineArray<float>, id2: PineArray<float>, biased: bool = true): float {\n if (id1.length !== id2.length) {\n return NaN;\n }\n const xs: number[] = [];\n const ys: number[] = [];\n for (let i = 0; i < id1.length; i++) {\n if (Number.isNaN(id1[i]!) || Number.isNaN(id2[i]!)) continue;\n xs.push(id1[i]!);\n ys.push(id2[i]!);\n }\n const n = xs.length;\n if (!n || (!biased && n < 2)) return NaN;\n let mean1 = 0;\n let mean2 = 0;\n for (let i = 0; i < n; i++) {\n mean1 += xs[i]!;\n mean2 += ys[i]!;\n }\n mean1 /= n;\n mean2 /= n;\n // the co-moment is a running sum set to 0 when it is within 1e-10 of zero, as array.sum (#177)\n let sum = 0;\n for (let i = 0; i < n; i++) {\n sum += (xs[i]! - mean1) * (ys[i]! - mean2);\n if (Math.abs(sum) <= 1e-10) sum = 0;\n }\n return sum / (biased ? n : n - 1);\n}\n\n/**\n * Percentile Linear Interpolation\n *\n * Returns the value for which the specified percentage of array values are\n * less than or equal to it, using linear interpolation.\n *\n * @param id - Array of numeric values\n * @param percentage - Percentage (0-100)\n * @returns Percentile value using linear interpolation\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const p50 = array.percentile_linear_interpolation(arr, 50);\n * // Returns: 3 (median)\n * ```\n *\n * @remarks\n * - Uses linear interpolation between adjacent values\n * - Result may not be a member of the array\n * - Returns NaN if array is empty\n *\n * PineScript rules:\n * - 1-based position in the sorted array: `size * percentage / 100 + 0.5` (snapped to an integer within 1e-9),\n * clamped to the first / last value; between two values `lo * (1 - frac) + hi * frac`\n * - `na` values are sorted after all numbers; with an `na` in the array, a position between two values gives `na`\n * - an `na` percentage gives `na`; a percentage outside 0 .. 100 is a runtime error (throws)\n */\nexport function percentile_linear_interpolation(id: PineArray<float>, percentage: float): float {\n if (id.length === 0 || Number.isNaN(percentage)) {\n return NaN;\n }\n checkPercentage('percentile_linear_interpolation', percentage);\n const s = sortedNaLast(id);\n const n = s.length;\n let pos = (n * percentage) / 100 + 0.5;\n const nearest = Math.round(pos);\n if (Math.abs(pos - nearest) < 1e-9) pos = nearest;\n if (pos <= 1) return s[0]!;\n if (pos >= n) return s[n - 1]!;\n const lower = Math.floor(pos);\n const frac = pos - lower;\n if (frac === 0) return s[lower - 1]!;\n if (Number.isNaN(s[n - 1]!)) return NaN;\n return s[lower - 1]! * (1 - frac) + s[lower]! * frac;\n}\n\n/** Array values sorted ascending, `na` values after the numbers (array.percentile_*). */\nfunction sortedNaLast(id: PineArray<float>): number[] {\n const numbers = id.filter((v) => !Number.isNaN(v)).sort((a, b) => a - b);\n return [...numbers, ...Array<number>(id.length - numbers.length).fill(NaN)];\n}\n\n/** A percentage outside 0 .. 100 is a PineScript runtime error. */\nfunction checkPercentage(name: string, percentage: number): void {\n if (!(percentage >= 0 && percentage <= 100)) {\n throw new Error(`array.${name}: percentage ${percentage} must be between 0 and 100`);\n }\n}\n\n/**\n * Percentile Nearest Rank\n *\n * Returns the value for which the specified percentage of array values are\n * less than or equal to it, using the nearest-rank method.\n *\n * @param id - Array of numeric values\n * @param percentage - Percentage (0-100)\n * @returns Percentile value using nearest rank\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const p50 = array.percentile_nearest_rank(arr, 50);\n * // Returns: 3 (median, always a member of array)\n * ```\n *\n * @remarks\n * - Result is always a member of the array\n * - Uses nearest-rank method (no interpolation)\n * - Returns NaN if array is empty\n *\n * PineScript rules:\n * - the value at rank `ceil(percentage * size / 100)` (clamped to 1 .. size) of the sorted array\n * - `na` values are sorted after all numbers (na when that rank holds an `na`)\n * - an `na` percentage counts as 0; a percentage outside 0 .. 100 is a runtime error (throws)\n */\nexport function percentile_nearest_rank(id: PineArray<float>, percentage: float): float {\n if (id.length === 0) {\n return NaN;\n }\n const pct = Number.isNaN(percentage) ? 0 : percentage;\n checkPercentage('percentile_nearest_rank', pct);\n const s = sortedNaLast(id);\n const rank = Math.min(s.length, Math.max(1, Math.ceil((pct * s.length) / 100)));\n return s[rank - 1]!;\n}\n\n/**\n * Percent Rank\n *\n * Returns the percentile rank of the element at the specified index.\n * The percentile rank is the percentage of elements that are less than\n * or equal to the reference value.\n *\n * @param id - Array of numeric values\n * @param index - Index of element to rank\n * @returns Percentile rank (0-100)\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const rank = array.percentrank(arr, 2); // Value at index 2 is 3\n * // Returns: 50 ((3 - 1) * 100 / (5 - 1))\n * ```\n *\n * @remarks\n * - Range: 0 to 100\n *\n * PineScript rules:\n * - `(count - 1) * 100 / (size - 1)`, with `count` the number of non-na elements <= the element (exact\n * comparison, no 1e-10 tolerance); `na` elements count in the size\n * - an `na` element, a one-element array or an empty array gives NaN\n * - an `na` index counts as 0; an index outside `0 .. size - 1` is a runtime error (throws)\n */\nexport function percentrank(id: PineArray<float>, index: int): float {\n const i = Number.isNaN(index) ? 0 : Math.trunc(index);\n if (id.length === 0) {\n return NaN;\n }\n if (i < 0 || i >= id.length) {\n throw new Error(`array.percentrank: index ${i} is out of bounds, array size is ${id.length}`);\n }\n if (id.length === 1) {\n return NaN;\n }\n const value = id[i]!;\n if (Number.isNaN(value)) {\n return NaN;\n }\n let count = 0;\n for (const v of id) {\n if (v <= value) count++;\n }\n return ((count - 1) * 100) / (id.length - 1);\n}\n\n/**\n * Sort Indices\n *\n * Returns an array of indices which, when used to index the original array,\n * will access its elements in their sorted order. Does not modify the original array.\n *\n * @param id - Array to get sorted indices from\n * @param order - Sort order: 'asc' or 'desc' (default: 'asc')\n * @returns Array of indices in sorted order\n *\n * @example\n * ```typescript\n * const arr = [5, -2, 0, 9, 1];\n * const indices = array.sort_indices(arr); // [1, 2, 4, 0, 3]\n * // arr[1] = -2 (smallest)\n * // arr[2] = 0\n * // arr[4] = 1\n * // arr[0] = 5\n * // arr[3] = 9 (largest)\n * ```\n *\n * @remarks\n * - Original array is not modified\n * - Returns indices that would sort the array\n * - Useful for maintaining correspondence with other arrays\n * - PineScript rule: the indices of `na` elements go where `array.sort` puts them (after the numbers in ascending\n * order, in their original order: `sort_indices([na, na, 5, 1])` is `[3, 2, 0, 1]`)\n */\nexport function sort_indices<T>(id: PineArray<T>, order: SortOrder = 'asc'): PineArray<int> {\n return sortedPositions(id, order);\n}\n\n/**\n * Standardize\n *\n * Returns an array of standardized elements (z-score normalization).\n * Each element is transformed to (value - mean) / stddev.\n *\n * @param id - Array of numeric values\n * @returns Array of standardized values (z-scores)\n *\n * @example\n * ```typescript\n * const arr = [1, 2, 3, 4, 5];\n * const standardized = array.standardize(arr);\n * // Mean = 3, StdDev \u2248 1.414\n * // Result \u2248 [-1.414, -0.707, 0, 0.707, 1.414]\n * ```\n *\n * @remarks\n * - Formula: z = (x - \u03BC) / \u03C3\n * - Result has mean of 0 and standard deviation of 1\n * - Useful for comparing values on different scales\n *\n * PineScript rules:\n * - \u03BC and \u03C3 are the population mean and standard deviation of the non-na elements, as `array.variance` (moment\n * form); `na` elements stay `na`\n * - when \u03C3 is 0 (all values equal) every non-na element gives 1\n */\nexport function standardize(id: PineArray<float>): PineArray<float> {\n const values = id.filter((v) => !Number.isNaN(v));\n if (!values.length) {\n return id.map(() => NaN);\n }\n const [p, q] = moments(values);\n const mean = p / values.length;\n const stdDev = Math.sqrt(Math.max(0, q / values.length - mean * mean));\n if (stdDev === 0) {\n return id.map((v) => (Number.isNaN(v) ? NaN : 1));\n }\n return id.map((v) => (Number.isNaN(v) ? NaN : (v - mean) / stdDev));\n}\n\n/**\n * New Type (User-Defined Type Array)\n *\n * Creates a new array of user-defined type elements.\n *\n * @param size - Initial size of array (default: 0)\n * @param initial_value - Initial value for all elements\n * @returns New array of user-defined type\n *\n * @example\n * ```typescript\n * // NOTE: User-defined types (UDTs) are not fully supported yet\n * // This is a placeholder for future implementation\n * const arr = array.newtype<MyType>(5);\n * ```\n *\n * @remarks\n * - **\u26A0\uFE0F LIMITED SUPPORT**: User-defined types (UDTs) require a type system\n * that is not yet fully implemented in this library\n * - This function currently works like `new_array<T>()` for basic types\n * - Full UDT support will be added in a future version\n * - See PineScript documentation for UDT usage patterns\n */\nexport function newtype<T>(size: simple_int = 0, initial_value?: T): PineArray<T> {\n // For now, this is just an alias for new_array\n // Full UDT support requires implementing the type system\n return new_array<T>(size, initial_value);\n}\n\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUO,SAAS,UAAaA,QAAmB,GAAG,eAAiC;AAClF,QAAM,MAAoB,CAAC;AAC3B,WAAS,IAAI,GAAG,IAAIA,OAAM,KAAK;AAC7B,QAAI,KAAK,aAAkB;AAAA,EAC7B;AACA,SAAO;AACT;AAKO,SAAS,KAAQ,IAAuB;AAC7C,SAAO,GAAG;AACZ;AAGA,SAAS,KAAK,GAAqB;AACjC,SAAO,MAAM,UAAa,MAAM,QAAS,OAAO,MAAM,YAAY,OAAO,MAAM,CAAC;AAClF;AAGA,SAAS,KAAQ,IAAqB;AACpC,SAAQ,GAAG,WAAW,KAAK,OAAO,GAAG,CAAC,MAAM,WAAW,MAAM;AAC/D;AAMA,SAAS,SAAS,MAAc,IAAwB,OAAe,QAAQ,GAAW;AACxF,QAAM,IAAI,KAAK,MAAM,KAAK;AAC1B,QAAM,IAAI,GAAG;AACb,MAAI,IAAI,CAAC,KAAK,KAAK,IAAI,OAAO;AAC5B,UAAM,IAAI,MAAM,aAAa,IAAI,uBAAuB,CAAC,oCAAoC,CAAC,GAAG;AAAA,EACnG;AACA,SAAO,IAAI,IAAI,IAAI,IAAI;AACzB;AAaO,SAAS,IAAO,IAAkB,OAAsB;AAC7D,MAAI,OAAO,MAAM,KAAK,EAAG,QAAO,KAAK,EAAE;AACvC,SAAO,GAAG,SAAS,OAAO,IAAI,KAAK,CAAC;AACtC;AAQO,SAAS,IAAO,IAAkB,OAAmB,OAAgB;AAC1E,MAAI,OAAO,MAAM,KAAK,EAAG;AACzB,KAAG,SAAS,OAAO,IAAI,KAAK,CAAC,IAAI;AACnC;AAKO,SAAS,KAAQ,IAAkB,OAAgB;AACxD,KAAG,KAAK,KAAK;AACf;AAKO,SAAS,IAAO,IAAqB;AAC1C,SAAO,GAAG,IAAI;AAChB;AAKO,SAAS,QAAW,IAAkB,OAAgB;AAC3D,KAAG,QAAQ,KAAK;AAClB;AAKO,SAAS,MAAS,IAAqB;AAC5C,SAAO,GAAG,MAAM;AAClB;AAKO,SAAS,MAAS,IAAwB;AAC/C,KAAG,SAAS;AACd;AAQO,SAAS,OAAU,IAAkB,OAAmB,OAAgB;AAC7E,MAAI,OAAO,MAAM,KAAK,GAAG;AACvB,OAAG,KAAK,KAAK;AACb;AAAA,EACF;AACA,KAAG,OAAO,SAAS,UAAU,IAAI,OAAO,CAAC,GAAG,GAAG,KAAK;AACtD;AAQO,SAAS,OAAU,IAAkB,OAAsB;AAChE,MAAI,OAAO,MAAM,KAAK,EAAG,QAAO,KAAK,EAAE;AACvC,SAAO,GAAG,OAAO,SAAS,UAAU,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;AACtD;AAGA,SAAS,UAAU,GAAY,GAAqB;AAClD,MAAI,KAAK,CAAC,KAAK,KAAK,CAAC,EAAG,QAAO;AAC/B,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AAClD,UAAM,IAAI,IAAI;AACd,WAAO,UAAU,KAAK,KAAK;AAAA,EAC7B;AACA,SAAO;AACT;AAOO,SAAS,SAAY,IAAkB,OAAgB;AAC5D,SAAO,QAAQ,IAAI,KAAK,KAAK;AAC/B;AAOO,SAAS,QAAW,IAAkB,OAAe;AAC1D,WAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK;AAClC,QAAI,UAAU,GAAG,CAAC,GAAG,KAAK,EAAG,QAAO;AAAA,EACtC;AACA,SAAO;AACT;AAOO,SAAS,YAAe,IAAkB,OAAe;AAC9D,WAAS,IAAI,GAAG,SAAS,GAAG,KAAK,GAAG,KAAK;AACvC,QAAI,UAAU,GAAG,CAAC,GAAG,KAAK,EAAG,QAAO;AAAA,EACtC;AACA,SAAO;AACT;AAKO,SAAS,KAAQ,IAAgC;AACtD,SAAO,CAAC,GAAG,EAAE;AACf;AAKO,SAAS,OAAU,KAAmB,KAAiC;AAC5E,aAAW,KAAK,MAAM,KAAK,GAAG,EAAG,KAAI,KAAK,CAAC;AAC3C,SAAO;AACT;AAKO,SAAS,KAAK,IAAoB,YAAoB,KAAa;AACxE,SAAO,GAAG,KAAK,SAAS;AAC1B;AAKO,SAAS,QAAW,IAAwB;AACjD,KAAG,QAAQ;AACb;AAaO,SAAS,MAAS,IAAkB,YAAwB,UAAqC;AACtG,QAAM,IAAI,GAAG;AACb,QAAM,QAAQ,OAAO,MAAM,UAAU,IAAI,IAAI,KAAK,MAAM,UAAU;AAClE,QAAM,OAAO,aAAa,UAAa,OAAO,MAAM,QAAQ,IAAI,IAAI,KAAK,MAAM,QAAQ;AACvF,MAAI,QAAQ,KAAK,SAAS,EAAG,OAAM,IAAI,MAAM,sBAAsB,KAAK,oCAAoC,CAAC,EAAE;AAC/G,MAAI,OAAO,KAAK,OAAO,EAAG,OAAM,IAAI,MAAM,sBAAsB,IAAI,oCAAoC,CAAC,EAAE;AAC3G,MAAI,QAAQ,KAAM,OAAM,IAAI,MAAM,2BAA2B,KAAK,6BAA6B,IAAI,EAAE;AACrG,SAAO,UAAU,IAAI,OAAO,OAAO,KAAK;AAC1C;AAGA,SAAS,SAAS,GAA4B;AAC5C,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,QAAM,IAAI,OAAO,CAAC;AAClB,SAAO,OAAO,UAAU,CAAC,KAAK,KAAK,KAAK,OAAO,CAAC,MAAM,IAAI,IAAI;AAChE;AAMA,SAAS,UAAa,QAAsB,OAAeA,OAA4B;AACrF,QAAM,SAAS,CAAC,WAAyB;AACvC,QAAI,SAASA,MAAM,QAAO,OAAO,QAAQA,OAAM,GAAG,GAAG,MAAS,SAASA,KAAI,EAAE,KAAK,MAAc,CAAC;AAAA,aACxF,SAASA,MAAM,QAAO,OAAO,QAAQ,QAAQA,QAAO,MAAM;AACnE,IAAAA,QAAO;AAAA,EACT;AACA,SAAO,IAAI,MAAW,CAAC,GAAG;AAAA,IACxB,IAAI,QAAQ,GAAG,UAAU;AACvB,YAAM,IAAI,SAAS,CAAC;AACpB,UAAI,KAAK,EAAG,QAAO,IAAIA,QAAO,OAAO,QAAQ,CAAC,IAAI;AAClD,UAAI,MAAM,SAAU,QAAOA;AAC3B,aAAO,QAAQ,IAAI,QAAQ,GAAG,QAAQ;AAAA,IACxC;AAAA,IACA,IAAI,QAAQ,GAAG,OAAO,UAAU;AAC9B,YAAM,IAAI,SAAS,CAAC;AACpB,UAAI,KAAK,GAAG;AACV,YAAI,KAAKA,MAAM,QAAO,IAAI,CAAC;AAC3B,eAAO,QAAQ,CAAC,IAAI;AACpB,eAAO;AAAA,MACT;AACA,UAAI,MAAM,UAAU;AAClB,eAAO,OAAO,KAAK,CAAC;AACpB,eAAO;AAAA,MACT;AACA,aAAO,QAAQ,IAAI,QAAQ,GAAG,OAAO,QAAQ;AAAA,IAC/C;AAAA,IACA,IAAI,QAAQ,GAAG;AACb,YAAM,IAAI,SAAS,CAAC;AACpB,aAAO,KAAK,IAAI,IAAIA,QAAO,QAAQ,IAAI,QAAQ,CAAC;AAAA,IAClD;AAAA;AAAA,IAEA,eAAe,QAAQ,GAAG;AACxB,aAAO,SAAS,CAAC,KAAK,IAAI,OAAO,QAAQ,eAAe,QAAQ,CAAC;AAAA,IACnE;AAAA,IACA,QAAQ,QAAQ;AACd,aAAO,CAAC,GAAG,MAAM,KAAK,EAAE,QAAQA,MAAK,GAAG,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC,GAAG,GAAG,QAAQ,QAAQ,MAAM,CAAC;AAAA,IAC1F;AAAA,IACA,yBAAyB,QAAQ,GAAG;AAClC,YAAM,IAAI,SAAS,CAAC;AACpB,UAAI,KAAK,GAAG;AACV,eAAO,IAAIA,QAAO,EAAE,OAAO,OAAO,QAAQ,CAAC,GAAG,UAAU,MAAM,YAAY,MAAM,cAAc,KAAK,IAAI;AAAA,MACzG;AACA,UAAI,MAAM,SAAU,QAAO,EAAE,OAAOA,OAAM,UAAU,MAAM,YAAY,OAAO,cAAc,MAAM;AACjG,aAAO,QAAQ,yBAAyB,QAAQ,CAAC;AAAA,IACnD;AAAA,EACF,CAAC;AACH;AASA,SAAS,gBAAmB,IAAkB,OAA4B;AACxE,QAAM,SAAmB,CAAC;AAC1B,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,IAAK,EAAC,KAAK,GAAG,CAAC,CAAC,IAAI,MAAM,QAAQ,KAAK,CAAC;AACvE,SAAO,KAAK,CAAC,GAAG,MAAM;AACpB,UAAM,IAAI,GAAG,CAAC;AACd,UAAM,IAAI,GAAG,CAAC;AACd,WAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAAA,EAClC,CAAC;AACD,QAAM,UAAU,OAAO,SAAS,KAAK,OAAO,GAAG,OAAO,CAAC,CAAE,MAAM;AAC/D,QAAM,YAAY,UAAU,CAAC,GAAG,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,QAAQ,GAAG,GAAG;AACpE,MAAI,UAAU,UAAU,UAAU,aAAc,WAAU,QAAQ;AAClE,SAAO;AACT;AAQO,SAAS,KAAQ,IAAkB,QAAmB,OAAa;AACxE,QAAM,SAAS,gBAAgB,IAAI,KAAK,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE;AAC3D,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,IAAG,CAAC,IAAI,OAAO,CAAC;AAC1D;AAMO,SAAS,IAAI,IAA6B;AAC/C,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,aAAW,KAAK,IAAI;AAClB,QAAI,OAAO,MAAM,CAAC,EAAG;AACrB;AACA,aAAS;AACT,QAAI,KAAK,IAAI,KAAK,KAAK,MAAO,SAAQ;AAAA,EACxC;AACA,SAAO,QAAQ,QAAQ;AACzB;AAKO,SAAS,IAAI,IAA6B;AAC/C,QAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC;AAChD,SAAO,OAAO,SAAS,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,OAAO,SAAS;AAC7E;AAGA,SAAS,SAAS,MAAc,IAAsB,KAAa,SAAkD;AACnH,QAAM,OAAO,OAAO,MAAM,GAAG,IAAI,IAAI,KAAK,MAAM,GAAG;AACnD,QAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC;AAChD,MAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,MAAI,OAAO,KAAK,QAAQ,GAAG,QAAQ;AACjC,UAAM,IAAI,MAAM,SAAS,IAAI,SAAS,IAAI,oCAAoC,GAAG,MAAM,EAAE;AAAA,EAC3F;AACA,SAAO,KAAK,OAAO;AACnB,SAAO,OAAO,KAAK,IAAI,MAAM,OAAO,SAAS,CAAC,CAAC;AACjD;AAQO,SAAS,IAAI,IAAsB,MAAkB,GAAU;AACpE,SAAO,SAAS,OAAO,IAAI,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACjD;AAQO,SAAS,IAAI,IAAsB,MAAkB,GAAU;AACpE,SAAO,SAAS,OAAO,IAAI,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACjD;AAMO,SAAS,OAAO,IAA6B;AAClD,QAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACtE,MAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,QAAM,MAAM,KAAK,MAAM,OAAO,SAAS,CAAC;AACxC,SAAO,OAAO,SAAS,MAAM,KAAK,OAAO,MAAM,CAAC,IAAK,OAAO,GAAG,KAAM,IAAI,OAAO,GAAG;AACrF;AAOO,SAAS,KAAK,IAA6B;AAChD,QAAM,YAAY,oBAAI,IAAgB;AACtC,aAAW,KAAK,IAAI;AAClB,QAAI,CAAC,OAAO,MAAM,CAAC,EAAG,WAAU,IAAI,IAAI,UAAU,IAAI,CAAC,KAAK,KAAK,CAAC;AAAA,EACpE;AACA,MAAI,OAAO;AACX,MAAI,YAAY;AAChB,aAAW,CAAC,GAAG,KAAK,KAAK,WAAW;AAClC,QAAI,QAAQ,aAAc,UAAU,aAAa,IAAI,MAAO;AAC1D,aAAO;AACP,kBAAY;AAAA,IACd;AAAA,EACF;AACA,SAAO;AACT;AAMO,SAAS,MAAM,IAAsB,SAAe,MAAa;AACtE,SAAO,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC;AACvC;AAGA,SAAS,QAAQ,QAAoC;AACnD,MAAI,IAAI;AACR,MAAI,IAAI;AACR,aAAW,KAAK,OAAQ,MAAK;AAC7B,aAAW,KAAK,OAAQ,MAAK,IAAI;AACjC,SAAO,CAAC,GAAG,CAAC;AACd;AASO,SAAS,SAAS,IAAsB,SAAe,MAAa;AACzE,QAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC;AAChD,QAAM,IAAI,OAAO;AACjB,MAAI,CAAC,EAAG,QAAO;AACf,MAAI,IAAI,EAAG,QAAO,SAAS,IAAI;AAC/B,QAAM,CAAC,GAAG,CAAC,IAAI,QAAQ,MAAM;AAC7B,QAAM,OAAO,IAAI;AACjB,SAAO,SAAS,KAAK,IAAI,GAAG,IAAI,IAAI,OAAO,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAM,KAAK,IAAI,KAAM,IAAI;AACnG;AAKO,SAAS,KAAQ,IAAkB,OAAU,aAAyB,GAAG,UAA6B;AAE3G,QAAM,QAAQ,eAAe,UAAa,eAAe,QAAQ,OAAO,MAAM,UAAU,IAAI,IAAI;AAChG,QAAM,MAAM,aAAa,UAAa,aAAa,QAAQ,OAAO,MAAM,QAAQ,IAAI,GAAG,SAAS;AAChG,aAAW,KAAK,CAAC,OAAO,GAAG,GAAG;AAC5B,QAAI,IAAI,KAAK,IAAI,GAAG,OAAQ,OAAM,IAAI,MAAM,qBAAqB,CAAC,oCAAoC,GAAG,MAAM,EAAE;AAAA,EACnH;AACA,WAAS,IAAI,OAAO,IAAI,KAAK,KAAK;AAChC,OAAG,CAAC,IAAI;AAAA,EACV;AACF;AAWO,SAAS,QAAW,QAA2B;AACpD,SAAO,CAAC,GAAG,MAAM;AACnB;AAkBO,SAAS,MAAS,IAAqB;AAE5C,MAAI,GAAG,WAAW,EAAG,OAAM,IAAI,MAAM,6CAA6C;AAClF,SAAO,GAAG,CAAC;AACb;AAkBO,SAAS,KAAQ,IAAqB;AAE3C,MAAI,GAAG,WAAW,EAAG,OAAM,IAAI,MAAM,4CAA4C;AACjF,SAAO,GAAG,GAAG,SAAS,CAAC;AACzB;AAMO,SAAS,KAAK,IAA2B;AAC9C,SAAO,GAAG,KAAK,CAAC,MAAM,MAAM,IAAI;AAClC;AAMO,SAAS,MAAM,IAA2B;AAC/C,SAAO,GAAG,SAAS,KAAK,GAAG,MAAM,CAAC,MAAM,MAAM,IAAI;AACpD;AAiBO,SAAS,SAASA,QAAmB,GAAG,gBAAsB,OAAwB;AAC3F,SAAO,UAAgBA,OAAM,aAAa;AAC5C;AAiBO,SAAS,UAAUA,QAAmB,GAAG,gBAAuB,KAAuB;AAC5F,SAAO,UAAiBA,OAAM,aAAa;AAC7C;AAiBO,SAAS,QAAQA,QAAmB,GAAG,gBAAqB,KAAqB;AACtF,SAAO,UAAeA,OAAM,aAAa;AAC3C;AAiBO,SAAS,WAAWA,QAAmB,GAAG,eAA2C;AAC1F,SAAO,UAAkBA,OAAM,aAAa;AAC9C;AAiBO,SAAS,UAAUA,QAAmB,GAAG,eAAyC;AACvF,SAAO,UAAiBA,OAAM,aAAa;AAC7C;AA8BO,SAAS,SAASA,QAAmB,GAAG,eAAuC;AACpF,SAAO,UAAgBA,OAAM,aAAa;AAC5C;AAiCO,SAAS,QAAQA,QAAmB,GAAG,eAAqC;AACjF,SAAO,UAAeA,OAAM,aAAa;AAC3C;AAiCO,SAAS,UAAUA,QAAmB,GAAG,eAAyC;AACvF,SAAO,UAAiBA,OAAM,aAAa;AAC7C;AA8BO,SAAS,aAAaA,QAAmB,GAAG,eAA+C;AAChG,SAAO,UAAoBA,OAAM,aAAa;AAChD;AASO,SAAS,UAAUA,QAAmB,GAAG,eAAyC;AACvF,SAAO,UAAiBA,OAAM,aAAa;AAC7C;AAiBO,SAAS,IAAI,IAAwC;AAC1D,SAAO,GAAG,IAAI,OAAK,KAAK,IAAI,CAAC,CAAC;AAChC;AAoBO,SAAS,MAAM,IAA6B;AACjD,MAAI,GAAG,WAAW,GAAG;AACnB,WAAO;AAAA,EACT;AACA,SAAO,IAAI,EAAE,IAAI,IAAI,EAAE;AACzB;AAwBO,SAAS,cAAc,IAAsB,KAAiB;AACnE,MAAI,OAAO;AACX,MAAI,QAAQ,GAAG,SAAS;AAExB,SAAO,QAAQ,OAAO;AACpB,UAAM,MAAM,KAAK,OAAO,OAAO,SAAS,CAAC;AAEzC,QAAI,GAAG,GAAG,MAAO,KAAK;AACpB,aAAO;AAAA,IACT;AAEA,QAAI,GAAG,GAAG,IAAK,KAAK;AAClB,aAAO,MAAM;AAAA,IACf,OAAO;AACL,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AACT;AAiCO,SAAS,uBAAuB,IAAsB,KAAiB;AAC5E,MAAI,GAAG,WAAW,EAAG,QAAO;AAC5B,QAAM,KAAK,YAAY,IAAI,KAAK,KAAK;AACrC,SAAO,KAAK,GAAG,UAAU,cAAc,GAAG,EAAE,GAAI,GAAG,MAAM,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,CAAC;AACtF;AAKA,SAAS,cAAc,GAAU,GAAkB;AACjD,QAAM,KAAK,OAAO,MAAM,CAAC;AACzB,QAAM,KAAK,OAAO,MAAM,CAAC;AACzB,MAAI,MAAM,GAAI,QAAO,OAAO,KAAK,IAAI,KAAK,IAAI;AAC9C,SAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAClC;AAGA,SAAS,YAAY,IAAsB,KAAY,OAAqB;AAC1E,MAAI,KAAK;AACT,MAAI,KAAK,GAAG;AACZ,SAAO,KAAK,IAAI;AACd,UAAM,MAAO,KAAK,OAAQ;AAC1B,UAAM,IAAI,cAAc,GAAG,GAAG,GAAI,GAAG;AACrC,QAAI,IAAI,KAAM,SAAS,MAAM,EAAI,MAAK,MAAM;AAAA,QACvC,MAAK;AAAA,EACZ;AACA,SAAO;AACT;AAiCO,SAAS,wBAAwB,IAAsB,KAAiB;AAC7E,MAAI,GAAG,WAAW,EAAG,QAAO;AAC5B,QAAM,KAAK,YAAY,IAAI,KAAK,IAAI;AACpC,SAAO,KAAK,KAAK,cAAc,GAAG,KAAK,CAAC,GAAI,GAAG,MAAM,IAAI,KAAK,IAAI;AACpE;AA8BO,SAAS,WAAW,KAAuB,KAAuB,SAAe,MAAa;AACnG,MAAI,IAAI,WAAW,IAAI,QAAQ;AAC7B,WAAO;AAAA,EACT;AACA,QAAM,KAAe,CAAC;AACtB,QAAM,KAAe,CAAC;AACtB,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,QAAI,OAAO,MAAM,IAAI,CAAC,CAAE,KAAK,OAAO,MAAM,IAAI,CAAC,CAAE,EAAG;AACpD,OAAG,KAAK,IAAI,CAAC,CAAE;AACf,OAAG,KAAK,IAAI,CAAC,CAAE;AAAA,EACjB;AACA,QAAM,IAAI,GAAG;AACb,MAAI,CAAC,KAAM,CAAC,UAAU,IAAI,EAAI,QAAO;AACrC,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAS,GAAG,CAAC;AACb,aAAS,GAAG,CAAC;AAAA,EACf;AACA,WAAS;AACT,WAAS;AAET,MAAIC,OAAM;AACV,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,IAAAA,SAAQ,GAAG,CAAC,IAAK,UAAU,GAAG,CAAC,IAAK;AACpC,QAAI,KAAK,IAAIA,IAAG,KAAK,MAAO,CAAAA,OAAM;AAAA,EACpC;AACA,SAAOA,QAAO,SAAS,IAAI,IAAI;AACjC;AA8BO,SAAS,gCAAgC,IAAsB,YAA0B;AAC9F,MAAI,GAAG,WAAW,KAAK,OAAO,MAAM,UAAU,GAAG;AAC/C,WAAO;AAAA,EACT;AACA,kBAAgB,mCAAmC,UAAU;AAC7D,QAAM,IAAI,aAAa,EAAE;AACzB,QAAM,IAAI,EAAE;AACZ,MAAI,MAAO,IAAI,aAAc,MAAM;AACnC,QAAM,UAAU,KAAK,MAAM,GAAG;AAC9B,MAAI,KAAK,IAAI,MAAM,OAAO,IAAI,KAAM,OAAM;AAC1C,MAAI,OAAO,EAAG,QAAO,EAAE,CAAC;AACxB,MAAI,OAAO,EAAG,QAAO,EAAE,IAAI,CAAC;AAC5B,QAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,QAAM,OAAO,MAAM;AACnB,MAAI,SAAS,EAAG,QAAO,EAAE,QAAQ,CAAC;AAClC,MAAI,OAAO,MAAM,EAAE,IAAI,CAAC,CAAE,EAAG,QAAO;AACpC,SAAO,EAAE,QAAQ,CAAC,KAAM,IAAI,QAAQ,EAAE,KAAK,IAAK;AAClD;AAGA,SAAS,aAAa,IAAgC;AACpD,QAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACvE,SAAO,CAAC,GAAG,SAAS,GAAG,MAAc,GAAG,SAAS,QAAQ,MAAM,EAAE,KAAK,GAAG,CAAC;AAC5E;AAGA,SAAS,gBAAgB,MAAc,YAA0B;AAC/D,MAAI,EAAE,cAAc,KAAK,cAAc,MAAM;AAC3C,UAAM,IAAI,MAAM,SAAS,IAAI,gBAAgB,UAAU,4BAA4B;AAAA,EACrF;AACF;AA6BO,SAAS,wBAAwB,IAAsB,YAA0B;AACtF,MAAI,GAAG,WAAW,GAAG;AACnB,WAAO;AAAA,EACT;AACA,QAAM,MAAM,OAAO,MAAM,UAAU,IAAI,IAAI;AAC3C,kBAAgB,2BAA2B,GAAG;AAC9C,QAAM,IAAI,aAAa,EAAE;AACzB,QAAM,OAAO,KAAK,IAAI,EAAE,QAAQ,KAAK,IAAI,GAAG,KAAK,KAAM,MAAM,EAAE,SAAU,GAAG,CAAC,CAAC;AAC9E,SAAO,EAAE,OAAO,CAAC;AACnB;AA6BO,SAAS,YAAY,IAAsB,OAAmB;AACnE,QAAM,IAAI,OAAO,MAAM,KAAK,IAAI,IAAI,KAAK,MAAM,KAAK;AACpD,MAAI,GAAG,WAAW,GAAG;AACnB,WAAO;AAAA,EACT;AACA,MAAI,IAAI,KAAK,KAAK,GAAG,QAAQ;AAC3B,UAAM,IAAI,MAAM,4BAA4B,CAAC,oCAAoC,GAAG,MAAM,EAAE;AAAA,EAC9F;AACA,MAAI,GAAG,WAAW,GAAG;AACnB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,GAAG,CAAC;AAClB,MAAI,OAAO,MAAM,KAAK,GAAG;AACvB,WAAO;AAAA,EACT;AACA,MAAI,QAAQ;AACZ,aAAW,KAAK,IAAI;AAClB,QAAI,KAAK,MAAO;AAAA,EAClB;AACA,UAAS,QAAQ,KAAK,OAAQ,GAAG,SAAS;AAC5C;AA8BO,SAAS,aAAgB,IAAkB,QAAmB,OAAuB;AAC1F,SAAO,gBAAgB,IAAI,KAAK;AAClC;AA6BO,SAAS,YAAY,IAAwC;AAClE,QAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC;AAChD,MAAI,CAAC,OAAO,QAAQ;AAClB,WAAO,GAAG,IAAI,MAAM,GAAG;AAAA,EACzB;AACA,QAAM,CAAC,GAAG,CAAC,IAAI,QAAQ,MAAM;AAC7B,QAAM,OAAO,IAAI,OAAO;AACxB,QAAM,SAAS,KAAK,KAAK,KAAK,IAAI,GAAG,IAAI,OAAO,SAAS,OAAO,IAAI,CAAC;AACrE,MAAI,WAAW,GAAG;AAChB,WAAO,GAAG,IAAI,CAAC,MAAO,OAAO,MAAM,CAAC,IAAI,MAAM,CAAE;AAAA,EAClD;AACA,SAAO,GAAG,IAAI,CAAC,MAAO,OAAO,MAAM,CAAC,IAAI,OAAO,IAAI,QAAQ,MAAO;AACpE;AAyBO,SAAS,QAAWD,QAAmB,GAAG,eAAiC;AAGhF,SAAO,UAAaA,OAAM,aAAa;AACzC;",
|
|
6
6
|
"names": ["size", "sum"]
|
|
7
7
|
}
|
package/dist/cjs/box/index.js
CHANGED
|
@@ -80,8 +80,8 @@ function new_box(...args) {
|
|
|
80
80
|
force_overlay,
|
|
81
81
|
text_formatting
|
|
82
82
|
] = rest;
|
|
83
|
-
(0, import_registry.checkBarIndex)("box.new", "left", left, xloc);
|
|
84
|
-
(0, import_registry.checkBarIndex)("box.new", "right", right, xloc);
|
|
83
|
+
left = (0, import_registry.checkBarIndex)("box.new", "left", left, xloc);
|
|
84
|
+
right = (0, import_registry.checkBarIndex)("box.new", "right", right, xloc);
|
|
85
85
|
return (0, import_registry.register)("box", {
|
|
86
86
|
left,
|
|
87
87
|
top,
|
|
@@ -121,13 +121,13 @@ function copy(id) {
|
|
|
121
121
|
}
|
|
122
122
|
function set_left(id, left) {
|
|
123
123
|
if ((0, import_registry.isDeleted)(id)) return id;
|
|
124
|
-
(0, import_registry.checkBarIndex)("box.set_(left*/xloc)", "left", left, id.xloc);
|
|
124
|
+
left = (0, import_registry.checkBarIndex)("box.set_(left*/xloc)", "left", left, id.xloc);
|
|
125
125
|
id.left = left;
|
|
126
126
|
return id;
|
|
127
127
|
}
|
|
128
128
|
function set_right(id, right) {
|
|
129
129
|
if ((0, import_registry.isDeleted)(id)) return id;
|
|
130
|
-
(0, import_registry.checkBarIndex)("box.set_(right*/xlock)", "right", right, id.xloc);
|
|
130
|
+
right = (0, import_registry.checkBarIndex)("box.set_(right*/xlock)", "right", right, id.xloc);
|
|
131
131
|
id.right = right;
|
|
132
132
|
return id;
|
|
133
133
|
}
|
|
@@ -143,14 +143,14 @@ function set_bottom(id, bottom) {
|
|
|
143
143
|
}
|
|
144
144
|
function set_lefttop(id, left, top) {
|
|
145
145
|
if ((0, import_registry.isDeleted)(id)) return id;
|
|
146
|
-
(0, import_registry.checkBarIndex)("box.set_(left*/xloc)", "left", left, id.xloc);
|
|
146
|
+
left = (0, import_registry.checkBarIndex)("box.set_(left*/xloc)", "left", left, id.xloc);
|
|
147
147
|
id.left = left;
|
|
148
148
|
id.top = top;
|
|
149
149
|
return id;
|
|
150
150
|
}
|
|
151
151
|
function set_rightbottom(id, right, bottom) {
|
|
152
152
|
if ((0, import_registry.isDeleted)(id)) return id;
|
|
153
|
-
(0, import_registry.checkBarIndex)("box.set_(right*/xlock)", "right", right, id.xloc);
|
|
153
|
+
right = (0, import_registry.checkBarIndex)("box.set_(right*/xlock)", "right", right, id.xloc);
|
|
154
154
|
id.right = right;
|
|
155
155
|
id.bottom = bottom;
|
|
156
156
|
return id;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/box/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Box namespace\n * Functions for creating and manipulating box drawing objects.\n *\n * @remarks\n * Box objects represent rectangular areas on the chart. The getter functions\n * (get_top, get_bottom, get_left, get_right) enable computational use cases like:\n * - Gap detection and tracking (detecting when price fills gaps)\n * - Range breakout analysis (detecting when price breaks out of consolidation)\n * - Rectangle pattern recognition\n *\n * @version 6\n */\n\nimport { all as allDrawings, checkBarIndex, isDeleted, register, remove } from '../drawing/registry.js';\nimport type { ChartPoint, Box, color } from '../types/index.js';\n\ntype BoxXloc = 'bar_index' | 'bar_time';\ntype BoxExtend = 'none' | 'left' | 'right' | 'both';\n\n/**\n * Creates a new box (PineScript `box.new`), with two chart points or with coordinates, in PineScript's\n * parameter order:\n *\n * - `box.new(top_left, bottom_right, border_color?, border_width?, border_style?, extend?, xloc?, bgcolor?,\n * text?, text_size?, text_color?, text_halign?, text_valign?, text_wrap?, text_font_family?,\n * force_overlay?, text_formatting?)`\n * - `box.new(left, top, right, bottom, border_color?, border_width?, border_style?, extend?, xloc?, ...)`\n *\n * With chart points, x is `point.index` for `bar_index` boxes and `point.time` for `bar_time` boxes.\n *\n * @example\n * ```typescript\n * // Gap box from bar 10 to 20, between 100 and 105, extended to the right\n * const gap = box.new(10, 105, 20, 100, '#2196F3', 1, 'solid', 'right');\n * ```\n */\nexport function new_box(\n top_left: ChartPoint,\n bottom_right: ChartPoint,\n border_color?: color,\n border_width?: number,\n border_style?: 'solid' | 'dotted' | 'dashed',\n extend?: BoxExtend,\n xloc?: BoxXloc,\n bgcolor?: color,\n text?: string,\n text_size?: string | number,\n text_color?: color,\n text_halign?: 'left' | 'center' | 'right',\n text_valign?: 'top' | 'center' | 'bottom',\n text_wrap?: 'none' | 'auto',\n text_font_family?: 'default' | 'monospace',\n force_overlay?: boolean,\n text_formatting?: number\n): Box;\nexport function new_box(\n left: number,\n top: number,\n right: number,\n bottom: number,\n border_color?: color,\n border_width?: number,\n border_style?: 'solid' | 'dotted' | 'dashed',\n extend?: BoxExtend,\n xloc?: BoxXloc,\n bgcolor?: color,\n text?: string,\n text_size?: string | number,\n text_color?: color,\n text_halign?: 'left' | 'center' | 'right',\n text_valign?: 'top' | 'center' | 'bottom',\n text_wrap?: 'none' | 'auto',\n text_font_family?: 'default' | 'monospace',\n force_overlay?: boolean,\n text_formatting?: number\n): Box;\nexport function new_box(...args: unknown[]): Box {\n let left: number, top: number, right: number, bottom: number, rest: unknown[];\n if (typeof args[0] === 'object' && args[0] !== null) {\n const [tl, br, ...others] = args as [ChartPoint, ChartPoint, ...unknown[]];\n const xloc = (others[4] as BoxXloc | undefined) ?? 'bar_index';\n [left, top, right, bottom, rest] = [pointX(tl, xloc), tl.price, pointX(br, xloc), br.price, others];\n } else {\n [left, top, right, bottom] = args as [number, number, number, number];\n rest = args.slice(4);\n }\n const [border_color, border_width, border_style, extend, xloc, bgcolor, text, text_size, text_color,\n text_halign, text_valign, text_wrap, text_font_family, force_overlay, text_formatting] = rest as [\n color?, number?, ('solid' | 'dotted' | 'dashed')?, BoxExtend?, BoxXloc?, color?, string?,\n (string | number)?, color?, ('left' | 'center' | 'right')?, ('top' | 'center' | 'bottom')?,\n ('none' | 'auto')?, ('default' | 'monospace')?, boolean?, number?,\n ];\n checkBarIndex('box.new', 'left', left, xloc);\n checkBarIndex('box.new', 'right', right, xloc);\n return register('box', {\n left,\n top,\n right,\n bottom,\n xloc: xloc ?? 'bar_index',\n extend: extend ?? 'none',\n border_color,\n border_width: border_width ?? 1,\n border_style: border_style || 'solid',\n bgcolor,\n text,\n text_size,\n text_color,\n text_halign,\n text_valign,\n text_wrap,\n text_font_family,\n force_overlay: force_overlay ?? false,\n text_formatting,\n });\n}\n\n/**\n * Returns the left border x coordinate.\n *\n * @param id - Box object\n * @returns Left border coordinate (bar index or timestamp)\n *\n * @remarks\n * **COMPUTATIONAL USE**: Calculate gap duration, validate range timeframes\n *\n * @example\n * ```typescript\n * const gap = box.new(10, 105, 20, 100);\n * const currentBar = 30;\n * const duration = currentBar - box.get_left(gap); // Returns 20\n *\n * if (duration > 50) {\n * console.log('Gap has been open for 50+ bars');\n * }\n * ```\n */\nexport function get_left(id: Box): number {\n return id.left;\n}\n\n/**\n * Returns the right border x coordinate.\n *\n * @param id - Box object\n * @returns Right border coordinate (bar index or timestamp)\n *\n * @remarks\n * **COMPUTATIONAL USE**: Calculate gap duration, update trailing edges\n *\n * @example\n * ```typescript\n * const range = box.new(100, 155, 150, 145);\n * const width = box.get_right(range) - box.get_left(range); // Returns 50 bars\n * ```\n */\nexport function get_right(id: Box): number {\n return id.right;\n}\n\n/**\n * Returns the top border price level.\n *\n * @param id - Box object\n * @returns Top border price\n *\n * @remarks\n * **COMPUTATIONAL USE**: Detect breakouts above resistance, check gap fills\n *\n * @example\n * ```typescript\n * const gap = box.new(10, 105, 20, 100); // Bearish gap\n *\n * // Check if price has filled gap from below\n * const high = 106;\n * if (high > box.get_top(gap)) {\n * console.log('Gap completely filled!');\n * }\n * ```\n */\nexport function get_top(id: Box): number {\n return id.top;\n}\n\n/**\n * Returns the bottom border price level.\n *\n * @param id - Box object\n * @returns Bottom border price\n *\n * @remarks\n * **COMPUTATIONAL USE**: Detect breakouts below support, check gap fills\n *\n * @example\n * ```typescript\n * const gap = box.new(10, 105, 20, 100); // Bearish gap\n *\n * // Check if price has touched gap from above\n * const low = 104;\n * if (low < box.get_top(gap) && low > box.get_bottom(gap)) {\n * console.log('Price entered the gap!');\n * }\n * ```\n */\nexport function get_bottom(id: Box): number {\n return id.bottom;\n}\n\n/**\n * Creates a copy of the box object.\n *\n * @param id - Box object to copy\n * @returns New box object with same properties\n *\n * @remarks\n * Creates a shallow copy of the box. Modifications to the copy won't affect the original.\n *\n * @example\n * ```typescript\n * const originalBox = box.new(10, 105, 20, 100);\n * const copiedBox = box.copy(originalBox);\n *\n * // Modify copy without affecting original\n * copiedBox.top = 110;\n * ```\n */\nexport function copy(id: Box): Box {\n return register('box', { ...id });\n}\n\n// =============================================================================\n// COORDINATE SETTERS\n// =============================================================================\n\n/**\n * Sets the left border x coordinate.\n *\n * @param id - Box object to modify\n * @param left - New left border coordinate\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_left(box, 15); // Move left edge to bar 15\n * ```\n */\nexport function set_left(id: Box, left: number): Box {\n if (isDeleted(id)) return id;\n checkBarIndex('box.set_(left*/xloc)', 'left', left, id.xloc);\n id.left = left;\n return id;\n}\n\n/**\n * Sets the right border x coordinate.\n *\n * @param id - Box object to modify\n * @param right - New right border coordinate\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_right(box, 25); // Move right edge to bar 25\n * ```\n */\nexport function set_right(id: Box, right: number): Box {\n if (isDeleted(id)) return id;\n checkBarIndex('box.set_(right*/xlock)', 'right', right, id.xloc);\n id.right = right;\n return id;\n}\n\n/**\n * Sets the top border price level.\n *\n * @param id - Box object to modify\n * @param top - New top border price\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_top(box, 110); // Move top edge to price 110\n * ```\n */\nexport function set_top(id: Box, top: number): Box {\n if (isDeleted(id)) return id;\n id.top = top;\n return id;\n}\n\n/**\n * Sets the bottom border price level.\n *\n * @param id - Box object to modify\n * @param bottom - New bottom border price\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_bottom(box, 95); // Move bottom edge to price 95\n * ```\n */\nexport function set_bottom(id: Box, bottom: number): Box {\n if (isDeleted(id)) return id;\n id.bottom = bottom;\n return id;\n}\n\n/**\n * Sets the left and top coordinates.\n *\n * @param id - Box object to modify\n * @param left - New left border coordinate\n * @param top - New top border price\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_lefttop(box, 12, 108); // Move top-left corner\n * ```\n */\nexport function set_lefttop(id: Box, left: number, top: number): Box {\n if (isDeleted(id)) return id;\n checkBarIndex('box.set_(left*/xloc)', 'left', left, id.xloc);\n id.left = left;\n id.top = top;\n return id;\n}\n\n/**\n * Sets the right and bottom coordinates.\n *\n * @param id - Box object to modify\n * @param right - New right border coordinate\n * @param bottom - New bottom border price\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_rightbottom(box, 25, 98); // Move bottom-right corner\n * ```\n */\nexport function set_rightbottom(id: Box, right: number, bottom: number): Box {\n if (isDeleted(id)) return id;\n checkBarIndex('box.set_(right*/xlock)', 'right', right, id.xloc);\n id.right = right;\n id.bottom = bottom;\n return id;\n}\n\n/**\n * Sets the coordinate system for the box.\n *\n * @param id - Box object to modify\n * @param left - New left border coordinate\n * @param right - New right border coordinate\n * @param xloc - New coordinate system ('bar_index' or 'bar_time')\n * @returns Modified box object\n *\n * @remarks\n * When changing xloc, you must provide appropriate x coordinates for the new system.\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * // Change to timestamp-based coordinates\n * box.set_xloc(box, 1609459200000, 1609545600000, 'bar_time');\n * ```\n */\nexport function set_xloc(id: Box, left: number, right: number, xloc: 'bar_index' | 'bar_time'): Box {\n if (isDeleted(id)) return id;\n id.left = left;\n id.right = right;\n id.xloc = xloc;\n return id;\n}\n\n/**\n * Sets the horizontal extension mode.\n *\n * @param id - Box object to modify\n * @param extend - New extension mode\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_extend(box, 'right'); // Extend box to the right\n * ```\n */\nexport function set_extend(id: Box, extend: 'none' | 'left' | 'right' | 'both'): Box {\n if (isDeleted(id)) return id;\n id.extend = extend;\n return id;\n}\n\n// =============================================================================\n// STYLING SETTERS\n// =============================================================================\n\n/**\n * Sets the border color.\n *\n * @param id - Box object to modify\n * @param borderColor - New border color\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_border_color(box, '#FF0000'); // Red border\n * ```\n */\nexport function set_border_color(id: Box, borderColor: color): Box {\n if (isDeleted(id)) return id;\n id.border_color = borderColor;\n return id;\n}\n\n/**\n * Sets the border width.\n *\n * @param id - Box object to modify\n * @param width - New border width in pixels\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_border_width(box, 2); // Thicker border\n * ```\n */\nexport function set_border_width(id: Box, width: number): Box {\n if (isDeleted(id)) return id;\n id.border_width = width;\n return id;\n}\n\n/**\n * Sets the border style.\n *\n * @param id - Box object to modify\n * @param style - New border style\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_border_style(box, 'dashed'); // Dashed border\n * ```\n */\nexport function set_border_style(id: Box, style: 'solid' | 'dotted' | 'dashed'): Box {\n if (isDeleted(id)) return id;\n id.border_style = style;\n return id;\n}\n\n/**\n * Sets the background fill color.\n *\n * @param id - Box object to modify\n * @param bgColor - New background color\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_bgcolor(box, '#00FF0030'); // Transparent green fill\n * ```\n */\nexport function set_bgcolor(id: Box, bgColor: color): Box {\n if (isDeleted(id)) return id;\n id.bgcolor = bgColor;\n return id;\n}\n\n// =============================================================================\n// TEXT SETTERS\n// =============================================================================\n\n/**\n * Sets the text content.\n *\n * @param id - Box object to modify\n * @param text - New text content\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text(box, 'Gap Filled'); // Update text\n * ```\n */\nexport function set_text(id: Box, text: string): Box {\n if (isDeleted(id)) return id;\n id.text = text;\n return id;\n}\n\n/**\n * Sets the text color.\n *\n * @param id - Box object to modify\n * @param textColor - New text color\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text_color(box, '#FFFFFF'); // White text\n * ```\n */\nexport function set_text_color(id: Box, textColor: color): Box {\n if (isDeleted(id)) return id;\n id.text_color = textColor;\n return id;\n}\n\n/**\n * Sets the text size.\n *\n * @param id - Box object to modify\n * @param size - New text size\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text_size(box, 'large'); // Larger text\n * ```\n */\nexport function set_text_size(id: Box, size: string | number): Box {\n if (isDeleted(id)) return id;\n id.text_size = size;\n return id;\n}\n\n/**\n * Sets the horizontal text alignment.\n *\n * @param id - Box object to modify\n * @param align - New horizontal alignment\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text_halign(box, 'center'); // Center text horizontally\n * ```\n */\nexport function set_text_halign(id: Box, align: 'left' | 'center' | 'right'): Box {\n if (isDeleted(id)) return id;\n id.text_halign = align;\n return id;\n}\n\n/**\n * Sets the vertical text alignment.\n *\n * @param id - Box object to modify\n * @param align - New vertical alignment\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text_valign(box, 'center'); // Center text vertically\n * ```\n */\nexport function set_text_valign(id: Box, align: 'top' | 'center' | 'bottom'): Box {\n if (isDeleted(id)) return id;\n id.text_valign = align;\n return id;\n}\n\n/**\n * Sets the text wrapping mode.\n *\n * @param id - Box object to modify\n * @param wrap - New text wrap mode\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text_wrap(box, 'auto'); // Enable text wrapping\n * ```\n */\nexport function set_text_wrap(id: Box, wrap: 'none' | 'auto'): Box {\n if (isDeleted(id)) return id;\n id.text_wrap = wrap;\n return id;\n}\n\n/**\n * Sets the text font family.\n *\n * @param id - Box object to modify\n * @param font - New font family\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text_font_family(box, 'monospace'); // Monospace font\n * ```\n */\nexport function set_text_font_family(id: Box, font: 'default' | 'monospace'): Box {\n if (isDeleted(id)) return id;\n id.text_font_family = font;\n return id;\n}\n\n/**\n * Deletes the box object.\n *\n * @param id - Box object to delete\n *\n * @remarks\n * Removes the box from `box.all()`. As in PineScript, the deleted box is `na`: its getters\n * return NaN and its setters do nothing. Deleting it twice has no effect.\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.delete(box);\n * // box.all() no longer contains it\n * ```\n */\nexport function delete_box(id: Box): void {\n remove('box', id);\n}\n\n/** x coordinate of a chart point for an object's xloc (`na` when the point has no such coordinate). */\nfunction pointX(point: ChartPoint, xloc: 'bar_index' | 'bar_time'): number {\n const x = xloc === 'bar_time' ? point.time : point.index;\n return x ?? NaN;\n}\n\n/**\n * All live boxes, in creation order (PineScript `box.all`). A new array.\n */\nexport function all(): Box[] {\n return allDrawings('box');\n}\n\n/**\n * Sets the left and top borders from a chart point (`point.index` or `point.time` by xloc, and `point.price`).\n */\nexport function set_top_left_point(id: Box, point: ChartPoint): Box {\n if (isDeleted(id)) return id;\n id.left = pointX(point, id.xloc);\n id.top = point.price;\n return id;\n}\n\n/**\n * Sets the right and bottom borders from a chart point (`point.index` or `point.time` by xloc, and `point.price`).\n */\nexport function set_bottom_right_point(id: Box, point: ChartPoint): Box {\n if (isDeleted(id)) return id;\n id.right = pointX(point, id.xloc);\n id.bottom = point.price;\n return id;\n}\n\n/**\n * Sets the text formatting: `text.format_none`, `text.format_bold`, `text.format_italic`,\n * or `text.format_bold + text.format_italic`.\n */\nexport function set_text_formatting(id: Box, formatting: number): Box {\n if (isDeleted(id)) return id;\n id.text_formatting = formatting;\n return id;\n}\n\n// Alias to match PineScript API\nexport { new_box as new };\nexport { delete_box as delete };\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,sBAA+E;AA+DxE,SAAS,WAAW,MAAsB;AAC/C,MAAI,MAAc,KAAa,OAAe,QAAgB;AAC9D,MAAI,OAAO,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,MAAM;AACnD,UAAM,CAAC,IAAI,IAAI,GAAG,MAAM,IAAI;AAC5B,UAAMA,QAAQ,OAAO,CAAC,KAA6B;AACnD,KAAC,MAAM,KAAK,OAAO,QAAQ,IAAI,IAAI,CAAC,OAAO,IAAIA,KAAI,GAAG,GAAG,OAAO,OAAO,IAAIA,KAAI,GAAG,GAAG,OAAO,MAAM;AAAA,EACpG,OAAO;AACL,KAAC,MAAM,KAAK,OAAO,MAAM,IAAI;AAC7B,WAAO,KAAK,MAAM,CAAC;AAAA,EACrB;AACA,QAAM;AAAA,IAAC;AAAA,IAAc;AAAA,IAAc;AAAA,IAAc;AAAA,IAAQ;AAAA,IAAM;AAAA,IAAS;AAAA,IAAM;AAAA,IAAW;AAAA,IACvF;AAAA,IAAa;AAAA,IAAa;AAAA,IAAW;AAAA,IAAkB;AAAA,IAAe;AAAA,EAAe,IAAI;AAK3F,
|
|
4
|
+
"sourcesContent": ["/**\n * Box namespace\n * Functions for creating and manipulating box drawing objects.\n *\n * @remarks\n * Box objects represent rectangular areas on the chart. The getter functions\n * (get_top, get_bottom, get_left, get_right) enable computational use cases like:\n * - Gap detection and tracking (detecting when price fills gaps)\n * - Range breakout analysis (detecting when price breaks out of consolidation)\n * - Rectangle pattern recognition\n *\n * @version 6\n */\n\nimport { all as allDrawings, checkBarIndex, isDeleted, register, remove } from '../drawing/registry.js';\nimport type { ChartPoint, Box, color } from '../types/index.js';\n\ntype BoxXloc = 'bar_index' | 'bar_time';\ntype BoxExtend = 'none' | 'left' | 'right' | 'both';\n\n/**\n * Creates a new box (PineScript `box.new`), with two chart points or with coordinates, in PineScript's\n * parameter order:\n *\n * - `box.new(top_left, bottom_right, border_color?, border_width?, border_style?, extend?, xloc?, bgcolor?,\n * text?, text_size?, text_color?, text_halign?, text_valign?, text_wrap?, text_font_family?,\n * force_overlay?, text_formatting?)`\n * - `box.new(left, top, right, bottom, border_color?, border_width?, border_style?, extend?, xloc?, ...)`\n *\n * With chart points, x is `point.index` for `bar_index` boxes and `point.time` for `bar_time` boxes.\n *\n * @example\n * ```typescript\n * // Gap box from bar 10 to 20, between 100 and 105, extended to the right\n * const gap = box.new(10, 105, 20, 100, '#2196F3', 1, 'solid', 'right');\n * ```\n */\nexport function new_box(\n top_left: ChartPoint,\n bottom_right: ChartPoint,\n border_color?: color,\n border_width?: number,\n border_style?: 'solid' | 'dotted' | 'dashed',\n extend?: BoxExtend,\n xloc?: BoxXloc,\n bgcolor?: color,\n text?: string,\n text_size?: string | number,\n text_color?: color,\n text_halign?: 'left' | 'center' | 'right',\n text_valign?: 'top' | 'center' | 'bottom',\n text_wrap?: 'none' | 'auto',\n text_font_family?: 'default' | 'monospace',\n force_overlay?: boolean,\n text_formatting?: number\n): Box;\nexport function new_box(\n left: number,\n top: number,\n right: number,\n bottom: number,\n border_color?: color,\n border_width?: number,\n border_style?: 'solid' | 'dotted' | 'dashed',\n extend?: BoxExtend,\n xloc?: BoxXloc,\n bgcolor?: color,\n text?: string,\n text_size?: string | number,\n text_color?: color,\n text_halign?: 'left' | 'center' | 'right',\n text_valign?: 'top' | 'center' | 'bottom',\n text_wrap?: 'none' | 'auto',\n text_font_family?: 'default' | 'monospace',\n force_overlay?: boolean,\n text_formatting?: number\n): Box;\nexport function new_box(...args: unknown[]): Box {\n let left: number, top: number, right: number, bottom: number, rest: unknown[];\n if (typeof args[0] === 'object' && args[0] !== null) {\n const [tl, br, ...others] = args as [ChartPoint, ChartPoint, ...unknown[]];\n const xloc = (others[4] as BoxXloc | undefined) ?? 'bar_index';\n [left, top, right, bottom, rest] = [pointX(tl, xloc), tl.price, pointX(br, xloc), br.price, others];\n } else {\n [left, top, right, bottom] = args as [number, number, number, number];\n rest = args.slice(4);\n }\n const [border_color, border_width, border_style, extend, xloc, bgcolor, text, text_size, text_color,\n text_halign, text_valign, text_wrap, text_font_family, force_overlay, text_formatting] = rest as [\n color?, number?, ('solid' | 'dotted' | 'dashed')?, BoxExtend?, BoxXloc?, color?, string?,\n (string | number)?, color?, ('left' | 'center' | 'right')?, ('top' | 'center' | 'bottom')?,\n ('none' | 'auto')?, ('default' | 'monospace')?, boolean?, number?,\n ];\n left = checkBarIndex('box.new', 'left', left, xloc);\n right = checkBarIndex('box.new', 'right', right, xloc);\n return register('box', {\n left,\n top,\n right,\n bottom,\n xloc: xloc ?? 'bar_index',\n extend: extend ?? 'none',\n border_color,\n border_width: border_width ?? 1,\n border_style: border_style || 'solid',\n bgcolor,\n text,\n text_size,\n text_color,\n text_halign,\n text_valign,\n text_wrap,\n text_font_family,\n force_overlay: force_overlay ?? false,\n text_formatting,\n });\n}\n\n/**\n * Returns the left border x coordinate.\n *\n * @param id - Box object\n * @returns Left border coordinate (bar index or timestamp)\n *\n * @remarks\n * **COMPUTATIONAL USE**: Calculate gap duration, validate range timeframes\n *\n * @example\n * ```typescript\n * const gap = box.new(10, 105, 20, 100);\n * const currentBar = 30;\n * const duration = currentBar - box.get_left(gap); // Returns 20\n *\n * if (duration > 50) {\n * console.log('Gap has been open for 50+ bars');\n * }\n * ```\n */\nexport function get_left(id: Box): number {\n return id.left;\n}\n\n/**\n * Returns the right border x coordinate.\n *\n * @param id - Box object\n * @returns Right border coordinate (bar index or timestamp)\n *\n * @remarks\n * **COMPUTATIONAL USE**: Calculate gap duration, update trailing edges\n *\n * @example\n * ```typescript\n * const range = box.new(100, 155, 150, 145);\n * const width = box.get_right(range) - box.get_left(range); // Returns 50 bars\n * ```\n */\nexport function get_right(id: Box): number {\n return id.right;\n}\n\n/**\n * Returns the top border price level.\n *\n * @param id - Box object\n * @returns Top border price\n *\n * @remarks\n * **COMPUTATIONAL USE**: Detect breakouts above resistance, check gap fills\n *\n * @example\n * ```typescript\n * const gap = box.new(10, 105, 20, 100); // Bearish gap\n *\n * // Check if price has filled gap from below\n * const high = 106;\n * if (high > box.get_top(gap)) {\n * console.log('Gap completely filled!');\n * }\n * ```\n */\nexport function get_top(id: Box): number {\n return id.top;\n}\n\n/**\n * Returns the bottom border price level.\n *\n * @param id - Box object\n * @returns Bottom border price\n *\n * @remarks\n * **COMPUTATIONAL USE**: Detect breakouts below support, check gap fills\n *\n * @example\n * ```typescript\n * const gap = box.new(10, 105, 20, 100); // Bearish gap\n *\n * // Check if price has touched gap from above\n * const low = 104;\n * if (low < box.get_top(gap) && low > box.get_bottom(gap)) {\n * console.log('Price entered the gap!');\n * }\n * ```\n */\nexport function get_bottom(id: Box): number {\n return id.bottom;\n}\n\n/**\n * Creates a copy of the box object.\n *\n * @param id - Box object to copy\n * @returns New box object with same properties\n *\n * @remarks\n * Creates a shallow copy of the box. Modifications to the copy won't affect the original.\n *\n * @example\n * ```typescript\n * const originalBox = box.new(10, 105, 20, 100);\n * const copiedBox = box.copy(originalBox);\n *\n * // Modify copy without affecting original\n * copiedBox.top = 110;\n * ```\n */\nexport function copy(id: Box): Box {\n return register('box', { ...id });\n}\n\n// =============================================================================\n// COORDINATE SETTERS\n// =============================================================================\n\n/**\n * Sets the left border x coordinate.\n *\n * @param id - Box object to modify\n * @param left - New left border coordinate\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_left(box, 15); // Move left edge to bar 15\n * ```\n */\nexport function set_left(id: Box, left: number): Box {\n if (isDeleted(id)) return id;\n left = checkBarIndex('box.set_(left*/xloc)', 'left', left, id.xloc);\n id.left = left;\n return id;\n}\n\n/**\n * Sets the right border x coordinate.\n *\n * @param id - Box object to modify\n * @param right - New right border coordinate\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_right(box, 25); // Move right edge to bar 25\n * ```\n */\nexport function set_right(id: Box, right: number): Box {\n if (isDeleted(id)) return id;\n right = checkBarIndex('box.set_(right*/xlock)', 'right', right, id.xloc);\n id.right = right;\n return id;\n}\n\n/**\n * Sets the top border price level.\n *\n * @param id - Box object to modify\n * @param top - New top border price\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_top(box, 110); // Move top edge to price 110\n * ```\n */\nexport function set_top(id: Box, top: number): Box {\n if (isDeleted(id)) return id;\n id.top = top;\n return id;\n}\n\n/**\n * Sets the bottom border price level.\n *\n * @param id - Box object to modify\n * @param bottom - New bottom border price\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_bottom(box, 95); // Move bottom edge to price 95\n * ```\n */\nexport function set_bottom(id: Box, bottom: number): Box {\n if (isDeleted(id)) return id;\n id.bottom = bottom;\n return id;\n}\n\n/**\n * Sets the left and top coordinates.\n *\n * @param id - Box object to modify\n * @param left - New left border coordinate\n * @param top - New top border price\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_lefttop(box, 12, 108); // Move top-left corner\n * ```\n */\nexport function set_lefttop(id: Box, left: number, top: number): Box {\n if (isDeleted(id)) return id;\n left = checkBarIndex('box.set_(left*/xloc)', 'left', left, id.xloc);\n id.left = left;\n id.top = top;\n return id;\n}\n\n/**\n * Sets the right and bottom coordinates.\n *\n * @param id - Box object to modify\n * @param right - New right border coordinate\n * @param bottom - New bottom border price\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_rightbottom(box, 25, 98); // Move bottom-right corner\n * ```\n */\nexport function set_rightbottom(id: Box, right: number, bottom: number): Box {\n if (isDeleted(id)) return id;\n right = checkBarIndex('box.set_(right*/xlock)', 'right', right, id.xloc);\n id.right = right;\n id.bottom = bottom;\n return id;\n}\n\n/**\n * Sets the coordinate system for the box.\n *\n * @param id - Box object to modify\n * @param left - New left border coordinate\n * @param right - New right border coordinate\n * @param xloc - New coordinate system ('bar_index' or 'bar_time')\n * @returns Modified box object\n *\n * @remarks\n * When changing xloc, you must provide appropriate x coordinates for the new system.\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * // Change to timestamp-based coordinates\n * box.set_xloc(box, 1609459200000, 1609545600000, 'bar_time');\n * ```\n */\nexport function set_xloc(id: Box, left: number, right: number, xloc: 'bar_index' | 'bar_time'): Box {\n if (isDeleted(id)) return id;\n id.left = left;\n id.right = right;\n id.xloc = xloc;\n return id;\n}\n\n/**\n * Sets the horizontal extension mode.\n *\n * @param id - Box object to modify\n * @param extend - New extension mode\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_extend(box, 'right'); // Extend box to the right\n * ```\n */\nexport function set_extend(id: Box, extend: 'none' | 'left' | 'right' | 'both'): Box {\n if (isDeleted(id)) return id;\n id.extend = extend;\n return id;\n}\n\n// =============================================================================\n// STYLING SETTERS\n// =============================================================================\n\n/**\n * Sets the border color.\n *\n * @param id - Box object to modify\n * @param borderColor - New border color\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_border_color(box, '#FF0000'); // Red border\n * ```\n */\nexport function set_border_color(id: Box, borderColor: color): Box {\n if (isDeleted(id)) return id;\n id.border_color = borderColor;\n return id;\n}\n\n/**\n * Sets the border width.\n *\n * @param id - Box object to modify\n * @param width - New border width in pixels\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_border_width(box, 2); // Thicker border\n * ```\n */\nexport function set_border_width(id: Box, width: number): Box {\n if (isDeleted(id)) return id;\n id.border_width = width;\n return id;\n}\n\n/**\n * Sets the border style.\n *\n * @param id - Box object to modify\n * @param style - New border style\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_border_style(box, 'dashed'); // Dashed border\n * ```\n */\nexport function set_border_style(id: Box, style: 'solid' | 'dotted' | 'dashed'): Box {\n if (isDeleted(id)) return id;\n id.border_style = style;\n return id;\n}\n\n/**\n * Sets the background fill color.\n *\n * @param id - Box object to modify\n * @param bgColor - New background color\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_bgcolor(box, '#00FF0030'); // Transparent green fill\n * ```\n */\nexport function set_bgcolor(id: Box, bgColor: color): Box {\n if (isDeleted(id)) return id;\n id.bgcolor = bgColor;\n return id;\n}\n\n// =============================================================================\n// TEXT SETTERS\n// =============================================================================\n\n/**\n * Sets the text content.\n *\n * @param id - Box object to modify\n * @param text - New text content\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text(box, 'Gap Filled'); // Update text\n * ```\n */\nexport function set_text(id: Box, text: string): Box {\n if (isDeleted(id)) return id;\n id.text = text;\n return id;\n}\n\n/**\n * Sets the text color.\n *\n * @param id - Box object to modify\n * @param textColor - New text color\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text_color(box, '#FFFFFF'); // White text\n * ```\n */\nexport function set_text_color(id: Box, textColor: color): Box {\n if (isDeleted(id)) return id;\n id.text_color = textColor;\n return id;\n}\n\n/**\n * Sets the text size.\n *\n * @param id - Box object to modify\n * @param size - New text size\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text_size(box, 'large'); // Larger text\n * ```\n */\nexport function set_text_size(id: Box, size: string | number): Box {\n if (isDeleted(id)) return id;\n id.text_size = size;\n return id;\n}\n\n/**\n * Sets the horizontal text alignment.\n *\n * @param id - Box object to modify\n * @param align - New horizontal alignment\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text_halign(box, 'center'); // Center text horizontally\n * ```\n */\nexport function set_text_halign(id: Box, align: 'left' | 'center' | 'right'): Box {\n if (isDeleted(id)) return id;\n id.text_halign = align;\n return id;\n}\n\n/**\n * Sets the vertical text alignment.\n *\n * @param id - Box object to modify\n * @param align - New vertical alignment\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text_valign(box, 'center'); // Center text vertically\n * ```\n */\nexport function set_text_valign(id: Box, align: 'top' | 'center' | 'bottom'): Box {\n if (isDeleted(id)) return id;\n id.text_valign = align;\n return id;\n}\n\n/**\n * Sets the text wrapping mode.\n *\n * @param id - Box object to modify\n * @param wrap - New text wrap mode\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text_wrap(box, 'auto'); // Enable text wrapping\n * ```\n */\nexport function set_text_wrap(id: Box, wrap: 'none' | 'auto'): Box {\n if (isDeleted(id)) return id;\n id.text_wrap = wrap;\n return id;\n}\n\n/**\n * Sets the text font family.\n *\n * @param id - Box object to modify\n * @param font - New font family\n * @returns Modified box object\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.set_text_font_family(box, 'monospace'); // Monospace font\n * ```\n */\nexport function set_text_font_family(id: Box, font: 'default' | 'monospace'): Box {\n if (isDeleted(id)) return id;\n id.text_font_family = font;\n return id;\n}\n\n/**\n * Deletes the box object.\n *\n * @param id - Box object to delete\n *\n * @remarks\n * Removes the box from `box.all()`. As in PineScript, the deleted box is `na`: its getters\n * return NaN and its setters do nothing. Deleting it twice has no effect.\n *\n * @example\n * ```typescript\n * const box = box.new(10, 105, 20, 100);\n * box.delete(box);\n * // box.all() no longer contains it\n * ```\n */\nexport function delete_box(id: Box): void {\n remove('box', id);\n}\n\n/** x coordinate of a chart point for an object's xloc (`na` when the point has no such coordinate). */\nfunction pointX(point: ChartPoint, xloc: 'bar_index' | 'bar_time'): number {\n const x = xloc === 'bar_time' ? point.time : point.index;\n return x ?? NaN;\n}\n\n/**\n * All live boxes, in creation order (PineScript `box.all`). A new array.\n */\nexport function all(): Box[] {\n return allDrawings('box');\n}\n\n/**\n * Sets the left and top borders from a chart point (`point.index` or `point.time` by xloc, and `point.price`).\n */\nexport function set_top_left_point(id: Box, point: ChartPoint): Box {\n if (isDeleted(id)) return id;\n id.left = pointX(point, id.xloc);\n id.top = point.price;\n return id;\n}\n\n/**\n * Sets the right and bottom borders from a chart point (`point.index` or `point.time` by xloc, and `point.price`).\n */\nexport function set_bottom_right_point(id: Box, point: ChartPoint): Box {\n if (isDeleted(id)) return id;\n id.right = pointX(point, id.xloc);\n id.bottom = point.price;\n return id;\n}\n\n/**\n * Sets the text formatting: `text.format_none`, `text.format_bold`, `text.format_italic`,\n * or `text.format_bold + text.format_italic`.\n */\nexport function set_text_formatting(id: Box, formatting: number): Box {\n if (isDeleted(id)) return id;\n id.text_formatting = formatting;\n return id;\n}\n\n// Alias to match PineScript API\nexport { new_box as new };\nexport { delete_box as delete };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["xloc", "allDrawings"]
|
|
7
7
|
}
|
|
@@ -183,8 +183,8 @@ function loopSumSite(name, squares) {
|
|
|
183
183
|
let pending = false;
|
|
184
184
|
return (barIndex, value, length) => {
|
|
185
185
|
const len = Math.floor(length);
|
|
186
|
-
if (!(len >= 1)) throw new Error(`callsite.${name}: length must be at least 1 (got ${length})`);
|
|
187
186
|
(0, import_limits.checkSumLength)(name === "sum" ? "math.sum" : `ta.${name}`, len, barIndex);
|
|
187
|
+
if (!(len >= 1)) throw new Error(`callsite.${name}: length must be at least 1 (got ${length})`);
|
|
188
188
|
if (barIndex !== lastBar) {
|
|
189
189
|
if (pending) {
|
|
190
190
|
running.commit();
|