@rcrsr/rill-cli 0.6.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 (171) hide show
  1. package/LICENSE +21 -0
  2. package/dist/check/config.d.ts +20 -0
  3. package/dist/check/config.d.ts.map +1 -0
  4. package/dist/check/config.js +151 -0
  5. package/dist/check/config.js.map +1 -0
  6. package/dist/check/fixer.d.ts +39 -0
  7. package/dist/check/fixer.d.ts.map +1 -0
  8. package/dist/check/fixer.js +119 -0
  9. package/dist/check/fixer.js.map +1 -0
  10. package/dist/check/index.d.ts +10 -0
  11. package/dist/check/index.d.ts.map +1 -0
  12. package/dist/check/index.js +21 -0
  13. package/dist/check/index.js.map +1 -0
  14. package/dist/check/rules/anti-patterns.d.ts +65 -0
  15. package/dist/check/rules/anti-patterns.d.ts.map +1 -0
  16. package/dist/check/rules/anti-patterns.js +481 -0
  17. package/dist/check/rules/anti-patterns.js.map +1 -0
  18. package/dist/check/rules/closures.d.ts +66 -0
  19. package/dist/check/rules/closures.d.ts.map +1 -0
  20. package/dist/check/rules/closures.js +370 -0
  21. package/dist/check/rules/closures.js.map +1 -0
  22. package/dist/check/rules/collections.d.ts +90 -0
  23. package/dist/check/rules/collections.d.ts.map +1 -0
  24. package/dist/check/rules/collections.js +373 -0
  25. package/dist/check/rules/collections.js.map +1 -0
  26. package/dist/check/rules/conditionals.d.ts +41 -0
  27. package/dist/check/rules/conditionals.d.ts.map +1 -0
  28. package/dist/check/rules/conditionals.js +134 -0
  29. package/dist/check/rules/conditionals.js.map +1 -0
  30. package/dist/check/rules/flow.d.ts +46 -0
  31. package/dist/check/rules/flow.d.ts.map +1 -0
  32. package/dist/check/rules/flow.js +206 -0
  33. package/dist/check/rules/flow.js.map +1 -0
  34. package/dist/check/rules/formatting.d.ts +143 -0
  35. package/dist/check/rules/formatting.d.ts.map +1 -0
  36. package/dist/check/rules/formatting.js +656 -0
  37. package/dist/check/rules/formatting.js.map +1 -0
  38. package/dist/check/rules/helpers.d.ts +26 -0
  39. package/dist/check/rules/helpers.d.ts.map +1 -0
  40. package/dist/check/rules/helpers.js +66 -0
  41. package/dist/check/rules/helpers.js.map +1 -0
  42. package/dist/check/rules/index.d.ts +21 -0
  43. package/dist/check/rules/index.d.ts.map +1 -0
  44. package/dist/check/rules/index.js +78 -0
  45. package/dist/check/rules/index.js.map +1 -0
  46. package/dist/check/rules/loops.d.ts +77 -0
  47. package/dist/check/rules/loops.d.ts.map +1 -0
  48. package/dist/check/rules/loops.js +310 -0
  49. package/dist/check/rules/loops.js.map +1 -0
  50. package/dist/check/rules/naming.d.ts +21 -0
  51. package/dist/check/rules/naming.d.ts.map +1 -0
  52. package/dist/check/rules/naming.js +174 -0
  53. package/dist/check/rules/naming.js.map +1 -0
  54. package/dist/check/rules/strings.d.ts +28 -0
  55. package/dist/check/rules/strings.d.ts.map +1 -0
  56. package/dist/check/rules/strings.js +79 -0
  57. package/dist/check/rules/strings.js.map +1 -0
  58. package/dist/check/rules/types.d.ts +41 -0
  59. package/dist/check/rules/types.d.ts.map +1 -0
  60. package/dist/check/rules/types.js +167 -0
  61. package/dist/check/rules/types.js.map +1 -0
  62. package/dist/check/types.d.ts +112 -0
  63. package/dist/check/types.d.ts.map +1 -0
  64. package/dist/check/types.js +6 -0
  65. package/dist/check/types.js.map +1 -0
  66. package/dist/check/validator.d.ts +18 -0
  67. package/dist/check/validator.d.ts.map +1 -0
  68. package/dist/check/validator.js +110 -0
  69. package/dist/check/validator.js.map +1 -0
  70. package/dist/check/visitor.d.ts +33 -0
  71. package/dist/check/visitor.d.ts.map +1 -0
  72. package/dist/check/visitor.js +259 -0
  73. package/dist/check/visitor.js.map +1 -0
  74. package/dist/cli-check.d.ts +43 -0
  75. package/dist/cli-check.d.ts.map +1 -0
  76. package/dist/cli-check.js +366 -0
  77. package/dist/cli-check.js.map +1 -0
  78. package/dist/cli-error-enrichment.d.ts +73 -0
  79. package/dist/cli-error-enrichment.d.ts.map +1 -0
  80. package/dist/cli-error-enrichment.js +205 -0
  81. package/dist/cli-error-enrichment.js.map +1 -0
  82. package/dist/cli-error-formatter.d.ts +45 -0
  83. package/dist/cli-error-formatter.d.ts.map +1 -0
  84. package/dist/cli-error-formatter.js +218 -0
  85. package/dist/cli-error-formatter.js.map +1 -0
  86. package/dist/cli-eval.d.ts +15 -0
  87. package/dist/cli-eval.d.ts.map +1 -0
  88. package/dist/cli-eval.js +116 -0
  89. package/dist/cli-eval.js.map +1 -0
  90. package/dist/cli-exec.d.ts +58 -0
  91. package/dist/cli-exec.d.ts.map +1 -0
  92. package/dist/cli-exec.js +326 -0
  93. package/dist/cli-exec.js.map +1 -0
  94. package/dist/cli-explain.d.ts +24 -0
  95. package/dist/cli-explain.d.ts.map +1 -0
  96. package/dist/cli-explain.js +68 -0
  97. package/dist/cli-explain.js.map +1 -0
  98. package/dist/cli-lsp-diagnostic.d.ts +35 -0
  99. package/dist/cli-lsp-diagnostic.d.ts.map +1 -0
  100. package/dist/cli-lsp-diagnostic.js +98 -0
  101. package/dist/cli-lsp-diagnostic.js.map +1 -0
  102. package/dist/cli-module-loader.d.ts +19 -0
  103. package/dist/cli-module-loader.d.ts.map +1 -0
  104. package/dist/cli-module-loader.js +83 -0
  105. package/dist/cli-module-loader.js.map +1 -0
  106. package/dist/cli-shared.d.ts +62 -0
  107. package/dist/cli-shared.d.ts.map +1 -0
  108. package/dist/cli-shared.js +158 -0
  109. package/dist/cli-shared.js.map +1 -0
  110. package/dist/cli.d.ts +13 -0
  111. package/dist/cli.d.ts.map +1 -0
  112. package/dist/cli.js +62 -0
  113. package/dist/cli.js.map +1 -0
  114. package/dist/test-internal-import.d.ts +2 -0
  115. package/dist/test-internal-import.d.ts.map +1 -0
  116. package/dist/test-internal-import.js +7 -0
  117. package/dist/test-internal-import.js.map +1 -0
  118. package/package.json +24 -0
  119. package/src/check/config.ts +202 -0
  120. package/src/check/fixer.ts +174 -0
  121. package/src/check/index.ts +39 -0
  122. package/src/check/rules/anti-patterns.ts +585 -0
  123. package/src/check/rules/closures.ts +445 -0
  124. package/src/check/rules/collections.ts +437 -0
  125. package/src/check/rules/conditionals.ts +155 -0
  126. package/src/check/rules/flow.ts +262 -0
  127. package/src/check/rules/formatting.ts +811 -0
  128. package/src/check/rules/helpers.ts +89 -0
  129. package/src/check/rules/index.ts +140 -0
  130. package/src/check/rules/loops.ts +372 -0
  131. package/src/check/rules/naming.ts +242 -0
  132. package/src/check/rules/strings.ts +104 -0
  133. package/src/check/rules/types.ts +214 -0
  134. package/src/check/types.ts +163 -0
  135. package/src/check/validator.ts +136 -0
  136. package/src/check/visitor.ts +338 -0
  137. package/src/cli-check.ts +456 -0
  138. package/src/cli-error-enrichment.ts +274 -0
  139. package/src/cli-error-formatter.ts +313 -0
  140. package/src/cli-eval.ts +145 -0
  141. package/src/cli-exec.ts +408 -0
  142. package/src/cli-explain.ts +76 -0
  143. package/src/cli-lsp-diagnostic.ts +132 -0
  144. package/src/cli-module-loader.ts +101 -0
  145. package/src/cli-shared.ts +187 -0
  146. package/tests/check/cli-check.test.ts +189 -0
  147. package/tests/check/config.test.ts +350 -0
  148. package/tests/check/fixer.test.ts +373 -0
  149. package/tests/check/format-diagnostics.test.ts +327 -0
  150. package/tests/check/rules/anti-patterns.test.ts +467 -0
  151. package/tests/check/rules/closures.test.ts +192 -0
  152. package/tests/check/rules/collections.test.ts +380 -0
  153. package/tests/check/rules/conditionals.test.ts +185 -0
  154. package/tests/check/rules/flow.test.ts +250 -0
  155. package/tests/check/rules/formatting.test.ts +755 -0
  156. package/tests/check/rules/loops.test.ts +334 -0
  157. package/tests/check/rules/naming.test.ts +336 -0
  158. package/tests/check/rules/strings.test.ts +129 -0
  159. package/tests/check/rules/types.test.ts +257 -0
  160. package/tests/check/validator.test.ts +444 -0
  161. package/tests/check/visitor.test.ts +171 -0
  162. package/tests/cli/check.test.ts +801 -0
  163. package/tests/cli/error-enrichment.test.ts +510 -0
  164. package/tests/cli/error-formatter.test.ts +631 -0
  165. package/tests/cli/eval.test.ts +85 -0
  166. package/tests/cli/exec.test.ts +537 -0
  167. package/tests/cli-explain.test.ts +249 -0
  168. package/tests/cli-lsp-diagnostic.test.ts +202 -0
  169. package/tests/cli-shared.test.ts +439 -0
  170. package/tsconfig.json +9 -0
  171. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Flow and Capture Rules
