@coderyo/pine-lite 1.0.0-rc.2 → 1.0.0-rc.4

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/index.d.ts CHANGED
@@ -1,15 +1,152 @@
1
- interface PineVmResult {
2
- plots: number[];
1
+ import * as _coderyo_data from '@coderyo/data';
2
+
3
+ interface PineDiagnostic {
4
+ line: number;
5
+ col: number;
6
+ message: string;
7
+ severity: 'error' | 'warning';
8
+ endCol?: number;
9
+ }
10
+ declare function offsetToLineCol(source: string, offset: number): {
11
+ line: number;
12
+ col: number;
13
+ };
14
+ declare function diagnosticFromMessage(source: string, message: string): PineDiagnostic;
15
+ declare function diagnosticsFromMessages(source: string, messages: string[]): PineDiagnostic[];
16
+
17
+ type IrOp = {
18
+ op: 'push';
19
+ value: number;
20
+ } | {
21
+ op: 'load_series';
22
+ name: string;
23
+ } | {
24
+ op: 'load_var';
25
+ name: string;
26
+ } | {
27
+ op: 'store_var';
28
+ name: string;
29
+ } | {
30
+ op: 'call_ind';
31
+ fn: 'sma' | 'ema' | 'rsi';
32
+ series: string;
33
+ } | {
34
+ op: 'add';
35
+ } | {
36
+ op: 'sub';
37
+ } | {
38
+ op: 'mul';
39
+ } | {
40
+ op: 'div';
41
+ } | {
42
+ op: 'neg';
43
+ } | {
44
+ op: 'not';
45
+ } | {
46
+ op: 'cmp';
47
+ mode: 'eq' | 'ne' | 'lt' | 'gt' | 'le' | 'ge';
48
+ } | {
49
+ op: 'and';
50
+ } | {
51
+ op: 'or';
52
+ } | {
53
+ op: 'pop';
54
+ } | {
55
+ op: 'jump';
56
+ target: number;
57
+ } | {
58
+ op: 'jump_if_false';
59
+ target: number;
60
+ } | {
61
+ op: 'plot';
62
+ title: string;
63
+ };
64
+ interface PineIrProgram {
65
+ version: 2;
66
+ ops: IrOp[];
67
+ vars: string[];
68
+ plots: string[];
69
+ }
70
+
71
+ interface PinePlotSeries {
72
+ title: string;
73
+ values: (number | null)[];
74
+ }
75
+ interface PineRunResult {
76
+ plots: PinePlotSeries[];
77
+ }
78
+
79
+ type PineExpr = {
80
+ kind: 'number';
81
+ value: number;
82
+ } | {
83
+ kind: 'bool';
84
+ value: boolean;
85
+ } | {
86
+ kind: 'ident';
87
+ name: string;
88
+ } | {
89
+ kind: 'unary';
90
+ op: '-' | 'not';
91
+ arg: PineExpr;
92
+ } | {
93
+ kind: 'binary';
94
+ op: '+' | '-' | '*' | '/' | '==' | '!=' | '<' | '>' | '<=' | '>=' | 'and' | 'or';
95
+ left: PineExpr;
96
+ right: PineExpr;
97
+ } | {
98
+ kind: 'call';
99
+ name: string;
100
+ args: PineExpr[];
101
+ };
102
+ type PineStmt = {
103
+ kind: 'var';
104
+ name: string;
105
+ init: PineExpr;
106
+ } | {
107
+ kind: 'assign';
108
+ name: string;
109
+ value: PineExpr;
110
+ } | {
111
+ kind: 'plot';
112
+ expr: PineExpr;
113
+ title?: string;
114
+ } | {
115
+ kind: 'expr';
116
+ expr: PineExpr;
117
+ } | {
118
+ kind: 'if';
119
+ cond: PineExpr;
120
+ then: PineStmt[];
121
+ else?: PineStmt[];
122
+ } | {
123
+ kind: 'while';
124
+ cond: PineExpr;
125
+ body: PineStmt[];
126
+ } | {
127
+ kind: 'for';
128
+ name: string;
129
+ from: PineExpr;
130
+ to: PineExpr;
131
+ body: PineStmt[];
132
+ } | {
133
+ kind: 'block';
134
+ body: PineStmt[];
135
+ };
136
+ interface PineProgram {
137
+ kind: 'program';
138
+ body: PineStmt[];
3
139
  }
4
- /** Minimal stack VM stub (PR-18b) — no user scripts executed by default. */
5
- declare function runPineVm(ir: NonNullable<PineCompileResult['ir']>, length: number): PineVmResult;
6
140
 
7
- /** Pine-lite compile-only skeleton (PR-18a) */
8
141
  interface PineCompileResult {
9
142
  ok: boolean;
10
143
  errors: string[];
11
- ir?: unknown;
144
+ diagnostics: PineDiagnostic[];
145
+ ir?: PineIrProgram;
12
146
  }
13
- declare function compilePineLite(_source: string): PineCompileResult;
147
+ declare function compilePineLite(source: string): PineCompileResult;
148
+ declare function runPineLite(ir: PineIrProgram, bars: _coderyo_data.Bar[]): PineRunResult;
149
+ declare const PINE_SAMPLE_SCRIPT = "// Pine-lite \u2014 if / while / for\u3001\u6BD4\u8F03\u3001and/or/not\nvar len = 20\nif (close > 0) {\n plot(sma(close, len))\n} else {\n plot(open)\n}\nfor i = 1 to 2 {\n plot(rsi(close, 14))\n}\n";
150
+ declare const PINE_EDITOR_DEFAULT = "// Pine-lite \u2014 if / while / for\u3001\u6BD4\u8F03\u3001and/or/not\nvar len = 20\nif (close > 0) {\n plot(sma(close, len))\n} else {\n plot(open)\n}\nfor i = 1 to 2 {\n plot(rsi(close, 14))\n}\n";
14
151
 
15
- export { type PineCompileResult, type PineVmResult, compilePineLite, runPineVm };
152
+ export { PINE_EDITOR_DEFAULT, PINE_SAMPLE_SCRIPT, type PineCompileResult, type PineDiagnostic, type PineIrProgram, type PinePlotSeries, type PineProgram, type PineRunResult, compilePineLite, diagnosticFromMessage, diagnosticsFromMessages, offsetToLineCol, runPineLite };
package/dist/index.js CHANGED
@@ -1,16 +1,879 @@
1
+ // src/builtins.ts
2
+ var SERIES_IDENTIFIERS = /* @__PURE__ */ new Set([
3
+ "close",
4
+ "open",
5
+ "high",
6
+ "low",
7
+ "volume",
8
+ "hl2",
9
+ "hlc3"
10
+ ]);
11
+ var INDICATOR_BUILTINS = /* @__PURE__ */ new Set(["sma", "ema", "rsi"]);
12
+ function isBuiltin(name) {
13
+ return SERIES_IDENTIFIERS.has(name) || INDICATOR_BUILTINS.has(name);
14
+ }
15
+ function builtinArity(name) {
16
+ if (SERIES_IDENTIFIERS.has(name)) return 0;
17
+ if (name === "sma" || name === "ema" || name === "rsi") return 2;
18
+ return null;
19
+ }
20
+
21
+ // src/compile.ts
22
+ var Emitter = class {
23
+ ops = [];
24
+ plotIndex = 0;
25
+ emit(op) {
26
+ this.ops.push(op);
27
+ return this.ops.length - 1;
28
+ }
29
+ patchJump(index, target) {
30
+ const op = this.ops[index];
31
+ if (op.op === "jump" || op.op === "jump_if_false") op.target = target;
32
+ }
33
+ emitExpr(expr, errors, vars) {
34
+ switch (expr.kind) {
35
+ case "number":
36
+ this.emit({ op: "push", value: expr.value });
37
+ return true;
38
+ case "bool":
39
+ this.emit({ op: "push", value: expr.value ? 1 : 0 });
40
+ return true;
41
+ case "ident":
42
+ if (vars.has(expr.name)) {
43
+ this.emit({ op: "load_var", name: expr.name });
44
+ return true;
45
+ }
46
+ if (isBuiltin(expr.name) && builtinArity(expr.name) === 0) {
47
+ this.emit({ op: "load_series", name: expr.name });
48
+ return true;
49
+ }
50
+ errors.push(`Unknown identifier '${expr.name}'`);
51
+ return false;
52
+ case "unary":
53
+ if (!this.emitExpr(expr.arg, errors, vars)) return false;
54
+ this.emit({ op: expr.op === "not" ? "not" : "neg" });
55
+ return true;
56
+ case "binary":
57
+ if (expr.op === "and" || expr.op === "or") {
58
+ if (!this.emitExpr(expr.left, errors, vars) || !this.emitExpr(expr.right, errors, vars)) {
59
+ return false;
60
+ }
61
+ this.emit({ op: expr.op });
62
+ return true;
63
+ }
64
+ if (!this.emitExpr(expr.left, errors, vars) || !this.emitExpr(expr.right, errors, vars)) {
65
+ return false;
66
+ }
67
+ if (expr.op === "+" || expr.op === "-" || expr.op === "*" || expr.op === "/") {
68
+ this.emit({
69
+ op: expr.op === "+" ? "add" : expr.op === "-" ? "sub" : expr.op === "*" ? "mul" : "div"
70
+ });
71
+ return true;
72
+ }
73
+ this.emit({
74
+ op: "cmp",
75
+ mode: expr.op === "==" ? "eq" : expr.op === "!=" ? "ne" : expr.op === "<" ? "lt" : expr.op === ">" ? "gt" : expr.op === "<=" ? "le" : "ge"
76
+ });
77
+ return true;
78
+ case "call": {
79
+ const arity = builtinArity(expr.name);
80
+ if (arity == null) {
81
+ errors.push(`Unknown function '${expr.name}'`);
82
+ return false;
83
+ }
84
+ if (expr.args.length !== arity) {
85
+ errors.push(`'${expr.name}' expects ${arity} arguments, got ${expr.args.length}`);
86
+ return false;
87
+ }
88
+ const fn = expr.name;
89
+ if ((fn === "sma" || fn === "ema" || fn === "rsi") && expr.args[0]?.kind === "ident" && SERIES_IDENTIFIERS.has(expr.args[0].name)) {
90
+ if (!this.emitExpr(expr.args[1], errors, vars)) return false;
91
+ this.emit({ op: "call_ind", fn, series: expr.args[0].name });
92
+ return true;
93
+ }
94
+ for (const arg of expr.args) {
95
+ if (!this.emitExpr(arg, errors, vars)) return false;
96
+ }
97
+ return true;
98
+ }
99
+ default:
100
+ return false;
101
+ }
102
+ }
103
+ emitStmt(stmt, errors, vars, plots) {
104
+ switch (stmt.kind) {
105
+ case "block":
106
+ for (const s of stmt.body) this.emitStmt(s, errors, vars, plots);
107
+ break;
108
+ case "var":
109
+ vars.add(stmt.name);
110
+ if (this.emitExpr(stmt.init, errors, vars)) this.emit({ op: "store_var", name: stmt.name });
111
+ break;
112
+ case "assign":
113
+ if (!vars.has(stmt.name)) vars.add(stmt.name);
114
+ if (this.emitExpr(stmt.value, errors, vars)) this.emit({ op: "store_var", name: stmt.name });
115
+ break;
116
+ case "plot": {
117
+ if (!this.emitExpr(stmt.expr, errors, vars)) break;
118
+ const title = stmt.title ?? `plot_${this.plotIndex++}`;
119
+ plots.push(title);
120
+ this.emit({ op: "plot", title });
121
+ break;
122
+ }
123
+ case "expr":
124
+ if (this.emitExpr(stmt.expr, errors, vars)) this.emit({ op: "pop" });
125
+ break;
126
+ case "if": {
127
+ if (!this.emitExpr(stmt.cond, errors, vars)) break;
128
+ const jmpFalse = this.emit({ op: "jump_if_false", target: 0 });
129
+ for (const s of stmt.then) this.emitStmt(s, errors, vars, plots);
130
+ if (stmt.else?.length) {
131
+ const jmpEnd = this.emit({ op: "jump", target: 0 });
132
+ this.patchJump(jmpFalse, this.ops.length);
133
+ for (const s of stmt.else) this.emitStmt(s, errors, vars, plots);
134
+ this.patchJump(jmpEnd, this.ops.length);
135
+ } else {
136
+ this.patchJump(jmpFalse, this.ops.length);
137
+ }
138
+ break;
139
+ }
140
+ case "while": {
141
+ const loopStart = this.ops.length;
142
+ if (!this.emitExpr(stmt.cond, errors, vars)) break;
143
+ const jmpEnd = this.emit({ op: "jump_if_false", target: 0 });
144
+ for (const s of stmt.body) this.emitStmt(s, errors, vars, plots);
145
+ this.emit({ op: "jump", target: loopStart });
146
+ this.patchJump(jmpEnd, this.ops.length);
147
+ break;
148
+ }
149
+ case "for": {
150
+ vars.add(stmt.name);
151
+ if (!this.emitExpr(stmt.from, errors, vars)) break;
152
+ this.emit({ op: "store_var", name: stmt.name });
153
+ const loopStart = this.ops.length;
154
+ this.emit({ op: "load_var", name: stmt.name });
155
+ if (!this.emitExpr(stmt.to, errors, vars)) break;
156
+ this.emit({ op: "cmp", mode: "le" });
157
+ const jmpEnd = this.emit({ op: "jump_if_false", target: 0 });
158
+ for (const s of stmt.body) this.emitStmt(s, errors, vars, plots);
159
+ this.emit({ op: "load_var", name: stmt.name });
160
+ this.emit({ op: "push", value: 1 });
161
+ this.emit({ op: "add" });
162
+ this.emit({ op: "store_var", name: stmt.name });
163
+ this.emit({ op: "jump", target: loopStart });
164
+ this.patchJump(jmpEnd, this.ops.length);
165
+ break;
166
+ }
167
+ }
168
+ }
169
+ };
170
+ function compileAst(program) {
171
+ const errors = [];
172
+ const vars = /* @__PURE__ */ new Set();
173
+ const plots = [];
174
+ const emitter = new Emitter();
175
+ for (const stmt of program.body) {
176
+ emitter.emitStmt(stmt, errors, vars, plots);
177
+ }
178
+ if (errors.length) return { ir: null, errors };
179
+ return {
180
+ ir: { version: 2, ops: emitter.ops, vars: [...vars], plots },
181
+ errors
182
+ };
183
+ }
184
+
185
+ // src/diagnostics.ts
186
+ function offsetToLineCol(source, offset) {
187
+ let line = 1;
188
+ let col = 1;
189
+ for (let i = 0; i < offset && i < source.length; i++) {
190
+ if (source[i] === "\n") {
191
+ line++;
192
+ col = 1;
193
+ } else {
194
+ col++;
195
+ }
196
+ }
197
+ return { line, col };
198
+ }
199
+ function diagnosticFromMessage(source, message) {
200
+ const at = message.match(/\bat\s+(\d+)\b/);
201
+ if (at) {
202
+ const pos = Number(at[1]);
203
+ const { line, col } = offsetToLineCol(source, pos);
204
+ return { line, col, message: message.replace(/\s+at\s+\d+\s*$/, ""), severity: "error" };
205
+ }
206
+ return { line: 1, col: 1, message, severity: "error" };
207
+ }
208
+ function diagnosticsFromMessages(source, messages) {
209
+ return messages.map((m) => diagnosticFromMessage(source, m));
210
+ }
211
+
212
+ // src/lexer.ts
213
+ var KEYWORDS = {
214
+ var: "var",
215
+ plot: "plot",
216
+ if: "if",
217
+ else: "else",
218
+ while: "while",
219
+ for: "for",
220
+ to: "to",
221
+ and: "and",
222
+ or: "or",
223
+ not: "not",
224
+ true: "true",
225
+ false: "false"
226
+ };
227
+ function tokenize(source) {
228
+ const tokens = [];
229
+ const errors = [];
230
+ let i = 0;
231
+ let line = 1;
232
+ let col = 1;
233
+ const push = (type, value, pos, startLine, startCol) => {
234
+ tokens.push({ type, value, pos, line: startLine, col: startCol });
235
+ };
236
+ while (i < source.length) {
237
+ const pos = i;
238
+ const startLine = line;
239
+ const startCol = col;
240
+ const ch = source[i];
241
+ if (ch === " " || ch === " " || ch === "\r") {
242
+ i++;
243
+ col++;
244
+ continue;
245
+ }
246
+ if (ch === "\n") {
247
+ i++;
248
+ line++;
249
+ col = 1;
250
+ continue;
251
+ }
252
+ if (ch === "/" && source[i + 1] === "/") {
253
+ i += 2;
254
+ col += 2;
255
+ while (i < source.length && source[i] !== "\n") {
256
+ i++;
257
+ col++;
258
+ }
259
+ continue;
260
+ }
261
+ if (ch >= "0" && ch <= "9") {
262
+ let j = i + 1;
263
+ while (j < source.length && /[0-9.]/.test(source[j])) j++;
264
+ const raw = source.slice(i, j);
265
+ push("number", raw, pos, startLine, startCol);
266
+ col += j - i;
267
+ i = j;
268
+ continue;
269
+ }
270
+ if (/[A-Za-z_]/.test(ch)) {
271
+ let j = i + 1;
272
+ while (j < source.length && /[A-Za-z0-9_]/.test(source[j])) j++;
273
+ const word = source.slice(i, j);
274
+ const kw = KEYWORDS[word];
275
+ push(kw ?? "ident", word, pos, startLine, startCol);
276
+ col += j - i;
277
+ i = j;
278
+ continue;
279
+ }
280
+ if (ch === ":" && source[i + 1] === "=") {
281
+ push("assign", ":=", pos, startLine, startCol);
282
+ i += 2;
283
+ col += 2;
284
+ continue;
285
+ }
286
+ if (ch === "=" && source[i + 1] === "=") {
287
+ push("eq", "==", pos, startLine, startCol);
288
+ i += 2;
289
+ col += 2;
290
+ continue;
291
+ }
292
+ if (ch === "!" && source[i + 1] === "=") {
293
+ push("ne", "!=", pos, startLine, startCol);
294
+ i += 2;
295
+ col += 2;
296
+ continue;
297
+ }
298
+ if (ch === "<" && source[i + 1] === "=") {
299
+ push("le", "<=", pos, startLine, startCol);
300
+ i += 2;
301
+ col += 2;
302
+ continue;
303
+ }
304
+ if (ch === ">" && source[i + 1] === "=") {
305
+ push("ge", ">=", pos, startLine, startCol);
306
+ i += 2;
307
+ col += 2;
308
+ continue;
309
+ }
310
+ if (ch === "<") {
311
+ push("lt", "<", pos, startLine, startCol);
312
+ i++;
313
+ col++;
314
+ continue;
315
+ }
316
+ if (ch === ">") {
317
+ push("gt", ">", pos, startLine, startCol);
318
+ i++;
319
+ col++;
320
+ continue;
321
+ }
322
+ if (ch === "{") {
323
+ push("lbrace", "{", pos, startLine, startCol);
324
+ i++;
325
+ col++;
326
+ continue;
327
+ }
328
+ if (ch === "}") {
329
+ push("rbrace", "}", pos, startLine, startCol);
330
+ i++;
331
+ col++;
332
+ continue;
333
+ }
334
+ if (ch === "(") {
335
+ push("lparen", "(", pos, startLine, startCol);
336
+ i++;
337
+ col++;
338
+ continue;
339
+ }
340
+ if (ch === ")") {
341
+ push("rparen", ")", pos, startLine, startCol);
342
+ i++;
343
+ col++;
344
+ continue;
345
+ }
346
+ if (ch === ",") {
347
+ push("comma", ",", pos, startLine, startCol);
348
+ i++;
349
+ col++;
350
+ continue;
351
+ }
352
+ if (ch === "+") {
353
+ push("plus", "+", pos, startLine, startCol);
354
+ i++;
355
+ col++;
356
+ continue;
357
+ }
358
+ if (ch === "-") {
359
+ push("minus", "-", pos, startLine, startCol);
360
+ i++;
361
+ col++;
362
+ continue;
363
+ }
364
+ if (ch === "*") {
365
+ push("star", "*", pos, startLine, startCol);
366
+ i++;
367
+ col++;
368
+ continue;
369
+ }
370
+ if (ch === "/") {
371
+ push("slash", "/", pos, startLine, startCol);
372
+ i++;
373
+ col++;
374
+ continue;
375
+ }
376
+ if (ch === "=") {
377
+ push("eq", "=", pos, startLine, startCol);
378
+ i++;
379
+ col++;
380
+ continue;
381
+ }
382
+ errors.push(`Unexpected '${ch}' at line ${startLine}, col ${startCol}`);
383
+ i++;
384
+ col++;
385
+ }
386
+ tokens.push({ type: "eof", value: "", pos: i, line, col });
387
+ return { tokens, errors };
388
+ }
389
+
390
+ // src/parser.ts
391
+ function parseProgram(tokens) {
392
+ const errors = [];
393
+ let i = 0;
394
+ const peek = () => tokens[i];
395
+ const at = (t) => peek().type === t;
396
+ const err = (msg) => {
397
+ errors.push({ message: msg, line: peek().line, col: peek().col });
398
+ };
399
+ const eat = (t) => {
400
+ if (!at(t)) {
401
+ err(`Expected ${t}, got ${peek().type}`);
402
+ return false;
403
+ }
404
+ i++;
405
+ return true;
406
+ };
407
+ const parseBlock = () => {
408
+ if (at("lbrace")) {
409
+ i++;
410
+ const body2 = [];
411
+ while (!at("rbrace") && !at("eof")) {
412
+ const stmt2 = parseStmt();
413
+ if (!stmt2) break;
414
+ body2.push(stmt2);
415
+ }
416
+ if (!eat("rbrace")) return body2;
417
+ return body2;
418
+ }
419
+ const stmt = parseStmt();
420
+ return stmt ? [stmt] : [];
421
+ };
422
+ const parseOr = () => {
423
+ let left = parseAnd();
424
+ if (!left) return null;
425
+ while (at("or")) {
426
+ i++;
427
+ const right = parseAnd();
428
+ if (!right) return null;
429
+ left = { kind: "binary", op: "or", left, right };
430
+ }
431
+ return left;
432
+ };
433
+ const parseAnd = () => {
434
+ let left = parseCompare();
435
+ if (!left) return null;
436
+ while (at("and")) {
437
+ i++;
438
+ const right = parseCompare();
439
+ if (!right) return null;
440
+ left = { kind: "binary", op: "and", left, right };
441
+ }
442
+ return left;
443
+ };
444
+ const parseCompare = () => {
445
+ let left = parseAdd();
446
+ if (!left) return null;
447
+ const cmpTypes = ["eq", "ne", "lt", "gt", "le", "ge"];
448
+ while (cmpTypes.some((t) => at(t))) {
449
+ const t = peek().type;
450
+ const opMap = {
451
+ eq: "==",
452
+ ne: "!=",
453
+ lt: "<",
454
+ gt: ">",
455
+ le: "<=",
456
+ ge: ">="
457
+ };
458
+ i++;
459
+ const right = parseAdd();
460
+ if (!right) return null;
461
+ left = { kind: "binary", op: opMap[t], left, right };
462
+ }
463
+ return left;
464
+ };
465
+ const parseAdd = () => {
466
+ let left = parseMul();
467
+ if (!left) return null;
468
+ while (at("plus") || at("minus")) {
469
+ const op = peek().type === "plus" ? "+" : "-";
470
+ i++;
471
+ const right = parseMul();
472
+ if (!right) return null;
473
+ left = { kind: "binary", op, left, right };
474
+ }
475
+ return left;
476
+ };
477
+ const parseMul = () => {
478
+ let left = parseUnary();
479
+ if (!left) return null;
480
+ while (at("star") || at("slash")) {
481
+ const op = peek().type === "star" ? "*" : "/";
482
+ i++;
483
+ const right = parseUnary();
484
+ if (!right) return null;
485
+ left = { kind: "binary", op, left, right };
486
+ }
487
+ return left;
488
+ };
489
+ const parseUnary = () => {
490
+ if (at("not")) {
491
+ i++;
492
+ const arg = parseUnary();
493
+ return arg ? { kind: "unary", op: "not", arg } : null;
494
+ }
495
+ if (at("minus")) {
496
+ i++;
497
+ const arg = parseUnary();
498
+ return arg ? { kind: "unary", op: "-", arg } : null;
499
+ }
500
+ return parsePrimary();
501
+ };
502
+ const parsePrimary = () => {
503
+ const t = peek();
504
+ if (t.type === "number") {
505
+ i++;
506
+ return { kind: "number", value: Number(t.value) };
507
+ }
508
+ if (t.type === "true" || t.type === "false") {
509
+ i++;
510
+ return { kind: "bool", value: t.type === "true" };
511
+ }
512
+ if (t.type === "ident") {
513
+ const name = t.value;
514
+ i++;
515
+ if (at("lparen")) {
516
+ i++;
517
+ const args = [];
518
+ if (!at("rparen")) {
519
+ const first = parseOr();
520
+ if (!first) return null;
521
+ args.push(first);
522
+ while (at("comma")) {
523
+ i++;
524
+ const next = parseOr();
525
+ if (!next) return null;
526
+ args.push(next);
527
+ }
528
+ }
529
+ if (!eat("rparen")) return null;
530
+ return { kind: "call", name, args };
531
+ }
532
+ return { kind: "ident", name };
533
+ }
534
+ if (at("lparen")) {
535
+ i++;
536
+ const inner = parseOr();
537
+ if (!inner || !eat("rparen")) return null;
538
+ return inner;
539
+ }
540
+ err(`Unexpected token ${t.type}`);
541
+ return null;
542
+ };
543
+ const parseStmt = () => {
544
+ if (at("if")) {
545
+ i++;
546
+ if (!eat("lparen")) return null;
547
+ const cond = parseOr();
548
+ if (!cond || !eat("rparen")) return null;
549
+ const then = parseBlock();
550
+ let elseBody;
551
+ if (at("else")) {
552
+ i++;
553
+ elseBody = parseBlock();
554
+ }
555
+ return { kind: "if", cond, then, else: elseBody };
556
+ }
557
+ if (at("while")) {
558
+ i++;
559
+ if (!eat("lparen")) return null;
560
+ const cond = parseOr();
561
+ if (!cond || !eat("rparen")) return null;
562
+ const body2 = parseBlock();
563
+ return { kind: "while", cond, body: body2 };
564
+ }
565
+ if (at("for")) {
566
+ i++;
567
+ if (!at("ident")) {
568
+ err("Expected loop variable after for");
569
+ return null;
570
+ }
571
+ const name = peek().value;
572
+ i++;
573
+ if (!eat("eq")) return null;
574
+ const from = parseOr();
575
+ if (!from || !at("to")) {
576
+ err('Expected "to" in for loop');
577
+ return null;
578
+ }
579
+ i++;
580
+ const to = parseOr();
581
+ if (!to) return null;
582
+ const body2 = parseBlock();
583
+ return { kind: "for", name, from, to, body: body2 };
584
+ }
585
+ if (at("var")) {
586
+ i++;
587
+ if (!at("ident")) {
588
+ err("Expected identifier after var");
589
+ return null;
590
+ }
591
+ const name = peek().value;
592
+ i++;
593
+ if (!eat("eq")) return null;
594
+ const init = parseOr();
595
+ return init ? { kind: "var", name, init } : null;
596
+ }
597
+ if (at("plot")) {
598
+ i++;
599
+ if (!eat("lparen")) return null;
600
+ const expr = parseOr();
601
+ if (!expr || !eat("rparen")) return null;
602
+ return { kind: "plot", expr };
603
+ }
604
+ if (at("ident")) {
605
+ const name = peek().value;
606
+ i++;
607
+ if (at("assign") || at("eq")) {
608
+ i++;
609
+ const value = parseOr();
610
+ return value ? { kind: "assign", name, value } : null;
611
+ }
612
+ i--;
613
+ const expr = parseOr();
614
+ return expr ? { kind: "expr", expr } : null;
615
+ }
616
+ if (at("lbrace")) {
617
+ return { kind: "block", body: parseBlock() };
618
+ }
619
+ err(`Unexpected statement ${peek().type}`);
620
+ return null;
621
+ };
622
+ const body = [];
623
+ while (!at("eof")) {
624
+ const stmt = parseStmt();
625
+ if (!stmt) break;
626
+ body.push(stmt);
627
+ }
628
+ if (!at("eof")) err("Unexpected tokens after program end");
629
+ return { program: { kind: "program", body }, errors };
630
+ }
631
+
1
632
  // src/vm.ts
2
- function runPineVm(ir, length) {
3
- const plots = Array.from({ length }, (_, i) => Math.sin(i * 0.05));
4
- void ir;
5
- return { plots };
633
+ import { ema, rsi, sma } from "@coderyo/indicators";
634
+ var MAX_STEPS_PER_BAR = 1e5;
635
+ function barsForSeries(bars, series) {
636
+ switch (series) {
637
+ case "hl2":
638
+ return bars.map((b) => ({ ...b, c: (b.h + b.l) / 2 }));
639
+ case "hlc3":
640
+ return bars.map((b) => ({ ...b, c: (b.h + b.l + b.c) / 3 }));
641
+ case "open":
642
+ return bars.map((b) => ({ ...b, c: b.o }));
643
+ case "high":
644
+ return bars.map((b) => ({ ...b, c: b.h }));
645
+ case "low":
646
+ return bars.map((b) => ({ ...b, c: b.l }));
647
+ case "volume":
648
+ return bars.map((b) => ({ ...b, c: b.v ?? 0 }));
649
+ case "close":
650
+ default:
651
+ return bars;
652
+ }
653
+ }
654
+ function seriesAt(bars, series, index) {
655
+ const b = bars[index];
656
+ switch (series) {
657
+ case "open":
658
+ return b.o;
659
+ case "high":
660
+ return b.h;
661
+ case "low":
662
+ return b.l;
663
+ case "volume":
664
+ return b.v ?? 0;
665
+ case "hl2":
666
+ return (b.h + b.l) / 2;
667
+ case "hlc3":
668
+ return (b.h + b.l + b.c) / 3;
669
+ case "close":
670
+ default:
671
+ return b.c;
672
+ }
673
+ }
674
+ function indicatorAt(fn, bars, series, index, period) {
675
+ const src = barsForSeries(bars, series);
676
+ const p = Math.max(1, Math.floor(period));
677
+ const slice = src.slice(0, index + 1);
678
+ if (fn === "sma") return sma(slice, p)[index] ?? null;
679
+ if (fn === "ema") return ema(slice, p)[index] ?? null;
680
+ return rsi(slice, p)[index] ?? null;
681
+ }
682
+ function truthy(v) {
683
+ return Number.isFinite(v) && v !== 0;
684
+ }
685
+ function execOp(op, stack, bars, barIndex, vars, plotBuffers) {
686
+ const pop = () => stack.pop() ?? NaN;
687
+ switch (op.op) {
688
+ case "push":
689
+ stack.push(op.value);
690
+ break;
691
+ case "load_series":
692
+ stack.push(seriesAt(bars, op.name, barIndex));
693
+ break;
694
+ case "load_var": {
695
+ const s = vars.get(op.name);
696
+ stack.push(s?.[barIndex] ?? NaN);
697
+ break;
698
+ }
699
+ case "store_var": {
700
+ const v = pop();
701
+ const s = vars.get(op.name);
702
+ if (s) s[barIndex] = Number.isFinite(v) ? v : null;
703
+ break;
704
+ }
705
+ case "call_ind": {
706
+ const period = pop();
707
+ const v = indicatorAt(op.fn, bars, op.series, barIndex, period);
708
+ stack.push(v ?? NaN);
709
+ break;
710
+ }
711
+ case "add":
712
+ stack.push(pop() + pop());
713
+ break;
714
+ case "sub":
715
+ stack.push(pop() - pop());
716
+ break;
717
+ case "mul":
718
+ stack.push(pop() * pop());
719
+ break;
720
+ case "div": {
721
+ const b = pop();
722
+ const a = pop();
723
+ stack.push(b === 0 ? NaN : a / b);
724
+ break;
725
+ }
726
+ case "neg":
727
+ stack.push(-pop());
728
+ break;
729
+ case "not":
730
+ stack.push(truthy(pop()) ? 0 : 1);
731
+ break;
732
+ case "cmp": {
733
+ const b = pop();
734
+ const a = pop();
735
+ let r = false;
736
+ switch (op.mode) {
737
+ case "eq":
738
+ r = a === b;
739
+ break;
740
+ case "ne":
741
+ r = a !== b;
742
+ break;
743
+ case "lt":
744
+ r = a < b;
745
+ break;
746
+ case "gt":
747
+ r = a > b;
748
+ break;
749
+ case "le":
750
+ r = a <= b;
751
+ break;
752
+ case "ge":
753
+ r = a >= b;
754
+ break;
755
+ }
756
+ stack.push(r ? 1 : 0);
757
+ break;
758
+ }
759
+ case "and": {
760
+ const b = pop();
761
+ const a = pop();
762
+ stack.push(truthy(a) && truthy(b) ? 1 : 0);
763
+ break;
764
+ }
765
+ case "or": {
766
+ const b = pop();
767
+ const a = pop();
768
+ stack.push(truthy(a) || truthy(b) ? 1 : 0);
769
+ break;
770
+ }
771
+ case "pop":
772
+ pop();
773
+ break;
774
+ case "plot": {
775
+ const v = pop();
776
+ const buf = plotBuffers.get(op.title);
777
+ if (buf) buf[barIndex] = Number.isFinite(v) ? v : null;
778
+ break;
779
+ }
780
+ case "jump":
781
+ return op.target;
782
+ case "jump_if_false":
783
+ return truthy(pop()) ? -1 : op.target;
784
+ default:
785
+ break;
786
+ }
787
+ return -1;
788
+ }
789
+ function runPineIr(ir, bars) {
790
+ const n = bars.length;
791
+ const vars = /* @__PURE__ */ new Map();
792
+ for (const name of ir.vars) vars.set(name, Array.from({ length: n }, () => null));
793
+ const plotBuffers = /* @__PURE__ */ new Map();
794
+ for (const title of ir.plots) {
795
+ plotBuffers.set(title, Array.from({ length: n }, () => null));
796
+ }
797
+ for (let i = 0; i < n; i++) {
798
+ const stack = [];
799
+ let pc = 0;
800
+ let steps = 0;
801
+ while (pc < ir.ops.length && steps < MAX_STEPS_PER_BAR) {
802
+ steps++;
803
+ const jmp = execOp(ir.ops[pc], stack, bars, i, vars, plotBuffers);
804
+ if (jmp >= 0) pc = jmp;
805
+ else pc++;
806
+ }
807
+ }
808
+ return {
809
+ plots: ir.plots.map((title) => ({
810
+ title,
811
+ values: plotBuffers.get(title) ?? []
812
+ }))
813
+ };
6
814
  }
7
815
 
8
816
  // src/index.ts
9
- function compilePineLite(_source) {
10
- return { ok: true, errors: [], ir: { version: 0, plots: [] } };
817
+ var MAX_SOURCE_LEN = 32 * 1024;
818
+ function compilePineLite(source) {
819
+ const diagnostics = [];
820
+ const pushDiag = (line, col, message) => {
821
+ diagnostics.push({ line, col, message, severity: "error" });
822
+ };
823
+ if (source.length > MAX_SOURCE_LEN) {
824
+ const msg = `Source exceeds ${MAX_SOURCE_LEN} bytes`;
825
+ pushDiag(1, 1, msg);
826
+ return { ok: false, errors: [msg], diagnostics };
827
+ }
828
+ const { tokens, errors: lexErr } = tokenize(source);
829
+ for (const m of lexErr) diagnostics.push(diagnosticFromMessage(source, m));
830
+ if (lexErr.length) {
831
+ return { ok: false, errors: lexErr, diagnostics };
832
+ }
833
+ const { program, errors: parseErr } = parseProgram(tokens);
834
+ for (const e of parseErr) pushDiag(e.line, e.col, e.message);
835
+ if (parseErr.length || !program) {
836
+ return { ok: false, errors: parseErr.map((e) => e.message), diagnostics };
837
+ }
838
+ const { ir, errors: compileErr } = compileAst(program);
839
+ for (const m of compileErr) diagnostics.push(diagnosticFromMessage(source, m));
840
+ if (compileErr.length || !ir) {
841
+ return { ok: false, errors: compileErr, diagnostics };
842
+ }
843
+ if (ir.plots.length > 16) {
844
+ const msg = "Too many plot() calls (max 16)";
845
+ pushDiag(1, 1, msg);
846
+ return { ok: false, errors: [msg], diagnostics };
847
+ }
848
+ if (ir.vars.length > 256) {
849
+ const msg = "Too many variables (max 256)";
850
+ pushDiag(1, 1, msg);
851
+ return { ok: false, errors: [msg], diagnostics };
852
+ }
853
+ return { ok: true, errors: [], diagnostics, ir };
854
+ }
855
+ function runPineLite(ir, bars) {
856
+ return runPineIr(ir, bars);
857
+ }
858
+ var PINE_SAMPLE_SCRIPT = `// Pine-lite \u2014 if / while / for\u3001\u6BD4\u8F03\u3001and/or/not
859
+ var len = 20
860
+ if (close > 0) {
861
+ plot(sma(close, len))
862
+ } else {
863
+ plot(open)
864
+ }
865
+ for i = 1 to 2 {
866
+ plot(rsi(close, 14))
11
867
  }
868
+ `;
869
+ var PINE_EDITOR_DEFAULT = PINE_SAMPLE_SCRIPT;
12
870
  export {
871
+ PINE_EDITOR_DEFAULT,
872
+ PINE_SAMPLE_SCRIPT,
13
873
  compilePineLite,
14
- runPineVm
874
+ diagnosticFromMessage,
875
+ diagnosticsFromMessages,
876
+ offsetToLineCol,
877
+ runPineLite
15
878
  };
16
879
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/vm.ts","../src/index.ts"],"sourcesContent":["import type { PineCompileResult } from './index.js';\n\nexport interface PineVmResult {\n plots: number[];\n}\n\n/** Minimal stack VM stub (PR-18b) — no user scripts executed by default. */\nexport function runPineVm(ir: NonNullable<PineCompileResult['ir']>, length: number): PineVmResult {\n const plots = Array.from({ length }, (_, i) => Math.sin(i * 0.05));\n void ir;\n return { plots };\n}","/** Pine-lite compile-only skeleton (PR-18a) */\nexport interface PineCompileResult {\n ok: boolean;\n errors: string[];\n ir?: unknown;\n}\n\nexport function compilePineLite(_source: string): PineCompileResult {\n return { ok: true, errors: [], ir: { version: 0, plots: [] } };\n}\n\nexport * from './vm.js';"],"mappings":";AAOO,SAAS,UAAU,IAA0C,QAA8B;AAChG,QAAM,QAAQ,MAAM,KAAK,EAAE,OAAO,GAAG,CAAC,GAAG,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC;AACjE,OAAK;AACL,SAAO,EAAE,MAAM;AACjB;;;ACJO,SAAS,gBAAgB,SAAoC;AAClE,SAAO,EAAE,IAAI,MAAM,QAAQ,CAAC,GAAG,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,EAAE,EAAE;AAC/D;","names":[]}
1
+ {"version":3,"sources":["../src/builtins.ts","../src/compile.ts","../src/diagnostics.ts","../src/lexer.ts","../src/parser.ts","../src/vm.ts","../src/index.ts"],"sourcesContent":["/** Built-in series accessors and indicators (Pine-lite v1 whitelist). */\nexport const SERIES_IDENTIFIERS = new Set([\n 'close',\n 'open',\n 'high',\n 'low',\n 'volume',\n 'hl2',\n 'hlc3',\n]);\n\nexport const INDICATOR_BUILTINS = new Set(['sma', 'ema', 'rsi']);\n\nexport function isBuiltin(name: string): boolean {\n return SERIES_IDENTIFIERS.has(name) || INDICATOR_BUILTINS.has(name);\n}\n\nexport function builtinArity(name: string): number | null {\n if (SERIES_IDENTIFIERS.has(name)) return 0;\n if (name === 'sma' || name === 'ema' || name === 'rsi') return 2;\n return null;\n}","import type { PineExpr, PineProgram, PineStmt } from './ast.js';\nimport { builtinArity, isBuiltin, SERIES_IDENTIFIERS } from './builtins.js';\nimport type { IrOp, PineIrProgram } from './ir.js';\n\nclass Emitter {\n ops: IrOp[] = [];\n private plotIndex = 0;\n\n emit(op: IrOp): number {\n this.ops.push(op);\n return this.ops.length - 1;\n }\n\n patchJump(index: number, target: number): void {\n const op = this.ops[index]!;\n if (op.op === 'jump' || op.op === 'jump_if_false') op.target = target;\n }\n\n emitExpr(expr: PineExpr, errors: string[], vars: Set<string>): boolean {\n switch (expr.kind) {\n case 'number':\n this.emit({ op: 'push', value: expr.value });\n return true;\n case 'bool':\n this.emit({ op: 'push', value: expr.value ? 1 : 0 });\n return true;\n case 'ident':\n if (vars.has(expr.name)) {\n this.emit({ op: 'load_var', name: expr.name });\n return true;\n }\n if (isBuiltin(expr.name) && builtinArity(expr.name) === 0) {\n this.emit({ op: 'load_series', name: expr.name });\n return true;\n }\n errors.push(`Unknown identifier '${expr.name}'`);\n return false;\n case 'unary':\n if (!this.emitExpr(expr.arg, errors, vars)) return false;\n this.emit({ op: expr.op === 'not' ? 'not' : 'neg' });\n return true;\n case 'binary':\n if (expr.op === 'and' || expr.op === 'or') {\n if (!this.emitExpr(expr.left, errors, vars) || !this.emitExpr(expr.right, errors, vars)) {\n return false;\n }\n this.emit({ op: expr.op });\n return true;\n }\n if (!this.emitExpr(expr.left, errors, vars) || !this.emitExpr(expr.right, errors, vars)) {\n return false;\n }\n if (expr.op === '+' || expr.op === '-' || expr.op === '*' || expr.op === '/') {\n this.emit({\n op: expr.op === '+' ? 'add' : expr.op === '-' ? 'sub' : expr.op === '*' ? 'mul' : 'div',\n });\n return true;\n }\n this.emit({\n op: 'cmp',\n mode:\n expr.op === '=='\n ? 'eq'\n : expr.op === '!='\n ? 'ne'\n : expr.op === '<'\n ? 'lt'\n : expr.op === '>'\n ? 'gt'\n : expr.op === '<='\n ? 'le'\n : 'ge',\n });\n return true;\n case 'call': {\n const arity = builtinArity(expr.name);\n if (arity == null) {\n errors.push(`Unknown function '${expr.name}'`);\n return false;\n }\n if (expr.args.length !== arity) {\n errors.push(`'${expr.name}' expects ${arity} arguments, got ${expr.args.length}`);\n return false;\n }\n const fn = expr.name as 'sma' | 'ema' | 'rsi';\n if (\n (fn === 'sma' || fn === 'ema' || fn === 'rsi') &&\n expr.args[0]?.kind === 'ident' &&\n SERIES_IDENTIFIERS.has(expr.args[0].name)\n ) {\n if (!this.emitExpr(expr.args[1]!, errors, vars)) return false;\n this.emit({ op: 'call_ind', fn, series: expr.args[0].name });\n return true;\n }\n for (const arg of expr.args) {\n if (!this.emitExpr(arg, errors, vars)) return false;\n }\n return true;\n }\n default:\n return false;\n }\n }\n\n emitStmt(stmt: PineStmt, errors: string[], vars: Set<string>, plots: string[]): void {\n switch (stmt.kind) {\n case 'block':\n for (const s of stmt.body) this.emitStmt(s, errors, vars, plots);\n break;\n case 'var':\n vars.add(stmt.name);\n if (this.emitExpr(stmt.init, errors, vars)) this.emit({ op: 'store_var', name: stmt.name });\n break;\n case 'assign':\n if (!vars.has(stmt.name)) vars.add(stmt.name);\n if (this.emitExpr(stmt.value, errors, vars)) this.emit({ op: 'store_var', name: stmt.name });\n break;\n case 'plot': {\n if (!this.emitExpr(stmt.expr, errors, vars)) break;\n const title = stmt.title ?? `plot_${this.plotIndex++}`;\n plots.push(title);\n this.emit({ op: 'plot', title });\n break;\n }\n case 'expr':\n if (this.emitExpr(stmt.expr, errors, vars)) this.emit({ op: 'pop' });\n break;\n case 'if': {\n if (!this.emitExpr(stmt.cond, errors, vars)) break;\n const jmpFalse = this.emit({ op: 'jump_if_false', target: 0 });\n for (const s of stmt.then) this.emitStmt(s, errors, vars, plots);\n if (stmt.else?.length) {\n const jmpEnd = this.emit({ op: 'jump', target: 0 });\n this.patchJump(jmpFalse, this.ops.length);\n for (const s of stmt.else) this.emitStmt(s, errors, vars, plots);\n this.patchJump(jmpEnd, this.ops.length);\n } else {\n this.patchJump(jmpFalse, this.ops.length);\n }\n break;\n }\n case 'while': {\n const loopStart = this.ops.length;\n if (!this.emitExpr(stmt.cond, errors, vars)) break;\n const jmpEnd = this.emit({ op: 'jump_if_false', target: 0 });\n for (const s of stmt.body) this.emitStmt(s, errors, vars, plots);\n this.emit({ op: 'jump', target: loopStart });\n this.patchJump(jmpEnd, this.ops.length);\n break;\n }\n case 'for': {\n vars.add(stmt.name);\n if (!this.emitExpr(stmt.from, errors, vars)) break;\n this.emit({ op: 'store_var', name: stmt.name });\n const loopStart = this.ops.length;\n this.emit({ op: 'load_var', name: stmt.name });\n if (!this.emitExpr(stmt.to, errors, vars)) break;\n this.emit({ op: 'cmp', mode: 'le' });\n const jmpEnd = this.emit({ op: 'jump_if_false', target: 0 });\n for (const s of stmt.body) this.emitStmt(s, errors, vars, plots);\n this.emit({ op: 'load_var', name: stmt.name });\n this.emit({ op: 'push', value: 1 });\n this.emit({ op: 'add' });\n this.emit({ op: 'store_var', name: stmt.name });\n this.emit({ op: 'jump', target: loopStart });\n this.patchJump(jmpEnd, this.ops.length);\n break;\n }\n }\n }\n}\n\nexport function compileAst(program: PineProgram): { ir: PineIrProgram | null; errors: string[] } {\n const errors: string[] = [];\n const vars = new Set<string>();\n const plots: string[] = [];\n const emitter = new Emitter();\n\n for (const stmt of program.body) {\n emitter.emitStmt(stmt, errors, vars, plots);\n }\n\n if (errors.length) return { ir: null, errors };\n\n return {\n ir: { version: 2, ops: emitter.ops, vars: [...vars], plots },\n errors,\n };\n}","export interface PineDiagnostic {\n line: number;\n col: number;\n message: string;\n severity: 'error' | 'warning';\n endCol?: number;\n}\n\nexport function offsetToLineCol(source: string, offset: number): { line: number; col: number } {\n let line = 1;\n let col = 1;\n for (let i = 0; i < offset && i < source.length; i++) {\n if (source[i] === '\\n') {\n line++;\n col = 1;\n } else {\n col++;\n }\n }\n return { line, col };\n}\n\nexport function diagnosticFromMessage(source: string, message: string): PineDiagnostic {\n const at = message.match(/\\bat\\s+(\\d+)\\b/);\n if (at) {\n const pos = Number(at[1]);\n const { line, col } = offsetToLineCol(source, pos);\n return { line, col, message: message.replace(/\\s+at\\s+\\d+\\s*$/, ''), severity: 'error' };\n }\n return { line: 1, col: 1, message, severity: 'error' };\n}\n\nexport function diagnosticsFromMessages(source: string, messages: string[]): PineDiagnostic[] {\n return messages.map((m) => diagnosticFromMessage(source, m));\n}","import type { Token } from './tokens.js';\n\nconst KEYWORDS: Record<string, Token['type']> = {\n var: 'var',\n plot: 'plot',\n if: 'if',\n else: 'else',\n while: 'while',\n for: 'for',\n to: 'to',\n and: 'and',\n or: 'or',\n not: 'not',\n true: 'true',\n false: 'false',\n};\n\nexport function tokenize(source: string): { tokens: Token[]; errors: string[] } {\n const tokens: Token[] = [];\n const errors: string[] = [];\n let i = 0;\n let line = 1;\n let col = 1;\n\n const push = (type: Token['type'], value: string, pos: number, startLine: number, startCol: number) => {\n tokens.push({ type, value, pos, line: startLine, col: startCol });\n };\n\n while (i < source.length) {\n const pos = i;\n const startLine = line;\n const startCol = col;\n const ch = source[i]!;\n\n if (ch === ' ' || ch === '\\t' || ch === '\\r') {\n i++;\n col++;\n continue;\n }\n if (ch === '\\n') {\n i++;\n line++;\n col = 1;\n continue;\n }\n if (ch === '/' && source[i + 1] === '/') {\n i += 2;\n col += 2;\n while (i < source.length && source[i] !== '\\n') {\n i++;\n col++;\n }\n continue;\n }\n if (ch >= '0' && ch <= '9') {\n let j = i + 1;\n while (j < source.length && /[0-9.]/.test(source[j]!)) j++;\n const raw = source.slice(i, j);\n push('number', raw, pos, startLine, startCol);\n col += j - i;\n i = j;\n continue;\n }\n if (/[A-Za-z_]/.test(ch)) {\n let j = i + 1;\n while (j < source.length && /[A-Za-z0-9_]/.test(source[j]!)) j++;\n const word = source.slice(i, j);\n const kw = KEYWORDS[word];\n push(kw ?? 'ident', word, pos, startLine, startCol);\n col += j - i;\n i = j;\n continue;\n }\n if (ch === ':' && source[i + 1] === '=') {\n push('assign', ':=', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '=' && source[i + 1] === '=') {\n push('eq', '==', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '!' && source[i + 1] === '=') {\n push('ne', '!=', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '<' && source[i + 1] === '=') {\n push('le', '<=', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '>' && source[i + 1] === '=') {\n push('ge', '>=', pos, startLine, startCol);\n i += 2;\n col += 2;\n continue;\n }\n if (ch === '<') {\n push('lt', '<', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '>') {\n push('gt', '>', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '{') {\n push('lbrace', '{', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '}') {\n push('rbrace', '}', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '(') {\n push('lparen', '(', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === ')') {\n push('rparen', ')', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === ',') {\n push('comma', ',', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '+') {\n push('plus', '+', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '-') {\n push('minus', '-', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '*') {\n push('star', '*', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '/') {\n push('slash', '/', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n if (ch === '=') {\n push('eq', '=', pos, startLine, startCol);\n i++;\n col++;\n continue;\n }\n\n errors.push(`Unexpected '${ch}' at line ${startLine}, col ${startCol}`);\n i++;\n col++;\n }\n\n tokens.push({ type: 'eof', value: '', pos: i, line, col });\n return { tokens, errors };\n}","import type { PineExpr, PineProgram, PineStmt } from './ast.js';\nimport type { Token } from './tokens.js';\n\nexport function parseProgram(tokens: Token[]): {\n program: PineProgram | null;\n errors: Array<{ message: string; line: number; col: number }>;\n} {\n const errors: Array<{ message: string; line: number; col: number }> = [];\n let i = 0;\n\n const peek = () => tokens[i]!;\n const at = (t: Token['type']) => peek().type === t;\n const err = (msg: string) => {\n errors.push({ message: msg, line: peek().line, col: peek().col });\n };\n const eat = (t: Token['type']) => {\n if (!at(t)) {\n err(`Expected ${t}, got ${peek().type}`);\n return false;\n }\n i++;\n return true;\n };\n\n const parseBlock = (): PineStmt[] => {\n if (at('lbrace')) {\n i++;\n const body: PineStmt[] = [];\n while (!at('rbrace') && !at('eof')) {\n const stmt = parseStmt();\n if (!stmt) break;\n body.push(stmt);\n }\n if (!eat('rbrace')) return body;\n return body;\n }\n const stmt = parseStmt();\n return stmt ? [stmt] : [];\n };\n\n const parseOr = (): PineExpr | null => {\n let left = parseAnd();\n if (!left) return null;\n while (at('or')) {\n i++;\n const right = parseAnd();\n if (!right) return null;\n left = { kind: 'binary', op: 'or', left, right };\n }\n return left;\n };\n\n const parseAnd = (): PineExpr | null => {\n let left = parseCompare();\n if (!left) return null;\n while (at('and')) {\n i++;\n const right = parseCompare();\n if (!right) return null;\n left = { kind: 'binary', op: 'and', left, right };\n }\n return left;\n };\n\n const parseCompare = (): PineExpr | null => {\n let left = parseAdd();\n if (!left) return null;\n const cmpTypes = ['eq', 'ne', 'lt', 'gt', 'le', 'ge'] as const;\n while (cmpTypes.some((t) => at(t))) {\n const t = peek().type as (typeof cmpTypes)[number];\n const opMap = {\n eq: '==',\n ne: '!=',\n lt: '<',\n gt: '>',\n le: '<=',\n ge: '>=',\n } as const;\n i++;\n const right = parseAdd();\n if (!right) return null;\n left = { kind: 'binary', op: opMap[t], left, right };\n }\n return left;\n };\n\n const parseAdd = (): PineExpr | null => {\n let left = parseMul();\n if (!left) return null;\n while (at('plus') || at('minus')) {\n const op = peek().type === 'plus' ? '+' : '-';\n i++;\n const right = parseMul();\n if (!right) return null;\n left = { kind: 'binary', op, left, right };\n }\n return left;\n };\n\n const parseMul = (): PineExpr | null => {\n let left = parseUnary();\n if (!left) return null;\n while (at('star') || at('slash')) {\n const op = peek().type === 'star' ? '*' : '/';\n i++;\n const right = parseUnary();\n if (!right) return null;\n left = { kind: 'binary', op, left, right };\n }\n return left;\n };\n\n const parseUnary = (): PineExpr | null => {\n if (at('not')) {\n i++;\n const arg = parseUnary();\n return arg ? { kind: 'unary', op: 'not', arg } : null;\n }\n if (at('minus')) {\n i++;\n const arg = parseUnary();\n return arg ? { kind: 'unary', op: '-', arg } : null;\n }\n return parsePrimary();\n };\n\n const parsePrimary = (): PineExpr | null => {\n const t = peek();\n if (t.type === 'number') {\n i++;\n return { kind: 'number', value: Number(t.value) };\n }\n if (t.type === 'true' || t.type === 'false') {\n i++;\n return { kind: 'bool', value: t.type === 'true' };\n }\n if (t.type === 'ident') {\n const name = t.value;\n i++;\n if (at('lparen')) {\n i++;\n const args: PineExpr[] = [];\n if (!at('rparen')) {\n const first = parseOr();\n if (!first) return null;\n args.push(first);\n while (at('comma')) {\n i++;\n const next = parseOr();\n if (!next) return null;\n args.push(next);\n }\n }\n if (!eat('rparen')) return null;\n return { kind: 'call', name, args };\n }\n return { kind: 'ident', name };\n }\n if (at('lparen')) {\n i++;\n const inner = parseOr();\n if (!inner || !eat('rparen')) return null;\n return inner;\n }\n err(`Unexpected token ${t.type}`);\n return null;\n };\n\n const parseStmt = (): PineStmt | null => {\n if (at('if')) {\n i++;\n if (!eat('lparen')) return null;\n const cond = parseOr();\n if (!cond || !eat('rparen')) return null;\n const then = parseBlock();\n let elseBody: PineStmt[] | undefined;\n if (at('else')) {\n i++;\n elseBody = parseBlock();\n }\n return { kind: 'if', cond, then, else: elseBody };\n }\n if (at('while')) {\n i++;\n if (!eat('lparen')) return null;\n const cond = parseOr();\n if (!cond || !eat('rparen')) return null;\n const body = parseBlock();\n return { kind: 'while', cond, body };\n }\n if (at('for')) {\n i++;\n if (!at('ident')) {\n err('Expected loop variable after for');\n return null;\n }\n const name = peek().value;\n i++;\n if (!eat('eq')) return null;\n const from = parseOr();\n if (!from || !at('to')) {\n err('Expected \"to\" in for loop');\n return null;\n }\n i++;\n const to = parseOr();\n if (!to) return null;\n const body = parseBlock();\n return { kind: 'for', name, from, to, body };\n }\n if (at('var')) {\n i++;\n if (!at('ident')) {\n err('Expected identifier after var');\n return null;\n }\n const name = peek().value;\n i++;\n if (!eat('eq')) return null;\n const init = parseOr();\n return init ? { kind: 'var', name, init } : null;\n }\n if (at('plot')) {\n i++;\n if (!eat('lparen')) return null;\n const expr = parseOr();\n if (!expr || !eat('rparen')) return null;\n return { kind: 'plot', expr };\n }\n if (at('ident')) {\n const name = peek().value;\n i++;\n if (at('assign') || at('eq')) {\n i++;\n const value = parseOr();\n return value ? { kind: 'assign', name, value } : null;\n }\n i--;\n const expr = parseOr();\n return expr ? { kind: 'expr', expr } : null;\n }\n if (at('lbrace')) {\n return { kind: 'block', body: parseBlock() };\n }\n err(`Unexpected statement ${peek().type}`);\n return null;\n };\n\n const body: PineStmt[] = [];\n while (!at('eof')) {\n const stmt = parseStmt();\n if (!stmt) break;\n body.push(stmt);\n }\n\n if (!at('eof')) err('Unexpected tokens after program end');\n return { program: { kind: 'program', body }, errors };\n}","import type { Bar } from '@coderyo/data';\nimport { ema, rsi, sma } from '@coderyo/indicators';\nimport type { IrOp, PineIrProgram } from './ir.js';\n\nexport interface PinePlotSeries {\n title: string;\n values: (number | null)[];\n}\n\nexport interface PineRunResult {\n plots: PinePlotSeries[];\n}\n\nconst MAX_STEPS_PER_BAR = 100_000;\n\nfunction barsForSeries(bars: Bar[], series: string): Bar[] {\n switch (series) {\n case 'hl2':\n return bars.map((b) => ({ ...b, c: (b.h + b.l) / 2 }));\n case 'hlc3':\n return bars.map((b) => ({ ...b, c: (b.h + b.l + b.c) / 3 }));\n case 'open':\n return bars.map((b) => ({ ...b, c: b.o }));\n case 'high':\n return bars.map((b) => ({ ...b, c: b.h }));\n case 'low':\n return bars.map((b) => ({ ...b, c: b.l }));\n case 'volume':\n return bars.map((b) => ({ ...b, c: b.v ?? 0 }));\n case 'close':\n default:\n return bars;\n }\n}\n\nfunction seriesAt(bars: Bar[], series: string, index: number): number {\n const b = bars[index]!;\n switch (series) {\n case 'open':\n return b.o;\n case 'high':\n return b.h;\n case 'low':\n return b.l;\n case 'volume':\n return b.v ?? 0;\n case 'hl2':\n return (b.h + b.l) / 2;\n case 'hlc3':\n return (b.h + b.l + b.c) / 3;\n case 'close':\n default:\n return b.c;\n }\n}\n\nfunction indicatorAt(\n fn: 'sma' | 'ema' | 'rsi',\n bars: Bar[],\n series: string,\n index: number,\n period: number,\n): number | null {\n const src = barsForSeries(bars, series);\n const p = Math.max(1, Math.floor(period));\n const slice = src.slice(0, index + 1);\n if (fn === 'sma') return sma(slice, p)[index] ?? null;\n if (fn === 'ema') return ema(slice, p)[index] ?? null;\n return rsi(slice, p)[index] ?? null;\n}\n\nfunction truthy(v: number): boolean {\n return Number.isFinite(v) && v !== 0;\n}\n\nfunction execOp(\n op: IrOp,\n stack: number[],\n bars: Bar[],\n barIndex: number,\n vars: Map<string, (number | null)[]>,\n plotBuffers: Map<string, (number | null)[]>,\n): number {\n const pop = () => stack.pop() ?? NaN;\n switch (op.op) {\n case 'push':\n stack.push(op.value);\n break;\n case 'load_series':\n stack.push(seriesAt(bars, op.name, barIndex));\n break;\n case 'load_var': {\n const s = vars.get(op.name);\n stack.push(s?.[barIndex] ?? NaN);\n break;\n }\n case 'store_var': {\n const v = pop();\n const s = vars.get(op.name);\n if (s) s[barIndex] = Number.isFinite(v) ? v : null;\n break;\n }\n case 'call_ind': {\n const period = pop();\n const v = indicatorAt(op.fn, bars, op.series, barIndex, period);\n stack.push(v ?? NaN);\n break;\n }\n case 'add':\n stack.push(pop() + pop());\n break;\n case 'sub':\n stack.push(pop() - pop());\n break;\n case 'mul':\n stack.push(pop() * pop());\n break;\n case 'div': {\n const b = pop();\n const a = pop();\n stack.push(b === 0 ? NaN : a / b);\n break;\n }\n case 'neg':\n stack.push(-pop());\n break;\n case 'not':\n stack.push(truthy(pop()) ? 0 : 1);\n break;\n case 'cmp': {\n const b = pop();\n const a = pop();\n let r = false;\n switch (op.mode) {\n case 'eq':\n r = a === b;\n break;\n case 'ne':\n r = a !== b;\n break;\n case 'lt':\n r = a < b;\n break;\n case 'gt':\n r = a > b;\n break;\n case 'le':\n r = a <= b;\n break;\n case 'ge':\n r = a >= b;\n break;\n }\n stack.push(r ? 1 : 0);\n break;\n }\n case 'and': {\n const b = pop();\n const a = pop();\n stack.push(truthy(a) && truthy(b) ? 1 : 0);\n break;\n }\n case 'or': {\n const b = pop();\n const a = pop();\n stack.push(truthy(a) || truthy(b) ? 1 : 0);\n break;\n }\n case 'pop':\n pop();\n break;\n case 'plot': {\n const v = pop();\n const buf = plotBuffers.get(op.title);\n if (buf) buf[barIndex] = Number.isFinite(v) ? v : null;\n break;\n }\n case 'jump':\n return op.target;\n case 'jump_if_false':\n return truthy(pop()) ? -1 : op.target;\n default:\n break;\n }\n return -1;\n}\n\nexport function runPineIr(ir: PineIrProgram, bars: Bar[]): PineRunResult {\n const n = bars.length;\n const vars = new Map<string, (number | null)[]>();\n for (const name of ir.vars) vars.set(name, Array.from({ length: n }, () => null));\n\n const plotBuffers = new Map<string, (number | null)[]>();\n for (const title of ir.plots) {\n plotBuffers.set(title, Array.from({ length: n }, () => null));\n }\n\n for (let i = 0; i < n; i++) {\n const stack: number[] = [];\n let pc = 0;\n let steps = 0;\n while (pc < ir.ops.length && steps < MAX_STEPS_PER_BAR) {\n steps++;\n const jmp = execOp(ir.ops[pc]!, stack, bars, i, vars, plotBuffers);\n if (jmp >= 0) pc = jmp;\n else pc++;\n }\n }\n\n return {\n plots: ir.plots.map((title) => ({\n title,\n values: plotBuffers.get(title) ?? [],\n })),\n };\n}","import { compileAst } from './compile.js';\nimport { diagnosticFromMessage, type PineDiagnostic } from './diagnostics.js';\nimport { tokenize } from './lexer.js';\nimport { parseProgram } from './parser.js';\nimport type { PineIrProgram } from './ir.js';\nimport { runPineIr, type PinePlotSeries, type PineRunResult } from './vm.js';\n\nexport type { PinePlotSeries, PineRunResult, PineDiagnostic };\nexport type { PineIrProgram } from './ir.js';\nexport type { PineProgram } from './ast.js';\nexport { diagnosticFromMessage, diagnosticsFromMessages, offsetToLineCol } from './diagnostics.js';\n\nexport interface PineCompileResult {\n ok: boolean;\n errors: string[];\n diagnostics: PineDiagnostic[];\n ir?: PineIrProgram;\n}\n\nconst MAX_SOURCE_LEN = 32 * 1024;\n\nexport function compilePineLite(source: string): PineCompileResult {\n const diagnostics: PineDiagnostic[] = [];\n const pushDiag = (line: number, col: number, message: string) => {\n diagnostics.push({ line, col, message, severity: 'error' });\n };\n\n if (source.length > MAX_SOURCE_LEN) {\n const msg = `Source exceeds ${MAX_SOURCE_LEN} bytes`;\n pushDiag(1, 1, msg);\n return { ok: false, errors: [msg], diagnostics };\n }\n\n const { tokens, errors: lexErr } = tokenize(source);\n for (const m of lexErr) diagnostics.push(diagnosticFromMessage(source, m));\n if (lexErr.length) {\n return { ok: false, errors: lexErr, diagnostics };\n }\n\n const { program, errors: parseErr } = parseProgram(tokens);\n for (const e of parseErr) pushDiag(e.line, e.col, e.message);\n if (parseErr.length || !program) {\n return { ok: false, errors: parseErr.map((e) => e.message), diagnostics };\n }\n\n const { ir, errors: compileErr } = compileAst(program);\n for (const m of compileErr) diagnostics.push(diagnosticFromMessage(source, m));\n if (compileErr.length || !ir) {\n return { ok: false, errors: compileErr, diagnostics };\n }\n if (ir.plots.length > 16) {\n const msg = 'Too many plot() calls (max 16)';\n pushDiag(1, 1, msg);\n return { ok: false, errors: [msg], diagnostics };\n }\n if (ir.vars.length > 256) {\n const msg = 'Too many variables (max 256)';\n pushDiag(1, 1, msg);\n return { ok: false, errors: [msg], diagnostics };\n }\n\n return { ok: true, errors: [], diagnostics, ir };\n}\n\nexport function runPineLite(ir: PineIrProgram, bars: import('@coderyo/data').Bar[]): PineRunResult {\n return runPineIr(ir, bars);\n}\n\nexport const PINE_SAMPLE_SCRIPT = `// Pine-lite — if / while / for、比較、and/or/not\nvar len = 20\nif (close > 0) {\n plot(sma(close, len))\n} else {\n plot(open)\n}\nfor i = 1 to 2 {\n plot(rsi(close, 14))\n}\n`;\n\nexport const PINE_EDITOR_DEFAULT = PINE_SAMPLE_SCRIPT;"],"mappings":";AACO,IAAM,qBAAqB,oBAAI,IAAI;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,qBAAqB,oBAAI,IAAI,CAAC,OAAO,OAAO,KAAK,CAAC;AAExD,SAAS,UAAU,MAAuB;AAC/C,SAAO,mBAAmB,IAAI,IAAI,KAAK,mBAAmB,IAAI,IAAI;AACpE;AAEO,SAAS,aAAa,MAA6B;AACxD,MAAI,mBAAmB,IAAI,IAAI,EAAG,QAAO;AACzC,MAAI,SAAS,SAAS,SAAS,SAAS,SAAS,MAAO,QAAO;AAC/D,SAAO;AACT;;;ACjBA,IAAM,UAAN,MAAc;AAAA,EACZ,MAAc,CAAC;AAAA,EACP,YAAY;AAAA,EAEpB,KAAK,IAAkB;AACrB,SAAK,IAAI,KAAK,EAAE;AAChB,WAAO,KAAK,IAAI,SAAS;AAAA,EAC3B;AAAA,EAEA,UAAU,OAAe,QAAsB;AAC7C,UAAM,KAAK,KAAK,IAAI,KAAK;AACzB,QAAI,GAAG,OAAO,UAAU,GAAG,OAAO,gBAAiB,IAAG,SAAS;AAAA,EACjE;AAAA,EAEA,SAAS,MAAgB,QAAkB,MAA4B;AACrE,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,aAAK,KAAK,EAAE,IAAI,QAAQ,OAAO,KAAK,MAAM,CAAC;AAC3C,eAAO;AAAA,MACT,KAAK;AACH,aAAK,KAAK,EAAE,IAAI,QAAQ,OAAO,KAAK,QAAQ,IAAI,EAAE,CAAC;AACnD,eAAO;AAAA,MACT,KAAK;AACH,YAAI,KAAK,IAAI,KAAK,IAAI,GAAG;AACvB,eAAK,KAAK,EAAE,IAAI,YAAY,MAAM,KAAK,KAAK,CAAC;AAC7C,iBAAO;AAAA,QACT;AACA,YAAI,UAAU,KAAK,IAAI,KAAK,aAAa,KAAK,IAAI,MAAM,GAAG;AACzD,eAAK,KAAK,EAAE,IAAI,eAAe,MAAM,KAAK,KAAK,CAAC;AAChD,iBAAO;AAAA,QACT;AACA,eAAO,KAAK,uBAAuB,KAAK,IAAI,GAAG;AAC/C,eAAO;AAAA,MACT,KAAK;AACH,YAAI,CAAC,KAAK,SAAS,KAAK,KAAK,QAAQ,IAAI,EAAG,QAAO;AACnD,aAAK,KAAK,EAAE,IAAI,KAAK,OAAO,QAAQ,QAAQ,MAAM,CAAC;AACnD,eAAO;AAAA,MACT,KAAK;AACH,YAAI,KAAK,OAAO,SAAS,KAAK,OAAO,MAAM;AACzC,cAAI,CAAC,KAAK,SAAS,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,KAAK,SAAS,KAAK,OAAO,QAAQ,IAAI,GAAG;AACvF,mBAAO;AAAA,UACT;AACA,eAAK,KAAK,EAAE,IAAI,KAAK,GAAG,CAAC;AACzB,iBAAO;AAAA,QACT;AACA,YAAI,CAAC,KAAK,SAAS,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,KAAK,SAAS,KAAK,OAAO,QAAQ,IAAI,GAAG;AACvF,iBAAO;AAAA,QACT;AACA,YAAI,KAAK,OAAO,OAAO,KAAK,OAAO,OAAO,KAAK,OAAO,OAAO,KAAK,OAAO,KAAK;AAC5E,eAAK,KAAK;AAAA,YACR,IAAI,KAAK,OAAO,MAAM,QAAQ,KAAK,OAAO,MAAM,QAAQ,KAAK,OAAO,MAAM,QAAQ;AAAA,UACpF,CAAC;AACD,iBAAO;AAAA,QACT;AACA,aAAK,KAAK;AAAA,UACR,IAAI;AAAA,UACJ,MACE,KAAK,OAAO,OACR,OACA,KAAK,OAAO,OACV,OACA,KAAK,OAAO,MACV,OACA,KAAK,OAAO,MACV,OACA,KAAK,OAAO,OACV,OACA;AAAA,QAChB,CAAC;AACD,eAAO;AAAA,MACT,KAAK,QAAQ;AACX,cAAM,QAAQ,aAAa,KAAK,IAAI;AACpC,YAAI,SAAS,MAAM;AACjB,iBAAO,KAAK,qBAAqB,KAAK,IAAI,GAAG;AAC7C,iBAAO;AAAA,QACT;AACA,YAAI,KAAK,KAAK,WAAW,OAAO;AAC9B,iBAAO,KAAK,IAAI,KAAK,IAAI,aAAa,KAAK,mBAAmB,KAAK,KAAK,MAAM,EAAE;AAChF,iBAAO;AAAA,QACT;AACA,cAAM,KAAK,KAAK;AAChB,aACG,OAAO,SAAS,OAAO,SAAS,OAAO,UACxC,KAAK,KAAK,CAAC,GAAG,SAAS,WACvB,mBAAmB,IAAI,KAAK,KAAK,CAAC,EAAE,IAAI,GACxC;AACA,cAAI,CAAC,KAAK,SAAS,KAAK,KAAK,CAAC,GAAI,QAAQ,IAAI,EAAG,QAAO;AACxD,eAAK,KAAK,EAAE,IAAI,YAAY,IAAI,QAAQ,KAAK,KAAK,CAAC,EAAE,KAAK,CAAC;AAC3D,iBAAO;AAAA,QACT;AACA,mBAAW,OAAO,KAAK,MAAM;AAC3B,cAAI,CAAC,KAAK,SAAS,KAAK,QAAQ,IAAI,EAAG,QAAO;AAAA,QAChD;AACA,eAAO;AAAA,MACT;AAAA,MACA;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAAA,EAEA,SAAS,MAAgB,QAAkB,MAAmB,OAAuB;AACnF,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,mBAAW,KAAK,KAAK,KAAM,MAAK,SAAS,GAAG,QAAQ,MAAM,KAAK;AAC/D;AAAA,MACF,KAAK;AACH,aAAK,IAAI,KAAK,IAAI;AAClB,YAAI,KAAK,SAAS,KAAK,MAAM,QAAQ,IAAI,EAAG,MAAK,KAAK,EAAE,IAAI,aAAa,MAAM,KAAK,KAAK,CAAC;AAC1F;AAAA,MACF,KAAK;AACH,YAAI,CAAC,KAAK,IAAI,KAAK,IAAI,EAAG,MAAK,IAAI,KAAK,IAAI;AAC5C,YAAI,KAAK,SAAS,KAAK,OAAO,QAAQ,IAAI,EAAG,MAAK,KAAK,EAAE,IAAI,aAAa,MAAM,KAAK,KAAK,CAAC;AAC3F;AAAA,MACF,KAAK,QAAQ;AACX,YAAI,CAAC,KAAK,SAAS,KAAK,MAAM,QAAQ,IAAI,EAAG;AAC7C,cAAM,QAAQ,KAAK,SAAS,QAAQ,KAAK,WAAW;AACpD,cAAM,KAAK,KAAK;AAChB,aAAK,KAAK,EAAE,IAAI,QAAQ,MAAM,CAAC;AAC/B;AAAA,MACF;AAAA,MACA,KAAK;AACH,YAAI,KAAK,SAAS,KAAK,MAAM,QAAQ,IAAI,EAAG,MAAK,KAAK,EAAE,IAAI,MAAM,CAAC;AACnE;AAAA,MACF,KAAK,MAAM;AACT,YAAI,CAAC,KAAK,SAAS,KAAK,MAAM,QAAQ,IAAI,EAAG;AAC7C,cAAM,WAAW,KAAK,KAAK,EAAE,IAAI,iBAAiB,QAAQ,EAAE,CAAC;AAC7D,mBAAW,KAAK,KAAK,KAAM,MAAK,SAAS,GAAG,QAAQ,MAAM,KAAK;AAC/D,YAAI,KAAK,MAAM,QAAQ;AACrB,gBAAM,SAAS,KAAK,KAAK,EAAE,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAClD,eAAK,UAAU,UAAU,KAAK,IAAI,MAAM;AACxC,qBAAW,KAAK,KAAK,KAAM,MAAK,SAAS,GAAG,QAAQ,MAAM,KAAK;AAC/D,eAAK,UAAU,QAAQ,KAAK,IAAI,MAAM;AAAA,QACxC,OAAO;AACL,eAAK,UAAU,UAAU,KAAK,IAAI,MAAM;AAAA,QAC1C;AACA;AAAA,MACF;AAAA,MACA,KAAK,SAAS;AACZ,cAAM,YAAY,KAAK,IAAI;AAC3B,YAAI,CAAC,KAAK,SAAS,KAAK,MAAM,QAAQ,IAAI,EAAG;AAC7C,cAAM,SAAS,KAAK,KAAK,EAAE,IAAI,iBAAiB,QAAQ,EAAE,CAAC;AAC3D,mBAAW,KAAK,KAAK,KAAM,MAAK,SAAS,GAAG,QAAQ,MAAM,KAAK;AAC/D,aAAK,KAAK,EAAE,IAAI,QAAQ,QAAQ,UAAU,CAAC;AAC3C,aAAK,UAAU,QAAQ,KAAK,IAAI,MAAM;AACtC;AAAA,MACF;AAAA,MACA,KAAK,OAAO;AACV,aAAK,IAAI,KAAK,IAAI;AAClB,YAAI,CAAC,KAAK,SAAS,KAAK,MAAM,QAAQ,IAAI,EAAG;AAC7C,aAAK,KAAK,EAAE,IAAI,aAAa,MAAM,KAAK,KAAK,CAAC;AAC9C,cAAM,YAAY,KAAK,IAAI;AAC3B,aAAK,KAAK,EAAE,IAAI,YAAY,MAAM,KAAK,KAAK,CAAC;AAC7C,YAAI,CAAC,KAAK,SAAS,KAAK,IAAI,QAAQ,IAAI,EAAG;AAC3C,aAAK,KAAK,EAAE,IAAI,OAAO,MAAM,KAAK,CAAC;AACnC,cAAM,SAAS,KAAK,KAAK,EAAE,IAAI,iBAAiB,QAAQ,EAAE,CAAC;AAC3D,mBAAW,KAAK,KAAK,KAAM,MAAK,SAAS,GAAG,QAAQ,MAAM,KAAK;AAC/D,aAAK,KAAK,EAAE,IAAI,YAAY,MAAM,KAAK,KAAK,CAAC;AAC7C,aAAK,KAAK,EAAE,IAAI,QAAQ,OAAO,EAAE,CAAC;AAClC,aAAK,KAAK,EAAE,IAAI,MAAM,CAAC;AACvB,aAAK,KAAK,EAAE,IAAI,aAAa,MAAM,KAAK,KAAK,CAAC;AAC9C,aAAK,KAAK,EAAE,IAAI,QAAQ,QAAQ,UAAU,CAAC;AAC3C,aAAK,UAAU,QAAQ,KAAK,IAAI,MAAM;AACtC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,WAAW,SAAsE;AAC/F,QAAM,SAAmB,CAAC;AAC1B,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,QAAkB,CAAC;AACzB,QAAM,UAAU,IAAI,QAAQ;AAE5B,aAAW,QAAQ,QAAQ,MAAM;AAC/B,YAAQ,SAAS,MAAM,QAAQ,MAAM,KAAK;AAAA,EAC5C;AAEA,MAAI,OAAO,OAAQ,QAAO,EAAE,IAAI,MAAM,OAAO;AAE7C,SAAO;AAAA,IACL,IAAI,EAAE,SAAS,GAAG,KAAK,QAAQ,KAAK,MAAM,CAAC,GAAG,IAAI,GAAG,MAAM;AAAA,IAC3D;AAAA,EACF;AACF;;;ACpLO,SAAS,gBAAgB,QAAgB,QAA+C;AAC7F,MAAI,OAAO;AACX,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,UAAU,IAAI,OAAO,QAAQ,KAAK;AACpD,QAAI,OAAO,CAAC,MAAM,MAAM;AACtB;AACA,YAAM;AAAA,IACR,OAAO;AACL;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,MAAM,IAAI;AACrB;AAEO,SAAS,sBAAsB,QAAgB,SAAiC;AACrF,QAAM,KAAK,QAAQ,MAAM,gBAAgB;AACzC,MAAI,IAAI;AACN,UAAM,MAAM,OAAO,GAAG,CAAC,CAAC;AACxB,UAAM,EAAE,MAAM,IAAI,IAAI,gBAAgB,QAAQ,GAAG;AACjD,WAAO,EAAE,MAAM,KAAK,SAAS,QAAQ,QAAQ,mBAAmB,EAAE,GAAG,UAAU,QAAQ;AAAA,EACzF;AACA,SAAO,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,UAAU,QAAQ;AACvD;AAEO,SAAS,wBAAwB,QAAgB,UAAsC;AAC5F,SAAO,SAAS,IAAI,CAAC,MAAM,sBAAsB,QAAQ,CAAC,CAAC;AAC7D;;;AChCA,IAAM,WAA0C;AAAA,EAC9C,KAAK;AAAA,EACL,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,OAAO;AAAA,EACP,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AACT;AAEO,SAAS,SAAS,QAAuD;AAC9E,QAAM,SAAkB,CAAC;AACzB,QAAM,SAAmB,CAAC;AAC1B,MAAI,IAAI;AACR,MAAI,OAAO;AACX,MAAI,MAAM;AAEV,QAAM,OAAO,CAAC,MAAqB,OAAe,KAAa,WAAmB,aAAqB;AACrG,WAAO,KAAK,EAAE,MAAM,OAAO,KAAK,MAAM,WAAW,KAAK,SAAS,CAAC;AAAA,EAClE;AAEA,SAAO,IAAI,OAAO,QAAQ;AACxB,UAAM,MAAM;AACZ,UAAM,YAAY;AAClB,UAAM,WAAW;AACjB,UAAM,KAAK,OAAO,CAAC;AAEnB,QAAI,OAAO,OAAO,OAAO,OAAQ,OAAO,MAAM;AAC5C;AACA;AACA;AAAA,IACF;AACA,QAAI,OAAO,MAAM;AACf;AACA;AACA,YAAM;AACN;AAAA,IACF;AACA,QAAI,OAAO,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK;AACvC,WAAK;AACL,aAAO;AACP,aAAO,IAAI,OAAO,UAAU,OAAO,CAAC,MAAM,MAAM;AAC9C;AACA;AAAA,MACF;AACA;AAAA,IACF;AACA,QAAI,MAAM,OAAO,MAAM,KAAK;AAC1B,UAAI,IAAI,IAAI;AACZ,aAAO,IAAI,OAAO,UAAU,SAAS,KAAK,OAAO,CAAC,CAAE,EAAG;AACvD,YAAM,MAAM,OAAO,MAAM,GAAG,CAAC;AAC7B,WAAK,UAAU,KAAK,KAAK,WAAW,QAAQ;AAC5C,aAAO,IAAI;AACX,UAAI;AACJ;AAAA,IACF;AACA,QAAI,YAAY,KAAK,EAAE,GAAG;AACxB,UAAI,IAAI,IAAI;AACZ,aAAO,IAAI,OAAO,UAAU,eAAe,KAAK,OAAO,CAAC,CAAE,EAAG;AAC7D,YAAM,OAAO,OAAO,MAAM,GAAG,CAAC;AAC9B,YAAM,KAAK,SAAS,IAAI;AACxB,WAAK,MAAM,SAAS,MAAM,KAAK,WAAW,QAAQ;AAClD,aAAO,IAAI;AACX,UAAI;AACJ;AAAA,IACF;AACA,QAAI,OAAO,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK;AACvC,WAAK,UAAU,MAAM,KAAK,WAAW,QAAQ;AAC7C,WAAK;AACL,aAAO;AACP;AAAA,IACF;AACA,QAAI,OAAO,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK;AACvC,WAAK,MAAM,MAAM,KAAK,WAAW,QAAQ;AACzC,WAAK;AACL,aAAO;AACP;AAAA,IACF;AACA,QAAI,OAAO,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK;AACvC,WAAK,MAAM,MAAM,KAAK,WAAW,QAAQ;AACzC,WAAK;AACL,aAAO;AACP;AAAA,IACF;AACA,QAAI,OAAO,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK;AACvC,WAAK,MAAM,MAAM,KAAK,WAAW,QAAQ;AACzC,WAAK;AACL,aAAO;AACP;AAAA,IACF;AACA,QAAI,OAAO,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK;AACvC,WAAK,MAAM,MAAM,KAAK,WAAW,QAAQ;AACzC,WAAK;AACL,aAAO;AACP;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,WAAK,MAAM,KAAK,KAAK,WAAW,QAAQ;AACxC;AACA;AACA;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,WAAK,MAAM,KAAK,KAAK,WAAW,QAAQ;AACxC;AACA;AACA;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,WAAK,UAAU,KAAK,KAAK,WAAW,QAAQ;AAC5C;AACA;AACA;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,WAAK,UAAU,KAAK,KAAK,WAAW,QAAQ;AAC5C;AACA;AACA;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,WAAK,UAAU,KAAK,KAAK,WAAW,QAAQ;AAC5C;AACA;AACA;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,WAAK,UAAU,KAAK,KAAK,WAAW,QAAQ;AAC5C;AACA;AACA;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,WAAK,SAAS,KAAK,KAAK,WAAW,QAAQ;AAC3C;AACA;AACA;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,WAAK,QAAQ,KAAK,KAAK,WAAW,QAAQ;AAC1C;AACA;AACA;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,WAAK,SAAS,KAAK,KAAK,WAAW,QAAQ;AAC3C;AACA;AACA;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,WAAK,QAAQ,KAAK,KAAK,WAAW,QAAQ;AAC1C;AACA;AACA;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,WAAK,SAAS,KAAK,KAAK,WAAW,QAAQ;AAC3C;AACA;AACA;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,WAAK,MAAM,KAAK,KAAK,WAAW,QAAQ;AACxC;AACA;AACA;AAAA,IACF;AAEA,WAAO,KAAK,eAAe,EAAE,aAAa,SAAS,SAAS,QAAQ,EAAE;AACtE;AACA;AAAA,EACF;AAEA,SAAO,KAAK,EAAE,MAAM,OAAO,OAAO,IAAI,KAAK,GAAG,MAAM,IAAI,CAAC;AACzD,SAAO,EAAE,QAAQ,OAAO;AAC1B;;;ACpLO,SAAS,aAAa,QAG3B;AACA,QAAM,SAAgE,CAAC;AACvE,MAAI,IAAI;AAER,QAAM,OAAO,MAAM,OAAO,CAAC;AAC3B,QAAM,KAAK,CAAC,MAAqB,KAAK,EAAE,SAAS;AACjD,QAAM,MAAM,CAAC,QAAgB;AAC3B,WAAO,KAAK,EAAE,SAAS,KAAK,MAAM,KAAK,EAAE,MAAM,KAAK,KAAK,EAAE,IAAI,CAAC;AAAA,EAClE;AACA,QAAM,MAAM,CAAC,MAAqB;AAChC,QAAI,CAAC,GAAG,CAAC,GAAG;AACV,UAAI,YAAY,CAAC,SAAS,KAAK,EAAE,IAAI,EAAE;AACvC,aAAO;AAAA,IACT;AACA;AACA,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAkB;AACnC,QAAI,GAAG,QAAQ,GAAG;AAChB;AACA,YAAMA,QAAmB,CAAC;AAC1B,aAAO,CAAC,GAAG,QAAQ,KAAK,CAAC,GAAG,KAAK,GAAG;AAClC,cAAMC,QAAO,UAAU;AACvB,YAAI,CAACA,MAAM;AACX,QAAAD,MAAK,KAAKC,KAAI;AAAA,MAChB;AACA,UAAI,CAAC,IAAI,QAAQ,EAAG,QAAOD;AAC3B,aAAOA;AAAA,IACT;AACA,UAAM,OAAO,UAAU;AACvB,WAAO,OAAO,CAAC,IAAI,IAAI,CAAC;AAAA,EAC1B;AAEA,QAAM,UAAU,MAAuB;AACrC,QAAI,OAAO,SAAS;AACpB,QAAI,CAAC,KAAM,QAAO;AAClB,WAAO,GAAG,IAAI,GAAG;AACf;AACA,YAAM,QAAQ,SAAS;AACvB,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,EAAE,MAAM,UAAU,IAAI,MAAM,MAAM,MAAM;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,MAAuB;AACtC,QAAI,OAAO,aAAa;AACxB,QAAI,CAAC,KAAM,QAAO;AAClB,WAAO,GAAG,KAAK,GAAG;AAChB;AACA,YAAM,QAAQ,aAAa;AAC3B,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,EAAE,MAAM,UAAU,IAAI,OAAO,MAAM,MAAM;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,MAAuB;AAC1C,QAAI,OAAO,SAAS;AACpB,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,WAAW,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI;AACpD,WAAO,SAAS,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG;AAClC,YAAM,IAAI,KAAK,EAAE;AACjB,YAAM,QAAQ;AAAA,QACZ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN;AACA;AACA,YAAM,QAAQ,SAAS;AACvB,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,EAAE,MAAM,UAAU,IAAI,MAAM,CAAC,GAAG,MAAM,MAAM;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,MAAuB;AACtC,QAAI,OAAO,SAAS;AACpB,QAAI,CAAC,KAAM,QAAO;AAClB,WAAO,GAAG,MAAM,KAAK,GAAG,OAAO,GAAG;AAChC,YAAM,KAAK,KAAK,EAAE,SAAS,SAAS,MAAM;AAC1C;AACA,YAAM,QAAQ,SAAS;AACvB,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,EAAE,MAAM,UAAU,IAAI,MAAM,MAAM;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,MAAuB;AACtC,QAAI,OAAO,WAAW;AACtB,QAAI,CAAC,KAAM,QAAO;AAClB,WAAO,GAAG,MAAM,KAAK,GAAG,OAAO,GAAG;AAChC,YAAM,KAAK,KAAK,EAAE,SAAS,SAAS,MAAM;AAC1C;AACA,YAAM,QAAQ,WAAW;AACzB,UAAI,CAAC,MAAO,QAAO;AACnB,aAAO,EAAE,MAAM,UAAU,IAAI,MAAM,MAAM;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,MAAuB;AACxC,QAAI,GAAG,KAAK,GAAG;AACb;AACA,YAAM,MAAM,WAAW;AACvB,aAAO,MAAM,EAAE,MAAM,SAAS,IAAI,OAAO,IAAI,IAAI;AAAA,IACnD;AACA,QAAI,GAAG,OAAO,GAAG;AACf;AACA,YAAM,MAAM,WAAW;AACvB,aAAO,MAAM,EAAE,MAAM,SAAS,IAAI,KAAK,IAAI,IAAI;AAAA,IACjD;AACA,WAAO,aAAa;AAAA,EACtB;AAEA,QAAM,eAAe,MAAuB;AAC1C,UAAM,IAAI,KAAK;AACf,QAAI,EAAE,SAAS,UAAU;AACvB;AACA,aAAO,EAAE,MAAM,UAAU,OAAO,OAAO,EAAE,KAAK,EAAE;AAAA,IAClD;AACA,QAAI,EAAE,SAAS,UAAU,EAAE,SAAS,SAAS;AAC3C;AACA,aAAO,EAAE,MAAM,QAAQ,OAAO,EAAE,SAAS,OAAO;AAAA,IAClD;AACA,QAAI,EAAE,SAAS,SAAS;AACtB,YAAM,OAAO,EAAE;AACf;AACA,UAAI,GAAG,QAAQ,GAAG;AAChB;AACA,cAAM,OAAmB,CAAC;AAC1B,YAAI,CAAC,GAAG,QAAQ,GAAG;AACjB,gBAAM,QAAQ,QAAQ;AACtB,cAAI,CAAC,MAAO,QAAO;AACnB,eAAK,KAAK,KAAK;AACf,iBAAO,GAAG,OAAO,GAAG;AAClB;AACA,kBAAM,OAAO,QAAQ;AACrB,gBAAI,CAAC,KAAM,QAAO;AAClB,iBAAK,KAAK,IAAI;AAAA,UAChB;AAAA,QACF;AACA,YAAI,CAAC,IAAI,QAAQ,EAAG,QAAO;AAC3B,eAAO,EAAE,MAAM,QAAQ,MAAM,KAAK;AAAA,MACpC;AACA,aAAO,EAAE,MAAM,SAAS,KAAK;AAAA,IAC/B;AACA,QAAI,GAAG,QAAQ,GAAG;AAChB;AACA,YAAM,QAAQ,QAAQ;AACtB,UAAI,CAAC,SAAS,CAAC,IAAI,QAAQ,EAAG,QAAO;AACrC,aAAO;AAAA,IACT;AACA,QAAI,oBAAoB,EAAE,IAAI,EAAE;AAChC,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,MAAuB;AACvC,QAAI,GAAG,IAAI,GAAG;AACZ;AACA,UAAI,CAAC,IAAI,QAAQ,EAAG,QAAO;AAC3B,YAAM,OAAO,QAAQ;AACrB,UAAI,CAAC,QAAQ,CAAC,IAAI,QAAQ,EAAG,QAAO;AACpC,YAAM,OAAO,WAAW;AACxB,UAAI;AACJ,UAAI,GAAG,MAAM,GAAG;AACd;AACA,mBAAW,WAAW;AAAA,MACxB;AACA,aAAO,EAAE,MAAM,MAAM,MAAM,MAAM,MAAM,SAAS;AAAA,IAClD;AACA,QAAI,GAAG,OAAO,GAAG;AACf;AACA,UAAI,CAAC,IAAI,QAAQ,EAAG,QAAO;AAC3B,YAAM,OAAO,QAAQ;AACrB,UAAI,CAAC,QAAQ,CAAC,IAAI,QAAQ,EAAG,QAAO;AACpC,YAAMA,QAAO,WAAW;AACxB,aAAO,EAAE,MAAM,SAAS,MAAM,MAAAA,MAAK;AAAA,IACrC;AACA,QAAI,GAAG,KAAK,GAAG;AACb;AACA,UAAI,CAAC,GAAG,OAAO,GAAG;AAChB,YAAI,kCAAkC;AACtC,eAAO;AAAA,MACT;AACA,YAAM,OAAO,KAAK,EAAE;AACpB;AACA,UAAI,CAAC,IAAI,IAAI,EAAG,QAAO;AACvB,YAAM,OAAO,QAAQ;AACrB,UAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,GAAG;AACtB,YAAI,2BAA2B;AAC/B,eAAO;AAAA,MACT;AACA;AACA,YAAM,KAAK,QAAQ;AACnB,UAAI,CAAC,GAAI,QAAO;AAChB,YAAMA,QAAO,WAAW;AACxB,aAAO,EAAE,MAAM,OAAO,MAAM,MAAM,IAAI,MAAAA,MAAK;AAAA,IAC7C;AACA,QAAI,GAAG,KAAK,GAAG;AACb;AACA,UAAI,CAAC,GAAG,OAAO,GAAG;AAChB,YAAI,+BAA+B;AACnC,eAAO;AAAA,MACT;AACA,YAAM,OAAO,KAAK,EAAE;AACpB;AACA,UAAI,CAAC,IAAI,IAAI,EAAG,QAAO;AACvB,YAAM,OAAO,QAAQ;AACrB,aAAO,OAAO,EAAE,MAAM,OAAO,MAAM,KAAK,IAAI;AAAA,IAC9C;AACA,QAAI,GAAG,MAAM,GAAG;AACd;AACA,UAAI,CAAC,IAAI,QAAQ,EAAG,QAAO;AAC3B,YAAM,OAAO,QAAQ;AACrB,UAAI,CAAC,QAAQ,CAAC,IAAI,QAAQ,EAAG,QAAO;AACpC,aAAO,EAAE,MAAM,QAAQ,KAAK;AAAA,IAC9B;AACA,QAAI,GAAG,OAAO,GAAG;AACf,YAAM,OAAO,KAAK,EAAE;AACpB;AACA,UAAI,GAAG,QAAQ,KAAK,GAAG,IAAI,GAAG;AAC5B;AACA,cAAM,QAAQ,QAAQ;AACtB,eAAO,QAAQ,EAAE,MAAM,UAAU,MAAM,MAAM,IAAI;AAAA,MACnD;AACA;AACA,YAAM,OAAO,QAAQ;AACrB,aAAO,OAAO,EAAE,MAAM,QAAQ,KAAK,IAAI;AAAA,IACzC;AACA,QAAI,GAAG,QAAQ,GAAG;AAChB,aAAO,EAAE,MAAM,SAAS,MAAM,WAAW,EAAE;AAAA,IAC7C;AACA,QAAI,wBAAwB,KAAK,EAAE,IAAI,EAAE;AACzC,WAAO;AAAA,EACT;AAEA,QAAM,OAAmB,CAAC;AAC1B,SAAO,CAAC,GAAG,KAAK,GAAG;AACjB,UAAM,OAAO,UAAU;AACvB,QAAI,CAAC,KAAM;AACX,SAAK,KAAK,IAAI;AAAA,EAChB;AAEA,MAAI,CAAC,GAAG,KAAK,EAAG,KAAI,qCAAqC;AACzD,SAAO,EAAE,SAAS,EAAE,MAAM,WAAW,KAAK,GAAG,OAAO;AACtD;;;AChQA,SAAS,KAAK,KAAK,WAAW;AAY9B,IAAM,oBAAoB;AAE1B,SAAS,cAAc,MAAa,QAAuB;AACzD,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,KAAK,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;AAAA,IACvD,KAAK;AACH,aAAO,KAAK,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;AAAA,IAC7D,KAAK;AACH,aAAO,KAAK,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE;AAAA,IAC3C,KAAK;AACH,aAAO,KAAK,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE;AAAA,IAC3C,KAAK;AACH,aAAO,KAAK,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,EAAE;AAAA,IAC3C,KAAK;AACH,aAAO,KAAK,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,KAAK,EAAE,EAAE;AAAA,IAChD,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,SAAS,MAAa,QAAgB,OAAuB;AACpE,QAAM,IAAI,KAAK,KAAK;AACpB,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,EAAE;AAAA,IACX,KAAK;AACH,aAAO,EAAE;AAAA,IACX,KAAK;AACH,aAAO,EAAE;AAAA,IACX,KAAK;AACH,aAAO,EAAE,KAAK;AAAA,IAChB,KAAK;AACH,cAAQ,EAAE,IAAI,EAAE,KAAK;AAAA,IACvB,KAAK;AACH,cAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK;AAAA,IAC7B,KAAK;AAAA,IACL;AACE,aAAO,EAAE;AAAA,EACb;AACF;AAEA,SAAS,YACP,IACA,MACA,QACA,OACA,QACe;AACf,QAAM,MAAM,cAAc,MAAM,MAAM;AACtC,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,CAAC;AACxC,QAAM,QAAQ,IAAI,MAAM,GAAG,QAAQ,CAAC;AACpC,MAAI,OAAO,MAAO,QAAO,IAAI,OAAO,CAAC,EAAE,KAAK,KAAK;AACjD,MAAI,OAAO,MAAO,QAAO,IAAI,OAAO,CAAC,EAAE,KAAK,KAAK;AACjD,SAAO,IAAI,OAAO,CAAC,EAAE,KAAK,KAAK;AACjC;AAEA,SAAS,OAAO,GAAoB;AAClC,SAAO,OAAO,SAAS,CAAC,KAAK,MAAM;AACrC;AAEA,SAAS,OACP,IACA,OACA,MACA,UACA,MACA,aACQ;AACR,QAAM,MAAM,MAAM,MAAM,IAAI,KAAK;AACjC,UAAQ,GAAG,IAAI;AAAA,IACb,KAAK;AACH,YAAM,KAAK,GAAG,KAAK;AACnB;AAAA,IACF,KAAK;AACH,YAAM,KAAK,SAAS,MAAM,GAAG,MAAM,QAAQ,CAAC;AAC5C;AAAA,IACF,KAAK,YAAY;AACf,YAAM,IAAI,KAAK,IAAI,GAAG,IAAI;AAC1B,YAAM,KAAK,IAAI,QAAQ,KAAK,GAAG;AAC/B;AAAA,IACF;AAAA,IACA,KAAK,aAAa;AAChB,YAAM,IAAI,IAAI;AACd,YAAM,IAAI,KAAK,IAAI,GAAG,IAAI;AAC1B,UAAI,EAAG,GAAE,QAAQ,IAAI,OAAO,SAAS,CAAC,IAAI,IAAI;AAC9C;AAAA,IACF;AAAA,IACA,KAAK,YAAY;AACf,YAAM,SAAS,IAAI;AACnB,YAAM,IAAI,YAAY,GAAG,IAAI,MAAM,GAAG,QAAQ,UAAU,MAAM;AAC9D,YAAM,KAAK,KAAK,GAAG;AACnB;AAAA,IACF;AAAA,IACA,KAAK;AACH,YAAM,KAAK,IAAI,IAAI,IAAI,CAAC;AACxB;AAAA,IACF,KAAK;AACH,YAAM,KAAK,IAAI,IAAI,IAAI,CAAC;AACxB;AAAA,IACF,KAAK;AACH,YAAM,KAAK,IAAI,IAAI,IAAI,CAAC;AACxB;AAAA,IACF,KAAK,OAAO;AACV,YAAM,IAAI,IAAI;AACd,YAAM,IAAI,IAAI;AACd,YAAM,KAAK,MAAM,IAAI,MAAM,IAAI,CAAC;AAChC;AAAA,IACF;AAAA,IACA,KAAK;AACH,YAAM,KAAK,CAAC,IAAI,CAAC;AACjB;AAAA,IACF,KAAK;AACH,YAAM,KAAK,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC;AAChC;AAAA,IACF,KAAK,OAAO;AACV,YAAM,IAAI,IAAI;AACd,YAAM,IAAI,IAAI;AACd,UAAI,IAAI;AACR,cAAQ,GAAG,MAAM;AAAA,QACf,KAAK;AACH,cAAI,MAAM;AACV;AAAA,QACF,KAAK;AACH,cAAI,MAAM;AACV;AAAA,QACF,KAAK;AACH,cAAI,IAAI;AACR;AAAA,QACF,KAAK;AACH,cAAI,IAAI;AACR;AAAA,QACF,KAAK;AACH,cAAI,KAAK;AACT;AAAA,QACF,KAAK;AACH,cAAI,KAAK;AACT;AAAA,MACJ;AACA,YAAM,KAAK,IAAI,IAAI,CAAC;AACpB;AAAA,IACF;AAAA,IACA,KAAK,OAAO;AACV,YAAM,IAAI,IAAI;AACd,YAAM,IAAI,IAAI;AACd,YAAM,KAAK,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC;AACzC;AAAA,IACF;AAAA,IACA,KAAK,MAAM;AACT,YAAM,IAAI,IAAI;AACd,YAAM,IAAI,IAAI;AACd,YAAM,KAAK,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC;AACzC;AAAA,IACF;AAAA,IACA,KAAK;AACH,UAAI;AACJ;AAAA,IACF,KAAK,QAAQ;AACX,YAAM,IAAI,IAAI;AACd,YAAM,MAAM,YAAY,IAAI,GAAG,KAAK;AACpC,UAAI,IAAK,KAAI,QAAQ,IAAI,OAAO,SAAS,CAAC,IAAI,IAAI;AAClD;AAAA,IACF;AAAA,IACA,KAAK;AACH,aAAO,GAAG;AAAA,IACZ,KAAK;AACH,aAAO,OAAO,IAAI,CAAC,IAAI,KAAK,GAAG;AAAA,IACjC;AACE;AAAA,EACJ;AACA,SAAO;AACT;AAEO,SAAS,UAAU,IAAmB,MAA4B;AACvE,QAAM,IAAI,KAAK;AACf,QAAM,OAAO,oBAAI,IAA+B;AAChD,aAAW,QAAQ,GAAG,KAAM,MAAK,IAAI,MAAM,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC;AAEhF,QAAM,cAAc,oBAAI,IAA+B;AACvD,aAAW,SAAS,GAAG,OAAO;AAC5B,gBAAY,IAAI,OAAO,MAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC;AAAA,EAC9D;AAEA,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,QAAkB,CAAC;AACzB,QAAI,KAAK;AACT,QAAI,QAAQ;AACZ,WAAO,KAAK,GAAG,IAAI,UAAU,QAAQ,mBAAmB;AACtD;AACA,YAAM,MAAM,OAAO,GAAG,IAAI,EAAE,GAAI,OAAO,MAAM,GAAG,MAAM,WAAW;AACjE,UAAI,OAAO,EAAG,MAAK;AAAA,UACd;AAAA,IACP;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW;AAAA,MAC9B;AAAA,MACA,QAAQ,YAAY,IAAI,KAAK,KAAK,CAAC;AAAA,IACrC,EAAE;AAAA,EACJ;AACF;;;ACpMA,IAAM,iBAAiB,KAAK;AAErB,SAAS,gBAAgB,QAAmC;AACjE,QAAM,cAAgC,CAAC;AACvC,QAAM,WAAW,CAAC,MAAc,KAAa,YAAoB;AAC/D,gBAAY,KAAK,EAAE,MAAM,KAAK,SAAS,UAAU,QAAQ,CAAC;AAAA,EAC5D;AAEA,MAAI,OAAO,SAAS,gBAAgB;AAClC,UAAM,MAAM,kBAAkB,cAAc;AAC5C,aAAS,GAAG,GAAG,GAAG;AAClB,WAAO,EAAE,IAAI,OAAO,QAAQ,CAAC,GAAG,GAAG,YAAY;AAAA,EACjD;AAEA,QAAM,EAAE,QAAQ,QAAQ,OAAO,IAAI,SAAS,MAAM;AAClD,aAAW,KAAK,OAAQ,aAAY,KAAK,sBAAsB,QAAQ,CAAC,CAAC;AACzE,MAAI,OAAO,QAAQ;AACjB,WAAO,EAAE,IAAI,OAAO,QAAQ,QAAQ,YAAY;AAAA,EAClD;AAEA,QAAM,EAAE,SAAS,QAAQ,SAAS,IAAI,aAAa,MAAM;AACzD,aAAW,KAAK,SAAU,UAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;AAC3D,MAAI,SAAS,UAAU,CAAC,SAAS;AAC/B,WAAO,EAAE,IAAI,OAAO,QAAQ,SAAS,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY;AAAA,EAC1E;AAEA,QAAM,EAAE,IAAI,QAAQ,WAAW,IAAI,WAAW,OAAO;AACrD,aAAW,KAAK,WAAY,aAAY,KAAK,sBAAsB,QAAQ,CAAC,CAAC;AAC7E,MAAI,WAAW,UAAU,CAAC,IAAI;AAC5B,WAAO,EAAE,IAAI,OAAO,QAAQ,YAAY,YAAY;AAAA,EACtD;AACA,MAAI,GAAG,MAAM,SAAS,IAAI;AACxB,UAAM,MAAM;AACZ,aAAS,GAAG,GAAG,GAAG;AAClB,WAAO,EAAE,IAAI,OAAO,QAAQ,CAAC,GAAG,GAAG,YAAY;AAAA,EACjD;AACA,MAAI,GAAG,KAAK,SAAS,KAAK;AACxB,UAAM,MAAM;AACZ,aAAS,GAAG,GAAG,GAAG;AAClB,WAAO,EAAE,IAAI,OAAO,QAAQ,CAAC,GAAG,GAAG,YAAY;AAAA,EACjD;AAEA,SAAO,EAAE,IAAI,MAAM,QAAQ,CAAC,GAAG,aAAa,GAAG;AACjD;AAEO,SAAS,YAAY,IAAmB,MAAoD;AACjG,SAAO,UAAU,IAAI,IAAI;AAC3B;AAEO,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAY3B,IAAM,sBAAsB;","names":["body","stmt"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coderyo/pine-lite",
3
- "version": "1.0.0-rc.2",
3
+ "version": "1.0.0-rc.4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -9,12 +9,16 @@
9
9
  "import": "./dist/index.js"
10
10
  }
11
11
  },
12
+ "dependencies": {
13
+ "@coderyo/data": "1.0.0-rc.4",
14
+ "@coderyo/indicators": "1.0.0-rc.4"
15
+ },
12
16
  "devDependencies": {
13
17
  "tsup": "^8.5.0",
14
18
  "typescript": "^5.8.3",
15
19
  "vitest": "^3.2.4",
16
- "@coderyo/eslint-config": "0.0.0",
17
- "@coderyo/tsconfig": "0.0.0"
20
+ "@coderyo/tsconfig": "0.0.0",
21
+ "@coderyo/eslint-config": "0.0.0"
18
22
  },
19
23
  "files": [
20
24
  "dist"