roll-parser 2.3.2 → 3.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +175 -170
  3. package/dist/cli/args.d.ts +35 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/format.d.ts +20 -0
  6. package/dist/cli/format.d.ts.map +1 -0
  7. package/dist/cli/index.d.ts +8 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli.js +2608 -0
  10. package/dist/cli.js.map +28 -0
  11. package/dist/errors.d.ts +42 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/evaluator/evaluator.d.ts +121 -0
  14. package/dist/evaluator/evaluator.d.ts.map +1 -0
  15. package/dist/evaluator/index.d.ts +8 -0
  16. package/dist/evaluator/index.d.ts.map +1 -0
  17. package/dist/evaluator/modifiers/compare.d.ts +15 -0
  18. package/dist/evaluator/modifiers/compare.d.ts.map +1 -0
  19. package/dist/evaluator/modifiers/crit-threshold.d.ts +28 -0
  20. package/dist/evaluator/modifiers/crit-threshold.d.ts.map +1 -0
  21. package/dist/evaluator/modifiers/explode.d.ts +48 -0
  22. package/dist/evaluator/modifiers/explode.d.ts.map +1 -0
  23. package/dist/evaluator/modifiers/keep-drop.d.ts +44 -0
  24. package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -0
  25. package/dist/evaluator/modifiers/reroll.d.ts +33 -0
  26. package/dist/evaluator/modifiers/reroll.d.ts.map +1 -0
  27. package/dist/evaluator/modifiers/sort.d.ts +23 -0
  28. package/dist/evaluator/modifiers/sort.d.ts.map +1 -0
  29. package/dist/evaluator/modifiers/success-count.d.ts +28 -0
  30. package/dist/evaluator/modifiers/success-count.d.ts.map +1 -0
  31. package/dist/index.d.ts +20 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +2560 -0
  34. package/dist/index.js.map +26 -0
  35. package/dist/lexer/lexer.d.ts +90 -0
  36. package/dist/lexer/lexer.d.ts.map +1 -0
  37. package/dist/lexer/tokens.d.ts +107 -0
  38. package/dist/lexer/tokens.d.ts.map +1 -0
  39. package/dist/parser/ast.d.ts +368 -0
  40. package/dist/parser/ast.d.ts.map +1 -0
  41. package/dist/parser/parser.d.ts +145 -0
  42. package/dist/parser/parser.d.ts.map +1 -0
  43. package/dist/rng/index.d.ts +8 -0
  44. package/dist/rng/index.d.ts.map +1 -0
  45. package/dist/rng/mock.d.ts +36 -0
  46. package/dist/rng/mock.d.ts.map +1 -0
  47. package/dist/rng/seeded.d.ts +40 -0
  48. package/dist/rng/seeded.d.ts.map +1 -0
  49. package/dist/rng/types.d.ts +24 -0
  50. package/dist/rng/types.d.ts.map +1 -0
  51. package/dist/roll.d.ts +51 -0
  52. package/dist/roll.d.ts.map +1 -0
  53. package/dist/testing.d.ts +11 -0
  54. package/dist/testing.d.ts.map +1 -0
  55. package/dist/testing.js +41 -0
  56. package/dist/testing.js.map +11 -0
  57. package/dist/types.d.ts +246 -0
  58. package/dist/types.d.ts.map +1 -0
  59. package/package.json +66 -43
  60. package/src/cli/args.ts +73 -0
  61. package/src/cli/format.ts +49 -0
  62. package/src/cli/index.ts +92 -0
  63. package/src/errors.ts +90 -0
  64. package/src/evaluator/evaluator.ts +1552 -0
  65. package/src/evaluator/index.ts +14 -0
  66. package/src/evaluator/modifiers/compare.ts +29 -0
  67. package/src/evaluator/modifiers/crit-threshold.ts +59 -0
  68. package/src/evaluator/modifiers/explode.ts +219 -0
  69. package/src/evaluator/modifiers/keep-drop.ts +151 -0
  70. package/src/evaluator/modifiers/reroll.ts +165 -0
  71. package/src/evaluator/modifiers/sort.ts +30 -0
  72. package/src/evaluator/modifiers/success-count.ts +59 -0
  73. package/src/index.ts +90 -0
  74. package/src/lexer/lexer.ts +374 -0
  75. package/src/lexer/tokens.ts +187 -0
  76. package/src/parser/ast.ts +628 -0
  77. package/src/parser/parser.ts +1239 -0
  78. package/src/rng/index.ts +8 -0
  79. package/src/rng/mock.ts +65 -0
  80. package/src/rng/seeded.ts +157 -0
  81. package/src/rng/types.ts +25 -0
  82. package/src/roll.ts +74 -0
  83. package/src/testing.ts +16 -0
  84. package/src/types.ts +237 -0
  85. package/bin/help.txt +0 -19
  86. package/bin/roll-parser.js +0 -23
  87. package/dist/roll-parser.js +0 -697
  88. package/dist/roll-parser.min.js +0 -1
  89. package/index.js +0 -24
  90. package/src/complex/parse.js +0 -37
  91. package/src/complex/parseAndRoll.js +0 -21
  92. package/src/complex/parseAndRollClassic.js +0 -20
  93. package/src/complex/parseAndRollSimple.js +0 -19
  94. package/src/complex/parseAndRollWod.js +0 -20
  95. package/src/complex/parseClassicRoll.js +0 -22
  96. package/src/complex/parseSimpleRoll.js +0 -21
  97. package/src/complex/parseWodRoll.js +0 -21
  98. package/src/converter.js +0 -45
  99. package/src/grammar.js +0 -14
  100. package/src/mapper.js +0 -50
  101. package/src/normalizer.js +0 -51
  102. package/src/object/Result.js +0 -23
  103. package/src/object/Roll.js +0 -26
  104. package/src/object/Type.js +0 -5
  105. package/src/object/WodRoll.js +0 -29
  106. package/src/parser.js +0 -43
  107. package/src/random.js +0 -22
  108. package/src/roller.js +0 -106
  109. package/src/stringifier.js +0 -33
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Pratt parser for dice notation.
3
+ *
4
+ * @module parser/parser
5
+ */
6
+ import type { RollParserErrorCode } from '../errors.js';
7
+ import { RollParserError } from '../errors.js';
8
+ import { type Token } from '../lexer/tokens.js';
9
+ import type { ComparePoint } from '../types.js';
10
+ import type { ASTNode } from './ast.js';
11
+ /**
12
+ * Error thrown when the parser encounters invalid syntax.
13
+ */
14
+ export declare class ParseError extends RollParserError {
15
+ readonly position: number;
16
+ readonly token: Token | undefined;
17
+ constructor(message: string, code: RollParserErrorCode, position: number, token?: Token);
18
+ }
19
+ /**
20
+ * Pratt parser for dice notation.
21
+ *
22
+ * Uses binding power (precedence) to handle operator associativity and
23
+ * precedence without left recursion issues.
24
+ */
25
+ export declare class Parser {
26
+ private readonly tokens;
27
+ private pos;
28
+ private depth;
29
+ constructor(tokens: Token[]);
30
+ /**
31
+ * Parse the token stream into an AST.
32
+ */
33
+ parse(): ASTNode;
34
+ /**
35
+ * Parse an expression with minimum binding power.
36
+ */
37
+ private parseExpression;
38
+ /**
39
+ * NUD - Null Denotation.
40
+ * Handles tokens that appear at the start of an expression (prefix position).
41
+ */
42
+ private parseNud;
43
+ /**
44
+ * LED - Left Denotation.
45
+ * Handles tokens that appear between expressions (infix/postfix position).
46
+ */
47
+ private parseLed;
48
+ /**
49
+ * Zero-width span for synthetic nodes (implicit counts, `d%` sides) that
50
+ * have no source text of their own — anchored at the governing token.
51
+ */
52
+ private static syntheticLiteral;
53
+ private parseLiteral;
54
+ private parseUnaryMinus;
55
+ private parsePrefixDice;
56
+ private parseInfixDice;
57
+ private parsePrefixDicePercent;
58
+ private parseInfixDicePercent;
59
+ private parsePrefixFateDice;
60
+ private parseInfixFateDice;
61
+ private parseGrouped;
62
+ private parseGroup;
63
+ private parseVariable;
64
+ private parseFunctionCall;
65
+ private parseBinaryOp;
66
+ /**
67
+ * Rejects a dice token whose count operand is itself a bare (unparenthesized)
68
+ * dice expression. `4d6d1` would otherwise silently parse as `(4d6)d1` —
69
+ * roll 4d6, then use the result as a count of d1 dice — which is almost
70
+ * never intended: every major dice dialect reads `4d6d1` as "drop lowest 1".
71
+ * Both meanings stay reachable through explicit forms: `4d6dl1` to drop,
72
+ * `(4d6)d1` for nested dice.
73
+ */
74
+ private rejectBareDiceChain;
75
+ private rejectSuccessCountTarget;
76
+ /**
77
+ * Rejects `GroupNode` (or a wrapper-cloaked group) as the target of `token`.
78
+ * Explode, reroll, and crit-threshold wrap bare dice pools only — a group
79
+ * is a container of sub-expressions, so these modifiers have no defined
80
+ * semantics. Walks `Grouped`/`Modifier`/`Sort`/`CritThreshold` so wrappers
81
+ * cannot smuggle a group past the check (`{1d6}kh1cs>5`, `({1d6})!`,
82
+ * `{1d6}scs>5` all reject the same as `{1d6}!`/`{1d6}cs>5`).
83
+ *
84
+ * `singleSubRollPasses` opts the caller into the Stage 3 single-sub-roll
85
+ * passthrough rule (STAGE3.md "Group Semantics: Single vs Multi Sub-Roll"):
86
+ * a `Group` with one expression is the user's explicit flat-pool escape
87
+ * hatch and is equivalent to its unwrapped form. Currently only
88
+ * `parseCritThreshold` opts in — explode/reroll keep the strict reject so
89
+ * existing notation contracts don't shift.
90
+ */
91
+ private rejectGroupTarget;
92
+ private rejectVersusTarget;
93
+ private parseModifier;
94
+ private parseExplode;
95
+ private parseReroll;
96
+ private parseSort;
97
+ private parseCritThreshold;
98
+ private parseSuccessCount;
99
+ private parseVersus;
100
+ /**
101
+ * Checks whether the next token is a comparison operator.
102
+ */
103
+ isComparePointAhead(): boolean;
104
+ /**
105
+ * Parses a comparison operator followed by a value expression.
106
+ * Called by modifier parsers (explode, reroll, success counting).
107
+ *
108
+ * The threshold value is parsed at `BP.DICE_LEFT`, which binds tighter than
109
+ * arithmetic. This keeps the comparison bound to the dice pool on the left
110
+ * rather than letting arithmetic to the right be consumed into the
111
+ * threshold. As a consequence, `1d6>=5+2` parses as `(1d6>=5)+2` with
112
+ * threshold `5` — not `7`. Computed thresholds require parens:
113
+ * `1d6>=(5+2)`. Same binding applies to `parseSuccessCount` below.
114
+ *
115
+ * @returns A ComparePoint with the operator and value AST node
116
+ * @throws {ParseError} If the next token is not a comparison operator
117
+ */
118
+ parseComparePoint(): ComparePoint;
119
+ private getCompareOp;
120
+ private getOperatorSymbol;
121
+ private getLeftBp;
122
+ private getRightBp;
123
+ private peek;
124
+ private advance;
125
+ private expect;
126
+ private hasTokens;
127
+ }
128
+ /**
129
+ * Parse a dice notation string into an AST.
130
+ *
131
+ * @param notation - The dice notation to parse
132
+ * @returns The root AST node
133
+ * @throws {LexerError} If the input contains invalid characters
134
+ * @throws {ParseError} If the input has invalid syntax
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const ast = parse('2d6+3');
139
+ * // { type: 'BinaryOp', operator: '+',
140
+ * // left: { type: 'Dice', count: 2, sides: 6 },
141
+ * // right: { type: 'Literal', value: 3 } }
142
+ * ```
143
+ */
144
+ export declare function parse(notation: string): ASTNode;
145
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/parser/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,KAAK,KAAK,EAAa,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EACV,OAAO,EAkBR,MAAM,UAAU,CAAC;AAYlB;;GAEG;AACH,qBAAa,UAAW,SAAQ,eAAe;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;gBAEtB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAMxF;AAwED;;;;;GAKG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,KAAK,CAAK;gBAEN,MAAM,EAAE,KAAK,EAAE;IAI3B;;OAEG;IACH,KAAK,IAAI,OAAO;IAqBhB;;OAEG;IACH,OAAO,CAAC,eAAe;IA8BvB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IA4ChB;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAgEhB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAI/B,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,qBAAqB;IAc7B,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,UAAU;IA4BlB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,iBAAiB;IA0DzB,OAAO,CAAC,aAAa;IAmBrB;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,wBAAwB;IAgBhC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,aAAa;IAqDrB,OAAO,CAAC,YAAY;IA+DpB,OAAO,CAAC,WAAW;IAyCnB,OAAO,CAAC,SAAS;IAgDjB,OAAO,CAAC,kBAAkB;IA+E1B,OAAO,CAAC,iBAAiB;IA8CzB,OAAO,CAAC,WAAW;IA6BnB;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAW9B;;;;;;;;;;;;;OAaG;IACH,iBAAiB,IAAI,YAAY;IAajC,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,SAAS;IA2DjB,OAAO,CAAC,UAAU;IAoBlB,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,MAAM;IAed,OAAO,CAAC,SAAS;CAGlB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAI/C"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * RNG module - Seedable random number generation.
3
+ *
4
+ * @module rng
5
+ */
6
+ export type { RNG } from './types.js';
7
+ export { SeededRNG } from './seeded.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rng/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Mock RNG for deterministic testing.
3
+ *
4
+ * @module rng/mock
5
+ */
6
+ import type { RNG } from './types.js';
7
+ /**
8
+ * Error thrown when MockRNG exhausts its predefined values.
9
+ *
10
+ * This is intentional behavior to catch incorrect roll counts in tests.
11
+ * If you see this error, your test is consuming more random values than expected.
12
+ */
13
+ export declare class MockRNGExhaustedError extends Error {
14
+ readonly consumed: number;
15
+ constructor(consumed: number);
16
+ }
17
+ /**
18
+ * Creates a mock RNG that returns predefined values in sequence.
19
+ *
20
+ * IMPORTANT: Throws MockRNGExhaustedError when all values are consumed.
21
+ * This behavior catches incorrect roll counts in tests - it never wraps around.
22
+ *
23
+ * @param values - Array of values to return (dice results for nextInt, floats for next)
24
+ * @returns RNG instance returning predefined values
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const rng = createMockRng([4, 2, 6]);
29
+ * rng.nextInt(1, 6); // Returns 4
30
+ * rng.nextInt(1, 6); // Returns 2
31
+ * rng.nextInt(1, 6); // Returns 6
32
+ * rng.nextInt(1, 6); // Throws MockRNGExhaustedError
33
+ * ```
34
+ */
35
+ export declare function createMockRng(values: number[]): RNG;
36
+ //# sourceMappingURL=mock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/rng/mock.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM;CAK7B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAsBnD"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Seedable RNG using xorshift128 algorithm.
3
+ *
4
+ * @module rng/seeded
5
+ */
6
+ import type { RNG } from './types.js';
7
+ /**
8
+ * Seedable pseudo-random number generator using xorshift128.
9
+ *
10
+ * Produces reproducible sequences from identical seeds.
11
+ * Period: 2^128 - 1
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Same seed = same sequence
16
+ * const rng1 = new SeededRNG('test-seed');
17
+ * const rng2 = new SeededRNG('test-seed');
18
+ * rng1.nextInt(1, 6) === rng2.nextInt(1, 6); // true
19
+ * ```
20
+ */
21
+ export declare class SeededRNG implements RNG {
22
+ private s0;
23
+ private s1;
24
+ private s2;
25
+ private s3;
26
+ constructor(seed?: string | number);
27
+ private initState;
28
+ private hashString;
29
+ private nextUint32;
30
+ next(): number;
31
+ nextInt(min: number, max: number): number;
32
+ /**
33
+ * Unbiased sampling in `[0, range)` for ranges above 2^32, built from two
34
+ * uint32 draws combined into a 53-bit integer (the largest width JS numbers
35
+ * represent exactly). Ranges beyond 2^53 cannot be sampled without bias —
36
+ * throw instead of silently degrading.
37
+ */
38
+ private nextBoundedWide;
39
+ }
40
+ //# sourceMappingURL=seeded.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seeded.d.ts","sourceRoot":"","sources":["../../src/rng/seeded.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC;;;;;;;;;;;;;GAaG;AACH,qBAAa,SAAU,YAAW,GAAG;IACnC,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,EAAE,CAAS;gBAEP,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAelC,OAAO,CAAC,SAAS;IA+BjB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,UAAU;IAgBlB,IAAI,IAAI,MAAM;IAKd,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IA6BzC;;;;;OAKG;IACH,OAAO,CAAC,eAAe;CAiBxB"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Random Number Generator interface.
3
+ *
4
+ * All dice rolling MUST use this interface - never use Math.random() directly.
5
+ *
6
+ * @module rng/types
7
+ */
8
+ /**
9
+ * Random Number Generator interface for dice rolling.
10
+ */
11
+ export type RNG = {
12
+ /**
13
+ * Returns a random floating-point number in the range [0, 1).
14
+ */
15
+ next(): number;
16
+ /**
17
+ * Returns a random integer in the inclusive range [min, max].
18
+ *
19
+ * @param min - Minimum value (inclusive)
20
+ * @param max - Maximum value (inclusive)
21
+ */
22
+ nextInt(min: number, max: number): number;
23
+ };
24
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rng/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,MAAM,GAAG,GAAG;IAChB;;OAEG;IACH,IAAI,IAAI,MAAM,CAAC;IAEf;;;;;OAKG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3C,CAAC"}
package/dist/roll.d.ts ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Main public API for rolling dice expressions.
3
+ *
4
+ * @module roll
5
+ */
6
+ import type { RNG } from './rng/types.js';
7
+ import type { RollResult } from './types.js';
8
+ /**
9
+ * Options for the roll function.
10
+ */
11
+ export type RollOptions = {
12
+ /** Custom RNG instance (takes precedence over seed) */
13
+ rng?: RNG;
14
+ /** Seed for deterministic rolls (ignored if rng provided) */
15
+ seed?: string | number;
16
+ /** Maximum total dice allowed per evaluation (default: 10,000) */
17
+ maxDice?: number;
18
+ /** Maximum explosion iterations allowed per die (default: 1,000) */
19
+ maxExplodeIterations?: number;
20
+ /** Maximum reroll iterations allowed per die (default: 1,000) */
21
+ maxRerollIterations?: number;
22
+ /** Variable context for `@name` / `@{name}` references (default: empty) */
23
+ context?: Record<string, number>;
24
+ /** Behavior when a referenced variable is missing from context (default: 'throw') */
25
+ onMissingVariable?: 'throw' | 'zero';
26
+ };
27
+ /**
28
+ * Parses and evaluates a dice notation string.
29
+ *
30
+ * @param notation - Dice notation (e.g., "2d6+3", "4d6kh3")
31
+ * @param options - Optional configuration (RNG or seed)
32
+ * @returns Complete roll result with total and metadata
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * // Random roll
37
+ * const result = roll('2d6+3');
38
+ * console.log(result.total); // 5-15
39
+ *
40
+ * // Seeded for reproducibility
41
+ * const r1 = roll('4d6', { seed: 'test' });
42
+ * const r2 = roll('4d6', { seed: 'test' });
43
+ * r1.total === r2.total; // true
44
+ *
45
+ * // Custom RNG for testing
46
+ * const result = roll('1d20', { rng: createMockRng([15]) });
47
+ * result.total; // 15
48
+ * ```
49
+ */
50
+ export declare function roll(notation: string, options?: RollOptions): RollResult;
51
+ //# sourceMappingURL=roll.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roll.d.ts","sourceRoot":"","sources":["../src/roll.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAmB,UAAU,EAAE,MAAM,YAAY,CAAC;AAM9D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,uDAAuD;IACvD,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACtC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,UAAU,CAiB5E"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Test utilities for roll-parser consumers.
3
+ *
4
+ * Import from `roll-parser/testing` for deterministic dice testing.
5
+ *
6
+ * @module testing
7
+ */
8
+ import { MockRNGExhaustedError as _MockRNGExhaustedError, createMockRng as _createMockRng } from './rng/mock.js';
9
+ export declare const createMockRng: typeof _createMockRng;
10
+ export declare const MockRNGExhaustedError: typeof _MockRNGExhaustedError;
11
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,qBAAqB,IAAI,sBAAsB,EAC/C,aAAa,IAAI,cAAc,EAChC,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,aAAa,uBAAiB,CAAC;AAC5C,eAAO,MAAM,qBAAqB,+BAAyB,CAAC"}
@@ -0,0 +1,41 @@
1
+ // src/rng/mock.ts
2
+ class MockRNGExhaustedError extends Error {
3
+ consumed;
4
+ constructor(consumed) {
5
+ super(`MockRNG exhausted: consumed ${consumed} values, no more available`);
6
+ this.name = "MockRNGExhaustedError";
7
+ this.consumed = consumed;
8
+ }
9
+ }
10
+ function createMockRng(values) {
11
+ let index = 0;
12
+ const getNext = () => {
13
+ const value = values[index];
14
+ if (value === undefined) {
15
+ throw new MockRNGExhaustedError(index);
16
+ }
17
+ index++;
18
+ return value;
19
+ };
20
+ return {
21
+ next: getNext,
22
+ nextInt: (min, max) => {
23
+ const value = getNext();
24
+ if (value < min || value > max) {
25
+ throw new RangeError(`MockRNG value ${value} is out of bounds [${min}, ${max}]`);
26
+ }
27
+ return value;
28
+ }
29
+ };
30
+ }
31
+
32
+ // src/testing.ts
33
+ var createMockRng2 = createMockRng;
34
+ var MockRNGExhaustedError2 = MockRNGExhaustedError;
35
+ export {
36
+ createMockRng2 as createMockRng,
37
+ MockRNGExhaustedError2 as MockRNGExhaustedError
38
+ };
39
+
40
+ //# debugId=916ECEA68894E64864756E2164756E21
41
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/rng/mock.ts", "../src/testing.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Mock RNG for deterministic testing.\n *\n * @module rng/mock\n */\n\nimport type { RNG } from './types.js';\n\n/**\n * Error thrown when MockRNG exhausts its predefined values.\n *\n * This is intentional behavior to catch incorrect roll counts in tests.\n * If you see this error, your test is consuming more random values than expected.\n */\nexport class MockRNGExhaustedError extends Error {\n readonly consumed: number;\n\n constructor(consumed: number) {\n super(`MockRNG exhausted: consumed ${consumed} values, no more available`);\n this.name = 'MockRNGExhaustedError';\n this.consumed = consumed;\n }\n}\n\n/**\n * Creates a mock RNG that returns predefined values in sequence.\n *\n * IMPORTANT: Throws MockRNGExhaustedError when all values are consumed.\n * This behavior catches incorrect roll counts in tests - it never wraps around.\n *\n * @param values - Array of values to return (dice results for nextInt, floats for next)\n * @returns RNG instance returning predefined values\n *\n * @example\n * ```typescript\n * const rng = createMockRng([4, 2, 6]);\n * rng.nextInt(1, 6); // Returns 4\n * rng.nextInt(1, 6); // Returns 2\n * rng.nextInt(1, 6); // Returns 6\n * rng.nextInt(1, 6); // Throws MockRNGExhaustedError\n * ```\n */\nexport function createMockRng(values: number[]): RNG {\n let index = 0;\n\n const getNext = (): number => {\n const value = values[index];\n if (value === undefined) {\n throw new MockRNGExhaustedError(index);\n }\n index++;\n return value;\n };\n\n return {\n next: getNext,\n nextInt: (min: number, max: number): number => {\n const value = getNext();\n if (value < min || value > max) {\n throw new RangeError(`MockRNG value ${value} is out of bounds [${min}, ${max}]`);\n }\n return value;\n },\n };\n}\n",
6
+ "/**\n * Test utilities for roll-parser consumers.\n *\n * Import from `roll-parser/testing` for deterministic dice testing.\n *\n * @module testing\n */\n\n// Direct value exports force the bundler to inline the code\nimport {\n MockRNGExhaustedError as _MockRNGExhaustedError,\n createMockRng as _createMockRng,\n} from './rng/mock.js';\n\nexport const createMockRng = _createMockRng;\nexport const MockRNGExhaustedError = _MockRNGExhaustedError;\n"
7
+ ],
8
+ "mappings": ";AAcO,MAAM,8BAA8B,MAAM;AAAA,EACtC;AAAA,EAET,WAAW,CAAC,UAAkB;AAAA,IAC5B,MAAM,+BAA+B,oCAAoC;AAAA,IACzE,KAAK,OAAO;AAAA,IACZ,KAAK,WAAW;AAAA;AAEpB;AAoBO,SAAS,aAAa,CAAC,QAAuB;AAAA,EACnD,IAAI,QAAQ;AAAA,EAEZ,MAAM,UAAU,MAAc;AAAA,IAC5B,MAAM,QAAQ,OAAO;AAAA,IACrB,IAAI,UAAU,WAAW;AAAA,MACvB,MAAM,IAAI,sBAAsB,KAAK;AAAA,IACvC;AAAA,IACA;AAAA,IACA,OAAO;AAAA;AAAA,EAGT,OAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,CAAC,KAAa,QAAwB;AAAA,MAC7C,MAAM,QAAQ,QAAQ;AAAA,MACtB,IAAI,QAAQ,OAAO,QAAQ,KAAK;AAAA,QAC9B,MAAM,IAAI,WAAW,iBAAiB,2BAA2B,QAAQ,MAAM;AAAA,MACjF;AAAA,MACA,OAAO;AAAA;AAAA,EAEX;AAAA;;;ACjDK,IAAM,iBAAgB;AACtB,IAAM,yBAAwB;",
9
+ "debugId": "916ECEA68894E64864756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Shared type definitions for roll results and comparison primitives.
3
+ *
4
+ * @module types
5
+ */
6
+ import type { ASTNode } from './parser/ast.js';
7
+ /**
8
+ * Comparison operator for compare points.
9
+ */
10
+ export type CompareOp = '>' | '>=' | '<' | '<=' | '=';
11
+ /**
12
+ * A comparison threshold used by exploding dice, reroll, and success counting.
13
+ *
14
+ * The value is an ASTNode to support computed thresholds (e.g., `>=ceil(5)`),
15
+ * matching the pattern used by DiceNode.count and DiceNode.sides.
16
+ */
17
+ export type ComparePoint = {
18
+ operator: CompareOp;
19
+ value: ASTNode;
20
+ };
21
+ /**
22
+ * A ComparePoint whose value has been evaluated to a number. Used in
23
+ * `RollPart` where meta-expressions are already resolved.
24
+ */
25
+ export type ResolvedComparePoint = {
26
+ operator: CompareOp;
27
+ value: number;
28
+ };
29
+ /**
30
+ * A resolved crit threshold — `'default'` means the per-die default rule
31
+ * (`result === sides` for critical, `result === 1` for fumble).
32
+ */
33
+ export type ResolvedCritThreshold = ResolvedComparePoint | 'default';
34
+ /**
35
+ * Modifier flags applied to individual die results.
36
+ */
37
+ export type DieModifier = 'dropped' | 'kept' | 'exploded' | 'rerolled' | 'success' | 'failure' | 'meta';
38
+ /**
39
+ * PF2e Degree of Success. Produced by the `vs` operator when comparing a
40
+ * roll against a Difficulty Class. Ordering is significant — natural 20
41
+ * upgrades one step and natural 1 downgrades one step.
42
+ */
43
+ export declare enum DegreeOfSuccess {
44
+ CriticalFailure = 0,
45
+ Failure = 1,
46
+ Success = 2,
47
+ CriticalSuccess = 3
48
+ }
49
+ /**
50
+ * Individual die roll result with metadata.
51
+ */
52
+ export type DieResult = {
53
+ /**
54
+ * Number of sides on the die. Normal dice use `sides >= 1`. Fate/Fudge
55
+ * dice use `sides = 0` as a sentinel — they have no configurable sides
56
+ * and always produce results in {-1, 0, +1}.
57
+ */
58
+ sides: number;
59
+ /** The rolled value */
60
+ result: number;
61
+ /**
62
+ * Raw first roll before any mutation (e.g., compound-explode accumulation).
63
+ * Only populated when `result` has been overwritten with a computed value.
64
+ * Consumers that need the original face (nat-20 / nat-1 detection) should
65
+ * read `initialResult ?? result`.
66
+ */
67
+ initialResult?: number;
68
+ /** Modifiers applied to this die */
69
+ modifiers: DieModifier[];
70
+ /** True if rolled the maximum value (always false for Fate dice) */
71
+ critical: boolean;
72
+ /** True if rolled 1 (always false for Fate dice) */
73
+ fumble: boolean;
74
+ };
75
+ /**
76
+ * Per-spec keep/drop entry inside a flattened modifier chain. Counts are
77
+ * resolved at evaluation time (meta-expressions like `kh(1d2)` become the
78
+ * rolled number).
79
+ */
80
+ export type ModifierSpec = {
81
+ kind: 'keep' | 'drop';
82
+ selector: 'highest' | 'lowest';
83
+ count: number;
84
+ };
85
+ /**
86
+ * Fields shared by every RollPart variant. `start`/`end` mirror the source
87
+ * span of the AST node the part was evaluated from — present whenever the
88
+ * AST came from `parse()`, absent on hand-built ASTs.
89
+ */
90
+ type RollPartBase = {
91
+ /** Sub-total this part contributed to its parent. */
92
+ total: number;
93
+ start?: number;
94
+ end?: number;
95
+ };
96
+ /**
97
+ * Structured breakdown of an evaluated expression, mirroring the AST 1:1 —
98
+ * every ASTNode produces exactly one RollPart. Discriminants are lowercase
99
+ * camelCase to distinguish evaluation-tree types from `ASTNode.type`
100
+ * (PascalCase) at a glance.
101
+ *
102
+ * Invariants:
103
+ * - `RollResult.parts.total === RollResult.total`.
104
+ * - `successCount.total === successes - failures`.
105
+ * - `literal.total === value` and `variable.total === value`.
106
+ * - Each part's `rolls[]` shares `DieResult` references with
107
+ * `RollResult.rolls[]`; both reflect post-evaluation state (explode
108
+ * accumulation, reroll flags, keep/drop flags). No deep clone.
109
+ *
110
+ * Meta-expression sub-trees (`4d6kh(1d2)`, `(1+1)d6` counts/sides, computed
111
+ * thresholds) are not surfaced as nested parts — their resolved numbers
112
+ * appear in the owning part, and their dice are inspectable in
113
+ * `RollResult.rolls` via the `'meta'` modifier tag.
114
+ */
115
+ export type RollPart = (RollPartBase & {
116
+ type: 'literal';
117
+ value: number;
118
+ }) | (RollPartBase & {
119
+ type: 'variable';
120
+ name: string;
121
+ value: number;
122
+ }) | (RollPartBase & {
123
+ type: 'dice';
124
+ count: number;
125
+ sides: number;
126
+ rolls: DieResult[];
127
+ }) | (RollPartBase & {
128
+ type: 'fateDice';
129
+ count: number;
130
+ rolls: DieResult[];
131
+ }) | (RollPartBase & {
132
+ type: 'grouped';
133
+ inner: RollPart;
134
+ }) | (RollPartBase & {
135
+ type: 'binaryOp';
136
+ operator: '+' | '-' | '*' | '/' | '%' | '**';
137
+ left: RollPart;
138
+ right: RollPart;
139
+ }) | (RollPartBase & {
140
+ type: 'unaryOp';
141
+ operator: '-';
142
+ operand: RollPart;
143
+ }) | (RollPartBase & {
144
+ type: 'modifier';
145
+ specs: ModifierSpec[];
146
+ target: RollPart;
147
+ }) | (RollPartBase & {
148
+ type: 'explode';
149
+ variant: 'standard' | 'compound' | 'penetrating';
150
+ threshold?: ResolvedComparePoint;
151
+ target: RollPart;
152
+ }) | (RollPartBase & {
153
+ type: 'reroll';
154
+ once: boolean;
155
+ condition: ResolvedComparePoint;
156
+ target: RollPart;
157
+ }) | (RollPartBase & {
158
+ type: 'successCount';
159
+ threshold: ResolvedComparePoint;
160
+ failThreshold?: ResolvedComparePoint;
161
+ target: RollPart;
162
+ successes: number;
163
+ failures: number;
164
+ }) | (RollPartBase & {
165
+ type: 'versus';
166
+ roll: RollPart;
167
+ dc: RollPart;
168
+ degree: DegreeOfSuccess;
169
+ }) | (RollPartBase & {
170
+ type: 'functionCall';
171
+ name: string;
172
+ args: RollPart[];
173
+ }) | (RollPartBase & {
174
+ type: 'group';
175
+ parts: RollPart[];
176
+ keptIndices?: number[];
177
+ }) | (RollPartBase & {
178
+ type: 'sort';
179
+ order: 'ascending' | 'descending';
180
+ target: RollPart;
181
+ }) | (RollPartBase & {
182
+ type: 'critThreshold';
183
+ successThresholds: ResolvedCritThreshold[];
184
+ failThresholds: ResolvedCritThreshold[];
185
+ target: RollPart;
186
+ });
187
+ /** Convenience alias for consumers writing exhaustive switches. */
188
+ export type RollPartType = RollPart['type'];
189
+ /**
190
+ * Complete roll result with all metadata.
191
+ */
192
+ export type RollResult = {
193
+ /** Final computed total */
194
+ total: number;
195
+ /** Original input notation */
196
+ notation: string;
197
+ /** Normalized expression */
198
+ expression: string;
199
+ /** Rendered result with individual rolls shown */
200
+ rendered: string;
201
+ /** All individual die results */
202
+ rolls: DieResult[];
203
+ /** Structured breakdown of the evaluated expression, mirroring the AST 1:1. */
204
+ parts: RollPart;
205
+ /**
206
+ * Number of dice tagged as success across the whole expression. Present
207
+ * only when a success-counting modifier was used. Independent of `total` —
208
+ * arithmetic on top of a success count (e.g. `5d6>=5 * 2`) affects `total`
209
+ * but not `successes`.
210
+ */
211
+ successes?: number;
212
+ /**
213
+ * Number of dice tagged as failure across the whole expression. Present
214
+ * only when a success-counting modifier with a fail threshold was used.
215
+ */
216
+ failures?: number;
217
+ /**
218
+ * PF2e Degree of Success. Present only when the expression used the `vs`
219
+ * operator at the top level (e.g. `1d20+10 vs 25`).
220
+ */
221
+ degree?: DegreeOfSuccess;
222
+ /**
223
+ * Natural d20 value used for PF2e upgrade/downgrade — present only when
224
+ * exactly one kept d20 was rolled on the roll side of a `vs` expression.
225
+ */
226
+ natural?: number;
227
+ };
228
+ /**
229
+ * Options for the evaluate function.
230
+ */
231
+ export type EvaluateOptions = {
232
+ /** Original notation string (for result metadata) */
233
+ notation?: string;
234
+ /** Maximum total dice allowed per evaluation (default: 10,000) */
235
+ maxDice?: number;
236
+ /** Maximum explosion iterations allowed per die (default: 1,000) */
237
+ maxExplodeIterations?: number;
238
+ /** Maximum reroll iterations allowed per die (default: 1,000) */
239
+ maxRerollIterations?: number;
240
+ /** Variable context for `@name` / `@{name}` references (default: empty) */
241
+ context?: Record<string, number>;
242
+ /** Behavior when a referenced variable is missing from context (default: 'throw') */
243
+ onMissingVariable?: 'throw' | 'zero';
244
+ };
245
+ export {};
246
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,oBAAoB,GAAG,SAAS,CAAC;AAErE;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,MAAM,GACN,UAAU,GACV,UAAU,GACV,SAAS,GACT,SAAS,GACT,MAAM,CAAC;AAEX;;;;GAIG;AACH,oBAAY,eAAe;IACzB,eAAe,IAAI;IACnB,OAAO,IAAI;IACX,OAAO,IAAI;IACX,eAAe,IAAI;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,oEAAoE;IACpE,QAAQ,EAAE,OAAO,CAAC;IAClB,oDAAoD;IACpD,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,QAAQ,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;GAIG;AACH,KAAK,YAAY,GAAG;IAClB,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,QAAQ,GAChB,CAAC,YAAY,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GACnD,CAAC,YAAY,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAClE,CAAC,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,CAAC,GACnF,CAAC,YAAY,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,CAAC,GACxE,CAAC,YAAY,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC,GACrD,CAAC,YAAY,GAAG;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;IAC7C,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,QAAQ,CAAC;CACjB,CAAC,GACF,CAAC,YAAY,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC,GACtE,CAAC,YAAY,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC,GAC9E,CAAC,YAAY,GAAG;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,UAAU,GAAG,UAAU,GAAG,aAAa,CAAC;IACjD,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,MAAM,EAAE,QAAQ,CAAC;CAClB,CAAC,GACF,CAAC,YAAY,GAAG;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,oBAAoB,CAAC;IAChC,MAAM,EAAE,QAAQ,CAAC;CAClB,CAAC,GACF,CAAC,YAAY,GAAG;IACd,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,oBAAoB,CAAC;IAChC,aAAa,CAAC,EAAE,oBAAoB,CAAC;IACrC,MAAM,EAAE,QAAQ,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,GACF,CAAC,YAAY,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,CAAC,GAC1F,CAAC,YAAY,GAAG;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,EAAE,CAAA;CAAE,CAAC,GACzE,CAAC,YAAY,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,GAC7E,CAAC,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC,GACtF,CAAC,YAAY,GAAG;IACd,IAAI,EAAE,eAAe,CAAC;IACtB,iBAAiB,EAAE,qBAAqB,EAAE,CAAC;IAC3C,cAAc,EAAE,qBAAqB,EAAE,CAAC;IACxC,MAAM,EAAE,QAAQ,CAAC;CAClB,CAAC,CAAC;AAEP,mEAAmE;AACnE,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;AAE5C;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,+EAA+E;IAC/E,KAAK,EAAE,QAAQ,CAAC;IAChB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACtC,CAAC"}