3
+ * Enforces conventions for capture placement and flow patterns.
4
+ */
5
+ import { extractContextLine } from './helpers.js';
6
+ // ============================================================
7
+ // HELPER FUNCTIONS
8
+ // ============================================================
9
+ /**
10
+ * Check if a node is a capture node.
11
+ */
12
+ function isCaptureNode(node) {
13
+ return (typeof node === 'object' &&
14
+ node !== null &&
15
+ 'type' in node &&
16
+ node.type === 'Capture');
17
+ }
18
+ /**
19
+ * Check if a node contains a variable reference.
20
+ * For $ (pipe variable), checks for isPipeVar: true.
21
+ * For named variables, checks for the variable name.
22
+ * This is a simplified check - a full implementation would traverse the AST.
23
+ */
24
+ function referencesVariable(node, varName) {
25
+ if (!node)
26
+ return false;
27
+ // Convert node to string representation and check for variable usage
28
+ // This is a heuristic - proper implementation would need AST traversal
29
+ const nodeStr = JSON.stringify(node);
30
+ if (varName === '$') {
31
+ // Pipe variable has isPipeVar: true
32
+ return nodeStr.includes('"isPipeVar":true');
33
+ }
34
+ else {
35
+ // Named variable
36
+ return nodeStr.includes(`"name":"${varName}"`);
37
+ }
38
+ }
39
+ /**
40
+ * Get the primary expression from a PipeChain's head.
41
+ * ArithHead can be BinaryExprNode, UnaryExprNode, or PostfixExprNode.
42
+ */
43
+ function getPrimaryFromHead(chain) {
44
+ const head = chain.head;
45
+ // If head is PostfixExprNode, get its primary
46
+ if (head.type === 'PostfixExpr') {
47
+ return head.primary;
48
+ }
49
+ // For BinaryExprNode or UnaryExprNode, we can't easily get a single primary
50
+ return null;
51
+ }
52
+ // ============================================================
53
+ // CAPTURE_INLINE_CHAIN RULE
54
+ // ============================================================
55
+ /**
56
+ * Validates that captures use inline syntax when continuing the chain.
57
+ *
58
+ * Detects separate capture followed by variable usage:
59
+ * prompt("Read file") => $raw
60
+ * $raw -> log
61
+ *
62
+ * Suggests inline capture:
63
+ * prompt("Read file") => $raw -> log
64
+ *
65
+ * This is an informational rule - both patterns work, but inline is clearer.
66
+ *
67
+ * References:
68
+ * - docs/guide-conventions.md:56-74
69
+ */
70
+ export const CAPTURE_INLINE_CHAIN = {
71
+ code: 'CAPTURE_INLINE_CHAIN',
72
+ category: 'flow',
73
+ severity: 'info',
74
+ nodeTypes: ['Statement'],
75
+ validate(node, context) {
76
+ const statement = node;
77
+ const chain = statement.expression;
78
+ // Check if this chain ends with a capture
79
+ // Captures can be in terminator OR as the last pipe element
80
+ let captureNode = null;
81
+ if (chain.terminator && isCaptureNode(chain.terminator)) {
82
+ captureNode = chain.terminator;
83
+ }
84
+ else if (chain.pipes.length > 0) {
85
+ const lastPipe = chain.pipes[chain.pipes.length - 1];
86
+ if (lastPipe && isCaptureNode(lastPipe)) {
87
+ captureNode = lastPipe;
88
+ }
89
+ }
90
+ if (!captureNode) {
91
+ return [];
92
+ }
93
+ const capturedVarName = captureNode.name;
94
+ // Get all statements from the script
95
+ const statements = context.ast.statements;
96
+ const currentIndex = statements.indexOf(statement);
97
+ if (currentIndex === -1 || currentIndex === statements.length - 1) {
98
+ return [];
99
+ }
100
+ const nextStatement = statements[currentIndex + 1];
101
+ if (!nextStatement)
102
+ return [];
103
+ // Check if next statement is a Statement wrapping a PipeChain
104
+ if (nextStatement.type !== 'Statement') {
105
+ return [];
106
+ }
107
+ const nextStmt = nextStatement;
108
+ const nextChain = nextStmt.expression;
109
+ // Check if the head of the next chain is the captured variable
110
+ const headPrimary = getPrimaryFromHead(nextChain);
111
+ if (headPrimary &&
112
+ headPrimary.type === 'Variable' &&
113
+ 'name' in headPrimary &&
114
+ headPrimary.name === capturedVarName) {
115
+ // Found pattern: capture on one line, immediate usage on next line
116
+ return [
117
+ {
118
+ location: captureNode.span.start,
119
+ severity: 'info',
120
+ code: 'CAPTURE_INLINE_CHAIN',
121
+ message: `Consider inline capture: '=> $${capturedVarName} -> ...' instead of separate statements`,
122
+ context: extractContextLine(captureNode.span.start.line, context.source),
123
+ fix: null, // Complex fix - requires merging statements
124
+ },
125
+ ];
126
+ }
127
+ return [];
128
+ },
129
+ };
130
+ // ============================================================
131
+ // CAPTURE_BEFORE_BRANCH RULE
132
+ // ============================================================
133
+ /**
134
+ * Validates that values used in multiple branches are captured before the conditional.
135
+ *
136
+ * Detects conditionals where a function call or expression appears in multiple branches:
137
+ * checkStatus() -> .contains("OK") ? {
138
+ * "Success: {checkStatus()}"
139
+ * } ! {
140
+ * "Failed: {checkStatus()}"
141
+ * }
142
+ *
143
+ * Suggests capturing before branching:
144
+ * checkStatus() => $result
145
+ * $result -> .contains("OK") ? {
146
+ * "Success: {$result}"
147
+ * } ! {
148
+ * "Failed: {$result}"
149
+ * }
150
+ *
151
+ * This is an informational rule - detects potential inefficiency and clarity issues.
152
+ *
153
+ * References:
154
+ * - docs/guide-conventions.md:76-88
155
+ */
156
+ export const CAPTURE_BEFORE_BRANCH = {
157
+ code: 'CAPTURE_BEFORE_BRANCH',
158
+ category: 'flow',
159
+ severity: 'info',
160
+ nodeTypes: ['Conditional'],
161
+ validate(node, context) {
162
+ const conditional = node;
163
+ // Check if both branches exist
164
+ if (!conditional.elseBranch) {
165
+ return [];
166
+ }
167
+ // For piped conditionals (input is null), we can still suggest capturing
168
+ // For explicit conditionals, check if input is complex
169
+ const inputExpr = conditional.input;
170
+ // If input exists and is already a simple variable, no need to capture
171
+ if (inputExpr && inputExpr.type === 'PipeChain') {
172
+ const headPrimary = getPrimaryFromHead(inputExpr);
173
+ if (headPrimary &&
174
+ headPrimary.type === 'Variable' &&
175
+ inputExpr.pipes.length === 0 &&
176
+ !inputExpr.terminator) {
177
+ return [];
178
+ }
179
+ }
180
+ // Look for patterns where the input value might be used in both branches
181
+ // This is heuristic-based: we check if there's a $ reference in both branches
182
+ // which would be the piped value from the conditional input
183
+ const thenReferences = referencesVariable(conditional.thenBranch, '$');
184
+ // elseBranch can be BodyNode or ConditionalNode (for else-if chains)
185
+ const elseBranch = conditional.elseBranch;
186
+ const elseReferences = elseBranch && elseBranch.type !== 'Conditional'
187
+ ? referencesVariable(elseBranch, '$')
188
+ : false;
189
+ // If $ is used in both branches, suggest capturing the input value
190
+ // This makes it available in both branches with a clear name
191
+ if (thenReferences && elseReferences) {
192
+ return [
193
+ {
194
+ location: conditional.span.start,
195
+ severity: 'info',
196
+ code: 'CAPTURE_BEFORE_BRANCH',
197
+ message: 'Consider capturing value before conditional when used in multiple branches',
198
+ context: extractContextLine(conditional.span.start.line, context.source),
199
+ fix: null, // Complex fix - requires AST restructuring
200
+ },
201
+ ];
202
+ }
203
+ return [];
204
+ },
205
+ };
206
+ //# sourceMappingURL=flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.js","sourceRoot":"","sources":["../../../src/check/rules/flow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Formatting Rules
3
+ * Enforces style conventions from docs/guide-conventions.md:465-662.
4
+ */
5
+ import type { ValidationRule } from '../types.js';
6
+ import type { SourceSpan } from '@rcrsr/rill';
7
+ /**
8
+ * Enforces space on both sides of operators.
9
+ * Operators like +, -, ->, =>, ==, etc. should have spaces on both sides.
10
+ *
11
+ * Detection:
12
+ * - Extract operator text from source using source spans
13
+ * - Check if space exists before/after operator
14
+ *
15
+ * References:
16
+ * - docs/guide-conventions.md:467-482
17
+ */
18
+ export declare const SPACING_OPERATOR: ValidationRule;
19
+ /**
20
+ * Enforces space after { and before } in blocks.
21
+ * Braces for blocks, closures, etc. should have internal spacing.
22
+ *
23
+ * Detection:
24
+ * - Extract brace content from source
25
+ * - Check if opening { has space after, closing } has space before
26
+ *
27
+ * References:
28
+ * - docs/guide-conventions.md:497-508
29
+ */
30
+ export declare const SPACING_BRACES: ValidationRule;
31
+ /**
32
+ * Enforces no inner spaces for indexing brackets.
33
+ * Array/dict indexing should use $list[0] not $list[ 0 ].
34
+ *
35
+ * Detection:
36
+ * - PostfixExpr nodes with index access
37
+ * - Check for spaces inside brackets
38
+ *
39
+ * References:
40
+ * - docs/guide-conventions.md:526-535
41
+ */
42
+ export declare const SPACING_BRACKETS: ValidationRule;
43
+ /**
44
+ * Enforces no space before pipe, space after in closures.
45
+ * Closure parameters: |x| not | x |.
46
+ *
47
+ * Detection:
48
+ * - Extract closure parameter section from source
49
+ * - Check spacing around pipes
50
+ *
51
+ * References:
52
+ * - docs/guide-conventions.md:549-560
53
+ */
54
+ export declare const SPACING_CLOSURE: ValidationRule;
55
+ /**
56
+ * Enforces 2-space indent for continued lines.
57
+ * Pipe chains should indent continuation lines by 2 spaces.
58
+ *
59
+ * Detection:
60
+ * - Multi-line pipe chains
61
+ * - Check indentation of continuation lines
62
+ *
63
+ * References:
64
+ * - docs/guide-conventions.md:636-662
65
+ */
66
+ export declare const INDENT_CONTINUATION: ValidationRule;
67
+ /**
68
+ * Detect explicit $.method() patterns replaceable with .method.
69
+ *
70
+ * Flags method calls where the receiver is a bare $ (pipe variable).
71
+ * The implicit form .method is preferred when $ represents the current
72
+ * piped value (e.g., in blocks, closures, conditionals).
73
+ *
74
+ * Detection:
75
+ * - MethodCallNode with non-null receiverSpan
76
+ * - Receiver is bare $ (zero-width or single-char span)
77
+ * - Method call is first in chain (receiverSpan.end.offset <= 1)
78
+ *
79
+ * Note: Cannot use isBareReference() helper here because MethodCallNode.receiverSpan
80
+ * is a SourceSpan (position range), not an ExpressionNode. The helper requires
81
+ * an AST node to traverse. Instead, we detect bare $ by checking:
82
+ * 1. receiverSpan is zero-width (start == end) or single-char
83
+ * 2. Character at offset is '$'
84
+ * 3. Next character is '.' (not a variable name continuation)
85
+ *
86
+ * Examples:
87
+ * - $.upper() -> .upper
88
+ * - $.len -> .len
89
+ * - $.trim().upper() -> First method flagged, second is chained (not bare $)
90
+ *
91
+ * Not flagged:
92
+ * - .upper (receiverSpan is null)
93
+ * - $var.method() (receiverSpan is not bare $)
94
+ * - $.trim().upper() second method (receiverSpan covers $.trim())
95
+ *
96
+ * References:
97
+ * - docs/guide-conventions.md:587-598
98
+ */
99
+ export declare const IMPLICIT_DOLLAR_METHOD: ValidationRule;
100
+ /**
101
+ * Prefer foo over foo($) for global function calls.
102
+ * When single argument is bare $, prefer implicit form.
103
+ *
104
+ * Detection:
105
+ * - HostCall with single argument that is bare $
106
+ *
107
+ * References:
108
+ * - docs/guide-conventions.md:599-607
109
+ */
110
+ export declare const IMPLICIT_DOLLAR_FUNCTION: ValidationRule;
111
+ /**
112
+ * Prefer $fn over $fn($) for closure invocation.
113
+ * When single argument is bare $, prefer implicit form.
114
+ *
115
+ * Detection:
116
+ * - ClosureCall with single argument that is bare $
117
+ *
118
+ * References:
119
+ * - docs/guide-conventions.md:608-615
120
+ */
121
+ export declare const IMPLICIT_DOLLAR_CLOSURE: ValidationRule;
122
+ /**
123
+ * Warns on capture-only-to-continue patterns.
124
+ * Capturing a value just to use it immediately in the next line is unnecessary.
125
+ *
126
+ * Detection:
127
+ * - Capture node followed by immediate use of that variable only
128
+ * - Variable not referenced later in the script
129
+ *
130
+ * References:
131
+ * - docs/guide-conventions.md:617-634
132
+ */
133
+ export declare const THROWAWAY_CAPTURE: ValidationRule;
134
+ /**
135
+ * Validate that a SourceSpan has valid coordinates.
136
+ * Returns false if span, start, or end are missing,
137
+ * or if line/column values are less than 1.
138
+ *
139
+ * Exported for testing purposes to enable direct unit testing
140
+ * of edge cases (null spans, invalid coordinates).
141
+ */
142
+ export declare function isValidSpan(span: SourceSpan | null | undefined): boolean;
143
+ //# sourceMappingURL=formatting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../../src/check/rules/formatting.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,cAAc,EAKf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAMV,UAAU,EAOX,MAAM,aAAa,CAAC;AAOrB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,EAAE,cA0E9B,CAAC;AA6CF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,EAAE,cAkD5B,CAAC;AAMF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,EAAE,cA6G9B,CAAC;AAMF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,EAAE,cAgD7B,CAAC;AAMF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,EAAE,cAuDjC,CAAC;AAMF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,sBAAsB,EAAE,cA4DpC,CAAC;AAMF;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,EAAE,cA4CtC,CAAC;AAMF;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,EAAE,cAkDrC,CAAC;AAMF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,EAAE,cAW/B,CAAC;AAMF;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAgBxE"}