@alphacharts/script 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2416 @@
1
+ import { a as e, d as t, i as n, l as r, n as i, o as a, r as o, s, t as c } from "./builtins-BXxWK58s.js";
2
+ import { SOURCE_NAMES as l, StudyEngine as u, describeJoin as d, resolveParams as f } from "@alphacharts/indicators";
3
+ //#region src/diag.ts
4
+ var p = class {
5
+ text;
6
+ starts = [0];
7
+ constructor(e) {
8
+ this.text = e;
9
+ for (let t = 0; t < e.length; t++) e.charCodeAt(t) === 10 && this.starts.push(t + 1);
10
+ }
11
+ at(e) {
12
+ let t = 0, n = this.starts.length - 1;
13
+ for (; t < n;) {
14
+ let r = t + n + 1 >>> 1;
15
+ this.starts[r] <= e ? t = r : n = r - 1;
16
+ }
17
+ return {
18
+ line: t + 1,
19
+ column: e - this.starts[t] + 1
20
+ };
21
+ }
22
+ }, m = class {
23
+ max;
24
+ list = [];
25
+ map;
26
+ errors = 0;
27
+ constructor(e, t = 50) {
28
+ this.max = t, this.map = new p(e);
29
+ }
30
+ get errorCount() {
31
+ return this.errors;
32
+ }
33
+ error(e, t) {
34
+ this.add("error", e, t);
35
+ }
36
+ warn(e, t) {
37
+ this.add("warning", e, t);
38
+ }
39
+ add(e, t, n) {
40
+ if (this.errors > this.max) return;
41
+ e === "error" && (this.errors++, this.errors > this.max && (t = `too many errors; stopped after ${this.max}`));
42
+ let r = Math.max(n.to, n.from), i = this.map.at(n.from), a = this.map.at(r);
43
+ this.list.push({
44
+ severity: e,
45
+ message: t,
46
+ line: i.line,
47
+ column: i.column,
48
+ endLine: a.line,
49
+ endColumn: a.column,
50
+ from: n.from,
51
+ to: r
52
+ });
53
+ }
54
+ }, h = class extends Error {
55
+ span;
56
+ kind;
57
+ constructor(e, t = null, n = "build") {
58
+ super(e), this.span = t, this.kind = n, this.name = "ScriptError";
59
+ }
60
+ };
61
+ function g(e) {
62
+ return `${e.line}:${e.column}: ${e.severity}: ${e.message}`;
63
+ }
64
+ //#endregion
65
+ //#region src/parser.ts
66
+ var _ = /* @__PURE__ */ new Set([
67
+ "int",
68
+ "float",
69
+ "bool",
70
+ "string",
71
+ "color"
72
+ ]), v = /* @__PURE__ */ new Set([
73
+ ":=",
74
+ "+=",
75
+ "-=",
76
+ "*=",
77
+ "/=",
78
+ "%="
79
+ ]), y = 100, b = class extends Error {}, x = class {
80
+ t;
81
+ rep;
82
+ p = 0;
83
+ depth = 0;
84
+ constructor(e, t) {
85
+ this.t = e, this.rep = t;
86
+ }
87
+ get tok() {
88
+ return this.t[this.p];
89
+ }
90
+ kind() {
91
+ return this.t[this.p].kind;
92
+ }
93
+ peek(e = 1) {
94
+ return this.t[Math.min(this.p + e, this.t.length - 1)];
95
+ }
96
+ next() {
97
+ let e = this.tok;
98
+ return e.kind !== "eof" && this.p++, e;
99
+ }
100
+ isOp(e, t = this.tok) {
101
+ return t.kind === "op" && t.text === e;
102
+ }
103
+ isKw(e, t = this.tok) {
104
+ return t.kind === "kw" && t.text === e;
105
+ }
106
+ fail(e, t = this.tok) {
107
+ throw this.rep.error(e, t.from === t.to && this.tok.kind === "newline" ? {
108
+ from: t.from,
109
+ to: t.from
110
+ } : t), new b();
111
+ }
112
+ expectOp(e, t = `"${e}"`) {
113
+ return this.isOp(e) || this.fail(`expected ${t}, found ${this.describe()}`), this.next();
114
+ }
115
+ describe(e = this.tok) {
116
+ switch (e.kind) {
117
+ case "eof": return "end of input";
118
+ case "newline": return "end of line";
119
+ case "indent": return "an unexpected indent";
120
+ case "dedent": return "end of block";
121
+ case "str": return "a string";
122
+ case "num": return `"${e.text}"`;
123
+ default: return `"${e.text}"`;
124
+ }
125
+ }
126
+ program() {
127
+ let e = [];
128
+ for (; this.tok.kind !== "eof";) this.tok.kind === "newline" ? this.next() : this.kind() === "indent" ? (this.rep.error("unexpected indent", this.tok), this.skipBlock()) : this.kind() === "dedent" ? this.next() : this.statementRecovering(e);
129
+ return { body: e };
130
+ }
131
+ statementRecovering(e) {
132
+ try {
133
+ e.push(this.statement());
134
+ } catch (e) {
135
+ if (!(e instanceof b)) throw e;
136
+ this.sync();
137
+ }
138
+ }
139
+ sync() {
140
+ for (; this.tok.kind !== "newline" && this.tok.kind !== "eof" && this.tok.kind !== "dedent";) this.next();
141
+ this.tok.kind === "newline" && this.next(), this.kind() === "indent" && this.skipBlock();
142
+ }
143
+ skipBlock() {
144
+ let e = 0;
145
+ do
146
+ this.kind() === "indent" ? e++ : this.kind() === "dedent" && e--, this.next();
147
+ while (e > 0 && this.tok.kind !== "eof");
148
+ }
149
+ endStatement() {
150
+ this.tok.kind === "newline" ? this.next() : this.tok.kind !== "eof" && this.tok.kind !== "dedent" && this.fail(`unexpected ${this.describe()}; expected end of line`);
151
+ }
152
+ block() {
153
+ this.tok.kind !== "newline" && this.fail(`expected end of line before the indented block, found ${this.describe()}`), this.next(), this.kind() !== "indent" && this.fail("expected an indented block"), this.next();
154
+ let e = [];
155
+ for (; this.kind() !== "dedent" && this.kind() !== "eof";) this.tok.kind === "newline" ? this.next() : this.kind() === "indent" ? (this.rep.error("unexpected indent", this.tok), this.skipBlock()) : this.statementRecovering(e);
156
+ return this.kind() === "dedent" && this.next(), e.length === 0 && this.rep.error("a block needs at least one statement", this.t[Math.max(0, this.p - 1)]), e;
157
+ }
158
+ statement() {
159
+ let e = this.tok;
160
+ if (e.kind === "ident" && e.text === "_reserved") throw new b();
161
+ if (this.isKw("if")) return this.ifStmt();
162
+ if (this.isKw("for")) return this.forStmt();
163
+ if (this.isKw("var")) return this.next(), this.declaration(e.from, !0);
164
+ if (e.kind === "ident") {
165
+ let t = this.peek();
166
+ if (_.has(e.text) && t.kind === "ident" && this.isOp("=", this.peek(2)) || this.isOp("=", t)) return this.declaration(e.from, !1);
167
+ if (t.kind === "op" && v.has(t.text)) {
168
+ this.next();
169
+ let t = this.next().text, n = this.expr(), r = this.tok.from;
170
+ return this.endStatement(), {
171
+ k: "assign",
172
+ name: e.text,
173
+ nameSpan: e,
174
+ op: t,
175
+ value: n,
176
+ from: e.from,
177
+ to: Math.max(n.to, r)
178
+ };
179
+ }
180
+ }
181
+ if (this.isOp("[")) {
182
+ let t = [];
183
+ for (this.next();;) {
184
+ this.tok.kind !== "ident" && this.fail(`expected a name, found ${this.describe()}`);
185
+ let e = this.next();
186
+ if (t.push({
187
+ name: e.text,
188
+ span: e
189
+ }), this.isOp(",")) this.next();
190
+ else break;
191
+ }
192
+ this.expectOp("]"), this.expectOp("=", "\"=\" (a tuple of names must be assigned)");
193
+ let n = this.expr();
194
+ return this.endStatement(), {
195
+ k: "tuple",
196
+ names: t,
197
+ init: n,
198
+ from: e.from,
199
+ to: n.to
200
+ };
201
+ }
202
+ let t = this.expr();
203
+ return t.k !== "call" && this.fail("this expression has no effect; a statement is a declaration, an assignment, if, for or a call", t), this.endStatement(), {
204
+ k: "expr",
205
+ expr: t,
206
+ from: t.from,
207
+ to: t.to
208
+ };
209
+ }
210
+ declaration(e, t) {
211
+ let n = null;
212
+ this.tok.kind === "ident" && _.has(this.tok.text) && this.peek().kind === "ident" && (n = this.next().text), this.tok.kind !== "ident" && this.fail(`expected a variable name, found ${this.describe()}`);
213
+ let r = this.next();
214
+ this.expectOp("=");
215
+ let i = this.expr();
216
+ return this.endStatement(), {
217
+ k: "decl",
218
+ isVar: t,
219
+ type: n,
220
+ name: r.text,
221
+ nameSpan: r,
222
+ init: i,
223
+ from: e,
224
+ to: i.to
225
+ };
226
+ }
227
+ ifStmt() {
228
+ let e = this.next(), t = this.expr(), n = this.block(), r = null;
229
+ return this.isKw("else") && (this.next(), r = this.isKw("if") ? [this.ifStmt()] : this.block()), {
230
+ k: "if",
231
+ cond: t,
232
+ then: n,
233
+ else: r,
234
+ from: e.from,
235
+ to: this.t[this.p - 1].to
236
+ };
237
+ }
238
+ forStmt() {
239
+ let e = this.next();
240
+ this.tok.kind !== "ident" && this.fail(`expected a loop variable name, found ${this.describe()}`);
241
+ let t = this.next();
242
+ this.expectOp("=");
243
+ let n = this.expr();
244
+ this.isKw("to") || this.fail(`expected "to", found ${this.describe()}`), this.next();
245
+ let r = this.expr(), i = null;
246
+ this.isKw("by") && (this.next(), i = this.expr());
247
+ let a = this.block();
248
+ return {
249
+ k: "for",
250
+ name: t.text,
251
+ nameSpan: t,
252
+ lo: n,
253
+ hi: r,
254
+ by: i,
255
+ body: a,
256
+ from: e.from,
257
+ to: this.t[this.p - 1].to
258
+ };
259
+ }
260
+ expr() {
261
+ ++this.depth > y && this.fail("expression is nested too deeply");
262
+ try {
263
+ return this.ternary();
264
+ } finally {
265
+ this.depth--;
266
+ }
267
+ }
268
+ ternary() {
269
+ let e = this.or();
270
+ if (!this.isOp("?")) return e;
271
+ this.next();
272
+ let t = this.expr();
273
+ this.expectOp(":", "\":\" of the ternary");
274
+ let n = this.expr();
275
+ return {
276
+ k: "tern",
277
+ c: e,
278
+ a: t,
279
+ b: n,
280
+ from: e.from,
281
+ to: n.to
282
+ };
283
+ }
284
+ or() {
285
+ let e = this.and();
286
+ for (; this.isKw("or");) {
287
+ this.next();
288
+ let t = this.and();
289
+ e = {
290
+ k: "bin",
291
+ op: "or",
292
+ a: e,
293
+ b: t,
294
+ from: e.from,
295
+ to: t.to
296
+ };
297
+ }
298
+ return e;
299
+ }
300
+ and() {
301
+ let e = this.not();
302
+ for (; this.isKw("and");) {
303
+ this.next();
304
+ let t = this.not();
305
+ e = {
306
+ k: "bin",
307
+ op: "and",
308
+ a: e,
309
+ b: t,
310
+ from: e.from,
311
+ to: t.to
312
+ };
313
+ }
314
+ return e;
315
+ }
316
+ not() {
317
+ if (this.isKw("not")) {
318
+ let e = this.next();
319
+ ++this.depth > y && this.fail("expression is nested too deeply");
320
+ try {
321
+ let t = this.not();
322
+ return {
323
+ k: "un",
324
+ op: "not",
325
+ x: t,
326
+ from: e.from,
327
+ to: t.to
328
+ };
329
+ } finally {
330
+ this.depth--;
331
+ }
332
+ }
333
+ return this.cmp();
334
+ }
335
+ cmp() {
336
+ let e = this.add(), t = this.tok;
337
+ if (t.kind === "op" && (t.text === "==" || t.text === "!=" || t.text === "<" || t.text === "<=" || t.text === ">" || t.text === ">=")) {
338
+ this.next();
339
+ let n = this.add(), r = {
340
+ k: "bin",
341
+ op: t.text,
342
+ a: e,
343
+ b: n,
344
+ from: e.from,
345
+ to: n.to
346
+ }, i = this.tok;
347
+ return i.kind === "op" && [
348
+ "==",
349
+ "!=",
350
+ "<",
351
+ "<=",
352
+ ">",
353
+ ">="
354
+ ].includes(i.text) && this.fail("comparisons do not chain; combine them with 'and'", i), r;
355
+ }
356
+ return e;
357
+ }
358
+ add() {
359
+ let e = this.mul();
360
+ for (; this.isOp("+") || this.isOp("-");) {
361
+ let t = this.next().text, n = this.mul();
362
+ e = {
363
+ k: "bin",
364
+ op: t,
365
+ a: e,
366
+ b: n,
367
+ from: e.from,
368
+ to: n.to
369
+ };
370
+ }
371
+ return e;
372
+ }
373
+ mul() {
374
+ let e = this.unary();
375
+ for (; this.isOp("*") || this.isOp("/") || this.isOp("%");) {
376
+ let t = this.next().text, n = this.unary();
377
+ e = {
378
+ k: "bin",
379
+ op: t,
380
+ a: e,
381
+ b: n,
382
+ from: e.from,
383
+ to: n.to
384
+ };
385
+ }
386
+ return e;
387
+ }
388
+ unary() {
389
+ if (this.isOp("-") || this.isOp("+")) {
390
+ let e = this.next();
391
+ ++this.depth > y && this.fail("expression is nested too deeply");
392
+ try {
393
+ let t = this.unary();
394
+ return {
395
+ k: "un",
396
+ op: e.text,
397
+ x: t,
398
+ from: e.from,
399
+ to: t.to
400
+ };
401
+ } finally {
402
+ this.depth--;
403
+ }
404
+ }
405
+ return this.postfix();
406
+ }
407
+ postfix() {
408
+ let e = this.primary();
409
+ for (;;) if (this.isOp("(")) {
410
+ this.next();
411
+ let t = this.args(), n = this.expectOp(")", "\")\" to close the call");
412
+ e = {
413
+ k: "call",
414
+ callee: e,
415
+ args: t,
416
+ from: e.from,
417
+ to: n.to
418
+ };
419
+ } else if (this.isOp("[")) {
420
+ this.next();
421
+ let t = this.expr(), n = this.expectOp("]", "\"]\" to close the index");
422
+ e = {
423
+ k: "idx",
424
+ x: e,
425
+ i: t,
426
+ from: e.from,
427
+ to: n.to
428
+ };
429
+ } else if (this.isOp(".")) {
430
+ this.next(), this.tok.kind !== "ident" && this.fail(`expected a name after ".", found ${this.describe()}`);
431
+ let t = this.next();
432
+ e = {
433
+ k: "mem",
434
+ obj: e,
435
+ name: t.text,
436
+ nameSpan: t,
437
+ from: e.from,
438
+ to: t.to
439
+ };
440
+ } else return e;
441
+ }
442
+ args() {
443
+ let e = [];
444
+ if (this.isOp(")")) return e;
445
+ for (;;) {
446
+ if (this.tok.kind === "ident" && this.isOp("=", this.peek())) {
447
+ let t = this.next();
448
+ this.next(), e.push({
449
+ name: t.text,
450
+ nameSpan: t,
451
+ value: this.expr()
452
+ });
453
+ } else {
454
+ let t = this.expr();
455
+ e.push({
456
+ name: null,
457
+ value: t
458
+ });
459
+ }
460
+ if (this.isOp(",")) this.next();
461
+ else return e;
462
+ }
463
+ }
464
+ primary() {
465
+ let e = this.tok;
466
+ switch (e.kind) {
467
+ case "num": return this.next(), {
468
+ k: "num",
469
+ value: e.value,
470
+ float: /[.eE]/.test(e.text),
471
+ from: e.from,
472
+ to: e.to
473
+ };
474
+ case "str": return this.next(), {
475
+ k: "str",
476
+ value: e.text,
477
+ from: e.from,
478
+ to: e.to
479
+ };
480
+ case "color": return this.next(), {
481
+ k: "color",
482
+ value: e.text,
483
+ from: e.from,
484
+ to: e.to
485
+ };
486
+ case "ident": return this.next(), {
487
+ k: "id",
488
+ name: e.text,
489
+ from: e.from,
490
+ to: e.to
491
+ };
492
+ case "kw":
493
+ if (e.text === "true" || e.text === "false") return this.next(), {
494
+ k: "bool",
495
+ value: e.text === "true",
496
+ from: e.from,
497
+ to: e.to
498
+ };
499
+ break;
500
+ case "op":
501
+ if (e.text === "(") {
502
+ this.next();
503
+ let t = this.expr(), n = this.expectOp(")", "\")\"");
504
+ return {
505
+ ...t,
506
+ from: e.from,
507
+ to: n.to
508
+ };
509
+ }
510
+ if (e.text === "[") {
511
+ this.next();
512
+ let t = [];
513
+ if (!this.isOp("]")) for (; t.push(this.expr()), this.isOp(",");) this.next();
514
+ let n = this.expectOp("]", "\"]\"");
515
+ return {
516
+ k: "arr",
517
+ items: t,
518
+ from: e.from,
519
+ to: n.to
520
+ };
521
+ }
522
+ }
523
+ this.fail(`expected an expression, found ${this.describe()}`);
524
+ }
525
+ };
526
+ function S(e, n) {
527
+ return new x(t(e, n), n).program();
528
+ }
529
+ //#endregion
530
+ //#region src/limits.ts
531
+ var C = Object.freeze({
532
+ maxPeriod: 5e3,
533
+ maxLoopIterations: 1e4,
534
+ maxSteps: 2e6,
535
+ maxColumns: 512,
536
+ maxBytes: 536870912,
537
+ maxBars: 1e7,
538
+ maxFeeds: 8,
539
+ maxSourceChars: 2e5,
540
+ batchMs: 8e3,
541
+ tickMs: 1e3
542
+ }), w = 1e6, T = {
543
+ m: 6e4,
544
+ h: 36e5,
545
+ d: 864e5,
546
+ w: 6048e5
547
+ }, E = /^([1-9][0-9]{0,2})([mhdw])$/;
548
+ function D(e) {
549
+ let t = E.exec(e);
550
+ return t ? Number(t[1]) * T[t[2]] : null;
551
+ }
552
+ function O(e, t) {
553
+ return `${e ?? ""}\u0001${t ?? ""}`;
554
+ }
555
+ function k(e) {
556
+ let t = /* @__PURE__ */ new Map();
557
+ for (let n of e) {
558
+ let e = O(n.symbol, n.timeframe), r = t.get(e);
559
+ r || t.set(e, r = {
560
+ key: e,
561
+ symbol: n.symbol,
562
+ timeframe: n.timeframe,
563
+ fields: []
564
+ }), r.fields.includes(n.field) || r.fields.push(n.field);
565
+ }
566
+ return [...t.values()];
567
+ }
568
+ function A(e, t) {
569
+ if (!(Number.isFinite(t) && t > 0)) throw RangeError(`the chart's bar length must be a positive number of milliseconds, got ${String(t)}`);
570
+ if (e === null) return {
571
+ align: "same",
572
+ spanMs: t
573
+ };
574
+ let n = D(e);
575
+ if (n === null) throw RangeError(`timeframe "${e}" is not written like 5m, 1h, 1d or 1w`);
576
+ if (n < t) throw RangeError(`timeframe "${e}" is shorter than the chart's bars; an outside series must be on the chart's timeframe or a longer one`);
577
+ return n === t ? {
578
+ align: "same",
579
+ spanMs: n
580
+ } : {
581
+ align: "closed",
582
+ spanMs: n
583
+ };
584
+ }
585
+ //#endregion
586
+ //#region src/check.ts
587
+ var j = {
588
+ b: "na",
589
+ q: "const"
590
+ };
591
+ function M(...e) {
592
+ let t = "~";
593
+ for (let n of e) if (n !== "~") {
594
+ if (t === "~") t = n;
595
+ else if (t !== n) return "@";
596
+ }
597
+ return t;
598
+ }
599
+ var N = {
600
+ value: 0,
601
+ ohlc: 1,
602
+ ohlcv: 2
603
+ }, P = {
604
+ const: 0,
605
+ input: 1,
606
+ series: 2
607
+ }, F = (...e) => e.reduce((e, t) => P[t] > P[e] ? t : e, "const"), I = (e) => e.b === "int" || e.b === "float" || e.b === "na", L = (e) => e.q !== "series", R = (e) => e === j ? "na" : e.b === "tuple" ? `a tuple of ${e.elems.length} values (destructure it: [a, b] = ...)` : `${L(e) && e.b !== "na" || e.b === "na" ? "" : "series "}${e.b}`, z = class {
608
+ parent;
609
+ names = /* @__PURE__ */ new Map();
610
+ constructor(e) {
611
+ this.parent = e;
612
+ }
613
+ find(e) {
614
+ for (let t = this; t; t = t.parent) {
615
+ let n = t.names.get(e);
616
+ if (n) return n;
617
+ }
618
+ }
619
+ };
620
+ function B(e, t) {
621
+ for (let n of e) n.k === "assign" ? t.add(n.name) : n.k === "if" ? (B(n.then, t), n.else && B(n.else, t)) : n.k === "for" && B(n.body, t);
622
+ }
623
+ var V = (e) => e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, ""), H = class {
624
+ rep;
625
+ limits;
626
+ plan = {
627
+ title: "Script",
628
+ overlay: !1,
629
+ scale: "right",
630
+ dependencies: [],
631
+ inputs: [],
632
+ plots: [],
633
+ body: [],
634
+ needs: "value",
635
+ slots: 0,
636
+ stateVars: []
637
+ };
638
+ scope = new z(null);
639
+ assigned = /* @__PURE__ */ new Set();
640
+ depth = 0;
641
+ sawIndicator = !1;
642
+ keys = /* @__PURE__ */ new Set();
643
+ loops = 0;
644
+ constructor(e, t = C) {
645
+ this.rep = e, this.limits = t;
646
+ }
647
+ err(e, t) {
648
+ this.rep.error(e, t);
649
+ }
650
+ need(e) {
651
+ N[e] > N[this.plan.needs] && (this.plan.needs = e);
652
+ }
653
+ run(e) {
654
+ B(e.body, this.assigned);
655
+ for (let t of e.body) this.stmt(t, !0);
656
+ this.plan.body = e.body;
657
+ let t = this.plan.plots.find((e) => e.kind === "bgcolor");
658
+ return t && !this.plan.overlay && !this.plan.plots.some((e) => e.kind === "line" || e.kind === "histogram" || e.kind === "area") && this.err("bgcolor shades the pane the script draws in, and with overlay=false the script has a pane only if it plots a line, histogram or area: add a plot(...), or use indicator(..., overlay=true) to shade the price chart", t.span), this.plan;
659
+ }
660
+ declare(t, n, r) {
661
+ this.scope.find(t) ? this.err(`"${t}" is already declared`, r) : Object.prototype.hasOwnProperty.call(c, t) || e.has(t) || t === "na" || t === "nz" || a.has(t) ? this.err(`"${t}" is a built-in name and cannot be redeclared`, r) : (n.decl = r, this.scope.names.set(t, n));
662
+ }
663
+ slot() {
664
+ return this.plan.slots++;
665
+ }
666
+ stmt(e, t) {
667
+ switch (e.k) {
668
+ case "decl": return this.decl(e, t);
669
+ case "tuple": return this.tupleDecl(e, t);
670
+ case "assign": return this.assign(e);
671
+ case "if": return this.ifStmt(e);
672
+ case "for": return this.forStmt(e);
673
+ case "expr": {
674
+ let n = e.expr;
675
+ this.call(n, t ? "stmt" : "expr-block");
676
+ return;
677
+ }
678
+ }
679
+ }
680
+ decl(e, t) {
681
+ if (e.isVar && !t && this.err("'var' is only allowed at the top level of the script", e), e.init.k === "call" && this.calleeName(e.init) !== null && this.calleeName(e.init).startsWith("input.")) {
682
+ if (!t || e.isVar) {
683
+ this.err("input.* may only declare a top-level variable", e.init), this.skipInputArgs(e.init);
684
+ return;
685
+ }
686
+ this.inputDecl(e);
687
+ return;
688
+ }
689
+ let n = e.init.k === "call" ? this.calleeName(e.init) : null;
690
+ if (n === "plot" || n === "hline") {
691
+ if (!t) {
692
+ this.err(`${n}() is only allowed at the top level of the script`, e.init);
693
+ return;
694
+ }
695
+ (e.isVar || e.type) && this.err("a plot handle cannot be declared var or typed", e), this.call(e.init, "decl");
696
+ let i = {
697
+ name: e.name,
698
+ kind: "plot",
699
+ ty: r("plot"),
700
+ key: String(this.plan.plots.length - 1)
701
+ };
702
+ this.declare(e.name, i, e.nameSpan), e.sym = i;
703
+ return;
704
+ }
705
+ let i = this.expr(e.init), a = i;
706
+ if (i.b === "void" && (this.err("this expression has no value", e.init), a = j), i.b === "plot" && (this.err("a plot handle can only come from plot() or hline()", e.init), a = j), i.b === "tuple" && (this.err(`this call returns ${i.elems.length} values; destructure them: [a, b, ...] = ...`, e.init), a = j), e.type) {
707
+ let t = r(e.type, "const");
708
+ if (a !== j && !this.assignable(t, a)) {
709
+ if (t.b === "int" && a.b === "float") {
710
+ let t = ` (declare it float: float ${e.name} = 0.0, or var float ${e.name} = 0.0; there is no int() conversion)`;
711
+ this.err(`cannot assign ${R(a)} to ${e.type} "${e.name}"${t}`, e.init);
712
+ } else this.err(`cannot assign ${R(a)} to ${e.type} "${e.name}"`, e.init);
713
+ }
714
+ a = {
715
+ b: t.b,
716
+ q: a === j ? "series" : a.q
717
+ };
718
+ } else a.b === "na" && a !== j && (this.err(`cannot infer the type of "${e.name}" from na; declare it, e.g. float ${e.name} = na`, e.init), a = j);
719
+ let o = this.assigned.has(e.name);
720
+ if (t) {
721
+ if (e.isVar || o || e.init.st) {
722
+ let t = {
723
+ name: e.name,
724
+ kind: "state",
725
+ ty: {
726
+ b: a.b,
727
+ q: "series"
728
+ },
729
+ isVar: e.isVar,
730
+ slot: this.slot()
731
+ };
732
+ this.declare(e.name, t, e.nameSpan), e.sym = t, this.plan.stateVars.push(t);
733
+ } else {
734
+ let t = {
735
+ name: e.name,
736
+ kind: L(a) ? "simple" : "pure",
737
+ ty: a
738
+ };
739
+ t.kind === "pure" && (t.dom = e.init.dom ?? "@"), this.declare(e.name, t, e.nameSpan), e.sym = t;
740
+ }
741
+ } else {
742
+ let t = {
743
+ name: e.name,
744
+ kind: "local",
745
+ ty: {
746
+ b: a.b,
747
+ q: "series"
748
+ },
749
+ slot: this.slot()
750
+ };
751
+ this.declare(e.name, t, e.nameSpan), e.sym = t;
752
+ }
753
+ }
754
+ tupleDecl(e, t) {
755
+ if (!t) {
756
+ this.err("destructuring is only allowed at the top level of the script", e);
757
+ return;
758
+ }
759
+ let n = this.expr(e.init);
760
+ if (e.syms = [], n === j) for (let t of e.names) this.declare(t.name, {
761
+ name: t.name,
762
+ kind: "pure",
763
+ ty: o
764
+ }, t.span);
765
+ else if (n.b !== "tuple") {
766
+ this.err("only calls that return several values can be destructured", e.init);
767
+ for (let t of e.names) this.declare(t.name, {
768
+ name: t.name,
769
+ kind: "pure",
770
+ ty: o
771
+ }, t.span);
772
+ } else n.elems.length !== e.names.length && this.err(`this call returns ${n.elems.length} values, ${e.names.length} names given`, e), e.names.forEach((t, r) => {
773
+ this.assigned.has(t.name) && this.err(`"${t.name}" is destructured from a call and cannot be assigned with :=`, t.span);
774
+ let i = {
775
+ name: t.name,
776
+ kind: "pure",
777
+ ty: n.elems[r] ?? o,
778
+ dom: e.init.dom ?? "@"
779
+ };
780
+ this.declare(t.name, i, t.span), e.syms.push(i);
781
+ });
782
+ }
783
+ assign(e) {
784
+ let t = this.scope.find(e.name), n = this.expr(e.value);
785
+ if (!t) {
786
+ this.err(`"${e.name}" is not declared; declare it first with ${e.name} = ...`, e.nameSpan);
787
+ return;
788
+ }
789
+ if (e.sym = t, t.kind !== "state" && t.kind !== "local") {
790
+ let n = t.kind === "loop" ? "a loop counter" : t.kind === "input" ? "an input" : t.kind === "builtin" ? "a built-in series" : "not assignable here";
791
+ this.err(`cannot assign to "${e.name}": it is ${n}`, e.nameSpan);
792
+ return;
793
+ }
794
+ if (n === j) return;
795
+ let r = n;
796
+ if (e.op !== ":=") {
797
+ if (!I(t.ty) || !I(n)) {
798
+ this.err(`"${e.op}" needs numbers, got ${R(t.ty)} and ${R(n)}`, e);
799
+ return;
800
+ }
801
+ r = {
802
+ b: t.ty.b === "int" && n.b === "int" && e.op !== "/=" ? "int" : "float",
803
+ q: "series"
804
+ };
805
+ }
806
+ if (!this.assignable(t.ty, r)) {
807
+ if (t.ty.b === "int" && r.b === "float") {
808
+ let n = ` (declare it float: float ${e.name} = 0.0, or var float ${e.name} = 0.0; there is no int() conversion)`;
809
+ this.err(`cannot assign ${R(r)} to ${t.ty.b} "${e.name}"${n}`, e.value);
810
+ } else this.err(`cannot assign ${R(r)} to ${t.ty.b} "${e.name}"`, e.value);
811
+ }
812
+ }
813
+ ifStmt(e) {
814
+ let t = this.expr(e.cond);
815
+ t !== j && t.b !== "bool" && this.err(`the condition of if must be bool, got ${R(t)}`, e.cond), this.block(e.then), e.else && this.block(e.else);
816
+ }
817
+ block(e) {
818
+ let t = this.scope;
819
+ this.scope = new z(t), this.depth++;
820
+ for (let t of e) this.stmt(t, !1);
821
+ this.depth--, this.scope = t;
822
+ }
823
+ forStmt(e) {
824
+ let t = this.expr(e.lo), n = this.expr(e.hi), r = e.by ? this.expr(e.by) : null;
825
+ for (let [i, a] of [
826
+ [t, e.lo],
827
+ [n, e.hi],
828
+ [r, e.by]
829
+ ]) i && i !== j && i.b !== "int" && this.err(`a loop bound must be an int, got ${R(i)}`, a);
830
+ let i = (e) => e === null ? 1 : e.k === "num" ? e.value : e.k === "un" && e.op === "-" && e.x.k === "num" ? -e.x.value : void 0, a = i(e.lo), o = i(e.hi), s = i(e.by);
831
+ if (s === 0 && this.err("the loop step cannot be 0", e.by), a !== void 0 && o !== void 0 && s !== void 0 && s !== 0) {
832
+ let t = e.by ? Math.abs(s) : 1, n = Math.floor(Math.abs(o - a) / t) + 1;
833
+ n > this.limits.maxLoopIterations && this.err(`this loop runs ${n} times; the limit is ${this.limits.maxLoopIterations} iterations per loop`, e);
834
+ }
835
+ this.loops++;
836
+ let c = this.scope;
837
+ this.scope = new z(c);
838
+ let l = {
839
+ name: e.name,
840
+ kind: "loop",
841
+ ty: {
842
+ b: "int",
843
+ q: "series"
844
+ },
845
+ slot: this.slot()
846
+ };
847
+ this.declare(e.name, l, e.nameSpan), e.sym = l, this.depth++;
848
+ for (let t of e.body) this.stmt(t, !1);
849
+ this.depth--, this.scope = c;
850
+ }
851
+ assignable(e, t) {
852
+ return t === j || e === j || t.b === "na" || e.b === t.b || e.b === "float" && t.b === "int";
853
+ }
854
+ expr(e) {
855
+ let t = this.expr_(e);
856
+ return e.ty = t, e.dom = this.domOf(e), t;
857
+ }
858
+ domOf(e) {
859
+ if (e.ty === j || e.st) return "@";
860
+ switch (e.k) {
861
+ case "num":
862
+ case "str":
863
+ case "bool":
864
+ case "color":
865
+ case "arr": return "~";
866
+ case "mem": return e.obj.k === "id" && e.obj.name === "ta" && e.name === "tr" ? "@" : "~";
867
+ case "id": {
868
+ let t = e.sym;
869
+ return !t || t.kind === "simple" ? "~" : t.kind === "input" ? t.ty.b === "float" && t.ty.q === "series" ? "@" : "~" : t.kind === "pure" ? t.dom ?? "@" : "@";
870
+ }
871
+ case "un": return e.x.dom ?? "@";
872
+ case "bin": return M(e.a.dom ?? "@", e.b.dom ?? "@");
873
+ case "tern": return M(e.c.dom ?? "@", e.a.dom ?? "@", e.b.dom ?? "@");
874
+ case "idx": return M(e.x.dom ?? "@", e.i.dom ?? "@");
875
+ case "call": {
876
+ if (e.fn === "outside") return e.own && e.feed ? e.feed : "@";
877
+ let t = e.fn ? a.get(e.fn) : void 0;
878
+ if (!t || !e.bound) return "@";
879
+ let n = [];
880
+ t.params.forEach((t, r) => {
881
+ let i = e.bound[r];
882
+ i && t.kind === "series" && n.push(i.dom ?? "@");
883
+ });
884
+ let r = M(...n);
885
+ return r === "~" && (t.op === "kernel" || t.op === "study" || t.name === "ta.bb") ? "@" : r;
886
+ }
887
+ }
888
+ }
889
+ expr_(e) {
890
+ switch (e.k) {
891
+ case "num": return r(e.float || !Number.isInteger(e.value) ? "float" : "int");
892
+ case "str": return r("string");
893
+ case "bool": return r("bool");
894
+ case "color": return r("color");
895
+ case "arr": return this.err("array values are only allowed as options=[...] of input.string", e), j;
896
+ case "id": return this.ident(e);
897
+ case "mem": return this.member(e);
898
+ case "un": return this.unary(e);
899
+ case "bin": return this.binary(e);
900
+ case "tern": return this.ternary(e);
901
+ case "idx": return this.index(e);
902
+ case "call": return this.call(e, "expr");
903
+ }
904
+ }
905
+ ident(t) {
906
+ let n = this.scope.find(t.name);
907
+ if (n) return t.sym = n, (n.kind === "state" || n.kind === "local" || n.kind === "loop") && (t.st = !0), n.ty;
908
+ let i = c[t.name];
909
+ return i ? (this.need(i.needs), t.sym = {
910
+ name: t.name,
911
+ kind: "builtin",
912
+ ty: i.ty,
913
+ key: t.name
914
+ }, i.ty) : t.name === "na" ? r("na") : e.has(t.name) ? (this.err(`"${t.name}" is a namespace; use ${t.name}.<name>`, t), j) : a.has(t.name) ? (this.err(`"${t.name}" is a function; call it: ${t.name}(...)`, t), j) : (this.err(`unknown name "${t.name}"`, t), j);
915
+ }
916
+ member(t) {
917
+ if (t.obj.k !== "id" || !e.has(t.obj.name) || this.scope.find(t.obj.name)) return this.err("only namespace names can be followed by '.'", t), j;
918
+ let r = `${t.obj.name}.${t.name}`, i = n[r];
919
+ return i ? (t.cv = i.value, i.ty) : r === "ta.tr" ? (this.need("ohlc"), s) : a.has(r) ? (this.err(`"${r}" is a function; call it: ${r}(...)`, t), j) : (this.err(`unknown name "${r}"`, t.nameSpan), j);
920
+ }
921
+ unary(e) {
922
+ let t = this.expr(e.x);
923
+ return e.st = e.x.st ?? !1, t === j ? j : e.op === "not" ? t.b === "bool" ? t : (this.err(`"not" needs a bool, got ${R(t)}`, e), j) : I(t) ? t.b === "na" ? {
924
+ b: "float",
925
+ q: t.q
926
+ } : t : (this.err(`unary "${e.op}" needs a number, got ${R(t)}`, e), j);
927
+ }
928
+ binary(e) {
929
+ let t = this.expr(e.a), n = this.expr(e.b);
930
+ if (e.st = !!(e.a.st || e.b.st), t === j || n === j) return j;
931
+ let r = F(t.q, n.q);
932
+ switch (e.op) {
933
+ case "and":
934
+ case "or": return t.b !== "bool" || n.b !== "bool" ? (this.err(`"${e.op}" needs bool operands, got ${R(t)} and ${R(n)}`, e), j) : {
935
+ b: "bool",
936
+ q: r
937
+ };
938
+ case "==":
939
+ case "!=": return I(t) && I(n) || t.b === n.b && (t.b === "bool" || t.b === "string" || t.b === "color") ? (t.b === "string" || t.b === "color") && r === "series" ? (this.err("strings and colors can only be compared as constants or inputs", e), j) : {
940
+ b: "bool",
941
+ q: r
942
+ } : (this.err(`cannot compare ${R(t)} with ${R(n)}`, e), j);
943
+ case "<":
944
+ case "<=":
945
+ case ">":
946
+ case ">=": return !I(t) || !I(n) ? (this.err(`"${e.op}" needs numbers, got ${R(t)} and ${R(n)}`, e), j) : {
947
+ b: "bool",
948
+ q: r
949
+ };
950
+ default: return !I(t) || !I(n) ? (this.err(`"${e.op}" needs numbers, got ${R(t)} and ${R(n)}${t.b === "bool" || n.b === "bool" ? " (a bool is not a number: use a ternary)" : ""}`, e), j) : {
951
+ b: t.b === "int" && n.b === "int" && e.op !== "/" ? "int" : "float",
952
+ q: r
953
+ };
954
+ }
955
+ }
956
+ ternary(e) {
957
+ let t = this.expr(e.c), n = this.expr(e.a), r = this.expr(e.b);
958
+ if (e.st = !!(e.c.st || e.a.st || e.b.st), t !== j && t.b !== "bool" && this.err(`the condition of ?: must be bool, got ${R(t)}`, e.c), n === j || r === j) return j;
959
+ let i = F(t === j ? "const" : t.q, n.q, r.q);
960
+ return n.b === "na" ? {
961
+ b: r.b,
962
+ q: i
963
+ } : r.b === "na" ? {
964
+ b: n.b,
965
+ q: i
966
+ } : I(n) && I(r) ? {
967
+ b: n.b === "int" && r.b === "int" ? "int" : "float",
968
+ q: i
969
+ } : n.b === "string" && r.b === "string" && i === "series" ? (this.err("a string cannot depend on a series: the condition of ?: must be a constant or an input (a string is a label, not a value that changes per bar)", e), j) : n.b === r.b ? {
970
+ b: n.b,
971
+ q: i
972
+ } : (this.err(`the branches of ?: have different types: ${R(n)} and ${R(r)}`, e), j);
973
+ }
974
+ historyOk(e) {
975
+ return !e.st || e.k === "id" && e.sym?.kind === "state";
976
+ }
977
+ index(e) {
978
+ let t = this.expr(e.x), n = this.expr(e.i);
979
+ if (e.st = !!(e.x.st || e.i.st), t === j || n === j) return j;
980
+ if (t.q !== "series" || !(I(t) || t.b === "bool")) return this.err(`only a series can be indexed with [ ], this is ${R(t)}`, e.x), j;
981
+ if (n.b !== "int") return this.err(`the history offset must be an int, got ${R(n)}`, e.i), j;
982
+ if (!this.historyOk(e.x)) return this.err("history [ ] needs a plain series or a top-level variable; a block variable, loop counter or an expression of those has no earlier values. Assign the value to a top-level variable first", e.x), j;
983
+ let r = e.i.k === "num" ? e.i.value : e.i.k === "un" && e.i.op === "-" && e.i.x.k === "num" ? -e.i.x.value : void 0;
984
+ return r !== void 0 && (r < 0 || r > 1e6) && this.err(`the history offset must be between 0 and ${w}, got ${r}`, e.i), {
985
+ b: t.b,
986
+ q: "series"
987
+ };
988
+ }
989
+ calleeName(e) {
990
+ return e.callee.k === "id" ? e.callee.name : e.callee.k === "mem" && e.callee.obj.k === "id" ? `${e.callee.obj.name}.${e.callee.name}` : null;
991
+ }
992
+ skipInputArgs(e) {
993
+ for (let t of e.args) this.expr(t.value);
994
+ }
995
+ bind(e, t) {
996
+ let n = e.params.map(() => null), r = 0, i = !1;
997
+ for (let a of t.args) if (a.name === null) {
998
+ if (i) {
999
+ this.err("positional arguments must come before named ones", a.value);
1000
+ continue;
1001
+ }
1002
+ if (r >= e.params.length) return this.err(`${e.name} takes at most ${e.params.length} argument${e.params.length === 1 ? "" : "s"}, got ${t.args.length}`, a.value), n;
1003
+ n[r++] = a.value;
1004
+ } else {
1005
+ i = !0;
1006
+ let t = e.params.findIndex((e) => e.name === a.name);
1007
+ if (t < 0) {
1008
+ this.err(`${e.name} has no parameter "${a.name}" (parameters: ${e.params.map((e) => e.name).join(", ") || "none"})`, a.nameSpan ?? a.value);
1009
+ continue;
1010
+ }
1011
+ if (n[t]) {
1012
+ this.err(`parameter "${a.name}" is given twice`, a.nameSpan ?? a.value);
1013
+ continue;
1014
+ }
1015
+ n[t] = a.value;
1016
+ }
1017
+ return e.params.forEach((r, i) => {
1018
+ !r.opt && !n[i] && !(r.kind === "series" && 0) && this.err(`${e.name} needs the argument "${r.name}"`, t);
1019
+ }), n;
1020
+ }
1021
+ constVal(e) {
1022
+ switch (e.k) {
1023
+ case "num": return e.value;
1024
+ case "str": return e.value;
1025
+ case "bool": return e.value;
1026
+ case "color": return e.value;
1027
+ case "mem": return e.cv;
1028
+ case "un": return e.op === "-" && e.x.k === "num" ? -e.x.value : void 0;
1029
+ default: return;
1030
+ }
1031
+ }
1032
+ checkParam(e, t, n) {
1033
+ let r = n.ty ?? this.expr(n);
1034
+ if (r === j) return;
1035
+ let a = `argument "${t.name}" of ${e.name}`, o = () => {
1036
+ L(r) || this.err(`${a} must be a literal or an input, not a series value`, n);
1037
+ };
1038
+ switch (t.kind) {
1039
+ case "series":
1040
+ I(r) || this.err(`${a} must be a number series, got ${R(r)}`, n);
1041
+ break;
1042
+ case "any":
1043
+ (r.b === "void" || r.b === "plot" || r.b === "tuple") && this.err(`${a} must be a value`, n);
1044
+ break;
1045
+ case "num":
1046
+ if (!I(r) || r.b === "na") {
1047
+ this.err(`${a} must be a number, got ${R(r)}`, n);
1048
+ break;
1049
+ }
1050
+ o();
1051
+ break;
1052
+ case "int":
1053
+ if (r.b !== "int") {
1054
+ this.err(`${a} must be an int, got ${R(r)}`, n);
1055
+ break;
1056
+ }
1057
+ o();
1058
+ break;
1059
+ case "bool":
1060
+ case "string":
1061
+ case "color":
1062
+ if (r.b !== t.kind) {
1063
+ this.err(`${a} must be a ${t.kind}, got ${R(r)}`, n);
1064
+ break;
1065
+ }
1066
+ if (e.name === "plot" && t.name === "color" && n.k === "tern") break;
1067
+ if (o(), t.oneOf) {
1068
+ let e = this.constVal(n);
1069
+ typeof e == "string" && !t.oneOf.includes(e) && this.err(`${a} must be one of ${t.oneOf.map((e) => JSON.stringify(e)).join(", ")}, got ${JSON.stringify(e)}`, n);
1070
+ }
1071
+ break;
1072
+ case "enum": {
1073
+ let e = this.constVal(n);
1074
+ if (typeof e != "string" || !t.oneOf.includes(e) || n.k !== "mem") {
1075
+ let e = t.oneOf === i.plotStyle ? "plot.style_*" : t.oneOf === i.lineStyle ? "hline.style_*" : t.oneOf === i.shape ? "shape.*" : "location.*";
1076
+ this.err(`${a} must be one of ${e}`, n);
1077
+ }
1078
+ break;
1079
+ }
1080
+ case "strlist": break;
1081
+ case "plot": (n.k !== "id" || n.sym?.kind !== "plot") && this.err(`${a} must be a plot handle: p = plot(...)`, n);
1082
+ }
1083
+ let s = this.constVal(n);
1084
+ typeof s == "number" && (t.kind === "int" || t.kind === "num") && (t.min !== void 0 && s < t.min || t.max !== void 0 && s > t.max) && this.err(`${a} must be between ${t.min ?? "-inf"} and ${t.max ?? "inf"}, got ${s}`, n);
1085
+ }
1086
+ call(e, t) {
1087
+ let n = this.calleeName(e);
1088
+ if (n === null) {
1089
+ this.err("only named functions can be called", e.callee);
1090
+ for (let t of e.args) this.expr(t.value);
1091
+ return j;
1092
+ }
1093
+ let r = a.get(n);
1094
+ if (!r) {
1095
+ for (let t of e.args) this.expr(t.value);
1096
+ let t = [...a.keys()].filter((e) => e.endsWith(`.${n.split(".").pop()}`) || e === n.split(".").pop());
1097
+ return (n === "security" || n === "request.security") && t.unshift("outside"), this.err(`unknown function "${n}"${t.length ? `; did you mean ${t.slice(0, 3).join(", ")}?` : ""}`, e.callee), j;
1098
+ }
1099
+ if (e.fn = n, (n === "plot" || n === "hline" || n === "fill" || n === "plotshape" || n === "indicator" || n === "barcolor" || n === "bgcolor") && (this.depth > 0 || t === "expr" || t === "expr-block" ? this.err(`${n}() is only allowed as a statement at the top level of the script`, e) : t === "decl" && n !== "plot" && n !== "hline" && this.err(`${n}() does not return a handle`, e)), n.startsWith("input.") && t !== "decl") {
1100
+ this.err("input.* may only be the whole right-hand side of a top-level declaration: name = input.int(...)", e);
1101
+ for (let t of e.args) this.expr(t.value);
1102
+ return j;
1103
+ }
1104
+ let i = this.bind(r, e);
1105
+ e.bound = i, r.params.forEach((e, t) => {
1106
+ let n = i[t];
1107
+ n && e.kind !== "strlist" && this.expr(n);
1108
+ }), r.params.forEach((e, t) => {
1109
+ let n = i[t];
1110
+ n && e.kind !== "strlist" && this.checkParam(r, e, n);
1111
+ });
1112
+ let o = !1;
1113
+ for (let e of i) e?.st && (o = !0);
1114
+ e.st = o, r.needs && this.need(r.needs);
1115
+ let s = r.ret;
1116
+ switch (r.op) {
1117
+ case "kernel":
1118
+ case "study": return r.params.forEach((e, t) => {
1119
+ let n = i[t];
1120
+ n && n.st && e.kind === "series" && this.err(`argument "${e.name}" of ${r.name} depends on a variable that is declared var, assigned with :=, or is a block variable / loop counter. ${r.name} runs over whole columns, so its inputs must be known before the bar is evaluated`, n);
1121
+ }), e.st = !1, r.op === "study" && this.studySources(r, i), s;
1122
+ case "scalar": return {
1123
+ b: "float",
1124
+ q: F(...i.filter((e) => !!e).map((e) => e.ty.q))
1125
+ };
1126
+ case "special": return this.special(r, e, i, t, s);
1127
+ }
1128
+ }
1129
+ studySources(e, t) {}
1130
+ special(e, t, n, i, a) {
1131
+ let o = (t) => n[e.params.findIndex((e) => e.name === t)] ?? null;
1132
+ switch (e.name) {
1133
+ case "nz": {
1134
+ let e = o("replacement");
1135
+ return {
1136
+ b: "float",
1137
+ q: F(o("x").ty.q, e?.ty?.q ?? "const")
1138
+ };
1139
+ }
1140
+ case "na": return {
1141
+ b: "bool",
1142
+ q: o("x").ty.q
1143
+ };
1144
+ case "math.sum": return a;
1145
+ case "ta.change": {
1146
+ let e = o("source");
1147
+ return this.historyOk(e) || this.err("ta.change needs a plain series or a top-level variable, not an expression of changing variables", e), t.st = !!e.st, {
1148
+ b: "float",
1149
+ q: "series"
1150
+ };
1151
+ }
1152
+ case "ta.crossover":
1153
+ case "ta.crossunder":
1154
+ case "ta.cross":
1155
+ for (let t of [o("a"), o("b")]) this.historyOk(t) || this.err(`${e.name} needs plain series or top-level variables, not expressions of changing variables; assign the value to a variable first`, t);
1156
+ return t.st = !!(o("a").st || o("b").st), {
1157
+ b: "bool",
1158
+ q: "series"
1159
+ };
1160
+ case "ta.bb":
1161
+ for (let e of n) if (e?.st && e.ty.q === "series") {
1162
+ this.err("ta.bb needs inputs known before the bar is evaluated (no var / := / block variables)", e);
1163
+ break;
1164
+ }
1165
+ return t.st = !1, a;
1166
+ case "color.new": return r("color", F(...n.map((e) => e.ty.q)));
1167
+ case "indicator": return this.indicator(t, n);
1168
+ case "plot": return this.plot(t, n);
1169
+ case "hline": return this.hline(t, n);
1170
+ case "fill": return this.fill(t, n);
1171
+ case "plotshape": return this.plotshape(t, n);
1172
+ case "barcolor":
1173
+ case "bgcolor": return this.shade(e.name, t, n);
1174
+ case "outside": return this.outside(t, n, a);
1175
+ default: return e.name.startsWith("input.") ? r("void") : a;
1176
+ }
1177
+ }
1178
+ str(e) {
1179
+ if (!e) return;
1180
+ let t = this.constVal(e);
1181
+ if (typeof t == "string") return t;
1182
+ e.ty && e.ty !== j && e.ty.b === "string" && this.err("this must be a string literal", e);
1183
+ }
1184
+ int(e) {
1185
+ if (!e) return;
1186
+ let t = this.constVal(e);
1187
+ if (typeof t == "number") return t;
1188
+ e.ty && e.ty !== j && I(e.ty) && this.err("this must be a number literal", e);
1189
+ }
1190
+ offsetArg(e) {
1191
+ if (!e) return {};
1192
+ let t = this.constVal(e);
1193
+ return typeof t == "number" ? { offset: t } : e.ty && e.ty !== j && e.ty.b === "int" && L(e.ty) ? { offsetExpr: e } : {};
1194
+ }
1195
+ indicator(e, t) {
1196
+ this.sawIndicator && this.err("indicator() may be called only once", e), this.sawIndicator = !0;
1197
+ let n = this.str(t[0]);
1198
+ n !== void 0 && (this.plan.title = n);
1199
+ let i = this.str(t[1]);
1200
+ if (i !== void 0 && (this.plan.title = i), t[2]) {
1201
+ let e = this.constVal(t[2]);
1202
+ typeof e == "boolean" ? this.plan.overlay = e : t[2].ty && t[2].ty !== j && this.err("overlay must be true or false", t[2]);
1203
+ }
1204
+ let a = this.str(t[3]);
1205
+ return (a === "left" || a === "right") && (this.plan.scale = a), r("void");
1206
+ }
1207
+ colorRef(e, t) {
1208
+ if (!e || e.ty === j) return { value: t };
1209
+ let n = this.constVal(e);
1210
+ if (typeof n == "string" && e.ty?.b === "color") return { value: n };
1211
+ if (e.k === "id" && e.sym?.kind === "input" && e.sym.ty.b === "color") return { input: e.sym.key };
1212
+ if (e.k === "call" && e.fn === "color.new") {
1213
+ let n = this.colorRef(e.bound[0], t), r = e.bound[1] ? this.constVal(e.bound[1]) : void 0;
1214
+ if ("value" in n && typeof r == "number") return { value: U(n.value, r) };
1215
+ }
1216
+ return this.err("a color here must be a constant (color.red, #rrggbb, color.new(...)) or an input.color variable", e), { value: t };
1217
+ }
1218
+ nextKey(e, t) {
1219
+ let n = V(e) || `plot${t}`;
1220
+ /^[0-9]/.test(n) && (n = `p-${n}`);
1221
+ let r = n, i = 2;
1222
+ for (; this.keys.has(r);) r = `${n}-${i++}`;
1223
+ return this.keys.add(r), r;
1224
+ }
1225
+ plot(e, t) {
1226
+ let n = this.plan.plots.length;
1227
+ n >= 64 && this.err("a script may draw at most 64 plots", e);
1228
+ let i = this.str(t[1]) ?? `Plot ${n + 1}`, a = (t[4] ? this.constVal(t[4]) : void 0) ?? "line", o = this.int(t[3]), s = this.offsetArg(t[5]), c = t[6] ? this.colorRef(t[6], "#f23645") : void 0;
1229
+ c && "input" in c && this.err("color_down must be a constant color", t[6]);
1230
+ let l = [
1231
+ "#2962ff",
1232
+ "#ff6d00",
1233
+ "#089981",
1234
+ "#f23645",
1235
+ "#9c27b0",
1236
+ "#fbc02d"
1237
+ ][n % 6], u = t[2], d, f;
1238
+ if (u && u.k === "tern" && u.c.ty && u.c.ty !== j && u.c.ty.q === "series" && u.ty && u.ty.b === "color") {
1239
+ let e = this.colorRef(u.a, l), t = this.colorRef(u.b, l);
1240
+ a === "line" ? (!("value" in e) || !("value" in t)) && this.err("both colors of a color that depends on the bar must be constants (color.red, #rrggbb, color.new(...)), not an input.color", u) : this.err("a color that depends on the bar is for line plots; histogram and area take a constant color (a histogram can use color_down for negative values)", u), d = "value" in t ? t : { value: l }, "value" in e && "value" in t && a === "line" && (f = {
1241
+ cond: u.c,
1242
+ color: e.value
1243
+ });
1244
+ } else d = this.colorRef(u, l);
1245
+ return this.plan.plots.push({
1246
+ kind: a,
1247
+ key: this.nextKey(i, n + 1),
1248
+ title: i,
1249
+ color: d,
1250
+ expr: t[0],
1251
+ ...o !== void 0 && { width: o },
1252
+ ...s,
1253
+ ...c && "value" in c && { colorDown: c.value },
1254
+ ...f && { colorWhen: f },
1255
+ span: e
1256
+ }), r("plot");
1257
+ }
1258
+ shade(e, t, n) {
1259
+ let i = this.plan.plots.length;
1260
+ i >= 64 && this.err("a script may draw at most 64 plots", t);
1261
+ let a = n[0];
1262
+ a.ty && a.ty !== j && a.ty.b !== "bool" && this.err(`${e} needs a bool condition, got ${R(a.ty)}`, a);
1263
+ let o = `${e === "barcolor" ? "Bar color" : "Background"} ${i + 1}`;
1264
+ return this.plan.plots.push({
1265
+ kind: e,
1266
+ key: this.nextKey(o, i + 1),
1267
+ title: o,
1268
+ color: this.colorRef(n[1], e === "barcolor" ? "#fdd835" : "#2962ff33"),
1269
+ expr: a,
1270
+ span: t
1271
+ }), r("void");
1272
+ }
1273
+ outside(e, t, n) {
1274
+ let r = (e, t) => {
1275
+ if (!e || e.k === "id" && e.name === "na" && !e.sym) return null;
1276
+ if (e.k === "str") return e.value;
1277
+ e.ty && e.ty !== j && this.err(`the ${t} of outside() must be a string literal${t === "timeframe" ? " like \"1d\"" : ""}, or na for this chart's, not a computed value`, e);
1278
+ }, i = r(t[0], "symbol"), a = r(t[2], "timeframe");
1279
+ if (i === void 0 || a === void 0) return n;
1280
+ if (i !== null && (i.length < 1 || i.length > 128 || /[\u0000-\u001f]/.test(i))) return this.err("the symbol of outside() must be 1 to 128 printable characters", t[0]), n;
1281
+ if (a !== null && D(a) === null) return this.err(`the timeframe "${a}" is not written like 5m, 15m, 1h, 4h, 1d or 1w`, t[2]), n;
1282
+ if (i === null && a === null) return this.err("outside() needs a symbol or a timeframe; this chart's own series are close, open, high, low and volume", e), n;
1283
+ let o = (t[1] ? this.constVal(t[1]) : void 0) ?? "close";
1284
+ return e.feed = O(i, a), e.own = a !== null, this.plan.dependencies.some((e) => e.symbol === i && e.timeframe === a && e.field === o) || (this.plan.dependencies.push({
1285
+ symbol: i,
1286
+ field: o,
1287
+ timeframe: a
1288
+ }), k(this.plan.dependencies).length > this.limits.maxFeeds && this.err(`a script may read at most ${this.limits.maxFeeds} outside series (distinct symbol and timeframe pairs)`, e)), n;
1289
+ }
1290
+ hline(e, t) {
1291
+ let n = this.plan.plots.length, i = this.str(t[1]) ?? `Level ${n + 1}`, a = t[3] ? this.constVal(t[3]) : void 0;
1292
+ return this.plan.plots.push({
1293
+ kind: "hline",
1294
+ key: this.nextKey(i, n + 1),
1295
+ title: i,
1296
+ color: this.colorRef(t[2], "#787b86"),
1297
+ expr: t[0],
1298
+ ...a && { lineStyle: a },
1299
+ span: e
1300
+ }), r("plot");
1301
+ }
1302
+ fill(e, t) {
1303
+ let n = this.plan.plots.length, i = this.str(t[3]) ?? `Fill ${n + 1}`, a = (e) => e && e.k === "id" && e.sym?.kind === "plot" ? Number(e.sym.key) : void 0, o = a(t[0]), s = a(t[1]);
1304
+ for (let [e, n] of [[o, t[0]], [s, t[1]]]) {
1305
+ if (e === void 0) continue;
1306
+ let t = this.plan.plots[e];
1307
+ t.kind === "hline" ? t.column = !0 : t.kind !== "line" && this.err("fill needs line plots or hline levels (not histogram, area or markers)", n);
1308
+ }
1309
+ return o !== void 0 && o === s && this.err("fill needs two different plots", e), this.plan.plots.push({
1310
+ kind: "fill",
1311
+ key: this.nextKey(i, n + 1),
1312
+ title: i,
1313
+ color: this.colorRef(t[2], "#2962ff33"),
1314
+ ...o !== void 0 && { a: o },
1315
+ ...s !== void 0 && { b: s },
1316
+ span: e
1317
+ }), r("void");
1318
+ }
1319
+ plotshape(e, t) {
1320
+ let n = this.plan.plots.length, i = t[0], a = this.str(t[1]) ?? `Shape ${n + 1}`, o = (t[2] ? this.constVal(t[2]) : void 0) ?? "circle", s = (t[3] ? this.constVal(t[3]) : void 0) ?? "above", c = i.ty;
1321
+ c && c !== j && (c.b === "bool" && s === "value" ? this.err("location.absolute needs a number (the price to mark), not a bool", i) : c.b !== "bool" && s !== "value" ? this.err("plotshape marks bars where a bool is true; for a number use location=location.absolute", i) : c.b !== "bool" && !I(c) && this.err(`plotshape needs a bool or a number, got ${R(c)}`, i));
1322
+ let l = this.offsetArg(t[5]), u = this.int(t[6]), d = this.int(t[7]);
1323
+ return this.plan.plots.push({
1324
+ kind: "markers",
1325
+ key: this.nextKey(a, n + 1),
1326
+ title: a,
1327
+ color: this.colorRef(t[4], "#2962ff"),
1328
+ expr: i,
1329
+ shape: o,
1330
+ position: s,
1331
+ ...l,
1332
+ ...u !== void 0 && { last: u },
1333
+ ...d !== void 0 && { within: d },
1334
+ span: e
1335
+ }), r("void");
1336
+ }
1337
+ inputDecl(e) {
1338
+ let t = e.init, n = this.calleeName(t), i = a.get(n);
1339
+ if (!i) {
1340
+ this.err(`unknown function "${n}"`, t.callee), this.skipInputArgs(t);
1341
+ return;
1342
+ }
1343
+ t.fn = n;
1344
+ let s = this.bind(i, t);
1345
+ t.bound = s;
1346
+ let c = n.slice(6), u = (e) => i.params.findIndex((t) => t.name === e), d = (e) => s[u(e)] ?? null;
1347
+ i.params.forEach((e, t) => {
1348
+ let r = s[t];
1349
+ r && (e.kind === "strlist" ? (r.k !== "arr" || r.items.length === 0 || r.items.some((e) => e.k !== "str")) && this.err("options must be a non-empty list of string literals: options=[\"a\", \"b\"]", r) : (n !== "input.source" || e.name !== "defval") && (this.expr(r), this.checkParam(i, e, r), r.ty && r.ty !== j && r.ty.q !== "const" && e.kind !== "series" && this.err(`${e.name} of ${n} must be a literal`, r)));
1350
+ });
1351
+ let f = 0, p = d("defval"), m = this.str(d("title")) ?? e.name, h = {
1352
+ key: e.name,
1353
+ kind: c,
1354
+ label: m,
1355
+ default: 0,
1356
+ span: e.nameSpan
1357
+ };
1358
+ if (p) {
1359
+ if (n === "input.source") p.k === "id" && l.includes(p.name) && !this.scope.find(p.name) ? (f = p.name, p.ty = o, this.need(p.name === "close" ? "value" : "ohlc")) : this.err(`the default of input.source must be one of ${l.join(", ")}`, p);
1360
+ else {
1361
+ let e = this.constVal(p);
1362
+ e !== void 0 && (f = e);
1363
+ }
1364
+ }
1365
+ if (h.default = f, c === "int" || c === "float") {
1366
+ let e = d("minval") ? this.int(d("minval")) : void 0, n = d("maxval") ? this.int(d("maxval")) : void 0, r = d("step") ? this.int(d("step")) : void 0;
1367
+ e !== void 0 && (h.min = e), n !== void 0 && (h.max = n), r !== void 0 && (r <= 0 ? this.err("step must be positive", d("step")) : h.step = r), typeof f == "number" && (e !== void 0 && f < e || n !== void 0 && f > n) && this.err(`the default ${f} is outside [${e ?? "-inf"}, ${n ?? "inf"}]`, p), e !== void 0 && n !== void 0 && e > n && this.err("minval is above maxval", t);
1368
+ }
1369
+ if (c === "string") {
1370
+ let e = d("options"), t = e && e.k === "arr" ? e.items.filter((e) => e.k === "str").map((e) => e.value) : [];
1371
+ h.options = t, t.length > 0 && !t.includes(f) && this.err(`the default "${String(f)}" is not one of the options`, p);
1372
+ }
1373
+ c === "color" && typeof f == "string" && !/^#[0-9a-f]{6}([0-9a-f]{2})?$/.test(f) && this.err("the default must be a color", p), this.plan.inputs.push(h);
1374
+ let g = c === "source" ? o : r(c === "string" ? "string" : c, "input"), _ = {
1375
+ name: e.name,
1376
+ kind: "input",
1377
+ ty: g,
1378
+ key: e.name
1379
+ };
1380
+ this.declare(e.name, _, e.nameSpan), e.sym = _, e.init.ty = g;
1381
+ }
1382
+ };
1383
+ function U(e, t) {
1384
+ let n = e.slice(1);
1385
+ return `rgba(${parseInt(n.slice(0, 2), 16)},${parseInt(n.slice(2, 4), 16)},${parseInt(n.slice(4, 6), 16)},${Math.round((1 - t / 100) * 1e3) / 1e3})`;
1386
+ }
1387
+ function W(e, t, n = C) {
1388
+ return new H(t, n).run(e);
1389
+ }
1390
+ //#endregion
1391
+ //#region src/codegen.ts
1392
+ var G = NaN, K = (e) => e === e && e !== 0;
1393
+ function q(e) {
1394
+ let t = 2166136261;
1395
+ for (let n = 0; n < e.length; n++) t = Math.imul(t ^ e.charCodeAt(n), 16777619) >>> 0;
1396
+ return t.toString(16).padStart(8, "0");
1397
+ }
1398
+ function ee(e, t, n = C) {
1399
+ let r = [], i = [];
1400
+ for (let t of e.inputs) switch (t.kind) {
1401
+ case "int":
1402
+ r.push({
1403
+ key: t.key,
1404
+ label: t.label,
1405
+ type: "int",
1406
+ default: t.default,
1407
+ ...t.min !== void 0 && { min: t.min },
1408
+ ...t.max !== void 0 && { max: t.max },
1409
+ step: t.step ?? 1
1410
+ });
1411
+ break;
1412
+ case "float":
1413
+ r.push({
1414
+ key: t.key,
1415
+ label: t.label,
1416
+ type: "float",
1417
+ default: t.default,
1418
+ ...t.min !== void 0 && { min: t.min },
1419
+ ...t.max !== void 0 && { max: t.max },
1420
+ ...t.step !== void 0 && { step: t.step }
1421
+ });
1422
+ break;
1423
+ case "bool":
1424
+ r.push({
1425
+ key: t.key,
1426
+ label: t.label,
1427
+ type: "bool",
1428
+ default: t.default
1429
+ });
1430
+ break;
1431
+ case "string":
1432
+ r.push({
1433
+ key: t.key,
1434
+ label: t.label,
1435
+ type: "select",
1436
+ default: t.default,
1437
+ options: t.options
1438
+ });
1439
+ break;
1440
+ case "source":
1441
+ r.push({
1442
+ key: t.key,
1443
+ label: t.label,
1444
+ type: "source",
1445
+ default: t.default,
1446
+ options: l
1447
+ });
1448
+ break;
1449
+ case "color": i.push({
1450
+ key: t.key,
1451
+ label: t.label,
1452
+ default: t.default,
1453
+ plotKeys: []
1454
+ });
1455
+ }
1456
+ let a = (t) => e.inputs.find((e) => e.key === t).default, o = [], s = [], c = /* @__PURE__ */ new Map();
1457
+ return e.plots.forEach((t, r) => {
1458
+ let l = "value" in t.color ? t.color.value : a(t.color.input);
1459
+ "input" in t.color && i.find((e) => e.key === t.color.input).plotKeys.push(t.key);
1460
+ let u = {
1461
+ key: t.key,
1462
+ title: t.title
1463
+ };
1464
+ switch (t.kind) {
1465
+ case "line": {
1466
+ o.push(t.key);
1467
+ let i = t.colorWhen ? `${t.key}~when` : void 0;
1468
+ i && o.push(i), c.set(r, t.key), s.push({
1469
+ kind: "line",
1470
+ ...u,
1471
+ col: t.key,
1472
+ color: l,
1473
+ ...t.width !== void 0 && { width: t.width },
1474
+ ...J(t, e, n),
1475
+ ...i && { colorBy: {
1476
+ col: i,
1477
+ color: t.colorWhen.color
1478
+ } }
1479
+ });
1480
+ break;
1481
+ }
1482
+ case "barcolor":
1483
+ o.push(t.key), s.push({
1484
+ kind: "barcolor",
1485
+ ...u,
1486
+ col: t.key,
1487
+ color: l
1488
+ });
1489
+ break;
1490
+ case "bgcolor":
1491
+ o.push(t.key), s.push({
1492
+ kind: "bgcolor",
1493
+ ...u,
1494
+ col: t.key,
1495
+ color: l
1496
+ });
1497
+ break;
1498
+ case "histogram":
1499
+ o.push(t.key), s.push({
1500
+ kind: "histogram",
1501
+ ...u,
1502
+ col: t.key,
1503
+ color: l,
1504
+ ...t.colorDown && { colorDown: t.colorDown }
1505
+ });
1506
+ break;
1507
+ case "area":
1508
+ o.push(t.key), s.push({
1509
+ kind: "area",
1510
+ ...u,
1511
+ col: t.key,
1512
+ color: l
1513
+ });
1514
+ break;
1515
+ case "markers":
1516
+ o.push(t.key), s.push({
1517
+ kind: "markers",
1518
+ ...u,
1519
+ col: t.key,
1520
+ shape: t.shape,
1521
+ position: t.position,
1522
+ color: l,
1523
+ ...J(t, e, n),
1524
+ ...t.last !== void 0 && { last: t.last },
1525
+ ...t.within !== void 0 && { within: t.within }
1526
+ });
1527
+ break;
1528
+ case "hline":
1529
+ if (t.column) {
1530
+ let e = `${t.key}~level`;
1531
+ o.push(e), c.set(r, e);
1532
+ }
1533
+ s.push({
1534
+ kind: "hline",
1535
+ ...u,
1536
+ value: (r) => new Y(null, r, e, n).simpleNumber(t.expr),
1537
+ color: l,
1538
+ style: t.lineStyle ?? "dashed"
1539
+ });
1540
+ break;
1541
+ case "fill": s.push({
1542
+ kind: "fill",
1543
+ ...u,
1544
+ a: c.get(t.a),
1545
+ b: c.get(t.b),
1546
+ color: l
1547
+ });
1548
+ }
1549
+ }), {
1550
+ def: {
1551
+ id: `script-${q(t)}`,
1552
+ name: e.title,
1553
+ family: "tv",
1554
+ inputs: r,
1555
+ needs: e.needs,
1556
+ pane: e.overlay ? "overlay" : "new",
1557
+ ...e.scale === "left" && { scale: "left" },
1558
+ columns: o,
1559
+ plots: s,
1560
+ build: (t, r) => new Y(t, r, e, n).build(),
1561
+ reference: "alphacharts script"
1562
+ },
1563
+ colorInputs: i
1564
+ };
1565
+ }
1566
+ function J(e, t, n) {
1567
+ if (e.offsetExpr) {
1568
+ let r = e.offsetExpr;
1569
+ return { offset: (i) => {
1570
+ let a = new Y(null, i, t, n).simpleNumber(r);
1571
+ if (!Number.isInteger(a) || a < -5e3 || a > 5e3) throw new h(`offset must be a whole number between -5000 and 5000, got ${a}`, e.span, "runtime");
1572
+ return a;
1573
+ } };
1574
+ }
1575
+ return e.offset === void 0 ? {} : { offset: e.offset };
1576
+ }
1577
+ var Y = class {
1578
+ g;
1579
+ p;
1580
+ plan;
1581
+ limits;
1582
+ simple = /* @__PURE__ */ new Map();
1583
+ pure = /* @__PURE__ */ new Map();
1584
+ stateCols = /* @__PURE__ */ new Map();
1585
+ hoisted = /* @__PURE__ */ new Map();
1586
+ mats = /* @__PURE__ */ new Map();
1587
+ inits = /* @__PURE__ */ new Map();
1588
+ S;
1589
+ ctx = { steps: 0 };
1590
+ tr = null;
1591
+ bpy = null;
1592
+ fx;
1593
+ joinedCols = /* @__PURE__ */ new Map();
1594
+ sameCols = /* @__PURE__ */ new Map();
1595
+ constructor(e, t, n, r) {
1596
+ this.g = e, this.p = t, this.plan = n, this.limits = r, this.fx = {
1597
+ g: e,
1598
+ key: null
1599
+ }, this.S = new Float64Array(n.slots);
1600
+ for (let e of n.body) e.k === "decl" && e.sym && this.inits.set(e.sym, e.init);
1601
+ }
1602
+ G() {
1603
+ if (!this.fx.g) throw new h("a series is not available here");
1604
+ return this.fx.g;
1605
+ }
1606
+ feedDom(e) {
1607
+ let t = e.dom;
1608
+ return t !== void 0 && t !== "@" && t !== "~" ? t : null;
1609
+ }
1610
+ inFeed(e, t) {
1611
+ let n = this.fx;
1612
+ this.fx = {
1613
+ g: this.g.feed(e).graph,
1614
+ key: e
1615
+ };
1616
+ try {
1617
+ return t();
1618
+ } finally {
1619
+ this.fx = n;
1620
+ }
1621
+ }
1622
+ joinedCol(e, t) {
1623
+ let n = this.inFeed(e, () => this.colOf(t)), r = this.joinedCols.get(n);
1624
+ return r || this.joinedCols.set(n, r = this.G().joined(e, n)), r;
1625
+ }
1626
+ rawCol(e) {
1627
+ let t = e.bound[1], n = t && t.k === "str" ? t.value : "close";
1628
+ if (this.fx.key !== null) return this.G()[n];
1629
+ let r = `${e.feed}\u0002${n}`, i = this.sameCols.get(r);
1630
+ return i || this.sameCols.set(r, i = this.G().external(e.feed, n)), i;
1631
+ }
1632
+ build() {
1633
+ let e = this.G(), t = [];
1634
+ for (let e of this.plan.body) switch (e.k) {
1635
+ case "decl": {
1636
+ let n = e.sym;
1637
+ if (n.kind === "state") t.push(e);
1638
+ else if (n.kind === "pure") {
1639
+ let t = this.feedDom(e.init);
1640
+ this.pure.set(n, t ? this.inFeed(t, () => this.colOf(e.init)) : this.colOf(e.init));
1641
+ }
1642
+ break;
1643
+ }
1644
+ case "tuple": {
1645
+ let t = this.feedDom(e.init), n = t ? this.inFeed(t, () => this.hoist(e.init)) : this.hoist(e.init);
1646
+ e.syms.forEach((e, t) => this.pure.set(e, n[t]));
1647
+ break;
1648
+ }
1649
+ case "assign":
1650
+ case "if":
1651
+ case "for": t.push(e);
1652
+ }
1653
+ (t.length > 0 || this.plan.stateVars.length > 0) && this.buildExec(t);
1654
+ let n = [];
1655
+ for (let t of this.plan.plots) if (t.kind === "hline" && t.column) {
1656
+ let r = this.simpleNumber(t.expr);
1657
+ n.push(e.calc(() => r));
1658
+ } else t.kind !== "hline" && t.kind !== "fill" && (t.kind === "markers" || t.kind === "barcolor" || t.kind === "bgcolor" ? n.push(this.markers(t)) : (n.push(this.colOf(t.expr)), t.colorWhen && n.push(this.colOf(t.colorWhen.cond))));
1659
+ let r = e.cols.length;
1660
+ for (let t of e.feeds.values()) r += t.graph.cols.length;
1661
+ if (r > this.limits.maxColumns) throw new h(`the script needs ${r} columns; the limit is ${this.limits.maxColumns}`);
1662
+ return n;
1663
+ }
1664
+ markers(e) {
1665
+ let t = e.expr, n = this.ev(t, "col"), r = e.position === "value";
1666
+ return this.G().calc(r ? n : (e) => K(n(e)) ? 1 : G);
1667
+ }
1668
+ buildExec(e) {
1669
+ let t = this.G();
1670
+ for (let e of this.plan.stateVars) this.stateCols.set(e, t.col());
1671
+ let n = e.map((e) => this.stmt(e)), r = this.S, i = this.ctx;
1672
+ this.limits.maxSteps;
1673
+ let a = this.plan.stateVars.map((e) => ({
1674
+ slot: e.slot,
1675
+ col: this.stateCols.get(e),
1676
+ restore: !!e.isVar
1677
+ }));
1678
+ t.node((e, t, o) => {
1679
+ for (let e = t; e < o; e++) {
1680
+ i.steps = 0;
1681
+ for (let t of a) t.restore && (r[t.slot] = e > 0 ? t.col.v[e - 1] : G);
1682
+ for (let t of n) t(e);
1683
+ for (let t of a) t.col.v[e] = r[t.slot];
1684
+ }
1685
+ });
1686
+ }
1687
+ step(e) {
1688
+ if (++this.ctx.steps > this.limits.maxSteps) throw new h(`execution budget exceeded: more than ${this.limits.maxSteps} loop steps in one bar`, e, "budget");
1689
+ }
1690
+ stmt(e) {
1691
+ let t = this.S;
1692
+ switch (e.k) {
1693
+ case "decl": {
1694
+ let n = this.ev(e.init, "exec"), r = e.sym.slot;
1695
+ return e.isVar ? (e) => {
1696
+ e === 0 && (t[r] = n(e));
1697
+ } : (e) => {
1698
+ t[r] = n(e);
1699
+ };
1700
+ }
1701
+ case "assign": {
1702
+ let n = this.ev(e.value, "exec"), r = e.sym.slot;
1703
+ switch (e.op) {
1704
+ case ":=": return (e) => {
1705
+ t[r] = n(e);
1706
+ };
1707
+ case "+=": return (e) => {
1708
+ t[r] = t[r] + n(e);
1709
+ };
1710
+ case "-=": return (e) => {
1711
+ t[r] = t[r] - n(e);
1712
+ };
1713
+ case "*=": return (e) => {
1714
+ t[r] = t[r] * n(e);
1715
+ };
1716
+ case "/=": return (e) => {
1717
+ let i = n(e);
1718
+ t[r] = i === 0 ? G : t[r] / i;
1719
+ };
1720
+ default: return (e) => {
1721
+ let i = n(e);
1722
+ t[r] = i === 0 ? G : t[r] % i;
1723
+ };
1724
+ }
1725
+ }
1726
+ case "if": {
1727
+ let t = this.ev(e.cond, "exec"), n = e.then.map((e) => this.stmt(e)), r = (e.else ?? []).map((e) => this.stmt(e));
1728
+ return (e) => {
1729
+ for (let i of K(t(e)) ? n : r) i(e);
1730
+ };
1731
+ }
1732
+ case "for": {
1733
+ let n = this.ev(e.lo, "exec"), r = this.ev(e.hi, "exec"), i = e.by ? this.ev(e.by, "exec") : null, a = e.body.map((e) => this.stmt(e)), o = e.sym.slot, s = this.limits.maxLoopIterations;
1734
+ return (c) => {
1735
+ let l = n(c), u = r(c), d = i ? i(c) : l <= u ? 1 : -1;
1736
+ if (!Number.isFinite(l) || !Number.isFinite(u) || !Number.isFinite(d) || d === 0) throw new h("loop bounds must be finite and the step non-zero", e, "runtime");
1737
+ if (i && (d > 0 && l > u || d < 0 && l < u)) return;
1738
+ !i && l > u && (d = -1);
1739
+ let f = Math.floor(Math.abs(u - l) / Math.abs(d)) + 1;
1740
+ if (f > s) throw new h(`this loop would run ${f} times; the limit is ${s} iterations per loop`, e, "budget");
1741
+ let p = l;
1742
+ for (let n = 0; n < f; n++, p += d) {
1743
+ this.step(e), t[o] = p;
1744
+ for (let e of a) e(c);
1745
+ }
1746
+ };
1747
+ }
1748
+ default: return () => {};
1749
+ }
1750
+ }
1751
+ srcCol(e) {
1752
+ let t = this.G();
1753
+ switch (e) {
1754
+ case "volume": return t.volume;
1755
+ case "time": return t.time;
1756
+ case "bar_index": return t.calc((e) => e);
1757
+ case "bars_per_year": return this.fx.key === null ? this.bpy ??= t.barsPerYear() : t.barsPerYear();
1758
+ default: return t.src(e);
1759
+ }
1760
+ }
1761
+ colOf(e) {
1762
+ let t = this.feedDom(e);
1763
+ if (t && this.fx.key === null) return this.joinedCol(t, e);
1764
+ if (e.k === "call" && e.fn === "outside") return this.rawCol(e);
1765
+ let n = this.G();
1766
+ if (e.k === "id" && e.sym) {
1767
+ let t = e.sym;
1768
+ if (t.kind === "builtin") return this.memo(e, () => this.srcCol(t.key));
1769
+ if (t.kind === "pure") return this.pure.get(t);
1770
+ if (t.kind === "state") return this.stateCols.get(t);
1771
+ if (t.kind === "input" && t.ty.b === "float" && t.ty.q === "series") return this.srcCol(String(this.p[t.key]));
1772
+ }
1773
+ return e.k === "call" && this.isHoisted(e) ? this.hoist(e)[0] : this.memo(e, () => {
1774
+ let t = this.ev(e, "col");
1775
+ return n.calc(t);
1776
+ });
1777
+ }
1778
+ memo(e, t) {
1779
+ let n = this.mats.get(e);
1780
+ return n || this.mats.set(e, n = t()), n;
1781
+ }
1782
+ isHoisted(e) {
1783
+ let t = a.get(e.fn);
1784
+ return !!t && (t.op === "kernel" || t.op === "study" || t.name === "ta.bb");
1785
+ }
1786
+ num(e, t, n, r, i = !0) {
1787
+ let a = this.ev(e, "col")(0);
1788
+ if (!Number.isFinite(a) || i && !Number.isInteger(a) || a < n || a > r) throw new h(`${t} must be ${i ? "an integer" : "a number"} between ${n} and ${r}, got ${a}`, e, "build");
1789
+ return a;
1790
+ }
1791
+ hoist(e) {
1792
+ let t = this.hoisted.get(e);
1793
+ if (t) return t;
1794
+ let n = a.get(e.fn), r = e.bound, i = this.G(), o = this.limits.maxPeriod, s, c = (e) => this.num(r[e], `the length of ${n.name}`, 1, o);
1795
+ switch (n.name) {
1796
+ case "ta.sma":
1797
+ s = [i.sma(this.colOf(r[0]), c(1))];
1798
+ break;
1799
+ case "ta.ema":
1800
+ s = [i.ema(this.colOf(r[0]), c(1))];
1801
+ break;
1802
+ case "ta.wma":
1803
+ s = [i.wma(this.colOf(r[0]), c(1))];
1804
+ break;
1805
+ case "ta.rma":
1806
+ s = [i.rma(this.colOf(r[0]), c(1))];
1807
+ break;
1808
+ case "ta.highest":
1809
+ s = [i.highest(this.colOf(r[0]), c(1))];
1810
+ break;
1811
+ case "ta.lowest":
1812
+ s = [i.lowest(this.colOf(r[0]), c(1))];
1813
+ break;
1814
+ case "ta.highestbars":
1815
+ s = [i.highestBars(this.colOf(r[0]), c(1))];
1816
+ break;
1817
+ case "ta.lowestbars":
1818
+ s = [i.lowestBars(this.colOf(r[0]), c(1))];
1819
+ break;
1820
+ case "ta.stdev":
1821
+ case "ta.variance": {
1822
+ let e = !!r[2] && K(this.ev(r[2], "col")(0)), t = e ? this.num(r[1], `the length of ${n.name} with sample=true`, 2, o) : c(1);
1823
+ s = [n.name === "ta.stdev" ? i.stdev(this.colOf(r[0]), t, e) : i.variance(this.colOf(r[0]), t, e)];
1824
+ break;
1825
+ }
1826
+ case "ta.sum":
1827
+ case "math.sum":
1828
+ s = [i.sum(this.colOf(r[0]), c(1))];
1829
+ break;
1830
+ case "ta.linreg": {
1831
+ let e = this.num(r[1], "the length of ta.linreg", 2, o);
1832
+ s = [i.linreg(this.colOf(r[0]), e).value];
1833
+ break;
1834
+ }
1835
+ case "ta.atr":
1836
+ s = [i.atr(c(0))];
1837
+ break;
1838
+ case "ta.bb": {
1839
+ let e = a.get("ta.bbands").study, t = this.num(r[2], "mult of ta.bb", 0, 100, !1), n = this.runStudy(e, {
1840
+ length: c(1),
1841
+ multUp: t,
1842
+ multDn: t
1843
+ }, this.colOf(r[0]));
1844
+ s = [
1845
+ n[1],
1846
+ n[0],
1847
+ n[2]
1848
+ ];
1849
+ break;
1850
+ }
1851
+ default: s = this.hoistStudy(n, e);
1852
+ }
1853
+ return this.hoisted.set(e, s), s;
1854
+ }
1855
+ hoistStudy(e, t) {
1856
+ let n = e.study, r = {}, i = null;
1857
+ e.params.forEach((n, a) => {
1858
+ let o = t.bound[a];
1859
+ if (!o) return;
1860
+ let s = n.input;
1861
+ if (s.type === "source") {
1862
+ i = this.colOf(o);
1863
+ return;
1864
+ }
1865
+ if (s.type === "select") {
1866
+ r[s.key] = this.str(o);
1867
+ return;
1868
+ }
1869
+ if (s.type === "bool") {
1870
+ r[s.key] = K(this.ev(o, "col")(0));
1871
+ return;
1872
+ }
1873
+ let c = this.ev(o, "col")(0);
1874
+ if (!Number.isFinite(c) || s.type === "int" && !Number.isInteger(c) || s.min !== void 0 && c < s.min || s.max !== void 0 && c > s.max) throw new h(`${s.key} of ${e.name} must be ${s.type === "int" ? "an integer" : "a number"}${s.min === void 0 ? "" : ` >= ${s.min}`}${s.max === void 0 ? "" : ` <= ${s.max}`}, got ${c}`, o);
1875
+ r[s.key] = c;
1876
+ });
1877
+ try {
1878
+ return this.runStudy(n, r, i);
1879
+ } catch (n) {
1880
+ throw n instanceof h ? n : new h(`${e.name}: ${n instanceof Error ? n.message : String(n)}`, t);
1881
+ }
1882
+ }
1883
+ runStudy(e, t, n) {
1884
+ let r = f(e, t), i = Object.create(this.G());
1885
+ return n && (i.src = () => n), [...e.build(i, r)];
1886
+ }
1887
+ str(e) {
1888
+ switch (e.k) {
1889
+ case "str": return e.value;
1890
+ case "color": return e.value;
1891
+ case "mem": return String(e.cv);
1892
+ case "id": {
1893
+ let t = e.sym;
1894
+ if (t.kind === "input") return String(this.p[t.key]);
1895
+ if (t.kind === "simple") return String(this.simpleVal(t));
1896
+ break;
1897
+ }
1898
+ case "tern": return K(this.ev(e.c, "col")(0)) ? this.str(e.a) : this.str(e.b);
1899
+ case "call": if (e.fn === "color.new") return String(this.simpleVal2(e));
1900
+ }
1901
+ throw new h("this string cannot be evaluated here", e);
1902
+ }
1903
+ simpleVal2(e) {
1904
+ return String(e.fn);
1905
+ }
1906
+ simpleVal(e) {
1907
+ let t = this.simple.get(e);
1908
+ if (t !== void 0) return t;
1909
+ let n = this.inits.get(e), r = n.ty.b === "string" || n.ty.b === "color" ? this.str(n) : this.ev(n, "col")(0);
1910
+ return this.simple.set(e, r), r;
1911
+ }
1912
+ simpleNumber(e) {
1913
+ return this.ev(e, "col")(0);
1914
+ }
1915
+ hist(e, t, n, r) {
1916
+ let i = this.S, a = (e) => {
1917
+ throw new h(`the history offset must be an integer between 0 and ${w}, got ${e}`, r, "runtime");
1918
+ };
1919
+ if (e.k === "id" && e.sym?.kind === "state" && n === "exec") {
1920
+ let n = e.sym.slot, r = this.stateCols.get(e.sym);
1921
+ return (e) => {
1922
+ let o = t(e);
1923
+ return !Number.isInteger(o) || o < 0 || o > 1e6 ? a(o) : o === 0 ? i[n] : e - o >= 0 ? r.v[e - o] : G;
1924
+ };
1925
+ }
1926
+ let o = this.colOf(e);
1927
+ return (e) => {
1928
+ let n = t(e);
1929
+ return !Number.isInteger(n) || n < 0 || n > 1e6 ? a(n) : e - n >= 0 ? o.v[e - n] : G;
1930
+ };
1931
+ }
1932
+ ev(e, t) {
1933
+ let n = this.S, r = this.feedDom(e);
1934
+ if (r && this.fx.key === null) {
1935
+ let t = this.joinedCol(r, e);
1936
+ return (e) => t.v[e];
1937
+ }
1938
+ switch (e.k) {
1939
+ case "num": {
1940
+ let t = e.value;
1941
+ return () => t;
1942
+ }
1943
+ case "bool": {
1944
+ let t = +!!e.value;
1945
+ return () => t;
1946
+ }
1947
+ case "str":
1948
+ case "color":
1949
+ case "arr": throw new h("a string or color is not a number", e);
1950
+ case "id": {
1951
+ let r = e.sym;
1952
+ if (!r) return () => G;
1953
+ switch (r.kind) {
1954
+ case "builtin": {
1955
+ if (r.key === "bar_index") return (e) => e;
1956
+ let e = this.srcCol(r.key);
1957
+ return (t) => e.v[t];
1958
+ }
1959
+ case "input": {
1960
+ if (r.ty.b === "float" && r.ty.q === "series") {
1961
+ let e = this.srcCol(String(this.p[r.key]));
1962
+ return (t) => e.v[t];
1963
+ }
1964
+ let t = this.p[r.key];
1965
+ if (typeof t == "string") throw new h("a string is not a number", e);
1966
+ let n = typeof t == "boolean" ? +!!t : t;
1967
+ return () => n;
1968
+ }
1969
+ case "simple": {
1970
+ let t = this.simpleVal(r);
1971
+ if (typeof t == "string") throw new h("a string is not a number", e);
1972
+ return () => t;
1973
+ }
1974
+ case "pure": {
1975
+ let e = this.pure.get(r);
1976
+ return (t) => e.v[t];
1977
+ }
1978
+ case "state": {
1979
+ if (t === "exec") {
1980
+ let e = r.slot;
1981
+ return () => n[e];
1982
+ }
1983
+ let e = this.stateCols.get(r);
1984
+ return (t) => e.v[t];
1985
+ }
1986
+ case "local":
1987
+ case "loop": {
1988
+ let e = r.slot;
1989
+ return () => n[e];
1990
+ }
1991
+ default: throw new h("this name has no numeric value", e);
1992
+ }
1993
+ }
1994
+ case "mem":
1995
+ if (typeof e.cv == "number") {
1996
+ let t = e.cv;
1997
+ return () => t;
1998
+ }
1999
+ if (e.obj.k === "id" && e.name === "tr") {
2000
+ let e = this.tr ??= this.G().tr();
2001
+ return (t) => e.v[t];
2002
+ }
2003
+ throw new h("this name has no numeric value", e);
2004
+ case "un": {
2005
+ let n = this.ev(e.x, t);
2006
+ return e.op === "-" ? (e) => -n(e) : e.op === "+" ? n : (e) => +!K(n(e));
2007
+ }
2008
+ case "bin": return this.binary(e, t);
2009
+ case "tern": {
2010
+ let n = this.ev(e.c, t), r = this.ev(e.a, t), i = this.ev(e.b, t);
2011
+ return (e) => K(n(e)) ? r(e) : i(e);
2012
+ }
2013
+ case "idx": {
2014
+ let n = this.ev(e.i, t);
2015
+ return this.hist(e.x, n, t, e);
2016
+ }
2017
+ case "call": return this.callEv(e, t);
2018
+ }
2019
+ }
2020
+ binary(e, t) {
2021
+ let n = e.a.ty, r = e.b.ty;
2022
+ if ((e.op === "==" || e.op === "!=") && (n.b === "string" || n.b === "color") && n.b === r.b) {
2023
+ let t = this.str(e.a) === this.str(e.b), n = +(e.op === "==" === t);
2024
+ return () => n;
2025
+ }
2026
+ let i = this.ev(e.a, t), a = this.ev(e.b, t);
2027
+ switch (e.op) {
2028
+ case "+": return (e) => i(e) + a(e);
2029
+ case "-": return (e) => i(e) - a(e);
2030
+ case "*": return (e) => i(e) * a(e);
2031
+ case "/": return (e) => {
2032
+ let t = a(e);
2033
+ return t === 0 ? G : i(e) / t;
2034
+ };
2035
+ case "%": return (e) => {
2036
+ let t = a(e);
2037
+ return t === 0 ? G : i(e) % t;
2038
+ };
2039
+ case "<": return (e) => +(i(e) < a(e));
2040
+ case "<=": return (e) => +(i(e) <= a(e));
2041
+ case ">": return (e) => +(i(e) > a(e));
2042
+ case ">=": return (e) => +(i(e) >= a(e));
2043
+ case "==": return (e) => +(i(e) === a(e));
2044
+ case "!=": return (e) => {
2045
+ let t = i(e), n = a(e);
2046
+ return +(t === t && n === n && t !== n);
2047
+ };
2048
+ case "and": return (e) => K(i(e)) && K(a(e)) ? 1 : 0;
2049
+ case "or": return (e) => K(i(e)) || K(a(e)) ? 1 : 0;
2050
+ default: throw new h(`unknown operator ${e.op}`, e);
2051
+ }
2052
+ }
2053
+ callEv(e, t) {
2054
+ let n = a.get(e.fn), r = e.bound;
2055
+ if (n.name === "outside") {
2056
+ let t = this.rawCol(e);
2057
+ return (e) => t.v[e];
2058
+ }
2059
+ if (this.isHoisted(e)) {
2060
+ let t = this.hoist(e)[0];
2061
+ return (e) => t.v[e];
2062
+ }
2063
+ switch (n.name) {
2064
+ case "nz": {
2065
+ let e = this.ev(r[0], t), n = r[1] ? this.ev(r[1], t) : () => 0;
2066
+ return (t) => {
2067
+ let r = e(t);
2068
+ return r === r ? r : n(t);
2069
+ };
2070
+ }
2071
+ case "na": {
2072
+ let e = this.ev(r[0], t);
2073
+ return (t) => {
2074
+ let n = e(t);
2075
+ return n === n ? 0 : 1;
2076
+ };
2077
+ }
2078
+ case "ta.change": {
2079
+ let n = this.ev(r[0], t), i = this.hist(r[0], r[1] ? this.ev(r[1], t) : () => 1, t, e);
2080
+ return (e) => n(e) - i(e);
2081
+ }
2082
+ case "ta.crossover":
2083
+ case "ta.crossunder":
2084
+ case "ta.cross": {
2085
+ let i = this.ev(r[0], t), a = this.ev(r[1], t), o = this.hist(r[0], () => 1, t, e), s = this.hist(r[1], () => 1, t, e), c = (e) => i(e) > a(e) && o(e) <= s(e), l = (e) => i(e) < a(e) && o(e) >= s(e);
2086
+ return n.name === "ta.crossover" ? (e) => +!!c(e) : n.name === "ta.crossunder" ? (e) => +!!l(e) : (e) => c(e) || l(e) ? 1 : 0;
2087
+ }
2088
+ case "color.new": throw new h("a color is not a number", e);
2089
+ default:
2090
+ if (n.op === "scalar") {
2091
+ let e = n.fn, i = r.map((e) => this.ev(e, t));
2092
+ if (i.length === 1) {
2093
+ let t = i[0];
2094
+ return (n) => e(t(n));
2095
+ }
2096
+ let a = i[0], o = i[1];
2097
+ return (t) => e(a(t), o(t));
2098
+ }
2099
+ throw new h(`${n.name} cannot be used as a value here`, e);
2100
+ }
2101
+ }
2102
+ };
2103
+ //#endregion
2104
+ //#region src/compile.ts
2105
+ function X(e, t = C) {
2106
+ if (typeof e != "string") return {
2107
+ ok: !1,
2108
+ diagnostics: [{
2109
+ severity: "error",
2110
+ message: "the script must be a string",
2111
+ line: 1,
2112
+ column: 1,
2113
+ endLine: 1,
2114
+ endColumn: 1,
2115
+ from: 0,
2116
+ to: 0
2117
+ }]
2118
+ };
2119
+ if (e.length > t.maxSourceChars) return {
2120
+ ok: !1,
2121
+ diagnostics: [{
2122
+ severity: "error",
2123
+ message: `the script is ${e.length} characters; the limit is ${t.maxSourceChars}`,
2124
+ line: 1,
2125
+ column: 1,
2126
+ endLine: 1,
2127
+ endColumn: 1,
2128
+ from: 0,
2129
+ to: 0
2130
+ }]
2131
+ };
2132
+ let n = new m(e), r = S(e, n), i = null;
2133
+ if (n.errorCount === 0 && (i = W(r, n, t)), n.errorCount === 0 && i && i.plots.length === 0 && n.error("the script draws nothing: add plot(...)", {
2134
+ from: 0,
2135
+ to: Math.min(e.length, 1)
2136
+ }), n.errorCount > 0 || !i) return {
2137
+ ok: !1,
2138
+ diagnostics: n.list
2139
+ };
2140
+ let { def: a, colorInputs: o } = ee(i, e, t);
2141
+ return {
2142
+ ok: !0,
2143
+ study: a,
2144
+ colorInputs: o,
2145
+ inputs: i.inputs,
2146
+ title: i.title,
2147
+ diagnostics: n.list,
2148
+ source: e,
2149
+ plan: {
2150
+ overlay: i.overlay,
2151
+ scale: i.scale,
2152
+ dependencies: i.dependencies,
2153
+ needs: i.needs,
2154
+ plots: i.plots.map((e) => ({
2155
+ kind: e.kind,
2156
+ title: e.title,
2157
+ expr: e.expr ?? null
2158
+ })),
2159
+ body: i.body
2160
+ }
2161
+ };
2162
+ }
2163
+ //#endregion
2164
+ //#region src/sandbox.ts
2165
+ var Z = [
2166
+ "fetch",
2167
+ "XMLHttpRequest",
2168
+ "WebSocket",
2169
+ "WebTransport",
2170
+ "EventSource",
2171
+ "importScripts",
2172
+ "indexedDB",
2173
+ "caches",
2174
+ "BroadcastChannel",
2175
+ "SharedWorker",
2176
+ "Worker",
2177
+ "MessageChannel",
2178
+ "Request",
2179
+ "Response",
2180
+ "localStorage",
2181
+ "sessionStorage",
2182
+ "FileReader",
2183
+ "FileReaderSync",
2184
+ "Notification",
2185
+ "navigator",
2186
+ "location",
2187
+ "document",
2188
+ "window",
2189
+ "XMLHttpRequestUpload",
2190
+ "RTCPeerConnection"
2191
+ ];
2192
+ function te(e = globalThis) {
2193
+ let t = [], n = [];
2194
+ for (let r of Z) try {
2195
+ Object.defineProperty(e, r, {
2196
+ value: void 0,
2197
+ writable: !1,
2198
+ configurable: !1,
2199
+ enumerable: !1
2200
+ }), t.push(r);
2201
+ } catch {
2202
+ n.push(r);
2203
+ }
2204
+ let r = e, i = (e) => () => {
2205
+ throw Error(`${e} is not available to scripts`);
2206
+ };
2207
+ try {
2208
+ Object.defineProperty(e, "eval", {
2209
+ value: i("eval"),
2210
+ writable: !1,
2211
+ configurable: !1
2212
+ });
2213
+ } catch {
2214
+ n.push("eval");
2215
+ }
2216
+ if (r.Math) try {
2217
+ Object.defineProperty(r.Math, "random", {
2218
+ value: i("Math.random"),
2219
+ writable: !1,
2220
+ configurable: !1
2221
+ });
2222
+ } catch {
2223
+ n.push("Math.random");
2224
+ }
2225
+ if (r.Date) try {
2226
+ Object.defineProperty(r.Date, "now", {
2227
+ value: i("Date.now"),
2228
+ writable: !1,
2229
+ configurable: !1
2230
+ });
2231
+ } catch {
2232
+ n.push("Date.now");
2233
+ }
2234
+ let a = e;
2235
+ for (let e of [
2236
+ "Object",
2237
+ "Array",
2238
+ "Function",
2239
+ "String",
2240
+ "Number",
2241
+ "Boolean"
2242
+ ]) {
2243
+ let t = a[e]?.prototype;
2244
+ t && Object.freeze(t);
2245
+ }
2246
+ return {
2247
+ blocked: t,
2248
+ missing: n
2249
+ };
2250
+ }
2251
+ var ne = () => new Promise((e) => setTimeout(e, 0)), re = 65536;
2252
+ function Q(e) {
2253
+ return e instanceof h ? {
2254
+ message: e.message,
2255
+ ...e.span && {
2256
+ from: e.span.from,
2257
+ to: e.span.to
2258
+ },
2259
+ kind: e.kind
2260
+ } : {
2261
+ message: e instanceof Error ? e.message : String(e),
2262
+ kind: "build"
2263
+ };
2264
+ }
2265
+ function $(e, t, n = !1) {
2266
+ return {
2267
+ ...e,
2268
+ build: (r, i) => {
2269
+ let a = r;
2270
+ n && (a = Object.create(r), a.node = () => r.node(() => {}));
2271
+ let o = e.build(a, i);
2272
+ return r.node((e, n, r) => {
2273
+ t && r - n === 1 && t(n);
2274
+ }), o;
2275
+ }
2276
+ };
2277
+ }
2278
+ function ie(e) {
2279
+ let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set();
2280
+ return (a) => {
2281
+ let o = a;
2282
+ switch (o.type) {
2283
+ case "cancel":
2284
+ r.has(o.id) && n.add(o.id);
2285
+ return;
2286
+ case "dispose":
2287
+ t.delete(o.sid), i.add(o.sid);
2288
+ return;
2289
+ case "bar": {
2290
+ let n = t.get(o.sid);
2291
+ if (!n) {
2292
+ e({
2293
+ type: "tick-error",
2294
+ sid: o.sid,
2295
+ error: {
2296
+ message: "the script has no computed state in this worker (it was restarted); change an input to run it again",
2297
+ kind: "runtime"
2298
+ }
2299
+ });
2300
+ return;
2301
+ }
2302
+ try {
2303
+ let t = n.length, r = t > 0 ? n.graph.time.v[t - 1] : NaN;
2304
+ if (t > 0 && o.bar.time === r ? n.reviseLast(o.bar) : n.push(o.bar), n.length - 1 !== o.index) throw new h(`out of sync with the chart: bar ${o.index} arrived with ${n.length} bars computed`);
2305
+ let i = new Float64Array(n.outputs.length);
2306
+ n.outputs.forEach((e, t) => i[t] = e.v[o.index]), e({
2307
+ type: "values",
2308
+ sid: o.sid,
2309
+ index: o.index,
2310
+ values: i
2311
+ }, [i.buffer]);
2312
+ } catch (t) {
2313
+ e({
2314
+ type: "tick-error",
2315
+ sid: o.sid,
2316
+ error: Q(t)
2317
+ });
2318
+ }
2319
+ return;
2320
+ }
2321
+ case "feed-bar": {
2322
+ let n = t.get(o.sid);
2323
+ if (!n) {
2324
+ e({
2325
+ type: "tick-error",
2326
+ sid: o.sid,
2327
+ error: {
2328
+ message: "the script has no computed state in this worker (it was restarted); change an input to run it again",
2329
+ kind: "runtime"
2330
+ }
2331
+ });
2332
+ return;
2333
+ }
2334
+ try {
2335
+ if (!n.graph.feeds.has(o.key)) throw new h(`this script reads no outside series "${o.key}"`);
2336
+ if (!n.pushFeed(o.key, o.bar)) {
2337
+ e({
2338
+ type: "idle",
2339
+ sid: o.sid
2340
+ });
2341
+ return;
2342
+ }
2343
+ let t = n.length, r = new Float64Array(n.outputs.length);
2344
+ n.outputs.forEach((e, n) => r[n] = e.v[t - 1]), e({
2345
+ type: "values",
2346
+ sid: o.sid,
2347
+ index: t - 1,
2348
+ values: r
2349
+ }, [r.buffer]);
2350
+ } catch (t) {
2351
+ e({
2352
+ type: "tick-error",
2353
+ sid: o.sid,
2354
+ error: Q(t)
2355
+ });
2356
+ }
2357
+ return;
2358
+ }
2359
+ case "run":
2360
+ r.add(o.id), (async () => {
2361
+ try {
2362
+ let r = {
2363
+ ...C,
2364
+ ...o.limits
2365
+ }, a = X(o.source, r);
2366
+ if (!a.ok) throw new h(a.diagnostics.map((e) => `${e.line}:${e.column}: ${e.message}`).join("; "));
2367
+ let s = o.bars.time.length;
2368
+ if (s > r.maxBars) throw new h(`${s} bars exceed the limit of ${r.maxBars}`, null, "budget");
2369
+ let c = new u($(a.study), o.params), l = Object.entries(o.feeds ?? {});
2370
+ if (l.length > r.maxFeeds) throw new h(`${l.length} outside series exceed the limit of ${r.maxFeeds}`, null, "budget");
2371
+ let d = 0, f = 0, p = 0;
2372
+ for (let [e, t] of l) {
2373
+ let n = t.bars.time.length;
2374
+ if (n > r.maxBars) throw new h(`an outside series has ${n} bars; the limit is ${r.maxBars}`, null, "budget");
2375
+ let i = c.graph.feeds.get(e)?.graph.cols.length ?? 6;
2376
+ f += n, p += i, d += n * i * 8 * 3 + n * 6 * 8;
2377
+ }
2378
+ let m = c.graph.cols.length * s * 8 * 3 + d;
2379
+ if (m > r.maxBytes) {
2380
+ let e = `${(m / 2 ** 20).toFixed(0)} MiB`, t = `${(r.maxBytes / 2 ** 20).toFixed(0)} MiB`;
2381
+ throw l.length === 0 ? new h(`the script needs ${e} (3 x ${c.graph.cols.length} columns x ${s} bars x 8); the limit is ${t}`, null, "budget") : new h(`the script and its ${l.length} outside series need ${e} (3 x ${c.graph.cols.length} columns x ${s} bars x 8, and 3 x ${p} columns of ${f} outside bars in all, x 8, with a copy of their bars); the limit is ${t}`, null, "budget");
2382
+ }
2383
+ for (let [e, t] of l) c.setFeed(e, t.bars, t);
2384
+ if (!await c.loadChunked(o.bars, re, ne, () => n.has(o.id))) {
2385
+ e({
2386
+ type: "cancelled",
2387
+ id: o.id
2388
+ });
2389
+ return;
2390
+ }
2391
+ i.has(o.sid) || t.set(o.sid, c);
2392
+ let g = c.graph.cols.map((e) => e.v.slice());
2393
+ e({
2394
+ type: "result",
2395
+ id: o.id,
2396
+ n: c.length,
2397
+ buffers: g
2398
+ }, g.map((e) => e.buffer));
2399
+ } catch (t) {
2400
+ e({
2401
+ type: "error",
2402
+ id: o.id,
2403
+ error: Q(t)
2404
+ });
2405
+ } finally {
2406
+ n.delete(o.id), r.delete(o.id);
2407
+ }
2408
+ })();
2409
+ return;
2410
+ }
2411
+ };
2412
+ }
2413
+ //#endregion
2414
+ export { X as a, O as c, C as d, p as f, $ as i, k as l, g as m, te as n, A as o, h as p, ie as r, d as s, Z as t, D as u };
2415
+
2416
+ //# sourceMappingURL=sandbox-p2HPP8yl.js.map